Enable better node-hierarchy metaprogramming; NFC.
authorJohn McCall <rjmccall@apple.com>
Tue, 10 Dec 2019 21:23:43 +0000 (16:23 -0500)
committerJohn McCall <rjmccall@apple.com>
Sat, 14 Dec 2019 05:16:47 +0000 (00:16 -0500)
clang/utils/TableGen/ASTTableGen.cpp
clang/utils/TableGen/ASTTableGen.h
clang/utils/TableGen/ClangTypeNodesEmitter.cpp

index c28d5ba..11e0e42 100644 (file)
@@ -61,13 +61,11 @@ std::string clang::tblgen::StmtNode::getId() const {
 }
 
 // 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);
@@ -76,10 +74,9 @@ static void visitASTNodeRecursive(NodeClass node, NodeClass base,
   }
 }
 
-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 ")
@@ -90,9 +87,9 @@ static void visitHierarchy(RecordKeeper &records,
   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)
@@ -105,26 +102,11 @@ static void visitHierarchy(RecordKeeper &records,
     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);
-}
index 46f0ee8..185f809 100644 (file)
@@ -110,6 +110,19 @@ public:
   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 {
@@ -119,6 +132,19 @@ public:
   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 {
@@ -128,6 +154,19 @@ public:
   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
@@ -136,18 +175,19 @@ template <class NodeClass>
 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
index ee12a6b..690042f 100644 (file)
@@ -137,7 +137,7 @@ void TypeNodeEmitter::emitFallbackDefine(StringRef macroName,
 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;