Index: lib/Format/Format.cpp =================================================================== --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -1386,6 +1386,7 @@ LangOpts.CPlusPlus = 1; LangOpts.CPlusPlus11 = Style.Standard == FormatStyle::LS_Cpp03 ? 0 : 1; LangOpts.CPlusPlus14 = Style.Standard == FormatStyle::LS_Cpp03 ? 0 : 1; + LangOpts.CUDA = Style.Language == FormatStyle::LK_Cpp ? 1 : 0; LangOpts.LineComment = 1; bool AlternativeOperators = Style.Language != FormatStyle::LK_JavaScript && Style.Language != FormatStyle::LK_Java; Index: lib/Format/TokenAnnotator.cpp =================================================================== --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -63,6 +63,20 @@ next(); return true; } + if (CurrentToken->is(tok::greatergreatergreater)) { + // Treat >>> as 3 tokens in this context + static int Count; + if (Count == 0) Count = 3; + + Left->MatchingParen = CurrentToken; + CurrentToken->MatchingParen = Left; + CurrentToken->Type = TT_TemplateCloser; + --Count; + + // Only increment parser if 3 calls have been made + if (Count == 0) next(); + return true; + } if (CurrentToken->is(tok::question) && Style.Language == FormatStyle::LK_Java) { next(); @@ -1792,6 +1806,18 @@ Left.isOneOf(TT_TemplateCloser, TT_TemplateOpener)); if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser))) return Style.SpacesInAngles; + // Treat parameters in between <<< and >>> similar to template parameters + if (Left.is(tok::lesslessless) && Right.isNot(tok::greatergreatergreater)) + return Style.SpacesInAngles; + if (Right.is(tok::greatergreatergreater)) + return Style.SpacesInAngles; + // No space needed between identifier or ">" and "<<<". + if ((Left.is(tok::identifier) || Left.is(tok::greater)) && + Right.is(tok::lesslessless)) + return false; + // No space needed between ">>>" and "(" + if (Left.is(tok::greatergreatergreater) && Right.is(tok::l_paren)) + return false; if ((Right.is(TT_BinaryOperator) && !Left.is(tok::l_paren)) || Left.isOneOf(TT_BinaryOperator, TT_ConditionalExpr)) return true; Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -9613,6 +9613,18 @@ verifyFormat("A>();", Spaces); } +TEST_F(FormatTest, TrippleAngleBraces) { + verifyFormat("f<<<1, 1>>>();"); + verifyFormat("f<<<1, 1, 1, s>>>();"); + verifyFormat("f<<>>();"); + EXPECT_EQ("f<<<1, 1>>>();", + format("f <<< 1, 1 >>> ();")); + verifyFormat("f<<<1, 1>>>();"); + verifyFormat("f<1><<<1, 1>>>();"); + EXPECT_EQ("f<<<1, 1>>>();", + format("f< param > <<< 1, 1 >>> ();")); +} + TEST_F(FormatTest, HandleUnbalancedImplicitBracesAcrossPPBranches) { std::string code = "#if A\n" "#if B\n"