diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp index f61c5ff39e1ceb..7357cab6f976e2 100644 --- a/clang/lib/Tooling/Syntax/BuildTree.cpp +++ b/clang/lib/Tooling/Syntax/BuildTree.cpp @@ -343,9 +343,13 @@ class BuildTreeVisitor : public RecursiveASTVisitor { } 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 4de353091cdca8..b54d06319e8354 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 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;