Skip to content

Commit 04f627f

Browse files
committed
[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.
1 parent 7b4badf commit 04f627f

File tree

2 files changed

+70
-21
lines changed

2 files changed

+70
-21
lines changed

clang/lib/Tooling/Syntax/BuildTree.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -343,9 +343,13 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
343343
}
344344

345345
bool WalkUpFromTagDecl(TagDecl *C) {
346-
// Avoid building UnknownDeclaration here, syntatically 'struct X {}' and
347-
// similar are part of declaration specifiers and do not introduce a new
348-
// top-level declaration.
346+
// FIXME: build the ClassSpecifier node.
347+
if (C->isFreeStanding()) {
348+
// Class is a declaration specifier and needs a spanning declaration node.
349+
Builder.foldNode(Builder.getRange(C),
350+
new (allocator()) syntax::SimpleDeclaration);
351+
return true;
352+
}
349353
return true;
350354
}
351355

clang/unittests/Tooling/Syntax/TreeTest.cpp

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,50 @@ namespace foo = a;
590590
|-=
591591
|-a
592592
`-;
593+
)txt"},
594+
// Free-standing classes, must live inside a SimpleDeclaration.
595+
{R"cpp(
596+
sturct X;
597+
struct X {};
598+
599+
struct Y *y1;
600+
struct Y {} *y2;
601+
602+
struct {} *a1;
603+
)cpp",
604+
R"txt(
605+
*: TranslationUnit
606+
|-SimpleDeclaration
607+
| |-sturct
608+
| |-X
609+
| `-;
610+
|-SimpleDeclaration
611+
| |-struct
612+
| |-X
613+
| |-{
614+
| |-}
615+
| `-;
616+
|-SimpleDeclaration
617+
| |-struct
618+
| |-Y
619+
| |-*
620+
| |-y1
621+
| `-;
622+
|-SimpleDeclaration
623+
| |-struct
624+
| |-Y
625+
| |-{
626+
| |-}
627+
| |-*
628+
| |-y2
629+
| `-;
630+
`-SimpleDeclaration
631+
|-struct
632+
|-{
633+
|-}
634+
|-*
635+
|-a1
636+
`-;
593637
)txt"},
594638
{R"cpp(
595639
namespace ns {}
@@ -646,24 +690,25 @@ template <class T> struct X {
646690
| |-class
647691
| `-T
648692
|->
649-
|-struct
650-
|-X
651-
|-{
652-
|-UsingDeclaration
653-
| |-using
654-
| |-T
655-
| |-::
656-
| |-foo
657-
| `-;
658-
|-UsingDeclaration
659-
| |-using
660-
| |-typename
661-
| |-T
662-
| |-::
663-
| |-bar
664-
| `-;
665-
|-}
666-
`-;
693+
`-SimpleDeclaration
694+
|-struct
695+
|-X
696+
|-{
697+
|-UsingDeclaration
698+
| |-using
699+
| |-T
700+
| |-::
701+
| |-foo
702+
| `-;
703+
|-UsingDeclaration
704+
| |-using
705+
| |-typename
706+
| |-T
707+
| |-::
708+
| |-bar
709+
| `-;
710+
|-}
711+
`-;
667712
)txt"},
668713
{R"cpp(
669714
using type = int;

0 commit comments

Comments
 (0)