diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Format/TokenAnnotator.cpp | 30 | ||||
-rw-r--r-- | clang/test/Index/overriding-ftemplate-comments.cpp | 4 | ||||
-rw-r--r-- | clang/unittests/Format/TokenAnnotatorTest.cpp | 17 |
3 files changed, 38 insertions, 13 deletions
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 55c5ece..89e1341 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -127,7 +127,7 @@ public: SmallVector<ScopeType> &Scopes) : Style(Style), Line(Line), CurrentToken(Line.First), AutoFound(false), IsCpp(Style.isCpp()), LangOpts(getFormattingLangOpts(Style)), - Keywords(Keywords), Scopes(Scopes) { + Keywords(Keywords), Scopes(Scopes), TemplateDeclarationDepth(0) { assert(IsCpp == LangOpts.CXXOperatorNames); Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false)); resetTokenMetadata(); @@ -1266,16 +1266,22 @@ private: } bool parseTemplateDeclaration() { - if (CurrentToken && CurrentToken->is(tok::less)) { - CurrentToken->setType(TT_TemplateOpener); - next(); - if (!parseAngle()) - return false; - if (CurrentToken) - CurrentToken->Previous->ClosesTemplateDeclaration = true; - return true; - } - return false; + if (!CurrentToken || CurrentToken->isNot(tok::less)) + return false; + + CurrentToken->setType(TT_TemplateOpener); + next(); + + TemplateDeclarationDepth++; + const bool WellFormed = parseAngle(); + TemplateDeclarationDepth--; + if (!WellFormed) + return false; + + if (CurrentToken && TemplateDeclarationDepth == 0) + CurrentToken->Previous->ClosesTemplateDeclaration = true; + + return true; } bool consumeToken() { @@ -3091,6 +3097,8 @@ private: // same decision irrespective of the decisions for tokens leading up to it. // Store this information to prevent this from causing exponential runtime. llvm::SmallPtrSet<FormatToken *, 16> NonTemplateLess; + + int TemplateDeclarationDepth; }; static const int PrecedenceUnaryOperator = prec::PointerToMember + 1; diff --git a/clang/test/Index/overriding-ftemplate-comments.cpp b/clang/test/Index/overriding-ftemplate-comments.cpp index 169d45f..370b4cb 100644 --- a/clang/test/Index/overriding-ftemplate-comments.cpp +++ b/clang/test/Index/overriding-ftemplate-comments.cpp @@ -77,10 +77,10 @@ void comment_to_html_conversion_21(); template <class C1, template <class C2, template <class C3, class C4> class BBB > class AAA> void comment_to_html_conversion_22(); -// CHECK: FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}overriding-ftemplate-comments.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_22</Name><USR>c:@FT@>2#T#t>2#T#t>2#T#Tcomment_to_html_conversion_22#v#</USR><Declaration>template <class C1, template <class C2, template <class C3, class C4> class BBB>\n class AAA>\nvoid comment_to_html_conversion_22()</Declaration><TemplateParameters><Parameter><Name>C1</Name><Index>0</Index><Discussion><Para> Ccc 1 </Para></Discussion></Parameter><Parameter><Name>AAA</Name><Index>1</Index><Discussion><Para> Zzz </Para></Discussion></Parameter><Parameter><Name>C2</Name><Discussion><Para> Ccc 2 </Para></Discussion></Parameter><Parameter><Name>C3</Name><Discussion><Para> Ccc 3 </Para></Discussion></Parameter><Parameter><Name>C4</Name><Discussion><Para> Ccc 4 </Para></Discussion></Parameter><Parameter><Name>BBB</Name><Discussion><Para> Bbb</Para></Discussion></Parameter></TemplateParameters></Function>] +// CHECK: FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}overriding-ftemplate-comments.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_22</Name><USR>c:@FT@>2#T#t>2#T#t>2#T#Tcomment_to_html_conversion_22#v#</USR><Declaration>template <\n class C1,\n template <class C2, template <class C3, class C4> class BBB> class AAA>\nvoid comment_to_html_conversion_22()</Declaration><TemplateParameters><Parameter><Name>C1</Name><Index>0</Index><Discussion><Para> Ccc 1 </Para></Discussion></Parameter><Parameter><Name>AAA</Name><Index>1</Index><Discussion><Para> Zzz </Para></Discussion></Parameter><Parameter><Name>C2</Name><Discussion><Para> Ccc 2 </Para></Discussion></Parameter><Parameter><Name>C3</Name><Discussion><Para> Ccc 3 </Para></Discussion></Parameter><Parameter><Name>C4</Name><Discussion><Para> Ccc 4 </Para></Discussion></Parameter><Parameter><Name>BBB</Name><Discussion><Para> Bbb</Para></Discussion></Parameter></TemplateParameters></Function>] template<class CCC1, template<class CCC2, template<class CCC3, class CCC4> class QQQ> class PPP> void comment_to_html_conversion_22(); -// CHECK: FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}overriding-ftemplate-comments.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_22</Name><USR>c:@FT@>2#T#t>2#T#t>2#T#Tcomment_to_html_conversion_22#v#</USR><Declaration>template <class CCC1,\n template <class CCC2, template <class CCC3, class CCC4> class QQQ>\n class PPP>\nvoid comment_to_html_conversion_22()</Declaration><TemplateParameters><Parameter><Name>CCC1</Name><Index>0</Index><Discussion><Para> Ccc 1 </Para></Discussion></Parameter><Parameter><Name>PPP</Name><Index>1</Index><Discussion><Para> Zzz </Para></Discussion></Parameter><Parameter><Name>CCC2</Name><Discussion><Para> Ccc 2 </Para></Discussion></Parameter><Parameter><Name>CCC3</Name><Discussion><Para> Ccc 3 </Para></Discussion></Parameter><Parameter><Name>CCC4</Name><Discussion><Para> Ccc 4 </Para></Discussion></Parameter><Parameter><Name>QQQ</Name><Discussion><Para> Bbb</Para></Discussion></Parameter></TemplateParameters></Function>] +// CHECK: FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}overriding-ftemplate-comments.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_22</Name><USR>c:@FT@>2#T#t>2#T#t>2#T#Tcomment_to_html_conversion_22#v#</USR><Declaration>template <class CCC1,\n template <class CCC2,\n template <class CCC3, class CCC4> class QQQ> class PPP>\nvoid comment_to_html_conversion_22()</Declaration><TemplateParameters><Parameter><Name>CCC1</Name><Index>0</Index><Discussion><Para> Ccc 1 </Para></Discussion></Parameter><Parameter><Name>PPP</Name><Index>1</Index><Discussion><Para> Zzz </Para></Discussion></Parameter><Parameter><Name>CCC2</Name><Discussion><Para> Ccc 2 </Para></Discussion></Parameter><Parameter><Name>CCC3</Name><Discussion><Para> Ccc 3 </Para></Discussion></Parameter><Parameter><Name>CCC4</Name><Discussion><Para> Ccc 4 </Para></Discussion></Parameter><Parameter><Name>QQQ</Name><Discussion><Para> Bbb</Para></Discussion></Parameter></TemplateParameters></Function>] diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 12c4b7f..d3b310f 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -584,6 +584,23 @@ TEST_F(TokenAnnotatorTest, UnderstandsNonTemplateAngleBrackets) { EXPECT_TOKEN(Tokens[20], tok::greater, TT_BinaryOperator); } +TEST_F(TokenAnnotatorTest, UnderstandsTemplateTemplateParameters) { + auto Tokens = annotate("template <template <typename...> typename X,\n" + " template <typename...> class Y,\n" + " typename... T>\n" + "class A {};"); + ASSERT_EQ(Tokens.size(), 28u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::less, TT_TemplateOpener); + EXPECT_TOKEN(Tokens[3], tok::less, TT_TemplateOpener); + EXPECT_TOKEN(Tokens[6], tok::greater, TT_TemplateCloser); + EXPECT_FALSE(Tokens[6]->ClosesTemplateDeclaration); + EXPECT_TOKEN(Tokens[11], tok::less, TT_TemplateOpener); + EXPECT_TOKEN(Tokens[14], tok::greater, TT_TemplateCloser); + EXPECT_FALSE(Tokens[14]->ClosesTemplateDeclaration); + EXPECT_TOKEN(Tokens[21], tok::greater, TT_TemplateCloser); + EXPECT_TRUE(Tokens[21]->ClosesTemplateDeclaration); +} + TEST_F(TokenAnnotatorTest, UnderstandsWhitespaceSensitiveMacros) { FormatStyle Style = getLLVMStyle(); Style.WhitespaceSensitiveMacros.push_back("FOO"); |