https://github.com/XDeme updated https://github.com/llvm/llvm-project/pull/77013
>From 45d01cbc7ec958518b1739daa9e9b0dc35c2d194 Mon Sep 17 00:00:00 2001 From: XDeme <fernando.tagawa.gamail....@gmail.com> Date: Thu, 4 Jan 2024 19:04:21 -0300 Subject: [PATCH 1/4] [clang-format] Handle templated elaborated type specifier in function return type. The behaviour now is consistent with the non templated version --- clang/lib/Format/UnwrappedLineParser.cpp | 8 ++++++++ clang/unittests/Format/FormatTest.cpp | 4 +--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 684609747a5513..aaff6319dd45ef 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -3914,7 +3914,15 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { // (this would still leave us with an ambiguity between template function // and class declarations). if (FormatTok->isOneOf(tok::colon, tok::less)) { + int AngleNestingLevel = 0; do { + if (FormatTok->is(tok::less)) + ++AngleNestingLevel; + else if (FormatTok->is(tok::greater)) + --AngleNestingLevel; + + if (AngleNestingLevel == 0 && FormatTok->is(tok::r_paren)) + break; if (FormatTok->is(tok::l_brace)) { calculateBraceTypes(/*ExpectClassBody=*/true); if (!tryToParseBracedList()) diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 762fc8254bdfc9..f304407d0ce2f4 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -14583,9 +14583,7 @@ TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) { verifyFormat("template <> struct X < 15, i<3 && 42 < 50 && 33 < 28> {};"); verifyFormat("int i = SomeFunction(a<b, a> b);"); - // FIXME: - // This now gets parsed incorrectly as class definition. - // verifyFormat("class A<int> f() {\n}\nint n;"); + verifyFormat("class A<int> f() {}\nint n;"); // Elaborate types where incorrectly parsing the structural element would // break the indent. >From 7a7d298c1e25940cc0607ba55eac5677b3b02f46 Mon Sep 17 00:00:00 2001 From: XDeme <fernando.tagawa.gamail....@gmail.com> Date: Thu, 4 Jan 2024 21:53:11 -0300 Subject: [PATCH 2/4] Fix edge case in template specialization --- clang/lib/Format/UnwrappedLineParser.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index aaff6319dd45ef..dc6ece09059b5d 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -3903,6 +3903,15 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { parseParens(); } + auto IsTemplate = [&] { + FormatToken *Tok = InitialToken.Previous; + while (Tok) { + if (Tok->is(tok::kw_template)) + return true; + Tok = Tok->Previous; + } + return false; + }; // Note that parsing away template declarations here leads to incorrectly // accepting function declarations as record declarations. // In general, we cannot solve this problem. Consider: @@ -3921,8 +3930,10 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { else if (FormatTok->is(tok::greater)) --AngleNestingLevel; - if (AngleNestingLevel == 0 && FormatTok->is(tok::r_paren)) + if (AngleNestingLevel == 0 && !IsTemplate() && + FormatTok->is(tok::r_paren)) { break; + } if (FormatTok->is(tok::l_brace)) { calculateBraceTypes(/*ExpectClassBody=*/true); if (!tryToParseBracedList()) >From 019992a0e227755015bc46e637d406fee911b9b5 Mon Sep 17 00:00:00 2001 From: XDeme <fernando.tagawa.gamail....@gmail.com> Date: Thu, 4 Jan 2024 22:13:15 -0300 Subject: [PATCH 3/4] Add test --- clang/unittests/Format/FormatTest.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index f304407d0ce2f4..6ac290b64ca450 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -14584,6 +14584,7 @@ TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) { verifyFormat("int i = SomeFunction(a<b, a> b);"); verifyFormat("class A<int> f() {}\nint n;"); + verifyFormat("template <> class Foo<int> F() {\n} n;"); // Elaborate types where incorrectly parsing the structural element would // break the indent. >From e41076ed7799dc7867d8bb9854298da396307090 Mon Sep 17 00:00:00 2001 From: XDeme <fernando.tagawa.gamail....@gmail.com> Date: Sat, 6 Jan 2024 19:54:57 -0300 Subject: [PATCH 4/4] Add test --- clang/unittests/Format/TokenAnnotatorTest.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 2cafc0438ffb46..396ed1c003e975 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -2453,6 +2453,13 @@ TEST_F(TokenAnnotatorTest, BraceKind) { EXPECT_BRACE_KIND(Tokens[4], BK_Block); EXPECT_BRACE_KIND(Tokens[5], BK_Block); + Tokens = annotate("class Foo<int> f() {}"); + ASSERT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[5], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_FunctionLBrace); + EXPECT_BRACE_KIND(Tokens[8], BK_Block); + EXPECT_BRACE_KIND(Tokens[9], BK_Block); + Tokens = annotate("void f() override {};"); ASSERT_EQ(Tokens.size(), 9u) << Tokens; EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits