diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -429,11 +429,18 @@ if (Tokens.size() < 3) return false; + auto First = Tokens.end() - 3; bool FourthTokenIsLess = false; - if (Tokens.size() > 3) - FourthTokenIsLess = (Tokens.end() - 4)[0]->is(tok::less); - auto First = Tokens.end() - 3; + if (Tokens.size() > 3) { + auto Fourth = (Tokens.end() - 4)[0]; + FourthTokenIsLess = Fourth->is(tok::less); + + // Do not remove a whitespace between the two "<" e.g. "operator< <>". + if (First[2]->is(tok::greater) && Fourth->is(tok::kw_operator)) + return false; + } + if (First[2]->is(tok::less) || First[1]->isNot(tok::less) || First[0]->isNot(tok::less) || FourthTokenIsLess) return false; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3346,6 +3346,9 @@ if (Right.is(tok::l_brace) && Right.is(BK_BracedInit) && !Left.opensScope() && Style.SpaceBeforeCpp11BracedList) return true; + if (Left.is(tok::less) && Left.is(TT_OverloadedOperator) && + Right.is(TT_TemplateOpener)) + return true; } else if (Style.Language == FormatStyle::LK_Proto || Style.Language == FormatStyle::LK_TextProto) { if (Right.is(tok::period) && diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -9463,6 +9463,10 @@ verifyFormat("operator SomeType();"); verifyFormat("operator SomeType();"); verifyFormat("operator SomeType>();"); + verifyFormat("operator< <>();"); + verifyFormat("operator<< <>();"); + verifyFormat("< <>"); + verifyFormat("void *operator new(std::size_t size);"); verifyFormat("void *operator new[](std::size_t size);"); verifyFormat("void operator delete(void *ptr);");