[clang-tools-extra] [clang-reorder-fields] Handle macros fields declarations. (PR #118005)

Clement Courbet via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 28 05:48:25 PST 2024


https://github.com/legrosbuffle created https://github.com/llvm/llvm-project/pull/118005

Right now field with macro declarations break the tool:

```

struct Foo {
  Mutex mu;
  int x GUARDED_BY(mu);
  int y;
};
```

reordered by mu,y,x yields:

```
struct Foo {
  Mutex mu;
  int y GUARDED_BY(mu);
  int x;
};
```

>From f466390102406b3cfbfc9cfa52f7ec5e28f64fed Mon Sep 17 00:00:00 2001
From: Clement Courbet <courbet at google.com>
Date: Thu, 28 Nov 2024 10:46:58 +0000
Subject: [PATCH] [clang-reorder-fields] Handle macros fields declarations.

Right now field with macro declarations break the tool:

```

struct Foo {
  Mutex mu;
  int x GUARDED_BY(mu);
  int y;
};
```

reordered by mu,y,x yields:

```
struct Foo {
  Mutex mu;
  int y GUARDED_BY(mu);
  int x;
};
```
---
 .../ReorderFieldsAction.cpp                   | 29 +++++++++++++++++--
 .../FieldAnnotationsInMacros.cpp              |  9 ++++++
 2 files changed, 35 insertions(+), 3 deletions(-)
 create mode 100644 clang-tools-extra/test/clang-reorder-fields/FieldAnnotationsInMacros.cpp

diff --git a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
index 346437e20322e6..dc3a3b6211b7e4 100644
--- a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
+++ b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
@@ -116,6 +116,28 @@ findMembersUsedInInitExpr(const CXXCtorInitializer *Initializer,
   return Results;
 }
 
+/// Returns the full source range for the field declaration up to (not
+/// including) the trailing semicolumn, including potential macro invocations,
+/// e.g. `int a GUARDED_BY(mu);`.
+static SourceRange getFullFieldSourceRange(const FieldDecl &Field,
+                                           const ASTContext &Context) {
+  SourceRange Range = Field.getSourceRange();
+  SourceLocation End = Range.getEnd();
+  const SourceManager &SM = Context.getSourceManager();
+  const LangOptions &LangOpts = Context.getLangOpts();
+  while (true) {
+    std::optional<Token> CurrentToken = Lexer::findNextToken(End, SM, LangOpts);
+
+    if (!CurrentToken || CurrentToken->is(tok::semi))
+      break;
+
+    if (CurrentToken->is(tok::eof))
+      return Range; // Something is wrong, return the original range.
+    End = CurrentToken->getLastLoc();
+  }
+  return SourceRange(Range.getBegin(), End);
+}
+
 /// Reorders fields in the definition of a struct/class.
 ///
 /// At the moment reordering of fields with
@@ -145,9 +167,10 @@ static bool reorderFieldsInDefinition(
     const auto FieldIndex = Field->getFieldIndex();
     if (FieldIndex == NewFieldsOrder[FieldIndex])
       continue;
-    addReplacement(Field->getSourceRange(),
-                   Fields[NewFieldsOrder[FieldIndex]]->getSourceRange(),
-                   Context, Replacements);
+    addReplacement(
+        getFullFieldSourceRange(*Field, Context),
+        getFullFieldSourceRange(*Fields[NewFieldsOrder[FieldIndex]], Context),
+        Context, Replacements);
   }
   return true;
 }
diff --git a/clang-tools-extra/test/clang-reorder-fields/FieldAnnotationsInMacros.cpp b/clang-tools-extra/test/clang-reorder-fields/FieldAnnotationsInMacros.cpp
new file mode 100644
index 00000000000000..aedec9556aa55a
--- /dev/null
+++ b/clang-tools-extra/test/clang-reorder-fields/FieldAnnotationsInMacros.cpp
@@ -0,0 +1,9 @@
+// RUN: clang-reorder-fields -record-name Foo -fields-order y,x %s -- | FileCheck %s
+
+#define GUARDED_BY(x) __attribute__((guarded_by(x)))
+
+class Foo {
+  int x GUARDED_BY(x); // CHECK: {{^  int y;}}
+  int y;               // CHECK-NEXT: {{^  int x GUARDED_BY\(x\);}}
+};
+



More information about the cfe-commits mailing list