[clang] 04f627f - [Syntax] Build spanning SimpleDecalration for classes, structs, etc

Ilya Biryukov via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 3 03:33:39 PST 2020


Author: Ilya Biryukov
Date: 2020-01-03T12:33:11+01:00
New Revision: 04f627f6b9aeda924a83e75d281ab27a546d3515

URL: https://github.com/llvm/llvm-project/commit/04f627f6b9aeda924a83e75d281ab27a546d3515
DIFF: https://github.com/llvm/llvm-project/commit/04f627f6b9aeda924a83e75d281ab27a546d3515.diff

LOG: [Syntax] Build spanning SimpleDecalration for classes, structs, etc

When they are free-standing, e.g. `struct X;` or `struct X {};`.
Although this complicates the common case (of free-standing class
declarations), this ensures the less common case (e.g. `struct X {} a;`)
are handled uniformly and produce similar syntax trees.

Added: 
    

Modified: 
    clang/lib/Tooling/Syntax/BuildTree.cpp
    clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp
index f61c5ff39e1c..7357cab6f976 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -343,9 +343,13 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
   }
 
   bool WalkUpFromTagDecl(TagDecl *C) {
-    // Avoid building UnknownDeclaration here, syntatically 'struct X {}' and
-    // similar are part of declaration specifiers and do not introduce a new
-    // top-level declaration.
+    // FIXME: build the ClassSpecifier node.
+    if (C->isFreeStanding()) {
+      // Class is a declaration specifier and needs a spanning declaration node.
+      Builder.foldNode(Builder.getRange(C),
+                       new (allocator()) syntax::SimpleDeclaration);
+      return true;
+    }
     return true;
   }
 

diff  --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp b/clang/unittests/Tooling/Syntax/TreeTest.cpp
index 4de353091cdc..b54d06319e83 100644
--- a/clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -590,6 +590,50 @@ namespace foo = a;
   |-=
   |-a
   `-;
+)txt"},
+      // Free-standing classes, must live inside a SimpleDeclaration.
+      {R"cpp(
+sturct X;
+struct X {};
+
+struct Y *y1;
+struct Y {} *y2;
+
+struct {} *a1;
+    )cpp",
+       R"txt(
+*: TranslationUnit
+|-SimpleDeclaration
+| |-sturct
+| |-X
+| `-;
+|-SimpleDeclaration
+| |-struct
+| |-X
+| |-{
+| |-}
+| `-;
+|-SimpleDeclaration
+| |-struct
+| |-Y
+| |-*
+| |-y1
+| `-;
+|-SimpleDeclaration
+| |-struct
+| |-Y
+| |-{
+| |-}
+| |-*
+| |-y2
+| `-;
+`-SimpleDeclaration
+  |-struct
+  |-{
+  |-}
+  |-*
+  |-a1
+  `-;
 )txt"},
       {R"cpp(
 namespace ns {}
@@ -646,24 +690,25 @@ template <class T> struct X {
   | |-class
   | `-T
   |->
-  |-struct
-  |-X
-  |-{
-  |-UsingDeclaration
-  | |-using
-  | |-T
-  | |-::
-  | |-foo
-  | `-;
-  |-UsingDeclaration
-  | |-using
-  | |-typename
-  | |-T
-  | |-::
-  | |-bar
-  | `-;
-  |-}
-  `-;
+  `-SimpleDeclaration
+    |-struct
+    |-X
+    |-{
+    |-UsingDeclaration
+    | |-using
+    | |-T
+    | |-::
+    | |-foo
+    | `-;
+    |-UsingDeclaration
+    | |-using
+    | |-typename
+    | |-T
+    | |-::
+    | |-bar
+    | `-;
+    |-}
+    `-;
        )txt"},
       {R"cpp(
 using type = int;


        


More information about the cfe-commits mailing list