Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang-format] Fix handling of C-Style variable definition of a struct #76344

Closed
wants to merge 0 commits into from

Conversation

XDeme1
Copy link
Contributor

@XDeme1 XDeme1 commented Dec 24, 2023

Fixes #71939

The problem was happening because we were parsing struct Foo f{}; as a struct definition, so { was being defined as TT_StructLBrace

This patch handles struct Foo f{} and struct Foo<int> f{} case.

@llvmbot
Copy link
Collaborator

llvmbot commented Dec 24, 2023

@llvm/pr-subscribers-clang-format

Author: None (XDeme)

Changes

Fixes llvm/llvm-project#71939

The problem was happening because we were treating struct Foo f{}; as a struct definition, so { was being treated as TT_StructLBrace


Full diff: https://github.com/llvm/llvm-project/pull/76344.diff

3 Files Affected:

  • (modified) clang/lib/Format/UnwrappedLineParser.cpp (+8)
  • (modified) clang/unittests/Format/FormatTest.cpp (+1)
  • (modified) clang/unittests/Format/TokenAnnotatorTest.cpp (+6)
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) {

@XDeme1 XDeme1 marked this pull request as draft December 29, 2023 21:39
@XDeme1 XDeme1 marked this pull request as ready for review December 30, 2023 02:12
@XDeme1 XDeme1 marked this pull request as draft January 1, 2024 13:12
@XDeme1 XDeme1 closed this Jan 20, 2024
@XDeme1 XDeme1 deleted the 71939 branch January 21, 2024 04:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Inconsistent formatting for declaration when using C-style "struct Foo"
2 participants