https://github.com/XDeme updated https://github.com/llvm/llvm-project/pull/76344
>From a55c720f344645bdad3838aaa39b136c8b8ee6dc Mon Sep 17 00:00:00 2001 From: XDeme <fernando.tagawa.gamail....@gmail.com> Date: Sun, 24 Dec 2023 20:18:02 -0300 Subject: [PATCH 1/3] [clang-format] Fix handling of C-Style variable definition of a struct --- clang/lib/Format/UnwrappedLineParser.cpp | 8 ++++++++ clang/unittests/Format/FormatTest.cpp | 1 + clang/unittests/Format/TokenAnnotatorTest.cpp | 6 ++++++ 3 files changed, 15 insertions(+) diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 684609747a5513..9cacb0d175adae 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -3873,6 +3873,7 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { const FormatToken &InitialToken = *FormatTok; nextToken(); + int NonMacroIdentifierCount = 0; // The actual identifier can be a nested name specifier, and in macros // it is often token-pasted. // An [[attribute]] can be before the identifier. @@ -3898,6 +3899,8 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { FormatTok->is(tok::identifier) && FormatTok->TokenText != FormatTok->TokenText.upper(); nextToken(); + if (IsNonMacroIdentifier) + ++NonMacroIdentifierCount; // We can have macros in between 'class' and the class name. if (!IsNonMacroIdentifier && FormatTok->is(tok::l_paren)) parseParens(); @@ -3960,6 +3963,11 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { } }; if (FormatTok->is(tok::l_brace)) { + // Handles C-Style variable declaration of a struct + if (Style.isCpp() && NonMacroIdentifierCount == 2) { + parseBracedList(); + return; + } auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken); FormatTok->setFinalizedType(OpenBraceType); if (ParseAsExpr) { diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 762fc8254bdfc9..d37d1f58b51a4a 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -14548,6 +14548,7 @@ TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) { verifyFormat("struct foo f() {}\nint n;"); verifyFormat("class foo f() {}\nint n;"); verifyFormat("union foo f() {}\nint n;"); + verifyFormat("struct MACRO foo f{};"); // Templates. verifyFormat("template <class X> void f() {}\nint n;"); diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 2cafc0438ffb46..568574bf73a872 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -503,6 +503,12 @@ TEST_F(TokenAnnotatorTest, UnderstandsVariables) { annotate("inline bool var = is_integral_v<int> && is_signed_v<int>;"); EXPECT_EQ(Tokens.size(), 15u) << Tokens; EXPECT_TOKEN(Tokens[8], tok::ampamp, TT_BinaryOperator); + + Tokens = annotate("struct Foo f{};"); + EXPECT_EQ(Tokens.size(), 7u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::identifier, TT_Unknown); + EXPECT_TOKEN(Tokens[2], tok::identifier, TT_StartOfName); + EXPECT_TOKEN(Tokens[3], tok::l_brace, TT_Unknown); } TEST_F(TokenAnnotatorTest, UnderstandsVariableTemplates) { >From 9e2e88495e86f040aeca2a0f0bc69bff3e6986e4 Mon Sep 17 00:00:00 2001 From: XDeme <fernando.tagawa.gamail....@gmail.com> Date: Tue, 26 Dec 2023 14:11:09 -0300 Subject: [PATCH 2/3] Added support for templated structs --- clang/lib/Format/UnwrappedLineParser.cpp | 13 +++++++++++++ clang/unittests/Format/FormatTest.cpp | 3 ++- clang/unittests/Format/TokenAnnotatorTest.cpp | 6 ++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 9cacb0d175adae..e79eefd530451b 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -3917,6 +3917,8 @@ 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; + bool ColonFound = false; do { if (FormatTok->is(tok::l_brace)) { calculateBraceTypes(/*ExpectClassBody=*/true); @@ -3944,6 +3946,17 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { parseCSharpGenericTypeConstraint(); break; } + // Do not count identifiers inside a template angle brackets + if(FormatTok->is(tok::colon)) + ColonFound = true; + if (FormatTok->is(tok::less)) + ++AngleNestingLevel; + else if (FormatTok->is(tok::greater)) + --AngleNestingLevel; + if (AngleNestingLevel == 0 && !ColonFound && FormatTok->is(tok::identifier) && + FormatTok->TokenText != FormatTok->TokenText.upper()) { + ++NonMacroIdentifierCount; + } nextToken(); } while (!eof()); } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index d37d1f58b51a4a..04505e25b00c03 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -14543,12 +14543,13 @@ TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) { verifyFormat("struct foo a = {bar};\nint n;"); verifyFormat("class foo a = {bar};\nint n;"); verifyFormat("union foo a = {bar};\nint n;"); + verifyFormat("struct MACRO foo f{};"); + verifyFormat("struct MACRO foo<int> f{};"); // Elaborate types inside function definitions. verifyFormat("struct foo f() {}\nint n;"); verifyFormat("class foo f() {}\nint n;"); verifyFormat("union foo f() {}\nint n;"); - verifyFormat("struct MACRO foo f{};"); // Templates. verifyFormat("template <class X> void f() {}\nint n;"); diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 568574bf73a872..a78d9a4df16025 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -509,6 +509,12 @@ TEST_F(TokenAnnotatorTest, UnderstandsVariables) { EXPECT_TOKEN(Tokens[1], tok::identifier, TT_Unknown); EXPECT_TOKEN(Tokens[2], tok::identifier, TT_StartOfName); EXPECT_TOKEN(Tokens[3], tok::l_brace, TT_Unknown); + + Tokens = annotate("struct Foo<int> f{};"); + EXPECT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::identifier, TT_Unknown); + EXPECT_TOKEN(Tokens[5], tok::identifier, TT_StartOfName); + EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_Unknown); } TEST_F(TokenAnnotatorTest, UnderstandsVariableTemplates) { >From f278882b71ddeca883c7d6fe75f704f540da0ee9 Mon Sep 17 00:00:00 2001 From: XDeme <fernando.tagawa.gamail....@gmail.com> Date: Tue, 26 Dec 2023 14:14:40 -0300 Subject: [PATCH 3/3] Format and a missing else --- clang/lib/Format/UnwrappedLineParser.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index e79eefd530451b..c706c9cbd8d9b0 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -3947,13 +3947,14 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { break; } // Do not count identifiers inside a template angle brackets - if(FormatTok->is(tok::colon)) + if (FormatTok->is(tok::colon)) ColonFound = true; - if (FormatTok->is(tok::less)) + else if (FormatTok->is(tok::less)) ++AngleNestingLevel; else if (FormatTok->is(tok::greater)) --AngleNestingLevel; - if (AngleNestingLevel == 0 && !ColonFound && FormatTok->is(tok::identifier) && + if (AngleNestingLevel == 0 && !ColonFound && + FormatTok->is(tok::identifier) && FormatTok->TokenText != FormatTok->TokenText.upper()) { ++NonMacroIdentifierCount; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits