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 @@ -86,9 +86,8 @@ TrailingReturnType, ParametersAndQualifiers, MemberPointer, - Operator, NestedNameSpecifier, - NameQualifier + NameSpecifier }; /// For debugging purposes. llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, NodeKind K); @@ -156,7 +155,8 @@ ParametersAndQualifiers_parameter, ParametersAndQualifiers_trailingReturn, IdExpression_unqualifiedId, - IdExpression_qualifier + IdExpression_qualifier, + NestedNameSpecifier_specifier }; /// For debugging purposes. llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, NodeRole R); @@ -183,11 +183,11 @@ } }; -class NameQualifier final : public Tree { +class NameSpecifier final : public Tree { public: - NameQualifier() : Tree(NodeKind::NameQualifier) {} + NameSpecifier() : Tree(NodeKind::NameSpecifier) {} static bool classof(const Node *N) { - return N->kind() == NodeKind::NameQualifier; + return N->kind() == NodeKind::NameSpecifier; } }; @@ -198,20 +198,15 @@ return N->kind() <= NodeKind::NestedNameSpecifier; } - std::vector specifiers(); -}; - -/// An expression of an unknown kind, i.e. one not currently handled by the -/// syntax tree. -class UnknownExpression final : public Expression { -public: - UnknownExpression() : Expression(NodeKind::UnknownExpression) {} - static bool classof(const Node *N) { - return N->kind() == NodeKind::UnknownExpression; - } + std::vector specifiers(); }; /// An identifier expression, e.g. `n::S::a`. Modeled according to the grammar +/// id-expression: +/// unqualified-id +/// qualified-id +/// qualified-id: +/// nested-name-specifier template_opt unqualified-id class IdExpression final : public Expression { public: IdExpression() : Expression(NodeKind::IdExpression) {} @@ -219,8 +214,18 @@ return N->kind() == NodeKind::IdExpression; } + syntax::NestedNameSpecifier *qualifier(); syntax::Leaf *unqualifiedId(); - syntax::Leaf *qualifier(); +}; + +/// An expression of an unknown kind, i.e. one not currently handled by the +/// syntax tree. +class UnknownExpression final : public Expression { +public: + UnknownExpression() : Expression(NodeKind::UnknownExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::UnknownExpression; + } }; /// C++11 'nullptr' 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 @@ -609,35 +609,28 @@ } syntax::NestedNameSpecifier * - BuildNestedNameSpecifier(NestedNameSpecifierLoc NNS) { - if (!NNS) + BuildNestedNameSpecifier(NestedNameSpecifierLoc QualifierLoc) { + if (!QualifierLoc) return nullptr; - NestedNameSpecifierLoc it = NNS; - while (it) { - auto *NS = new (allocator()) syntax::NameQualifier; + 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); - it = it.getPrefix(); + Builder.markChild(NS, syntax::NodeRole::NestedNameSpecifier_specifier); } - syntax::NestedNameSpecifier *sNNS = - new (allocator()) syntax::NestedNameSpecifier; - Builder.foldNode(Builder.getRange(NNS.getSourceRange()), sNNS, nullptr); - return sNNS; + auto *NNS = new (allocator()) syntax::NestedNameSpecifier; + Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()), NNS, + nullptr); + return NNS; } bool WalkUpFromDeclRefExpr(DeclRefExpr *S) { - if (S->getNameInfo().getName().getNameKind() == - clang::DeclarationName::CXXOperatorName) { - return true; - } else { - auto *sNNS = BuildNestedNameSpecifier(S->getQualifierLoc()); - if (sNNS) - Builder.markChild(sNNS, syntax::NodeRole::IdExpression_qualifier); - Builder.markChildToken(S->getLocation(), - syntax::NodeRole::IdExpression_unqualifiedId); - Builder.foldNode(Builder.getExprRange(S), - new (allocator()) syntax::IdExpression, 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; } 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 @@ -96,10 +96,8 @@ return OS << "ParametersAndQualifiers"; case NodeKind::MemberPointer: return OS << "MemberPointer"; - case NodeKind::Operator: - return OS << "Operator"; - case NodeKind::NameQualifier: - return OS << "NameQualifier"; + case NodeKind::NameSpecifier: + return OS << "NameSpecifier"; case NodeKind::NestedNameSpecifier: return OS << "NestedNameSpecifier"; } @@ -170,19 +168,23 @@ return OS << "IdExpression_unqualifiedId"; case syntax::NodeRole::IdExpression_qualifier: return OS << "IdExpression_qualifier"; + case syntax::NodeRole::NestedNameSpecifier_specifier: + return OS << "NestedNameSpecifier_specifier"; } llvm_unreachable("invalid role"); } -std::vector syntax::NestedNameSpecifier::specifiers() { - std::vector Children; +std::vector syntax::NestedNameSpecifier::specifiers() { + std::vector Children; for (auto *C = firstChild(); C; C = C->nextSibling()) { - Children.push_back(llvm::cast(C)); + if (C->role() == syntax::NodeRole::NestedNameSpecifier_specifier) + Children.push_back(llvm::cast(C)); } return Children; } -syntax::Leaf *syntax::IdExpression::qualifier() { - return llvm::cast_or_null( + +syntax::NestedNameSpecifier *syntax::IdExpression::qualifier() { + return llvm::cast_or_null( findChild(syntax::NodeRole::IdExpression_qualifier)); } 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 @@ -802,15 +802,15 @@ | |-UnknownExpression | | |-IdExpression | | | |-NestedNameSpecifier - | | | | |-NameQualifier + | | | | |-NameSpecifier | | | | | `-:: - | | | | |-NameQualifier + | | | | |-NameSpecifier | | | | | |-a | | | | | `-:: - | | | | |-NameQualifier + | | | | |-NameSpecifier | | | | | |-b | | | | | `-:: - | | | | `-NameQualifier + | | | | `-NameSpecifier | | | | |-S | | | | `-:: | | | `-f @@ -1546,7 +1546,8 @@ | |-BinaryOperatorExpression | | |-IdExpression | | | `-x - | | |-= + | | |-IdExpression + | | | `-= | | `-IdExpression | | `-y | `-; @@ -1555,7 +1556,8 @@ | | |-UnknownExpression | | | `-IdExpression | | | `-x - | | |-+ + | | |-IdExpression + | | | `-+ | | `-IdExpression | | `-y | `-; @@ -1563,7 +1565,8 @@ | |-BinaryOperatorExpression | | |-IdExpression | | | `-x - | | |-< + | | |-IdExpression + | | | `-< | | `-IdExpression | | `-y | `-;