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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits