diff --git a/clang/include/clang/Tooling/Syntax/Nodes.h b/clang/include/clang/Tooling/Syntax/Nodes.h --- a/clang/include/clang/Tooling/Syntax/Nodes.h +++ b/clang/include/clang/Tooling/Syntax/Nodes.h @@ -45,6 +45,7 @@ BinaryOperatorExpression, CxxNullPtrExpression, IntegerLiteralExpression, + IdExpression, // Statements. UnknownStatement, @@ -84,7 +85,9 @@ ArraySubscript, TrailingReturnType, ParametersAndQualifiers, - MemberPointer + MemberPointer, + NestedNameSpecifier, + NameSpecifier }; /// For debugging purposes. llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, NodeKind K); @@ -150,7 +153,9 @@ ArraySubscript_sizeExpression, TrailingReturnType_declarator, ParametersAndQualifiers_parameter, - ParametersAndQualifiers_trailingReturn + ParametersAndQualifiers_trailingReturn, + IdExpression_unqualifiedId, + IdExpression_qualifier }; /// For debugging purposes. llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, NodeRole R); @@ -177,6 +182,36 @@ } }; +class NameSpecifier final : public Tree { +public: + NameSpecifier() : Tree(NodeKind::NameSpecifier) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::NameSpecifier; + } +}; + +class NestedNameSpecifier final : public Tree { +public: + NestedNameSpecifier() : Tree(NodeKind::NestedNameSpecifier) {} + static bool classof(const Node *N) { + return N->kind() <= NodeKind::NestedNameSpecifier; + } + + std::vector specifiers(); +}; + +/// An identifier expression, e.g. `n::S::a`. Modeled according to the grammar +class IdExpression final : public Expression { +public: + IdExpression() : Expression(NodeKind::IdExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::IdExpression; + } + + syntax::Leaf *unqualifiedId(); + syntax::NestedNameSpecifier *qualifier(); +}; + /// An expression of an unknown kind, i.e. one not currently handled by the /// syntax tree. class UnknownExpression final : public Expression { diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp --- a/clang/lib/Tooling/Syntax/BuildTree.cpp +++ b/clang/lib/Tooling/Syntax/BuildTree.cpp @@ -608,6 +608,32 @@ return true; } + syntax::NestedNameSpecifier * + BuildNestedNameSpecifier(NestedNameSpecifierLoc QualifierLoc) { + if (!QualifierLoc) + return nullptr; + for (auto it = QualifierLoc; it; it = it.getPrefix()) { + auto *NS = new (allocator()) syntax::NameSpecifier; + Builder.foldNode(Builder.getRange(it.getLocalSourceRange()), NS, nullptr); + Builder.markChild(NS, syntax::NodeRole::Unknown); + } + auto *NNS = new (allocator()) syntax::NestedNameSpecifier; + Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()), NNS, + nullptr); + return NNS; + } + + bool WalkUpFromDeclRefExpr(DeclRefExpr *S) { + if (auto *NNS = BuildNestedNameSpecifier(S->getQualifierLoc())) + Builder.markChild(NNS, syntax::NodeRole::IdExpression_qualifier); + + Builder.markChildToken(S->getLocation(), + syntax::NodeRole::IdExpression_unqualifiedId); + Builder.foldNode(Builder.getExprRange(S), + new (allocator()) syntax::IdExpression, S); + return true; + } + bool WalkUpFromIntegerLiteral(IntegerLiteral *S) { Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken); Builder.foldNode(Builder.getExprRange(S), diff --git a/clang/lib/Tooling/Syntax/Nodes.cpp b/clang/lib/Tooling/Syntax/Nodes.cpp --- a/clang/lib/Tooling/Syntax/Nodes.cpp +++ b/clang/lib/Tooling/Syntax/Nodes.cpp @@ -28,6 +28,8 @@ return OS << "PostfixUnaryOperatorExpression"; case NodeKind::BinaryOperatorExpression: return OS << "BinaryOperatorExpression"; + case NodeKind::IdExpression: + return OS << "IdExpression"; case NodeKind::UnknownStatement: return OS << "UnknownStatement"; case NodeKind::DeclarationStatement: @@ -94,6 +96,10 @@ return OS << "ParametersAndQualifiers"; case NodeKind::MemberPointer: return OS << "MemberPointer"; + case NodeKind::NameSpecifier: + return OS << "NameSpecifier"; + case NodeKind::NestedNameSpecifier: + return OS << "NestedNameSpecifier"; } llvm_unreachable("unknown node kind"); } @@ -158,10 +164,32 @@ return OS << "ParametersAndQualifiers_parameter"; case syntax::NodeRole::ParametersAndQualifiers_trailingReturn: return OS << "ParametersAndQualifiers_trailingReturn"; + case syntax::NodeRole::IdExpression_unqualifiedId: + return OS << "IdExpression_unqualifiedId"; + case syntax::NodeRole::IdExpression_qualifier: + return OS << "IdExpression_qualifier"; } llvm_unreachable("invalid role"); } +std::vector syntax::NestedNameSpecifier::specifiers() { + std::vector Children; + for (auto *C = firstChild(); C; C = C->nextSibling()) { + Children.push_back(llvm::cast(C)); + } + return Children; +} + +syntax::NestedNameSpecifier *syntax::IdExpression::qualifier() { + return llvm::cast_or_null( + findChild(syntax::NodeRole::IdExpression_qualifier)); +} + +syntax::Leaf *syntax::IdExpression::unqualifiedId() { + return llvm::cast_or_null( + findChild(syntax::NodeRole::IdExpression_unqualifiedId)); +} + syntax::Leaf *syntax::IntegerLiteralExpression::literalToken() { return llvm::cast_or_null( findChild(syntax::NodeRole::LiteralToken)); diff --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp b/clang/unittests/Tooling/Syntax/TreeTest.cpp --- a/clang/unittests/Tooling/Syntax/TreeTest.cpp +++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp @@ -485,7 +485,7 @@ | | |-SimpleDeclarator | | | `-x | | `-: - | |-UnknownExpression + | |-IdExpression | | `-a | |-) | `-EmptyStatement @@ -662,7 +662,7 @@ |-{ |-ExpressionStatement | |-UnknownExpression - | | |-UnknownExpression + | | |-IdExpression | | | `-test | | |-( | | `-) @@ -675,7 +675,7 @@ | |-) | |-ExpressionStatement | | |-UnknownExpression - | | | |-UnknownExpression + | | | |-IdExpression | | | | `-test | | | |-( | | | `-) @@ -683,7 +683,7 @@ | |-else | `-ExpressionStatement | |-UnknownExpression - | | |-UnknownExpression + | | |-IdExpression | | | `-test | | |-( | | `-) @@ -724,12 +724,10 @@ |-ExpressionStatement | |-BinaryOperatorExpression | | |-IdExpression - | | | `-UnqualifiedId - | | | `-a + | | | `-a | | |-= | | `-IdExpression - | | `-UnqualifiedId - | | `-b + | | `-b | `-; `-} )txt")); @@ -800,38 +798,22 @@ | `-) `-CompoundStatement |-{ - |-DeclarationStatement - | |-SimpleDeclaration - | | |-a - | | |-:: - | | |-b - | | |-:: - | | |-S - | | `-SimpleDeclarator - | | `-UnknownExpression - | | `-s - | `-; |-ExpressionStatement | |-UnknownExpression | | |-IdExpression | | | |-NestedNameSpecifier - | | | | |-NameQualifier - | | | | | |-GlobalNamespace - | | | | | `:: - | | | | |-NameQualifier - | | | | | |-NamespaceName - | | | | | | `-a + | | | | |-NameSpecifier + | | | | | `-:: + | | | | |-NameSpecifier + | | | | | |-a | | | | | `-:: - | | | | |-NameQualifier - | | | | | |-NamespaceName - | | | | | | `-b + | | | | |-NameSpecifier + | | | | | |-b | | | | | `-:: - | | | | `-NameQualifier - | | | | |-TypeName - | | | | | `-S + | | | | `-NameSpecifier + | | | | |-S | | | | `-:: - | | | `-UnqualifiedId - | | | `-f + | | | `-f | | |-( | | `-) | `-; @@ -1036,13 +1018,13 @@ |-{ |-ExpressionStatement | |-PostfixUnaryOperatorExpression - | | |-UnknownExpression + | | |-IdExpression | | | `-a | | `-++ | `-; |-ExpressionStatement | |-PostfixUnaryOperatorExpression - | | |-UnknownExpression + | | |-IdExpression | | | `-a | | `--- | `-; @@ -1088,61 +1070,61 @@ |-ExpressionStatement | |-PrefixUnaryOperatorExpression | | |--- - | | `-UnknownExpression + | | `-IdExpression | | `-a | `-; |-ExpressionStatement | |-PrefixUnaryOperatorExpression | | |-++ - | | `-UnknownExpression + | | `-IdExpression | | `-a | `-; |-ExpressionStatement | |-PrefixUnaryOperatorExpression | | |-~ - | | `-UnknownExpression + | | `-IdExpression | | `-a | `-; |-ExpressionStatement | |-PrefixUnaryOperatorExpression | | |-- - | | `-UnknownExpression + | | `-IdExpression | | `-a | `-; |-ExpressionStatement | |-PrefixUnaryOperatorExpression | | |-+ - | | `-UnknownExpression + | | `-IdExpression | | `-a | `-; |-ExpressionStatement | |-PrefixUnaryOperatorExpression | | |-& - | | `-UnknownExpression + | | `-IdExpression | | `-a | `-; |-ExpressionStatement | |-PrefixUnaryOperatorExpression | | |-* - | | `-UnknownExpression + | | `-IdExpression | | `-ap | `-; |-ExpressionStatement | |-PrefixUnaryOperatorExpression | | |-! - | | `-UnknownExpression + | | `-IdExpression | | `-a | `-; |-ExpressionStatement | |-PrefixUnaryOperatorExpression | | |-__real - | | `-UnknownExpression + | | `-IdExpression | | `-a | `-; |-ExpressionStatement | |-PrefixUnaryOperatorExpression | | |-__imag - | | `-UnknownExpression + | | `-IdExpression | | `-a | `-; `-} @@ -1183,13 +1165,13 @@ |-ExpressionStatement | |-PrefixUnaryOperatorExpression | | |-compl - | | `-UnknownExpression + | | `-IdExpression | | `-a | `-; |-ExpressionStatement | |-PrefixUnaryOperatorExpression | | |-not - | | `-UnknownExpression + | | `-IdExpression | | `-b | `-; `-} @@ -1242,7 +1224,7 @@ | `-; |-ExpressionStatement | |-BinaryOperatorExpression - | | |-UnknownExpression + | | |-IdExpression | | | `-a | | |-= | | `-IntegerLiteralExpression @@ -1250,7 +1232,7 @@ | `-; |-ExpressionStatement | |-BinaryOperatorExpression - | | |-UnknownExpression + | | |-IdExpression | | | `-a | | |-<<= | | `-IntegerLiteralExpression @@ -1274,7 +1256,7 @@ | `-; |-ExpressionStatement | |-BinaryOperatorExpression - | | |-UnknownExpression + | | |-IdExpression | | | `-a | | |-^= | | `-IntegerLiteralExpression @@ -1338,7 +1320,7 @@ | `-; |-ExpressionStatement | |-BinaryOperatorExpression - | | |-UnknownExpression + | | |-IdExpression | | | `-a | | |-xor_eq | | `-IntegerLiteralExpression @@ -1404,10 +1386,10 @@ |-ExpressionStatement | |-BinaryOperatorExpression | | |-BinaryOperatorExpression - | | | |-UnknownExpression + | | | |-IdExpression | | | | `-a | | | |-+ - | | | `-UnknownExpression + | | | `-IdExpression | | | `-b | | |-+ | | `-IntegerLiteralExpression @@ -1415,11 +1397,11 @@ | `-; |-ExpressionStatement | |-BinaryOperatorExpression - | | |-UnknownExpression + | | |-IdExpression | | | `-a | | |-= | | `-BinaryOperatorExpression - | | |-UnknownExpression + | | |-IdExpression | | | `-b | | |-= | | `-IntegerLiteralExpression @@ -1428,11 +1410,11 @@ |-ExpressionStatement | |-BinaryOperatorExpression | | |-BinaryOperatorExpression - | | | |-UnknownExpression + | | | |-IdExpression | | | | `-a | | | |-+ | | | `-BinaryOperatorExpression - | | | |-UnknownExpression + | | | |-IdExpression | | | | `-b | | | |-* | | | `-IntegerLiteralExpression @@ -1444,14 +1426,14 @@ |-ExpressionStatement | |-BinaryOperatorExpression | | |-BinaryOperatorExpression - | | | |-UnknownExpression + | | | |-IdExpression | | | | `-a | | | |-% | | | `-IntegerLiteralExpression | | | `-2 | | |-+ | | `-BinaryOperatorExpression - | | |-UnknownExpression + | | |-IdExpression | | | `-b | | |-* | | `-IntegerLiteralExpression @@ -1562,30 +1544,30 @@ |-{ |-ExpressionStatement | |-BinaryOperatorExpression - | | |-UnknownExpression + | | |-IdExpression | | | `-x - | | |-UnknownExpression + | | |-IdExpression | | | `-= - | | `-UnknownExpression + | | `-IdExpression | | `-y | `-; |-ExpressionStatement | |-BinaryOperatorExpression | | |-UnknownExpression - | | | `-UnknownExpression + | | | `-IdExpression | | | `-x - | | |-UnknownExpression + | | |-IdExpression | | | `-+ - | | `-UnknownExpression + | | `-IdExpression | | `-y | `-; |-ExpressionStatement | |-BinaryOperatorExpression - | | |-UnknownExpression + | | |-IdExpression | | | `-x - | | |-UnknownExpression + | | |-IdExpression | | | `-< - | | `-UnknownExpression + | | `-IdExpression | | `-y | `-; `-}