}
// A map from a node to each of its child nodes.
-template <class NodeClass>
-using ChildMap = std::multimap<NodeClass, NodeClass>;
+using ChildMap = std::multimap<ASTNode, ASTNode>;
-template <class NodeClass>
-static void visitASTNodeRecursive(NodeClass node, NodeClass base,
- const ChildMap<NodeClass> &map,
- ASTNodeHierarchyVisitor<NodeClass> visit) {
+static void visitASTNodeRecursive(ASTNode node, ASTNode base,
+ const ChildMap &map,
+ ASTNodeHierarchyVisitor<ASTNode> visit) {
visit(node, base);
auto i = map.lower_bound(node), e = map.upper_bound(node);
}
}
-template <class NodeClass>
static void visitHierarchy(RecordKeeper &records,
StringRef nodeClassName,
- ASTNodeHierarchyVisitor<NodeClass> visit) {
+ ASTNodeHierarchyVisitor<ASTNode> visit) {
// Check for the node class, just as a sanity check.
if (!records.getClass(nodeClassName)) {
PrintFatalError(Twine("cannot find definition for node class ")
auto nodes = records.getAllDerivedDefinitions(nodeClassName);
// Derive the child map.
- ChildMap<NodeClass> hierarchy;
- NodeClass root;
- for (NodeClass node : nodes) {
+ ChildMap hierarchy;
+ ASTNode root;
+ for (ASTNode node : nodes) {
if (auto base = node.getBase())
hierarchy.insert(std::make_pair(base, node));
else if (root)
PrintFatalError(Twine("no root node in ") + nodeClassName + " hierarchy");
// Now visit the map recursively, starting at the root node.
- visitASTNodeRecursive(root, NodeClass(), hierarchy, visit);
+ visitASTNodeRecursive(root, ASTNode(), hierarchy, visit);
}
-void clang::tblgen::visitASTNodeHierarchy(RecordKeeper &records,
- StringRef nodeClassName,
+void clang::tblgen::visitASTNodeHierarchyImpl(RecordKeeper &records,
+ StringRef nodeClassName,
ASTNodeHierarchyVisitor<ASTNode> visit) {
visitHierarchy(records, nodeClassName, visit);
}
-
-void clang::tblgen::visitDeclNodeHierarchy(RecordKeeper &records,
- ASTNodeHierarchyVisitor<DeclNode> visit) {
- visitHierarchy(records, DeclNodeClassName, visit);
-}
-
-void clang::tblgen::visitTypeNodeHierarchy(RecordKeeper &records,
- ASTNodeHierarchyVisitor<TypeNode> visit) {
- visitHierarchy(records, TypeNodeClassName, visit);
-}
-
-void clang::tblgen::visitStmtNodeHierarchy(RecordKeeper &records,
- ASTNodeHierarchyVisitor<StmtNode> visit) {
- visitHierarchy(records, StmtNodeClassName, visit);
-}
llvm::StringRef getId() const;
std::string getClassName() const;
DeclNode getBase() const { return DeclNode(ASTNode::getBase().getRecord()); }
+
+ static llvm::StringRef getASTHierarchyName() {
+ return "Decl";
+ }
+ static llvm::StringRef getASTIdTypeName() {
+ return "Decl::Kind";
+ }
+ static llvm::StringRef getASTIdAccessorName() {
+ return "getKind";
+ }
+ static llvm::StringRef getTableGenNodeClassName() {
+ return DeclNodeClassName;
+ }
};
class TypeNode : public ASTNode {
llvm::StringRef getId() const;
llvm::StringRef getClassName() const;
TypeNode getBase() const { return TypeNode(ASTNode::getBase().getRecord()); }
+
+ static llvm::StringRef getASTHierarchyName() {
+ return "Type";
+ }
+ static llvm::StringRef getASTIdTypeName() {
+ return "Type::TypeClass";
+ }
+ static llvm::StringRef getASTIdAccessorName() {
+ return "getTypeClass";
+ }
+ static llvm::StringRef getTableGenNodeClassName() {
+ return TypeNodeClassName;
+ }
};
class StmtNode : public ASTNode {
std::string getId() const;
llvm::StringRef getClassName() const;
StmtNode getBase() const { return StmtNode(ASTNode::getBase().getRecord()); }
+
+ static llvm::StringRef getASTHierarchyName() {
+ return "Stmt";
+ }
+ static llvm::StringRef getASTIdTypeName() {
+ return "Stmt::StmtClass";
+ }
+ static llvm::StringRef getASTIdAccessorName() {
+ return "getStmtClass";
+ }
+ static llvm::StringRef getTableGenNodeClassName() {
+ return StmtNodeClassName;
+ }
};
/// A visitor for an AST node hierarchy. Note that `base` can be null for
using ASTNodeHierarchyVisitor =
llvm::function_ref<void(NodeClass node, NodeClass base)>;
-void visitASTNodeHierarchy(llvm::RecordKeeper &records,
- llvm::StringRef nodeClassName,
- ASTNodeHierarchyVisitor<ASTNode> visit);
-
-void visitDeclNodeHierarchy(llvm::RecordKeeper &records,
- ASTNodeHierarchyVisitor<DeclNode> visit);
-
-void visitTypeNodeHierarchy(llvm::RecordKeeper &records,
- ASTNodeHierarchyVisitor<TypeNode> visit);
+void visitASTNodeHierarchyImpl(llvm::RecordKeeper &records,
+ llvm::StringRef nodeClassName,
+ ASTNodeHierarchyVisitor<ASTNode> visit);
-void visitStmtNodeHierarchy(llvm::RecordKeeper &records,
- ASTNodeHierarchyVisitor<StmtNode> visit);
+template <class NodeClass>
+void visitASTNodeHierarchy(llvm::RecordKeeper &records,
+ ASTNodeHierarchyVisitor<NodeClass> visit) {
+ visitASTNodeHierarchyImpl(records, NodeClass::getTableGenNodeClassName(),
+ [visit](ASTNode node, ASTNode base) {
+ visit(NodeClass(node.getRecord()),
+ NodeClass(base.getRecord()));
+ });
+}
} // end namespace clang::tblgen
} // end namespace clang
void TypeNodeEmitter::emitNodeInvocations() {
TypeNode lastType;
- visitTypeNodeHierarchy(Records, [&](TypeNode type, TypeNode base) {
+ visitASTNodeHierarchy<TypeNode>(Records, [&](TypeNode type, TypeNode base) {
// If this is the Type node itself, skip it; it can't be handled
// uniformly by metaprograms because it doesn't have a base.
if (!base) return;