[clang] fdbd599 - [SyntaxTree] Implement `NestedNameSpecifier` using the `List` base API
Eduardo Caldas via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 10 06:53:32 PDT 2020
Author: Eduardo Caldas
Date: 2020-08-10T13:43:21Z
New Revision: fdbd5996533dad25f00687f27ce8e7a8b7573ba3
URL: https://github.com/llvm/llvm-project/commit/fdbd5996533dad25f00687f27ce8e7a8b7573ba3
DIFF: https://github.com/llvm/llvm-project/commit/fdbd5996533dad25f00687f27ce8e7a8b7573ba3.diff
LOG: [SyntaxTree] Implement `NestedNameSpecifier` using the `List` base API
Added:
Modified:
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/lib/Tooling/Syntax/Tree.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Tooling/Syntax/Nodes.h b/clang/include/clang/Tooling/Syntax/Nodes.h
index fc44076621d6..8e65fa1d8923 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -173,8 +173,6 @@ enum class NodeRole : uint8_t {
ParametersAndQualifiers_trailingReturn,
IdExpression_id,
IdExpression_qualifier,
- NestedNameSpecifier_specifier,
- NestedNameSpecifier_delimiter,
ParenExpression_subExpression
};
/// For debugging purposes.
@@ -262,14 +260,15 @@ class SimpleTemplateNameSpecifier final : public NameSpecifier {
/// Models a `nested-name-specifier`. C++ [expr.prim.id.qual]
/// e.g. the `std::vector<int>::` in `std::vector<int>::size`.
-class NestedNameSpecifier final : public Tree {
+class NestedNameSpecifier final : public List {
public:
- NestedNameSpecifier() : Tree(NodeKind::NestedNameSpecifier) {}
+ NestedNameSpecifier() : List(NodeKind::NestedNameSpecifier) {}
static bool classof(const Node *N) {
return N->kind() <= NodeKind::NestedNameSpecifier;
}
std::vector<NameSpecifier *> specifiers();
- std::vector<Leaf *> delimiters();
+ std::vector<List::ElementAndDelimiter<syntax::NameSpecifier>>
+ specifiersAndDoubleColons();
};
/// Models an `unqualified-id`. C++ [expr.prim.id.unqual]
diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 4e76b3825b6f..76b86ac6424d 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -809,9 +809,8 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
if (!isa<syntax::GlobalNameSpecifier>(NS))
Builder.foldNode(Builder.getRange(getLocalSourceRange(it)).drop_back(),
NS, it);
- Builder.markChild(NS, syntax::NodeRole::NestedNameSpecifier_specifier);
- Builder.markChildToken(it.getEndLoc(),
- syntax::NodeRole::NestedNameSpecifier_delimiter);
+ Builder.markChild(NS, syntax::NodeRole::List_element);
+ Builder.markChildToken(it.getEndLoc(), syntax::NodeRole::List_delimiter);
}
auto *NNS = new (allocator()) syntax::NestedNameSpecifier;
Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()), NNS,
diff --git a/clang/lib/Tooling/Syntax/Nodes.cpp b/clang/lib/Tooling/Syntax/Nodes.cpp
index 5e8deb668352..bf3c3108cb69 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -200,30 +200,32 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeRole R) {
return OS << "IdExpression_id";
case syntax::NodeRole::IdExpression_qualifier:
return OS << "IdExpression_qualifier";
- case syntax::NodeRole::NestedNameSpecifier_specifier:
- return OS << "NestedNameSpecifier_specifier";
- case syntax::NodeRole::NestedNameSpecifier_delimiter:
- return OS << "NestedNameSpecifier_delimiter";
case syntax::NodeRole::ParenExpression_subExpression:
return OS << "ParenExpression_subExpression";
}
llvm_unreachable("invalid role");
}
-std::vector<syntax::Leaf *> syntax::NestedNameSpecifier::delimiters() {
- std::vector<syntax::Leaf *> Children;
- for (auto *C = firstChild(); C; C = C->nextSibling()) {
- assert(C->role() == syntax::NodeRole::NestedNameSpecifier_delimiter);
- Children.push_back(llvm::cast<syntax::Leaf>(C));
+// We could have an interator in list to not pay memory costs of temporary
+// vector
+std::vector<syntax::NameSpecifier *> syntax::NestedNameSpecifier::specifiers() {
+ auto specifiersAsNodes = getElementsAsNodes();
+ std::vector<syntax::NameSpecifier *> Children;
+ for (const auto &element : specifiersAsNodes) {
+ Children.push_back(llvm::cast<syntax::NameSpecifier>(element));
}
return Children;
}
-std::vector<syntax::NameSpecifier *> syntax::NestedNameSpecifier::specifiers() {
- std::vector<syntax::NameSpecifier *> Children;
- for (auto *C = firstChild(); C; C = C->nextSibling()) {
- assert(C->role() == syntax::NodeRole::NestedNameSpecifier_specifier);
- Children.push_back(cast<syntax::NameSpecifier>(C));
+std::vector<syntax::List::ElementAndDelimiter<syntax::NameSpecifier>>
+syntax::NestedNameSpecifier::specifiersAndDoubleColons() {
+ auto specifiersAsNodesAndDoubleColons = getElementsAsNodesAndDelimiters();
+ std::vector<syntax::List::ElementAndDelimiter<syntax::NameSpecifier>>
+ Children;
+ for (const auto &specifierAndDoubleColon : specifiersAsNodesAndDoubleColons) {
+ Children.push_back(
+ {llvm::cast<syntax::NameSpecifier>(specifierAndDoubleColon.element),
+ specifierAndDoubleColon.delimiter});
}
return Children;
}
diff --git a/clang/lib/Tooling/Syntax/Tree.cpp b/clang/lib/Tooling/Syntax/Tree.cpp
index 6070d1603eb8..70e3c8e02783 100644
--- a/clang/lib/Tooling/Syntax/Tree.cpp
+++ b/clang/lib/Tooling/Syntax/Tree.cpp
@@ -357,21 +357,32 @@ std::vector<syntax::Node *> syntax::List::getElementsAsNodes() {
return children;
}
-// The methods below can't be implemented without information about the derived
-// list. These methods will be implemented by switching on the derived list's
-// `NodeKind`
-
clang::tok::TokenKind syntax::List::getDelimiterTokenKind() {
- llvm_unreachable("There are no subclasses of List, thus "
- "getDelimiterTokenKind() cannot be called");
+ switch (this->kind()) {
+ case NodeKind::NestedNameSpecifier:
+ return clang::tok::coloncolon;
+ default:
+ llvm_unreachable("This is not a subclass of List, thus "
+ "getDelimiterTokenKind() cannot be called");
+ }
}
syntax::List::TerminationKind syntax::List::getTerminationKind() {
- llvm_unreachable("There are no subclasses of List, thus getTerminationKind() "
- "cannot be called");
+ switch (this->kind()) {
+ case NodeKind::NestedNameSpecifier:
+ return TerminationKind::Terminated;
+ default:
+ llvm_unreachable("This is not a subclass of List, thus "
+ "getTerminationKind() cannot be called");
+ }
}
bool syntax::List::canBeEmpty() {
- llvm_unreachable(
- "There are no subclasses of List, thus canBeEmpty() cannot be called");
+ switch (this->kind()) {
+ case NodeKind::NestedNameSpecifier:
+ return false;
+ default:
+ llvm_unreachable("This is not a subclass of List, thus canBeEmpty() "
+ "cannot be called");
+ }
}
More information about the cfe-commits
mailing list