diff options
Diffstat (limited to 'clang/utils/TableGen/ASTTableGen.h')
| -rw-r--r-- | clang/utils/TableGen/ASTTableGen.h | 113 |
1 files changed, 110 insertions, 3 deletions
diff --git a/clang/utils/TableGen/ASTTableGen.h b/clang/utils/TableGen/ASTTableGen.h index ae85fc9c22b..3d623aa45b2 100644 --- a/clang/utils/TableGen/ASTTableGen.h +++ b/clang/utils/TableGen/ASTTableGen.h @@ -14,9 +14,9 @@ // These are spellings in the tblgen files. -// The field name for the base-node property. -// Fortunately, this is common across all the hierarchies. +// Field names that are fortunately common across the hierarchies. #define BaseFieldName "Base" +#define AbstractFieldName "Abstract" // Comment node hierarchy. #define CommentNodeClassName "CommentNode" @@ -34,6 +34,113 @@ #define NeverCanonicalClassName "NeverCanonical" #define NeverCanonicalUnlessDependentClassName "NeverCanonicalUnlessDependent" #define LeafTypeClassName "LeafType" -#define AbstractFieldName "Abstract" + +// Property node hierarchy. +#define PropertyClassName "Property" +#define ClassFieldName "Class" + +namespace clang { +namespace tblgen { + +/// An (optional) reference to a TableGen node representing a class +/// in one of Clang's AST hierarchies. +class ASTNode { + llvm::Record *Record; +public: + ASTNode(llvm::Record *record = nullptr) : Record(record) {} + + explicit operator bool() const { return Record != nullptr; } + + llvm::Record *getRecord() const { return Record; } + llvm::StringRef getName() const { + assert(Record && "getting name of null record"); + return Record->getName(); + } + llvm::ArrayRef<llvm::SMLoc> getLoc() const { + assert(Record && "getting location of null record"); + return Record->getLoc(); + } + + /// Return the node for the base, if there is one. + ASTNode getBase() const { + assert(Record && "getting base of null record"); + return Record->getValueAsOptionalDef(BaseFieldName); + } + + /// Is the corresponding class abstract? + bool isAbstract() const { + assert(Record && "querying null record"); + return Record->getValueAsBit(AbstractFieldName); + } + + /// Does the node inherit from the given TableGen class? + bool isSubClassOf(llvm::StringRef className) const { + assert(Record && "querying null record"); + return Record->isSubClassOf(className); + } + + friend bool operator<(ASTNode lhs, ASTNode rhs) { + assert(lhs && rhs && "sorting null nodes"); + return lhs.getName() < rhs.getName(); + } + friend bool operator>(ASTNode lhs, ASTNode rhs) { return rhs < lhs; } + friend bool operator<=(ASTNode lhs, ASTNode rhs) { return !(rhs < lhs); } + friend bool operator>=(ASTNode lhs, ASTNode rhs) { return !(lhs < rhs); } + + friend bool operator==(ASTNode lhs, ASTNode rhs) { + // This should handle null nodes. + return lhs.getRecord() == rhs.getRecord(); + } + friend bool operator!=(ASTNode lhs, ASTNode rhs) { return !(lhs == rhs); } +}; + +class DeclNode : public ASTNode { +public: + DeclNode(llvm::Record *record = nullptr) : ASTNode(record) {} + + llvm::StringRef getId() const; + std::string getClassName() const; + DeclNode getBase() const { return DeclNode(ASTNode::getBase().getRecord()); } +}; + +class TypeNode : public ASTNode { +public: + TypeNode(llvm::Record *record = nullptr) : ASTNode(record) {} + + llvm::StringRef getId() const; + llvm::StringRef getClassName() const; + TypeNode getBase() const { return TypeNode(ASTNode::getBase().getRecord()); } +}; + +class StmtNode : public ASTNode { +public: + StmtNode(llvm::Record *record = nullptr) : ASTNode(record) {} + + std::string getId() const; + llvm::StringRef getClassName() const; + StmtNode getBase() const { return StmtNode(ASTNode::getBase().getRecord()); } +}; + +/// A visitor for an AST node hierarchy. Note that `base` can be null for +/// the root class. +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 visitStmtNodeHierarchy(llvm::RecordKeeper &records, + ASTNodeHierarchyVisitor<StmtNode> visit); + +} // end namespace clang::tblgen +} // end namespace clang #endif |

