[clang] baf91d0 - [NFC] Add a tablegen node for the root of the AST node hierarchies.

John McCall via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 25 16:39:34 PDT 2019


Author: John McCall
Date: 2019-10-25T16:39:21-07:00
New Revision: baf91d02da6e68c4ee6723ef68911fcd80ece6a5

URL: https://github.com/llvm/llvm-project/commit/baf91d02da6e68c4ee6723ef68911fcd80ece6a5
DIFF: https://github.com/llvm/llvm-project/commit/baf91d02da6e68c4ee6723ef68911fcd80ece6a5.diff

LOG: [NFC] Add a tablegen node for the root of the AST node hierarchies.

This is useful for the property databases we want to add for abstract
serialization, since root classes can have interesting properties.

Added: 
    clang/utils/TableGen/ClangASTEmitters.h

Modified: 
    clang/include/clang/Basic/CommentNodes.td
    clang/include/clang/Basic/DeclNodes.td
    clang/include/clang/Basic/StmtNodes.td
    clang/include/clang/Basic/TypeNodes.td
    clang/utils/TableGen/ClangASTNodesEmitter.cpp
    clang/utils/TableGen/ClangAttrEmitter.cpp
    clang/utils/TableGen/ClangTypeNodesEmitter.cpp
    clang/utils/TableGen/TableGen.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/CommentNodes.td b/clang/include/clang/Basic/CommentNodes.td
index 7bf32b78b5b6..e58ff4c98bd5 100644
--- a/clang/include/clang/Basic/CommentNodes.td
+++ b/clang/include/clang/Basic/CommentNodes.td
@@ -1,27 +1,25 @@
-class Comment<bit abstract = 0> {
+class CommentNode<CommentNode base, bit abstract = 0> {
+  CommentNode Base = base;
   bit Abstract = abstract;
 }
 
-class DComment<Comment base, bit abstract = 0> : Comment<abstract> {
-  Comment Base = base;
-}
-
-def InlineContentComment : Comment<1>;
-  def TextComment : DComment<InlineContentComment>;
-  def InlineCommandComment : DComment<InlineContentComment>;
-  def HTMLTagComment : DComment<InlineContentComment, 1>;
-    def HTMLStartTagComment : DComment<HTMLTagComment>;
-    def HTMLEndTagComment : DComment<HTMLTagComment>;
+def Comment : CommentNode<?, 1>;
+def InlineContentComment : CommentNode<Comment, 1>;
+  def TextComment : CommentNode<InlineContentComment>;
+  def InlineCommandComment : CommentNode<InlineContentComment>;
+  def HTMLTagComment : CommentNode<InlineContentComment, 1>;
+    def HTMLStartTagComment : CommentNode<HTMLTagComment>;
+    def HTMLEndTagComment : CommentNode<HTMLTagComment>;
 
-def BlockContentComment : Comment<1>;
-  def ParagraphComment : DComment<BlockContentComment>;
-  def BlockCommandComment : DComment<BlockContentComment>;
-    def ParamCommandComment : DComment<BlockCommandComment>;
-    def TParamCommandComment : DComment<BlockCommandComment>;
-    def VerbatimBlockComment : DComment<BlockCommandComment>;
-    def VerbatimLineComment : DComment<BlockCommandComment>;
+def BlockContentComment : CommentNode<Comment, 1>;
+  def ParagraphComment : CommentNode<BlockContentComment>;
+  def BlockCommandComment : CommentNode<BlockContentComment>;
+    def ParamCommandComment : CommentNode<BlockCommandComment>;
+    def TParamCommandComment : CommentNode<BlockCommandComment>;
+    def VerbatimBlockComment : CommentNode<BlockCommandComment>;
+    def VerbatimLineComment : CommentNode<BlockCommandComment>;
 
-def VerbatimBlockLineComment : Comment;
+def VerbatimBlockLineComment : CommentNode<Comment>;
 
-def FullComment : Comment;
+def FullComment : CommentNode<Comment>;
 

diff  --git a/clang/include/clang/Basic/DeclNodes.td b/clang/include/clang/Basic/DeclNodes.td
index 2d3fa6b6147f..fa4d1b4f47e7 100644
--- a/clang/include/clang/Basic/DeclNodes.td
+++ b/clang/include/clang/Basic/DeclNodes.td
@@ -1,105 +1,103 @@
 class AttrSubject;
 
-class Decl<string diagSpelling = "", bit abstract = 0> : AttrSubject {
+class DeclNode<DeclNode base, string diagSpelling = "", bit abstract = 0>
+    : AttrSubject {
+  DeclNode Base = base;
   bit Abstract = abstract;
   string DiagSpelling = diagSpelling;
 }
 
-class DDecl<Decl base, string diagSpelling = "", bit abstract = 0>
-    : Decl<diagSpelling, abstract> {
-  Decl Base = base;
-}
-
 class DeclContext {}
 
-def TranslationUnit : Decl, DeclContext;
-def PragmaComment : Decl;
-def PragmaDetectMismatch : Decl;
-def ExternCContext : Decl, DeclContext;
-def Named : Decl<"named declarations", 1>;
-  def Namespace : DDecl<Named, "namespaces">, DeclContext;
-  def UsingDirective : DDecl<Named>;
-  def NamespaceAlias : DDecl<Named>;
-  def Label : DDecl<Named, "labels">;
-  def Type : DDecl<Named, "types", 1>;
-    def TypedefName : DDecl<Type, "typedefs", 1>;
-      def Typedef : DDecl<TypedefName>;
-      def TypeAlias : DDecl<TypedefName>;
-      def ObjCTypeParam : DDecl<TypedefName>;
-    def UnresolvedUsingTypename : DDecl<Type>;
-    def Tag : DDecl<Type, "tag types", 1>, DeclContext;
-      def Enum : DDecl<Tag, "enums">;
-      def Record : DDecl<Tag, "structs, unions, classes">;
-        def CXXRecord : DDecl<Record, "classes">;
-          def ClassTemplateSpecialization : DDecl<CXXRecord>;
+def Decl : DeclNode<?, "", 1>;
+def TranslationUnit : DeclNode<Decl>, DeclContext;
+def PragmaComment : DeclNode<Decl>;
+def PragmaDetectMismatch : DeclNode<Decl>;
+def ExternCContext : DeclNode<Decl>, DeclContext;
+def Named : DeclNode<Decl, "named declarations", 1>;
+  def Namespace : DeclNode<Named, "namespaces">, DeclContext;
+  def UsingDirective : DeclNode<Named>;
+  def NamespaceAlias : DeclNode<Named>;
+  def Label : DeclNode<Named, "labels">;
+  def Type : DeclNode<Named, "types", 1>;
+    def TypedefName : DeclNode<Type, "typedefs", 1>;
+      def Typedef : DeclNode<TypedefName>;
+      def TypeAlias : DeclNode<TypedefName>;
+      def ObjCTypeParam : DeclNode<TypedefName>;
+    def UnresolvedUsingTypename : DeclNode<Type>;
+    def Tag : DeclNode<Type, "tag types", 1>, DeclContext;
+      def Enum : DeclNode<Tag, "enums">;
+      def Record : DeclNode<Tag, "structs, unions, classes">;
+        def CXXRecord : DeclNode<Record, "classes">;
+          def ClassTemplateSpecialization : DeclNode<CXXRecord>;
             def ClassTemplatePartialSpecialization
-              : DDecl<ClassTemplateSpecialization>;
-    def TemplateTypeParm : DDecl<Type>;
-  def Value : DDecl<Named, "value declarations", 1>;
-    def EnumConstant : DDecl<Value, "enumerators">;
-    def UnresolvedUsingValue : DDecl<Value>;
-    def IndirectField : DDecl<Value>;
-    def Binding : DDecl<Value>;
-    def OMPDeclareReduction : DDecl<Value>, DeclContext;
-    def OMPDeclareMapper : DDecl<Value>, DeclContext;
-    def Declarator : DDecl<Value, "declarators", 1>;
-      def Field : DDecl<Declarator, "non-static data members">;
-        def ObjCIvar : DDecl<Field>;
-        def ObjCAtDefsField : DDecl<Field>;
-      def MSProperty : DDecl<Declarator>;
-      def Function : DDecl<Declarator, "functions">, DeclContext;
-        def CXXDeductionGuide : DDecl<Function>;
-        def CXXMethod : DDecl<Function>;
-          def CXXConstructor : DDecl<CXXMethod>;
-          def CXXDestructor : DDecl<CXXMethod>;
-          def CXXConversion : DDecl<CXXMethod>;
-      def Var : DDecl<Declarator, "variables">;
-        def VarTemplateSpecialization : DDecl<Var>;
+              : DeclNode<ClassTemplateSpecialization>;
+    def TemplateTypeParm : DeclNode<Type>;
+  def Value : DeclNode<Named, "value declarations", 1>;
+    def EnumConstant : DeclNode<Value, "enumerators">;
+    def UnresolvedUsingValue : DeclNode<Value>;
+    def IndirectField : DeclNode<Value>;
+    def Binding : DeclNode<Value>;
+    def OMPDeclareReduction : DeclNode<Value>, DeclContext;
+    def OMPDeclareMapper : DeclNode<Value>, DeclContext;
+    def Declarator : DeclNode<Value, "declarators", 1>;
+      def Field : DeclNode<Declarator, "non-static data members">;
+        def ObjCIvar : DeclNode<Field>;
+        def ObjCAtDefsField : DeclNode<Field>;
+      def MSProperty : DeclNode<Declarator>;
+      def Function : DeclNode<Declarator, "functions">, DeclContext;
+        def CXXDeductionGuide : DeclNode<Function>;
+        def CXXMethod : DeclNode<Function>;
+          def CXXConstructor : DeclNode<CXXMethod>;
+          def CXXDestructor : DeclNode<CXXMethod>;
+          def CXXConversion : DeclNode<CXXMethod>;
+      def Var : DeclNode<Declarator, "variables">;
+        def VarTemplateSpecialization : DeclNode<Var>;
           def VarTemplatePartialSpecialization
-            : DDecl<VarTemplateSpecialization>;
-        def ImplicitParam : DDecl<Var>;
-        def ParmVar : DDecl<Var, "parameters">;
-        def Decomposition : DDecl<Var>;
-        def OMPCapturedExpr : DDecl<Var>;
-      def NonTypeTemplateParm : DDecl<Declarator>;
-  def Template : DDecl<Named, "templates", 1>;
-    def RedeclarableTemplate : DDecl<Template, "redeclarable templates", 1>;
-      def FunctionTemplate : DDecl<RedeclarableTemplate>;
-      def ClassTemplate : DDecl<RedeclarableTemplate>;
-      def VarTemplate : DDecl<RedeclarableTemplate>;
-      def TypeAliasTemplate : DDecl<RedeclarableTemplate>;
-    def TemplateTemplateParm : DDecl<Template>;
-    def BuiltinTemplate : DDecl<Template>;
-    def Concept : DDecl<Template>;
-  def Using : DDecl<Named>;
-  def UsingPack : DDecl<Named>;
-  def UsingShadow : DDecl<Named>;
-    def ConstructorUsingShadow : DDecl<UsingShadow>;
-  def ObjCMethod : DDecl<Named, "Objective-C methods">, DeclContext;
-  def ObjCContainer : DDecl<Named, "Objective-C containers", 1>, DeclContext;
-    def ObjCCategory : DDecl<ObjCContainer>;
-    def ObjCProtocol : DDecl<ObjCContainer, "Objective-C protocols">;
-    def ObjCInterface : DDecl<ObjCContainer, "Objective-C interfaces">;
+            : DeclNode<VarTemplateSpecialization>;
+        def ImplicitParam : DeclNode<Var>;
+        def ParmVar : DeclNode<Var, "parameters">;
+        def Decomposition : DeclNode<Var>;
+        def OMPCapturedExpr : DeclNode<Var>;
+      def NonTypeTemplateParm : DeclNode<Declarator>;
+  def Template : DeclNode<Named, "templates", 1>;
+    def RedeclarableTemplate : DeclNode<Template, "redeclarable templates", 1>;
+      def FunctionTemplate : DeclNode<RedeclarableTemplate>;
+      def ClassTemplate : DeclNode<RedeclarableTemplate>;
+      def VarTemplate : DeclNode<RedeclarableTemplate>;
+      def TypeAliasTemplate : DeclNode<RedeclarableTemplate>;
+    def TemplateTemplateParm : DeclNode<Template>;
+    def BuiltinTemplate : DeclNode<Template>;
+    def Concept : DeclNode<Template>;
+  def Using : DeclNode<Named>;
+  def UsingPack : DeclNode<Named>;
+  def UsingShadow : DeclNode<Named>;
+    def ConstructorUsingShadow : DeclNode<UsingShadow>;
+  def ObjCMethod : DeclNode<Named, "Objective-C methods">, DeclContext;
+  def ObjCContainer : DeclNode<Named, "Objective-C containers", 1>, DeclContext;
+    def ObjCCategory : DeclNode<ObjCContainer>;
+    def ObjCProtocol : DeclNode<ObjCContainer, "Objective-C protocols">;
+    def ObjCInterface : DeclNode<ObjCContainer, "Objective-C interfaces">;
     def ObjCImpl
-        : DDecl<ObjCContainer, "Objective-C implementation declarations", 1>;
-      def ObjCCategoryImpl : DDecl<ObjCImpl>;
-      def ObjCImplementation : DDecl<ObjCImpl>;
-  def ObjCProperty : DDecl<Named, "Objective-C properties">;
-  def ObjCCompatibleAlias : DDecl<Named>;
-def LinkageSpec : Decl, DeclContext;
-def Export : Decl, DeclContext;
-def ObjCPropertyImpl : Decl;
-def FileScopeAsm : Decl;
-def AccessSpec : Decl;
-def Friend : Decl;
-def FriendTemplate : Decl;
-def StaticAssert : Decl;
-def Block : Decl<"blocks">, DeclContext;
-def Captured : Decl, DeclContext;
-def ClassScopeFunctionSpecialization : Decl;
-def Import : Decl;
-def OMPThreadPrivate : Decl;
-def OMPAllocate : Decl;
-def OMPRequires : Decl;
-def Empty : Decl;
+        : DeclNode<ObjCContainer, "Objective-C implementation declarations", 1>;
+      def ObjCCategoryImpl : DeclNode<ObjCImpl>;
+      def ObjCImplementation : DeclNode<ObjCImpl>;
+  def ObjCProperty : DeclNode<Named, "Objective-C properties">;
+  def ObjCCompatibleAlias : DeclNode<Named>;
+def LinkageSpec : DeclNode<Decl>, DeclContext;
+def Export : DeclNode<Decl>, DeclContext;
+def ObjCPropertyImpl : DeclNode<Decl>;
+def FileScopeAsm : DeclNode<Decl>;
+def AccessSpec : DeclNode<Decl>;
+def Friend : DeclNode<Decl>;
+def FriendTemplate : DeclNode<Decl>;
+def StaticAssert : DeclNode<Decl>;
+def Block : DeclNode<Decl, "blocks">, DeclContext;
+def Captured : DeclNode<Decl>, DeclContext;
+def ClassScopeFunctionSpecialization : DeclNode<Decl>;
+def Import : DeclNode<Decl>;
+def OMPThreadPrivate : DeclNode<Decl>;
+def OMPAllocate : DeclNode<Decl>;
+def OMPRequires : DeclNode<Decl>;
+def Empty : DeclNode<Decl>;
 

diff  --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td
index 59444b2919a9..18b46e6aa103 100644
--- a/clang/include/clang/Basic/StmtNodes.td
+++ b/clang/include/clang/Basic/StmtNodes.td
@@ -1,266 +1,264 @@
 class AttrSubject;
 
-class Stmt<bit abstract = 0> : AttrSubject {
+class StmtNode<StmtNode base, bit abstract = 0> : AttrSubject {
+	StmtNode Base = base;
   bit Abstract = abstract;
 }
 
-class DStmt<Stmt base, bit abstract = 0> : Stmt<abstract> {
-  Stmt Base = base;
-}
-
 // Statements
-def NullStmt : Stmt;
-def CompoundStmt : Stmt;
-def IfStmt : Stmt;
-def SwitchStmt : Stmt;
-def WhileStmt : Stmt;
-def DoStmt : Stmt;
-def ForStmt : Stmt;
-def GotoStmt : Stmt;
-def IndirectGotoStmt : Stmt;
-def ContinueStmt : Stmt;
-def BreakStmt : Stmt;
-def ReturnStmt : Stmt;
-def DeclStmt  : Stmt;
-def SwitchCase : Stmt<1>;
-def CaseStmt : DStmt<SwitchCase>;
-def DefaultStmt : DStmt<SwitchCase>;
-def CapturedStmt : Stmt;
+def Stmt : StmtNode<?, 1>;
+def NullStmt : StmtNode<Stmt>;
+def CompoundStmt : StmtNode<Stmt>;
+def IfStmt : StmtNode<Stmt>;
+def SwitchStmt : StmtNode<Stmt>;
+def WhileStmt : StmtNode<Stmt>;
+def DoStmt : StmtNode<Stmt>;
+def ForStmt : StmtNode<Stmt>;
+def GotoStmt : StmtNode<Stmt>;
+def IndirectGotoStmt : StmtNode<Stmt>;
+def ContinueStmt : StmtNode<Stmt>;
+def BreakStmt : StmtNode<Stmt>;
+def ReturnStmt : StmtNode<Stmt>;
+def DeclStmt  : StmtNode<Stmt>;
+def SwitchCase : StmtNode<Stmt, 1>;
+def CaseStmt : StmtNode<SwitchCase>;
+def DefaultStmt : StmtNode<SwitchCase>;
+def CapturedStmt : StmtNode<Stmt>;
 
 // Statements that might produce a value (for example, as the last non-null
 // statement in a GNU statement-expression).
-def ValueStmt : Stmt<1>;
-def LabelStmt : DStmt<ValueStmt>;
-def AttributedStmt : DStmt<ValueStmt>;
+def ValueStmt : StmtNode<Stmt, 1>;
+def LabelStmt : StmtNode<ValueStmt>;
+def AttributedStmt : StmtNode<ValueStmt>;
 
 // Asm statements
-def AsmStmt : Stmt<1>;
-def GCCAsmStmt : DStmt<AsmStmt>;
-def MSAsmStmt : DStmt<AsmStmt>;
+def AsmStmt : StmtNode<Stmt, 1>;
+def GCCAsmStmt : StmtNode<AsmStmt>;
+def MSAsmStmt : StmtNode<AsmStmt>;
 
 // Obj-C statements
-def ObjCAtTryStmt : Stmt;
-def ObjCAtCatchStmt : Stmt;
-def ObjCAtFinallyStmt : Stmt;
-def ObjCAtThrowStmt : Stmt;
-def ObjCAtSynchronizedStmt : Stmt;
-def ObjCForCollectionStmt : Stmt;
-def ObjCAutoreleasePoolStmt : Stmt;
+def ObjCAtTryStmt : StmtNode<Stmt>;
+def ObjCAtCatchStmt : StmtNode<Stmt>;
+def ObjCAtFinallyStmt : StmtNode<Stmt>;
+def ObjCAtThrowStmt : StmtNode<Stmt>;
+def ObjCAtSynchronizedStmt : StmtNode<Stmt>;
+def ObjCForCollectionStmt : StmtNode<Stmt>;
+def ObjCAutoreleasePoolStmt : StmtNode<Stmt>;
 
 // C++ statements
-def CXXCatchStmt : Stmt;
-def CXXTryStmt : Stmt;
-def CXXForRangeStmt : Stmt;
+def CXXCatchStmt : StmtNode<Stmt>;
+def CXXTryStmt : StmtNode<Stmt>;
+def CXXForRangeStmt : StmtNode<Stmt>;
 
 // C++ Coroutines TS statements
-def CoroutineBodyStmt : Stmt;
-def CoreturnStmt : Stmt;
+def CoroutineBodyStmt : StmtNode<Stmt>;
+def CoreturnStmt : StmtNode<Stmt>;
 
 // Expressions
-def Expr : DStmt<ValueStmt, 1>;
-def PredefinedExpr : DStmt<Expr>;
-def DeclRefExpr : DStmt<Expr>;
-def IntegerLiteral : DStmt<Expr>;
-def FixedPointLiteral : DStmt<Expr>;
-def FloatingLiteral : DStmt<Expr>;
-def ImaginaryLiteral : DStmt<Expr>;
-def StringLiteral : DStmt<Expr>;
-def CharacterLiteral : DStmt<Expr>;
-def ParenExpr : DStmt<Expr>;
-def UnaryOperator : DStmt<Expr>;
-def OffsetOfExpr : DStmt<Expr>;
-def UnaryExprOrTypeTraitExpr : DStmt<Expr>;
-def ArraySubscriptExpr : DStmt<Expr>;
-def OMPArraySectionExpr : DStmt<Expr>;
-def CallExpr : DStmt<Expr>;
-def MemberExpr : DStmt<Expr>;
-def CastExpr : DStmt<Expr, 1>;
-def BinaryOperator : DStmt<Expr>;
-def CompoundAssignOperator : DStmt<BinaryOperator>;
-def AbstractConditionalOperator : DStmt<Expr, 1>;
-def ConditionalOperator : DStmt<AbstractConditionalOperator>;
-def BinaryConditionalOperator : DStmt<AbstractConditionalOperator>;
-def ImplicitCastExpr : DStmt<CastExpr>;
-def ExplicitCastExpr : DStmt<CastExpr, 1>;
-def CStyleCastExpr : DStmt<ExplicitCastExpr>;
-def CompoundLiteralExpr : DStmt<Expr>;
-def ExtVectorElementExpr : DStmt<Expr>;
-def InitListExpr : DStmt<Expr>;
-def DesignatedInitExpr : DStmt<Expr>;
-def DesignatedInitUpdateExpr : DStmt<Expr>;
-def ImplicitValueInitExpr : DStmt<Expr>;
-def NoInitExpr : DStmt<Expr>;
-def ArrayInitLoopExpr : DStmt<Expr>;
-def ArrayInitIndexExpr : DStmt<Expr>;
-def ParenListExpr : DStmt<Expr>;
-def VAArgExpr : DStmt<Expr>;
-def GenericSelectionExpr : DStmt<Expr>;
-def PseudoObjectExpr : DStmt<Expr>;
-def SourceLocExpr : DStmt<Expr>;
+def Expr : StmtNode<ValueStmt, 1>;
+def PredefinedExpr : StmtNode<Expr>;
+def DeclRefExpr : StmtNode<Expr>;
+def IntegerLiteral : StmtNode<Expr>;
+def FixedPointLiteral : StmtNode<Expr>;
+def FloatingLiteral : StmtNode<Expr>;
+def ImaginaryLiteral : StmtNode<Expr>;
+def StringLiteral : StmtNode<Expr>;
+def CharacterLiteral : StmtNode<Expr>;
+def ParenExpr : StmtNode<Expr>;
+def UnaryOperator : StmtNode<Expr>;
+def OffsetOfExpr : StmtNode<Expr>;
+def UnaryExprOrTypeTraitExpr : StmtNode<Expr>;
+def ArraySubscriptExpr : StmtNode<Expr>;
+def OMPArraySectionExpr : StmtNode<Expr>;
+def CallExpr : StmtNode<Expr>;
+def MemberExpr : StmtNode<Expr>;
+def CastExpr : StmtNode<Expr, 1>;
+def BinaryOperator : StmtNode<Expr>;
+def CompoundAssignOperator : StmtNode<BinaryOperator>;
+def AbstractConditionalOperator : StmtNode<Expr, 1>;
+def ConditionalOperator : StmtNode<AbstractConditionalOperator>;
+def BinaryConditionalOperator : StmtNode<AbstractConditionalOperator>;
+def ImplicitCastExpr : StmtNode<CastExpr>;
+def ExplicitCastExpr : StmtNode<CastExpr, 1>;
+def CStyleCastExpr : StmtNode<ExplicitCastExpr>;
+def CompoundLiteralExpr : StmtNode<Expr>;
+def ExtVectorElementExpr : StmtNode<Expr>;
+def InitListExpr : StmtNode<Expr>;
+def DesignatedInitExpr : StmtNode<Expr>;
+def DesignatedInitUpdateExpr : StmtNode<Expr>;
+def ImplicitValueInitExpr : StmtNode<Expr>;
+def NoInitExpr : StmtNode<Expr>;
+def ArrayInitLoopExpr : StmtNode<Expr>;
+def ArrayInitIndexExpr : StmtNode<Expr>;
+def ParenListExpr : StmtNode<Expr>;
+def VAArgExpr : StmtNode<Expr>;
+def GenericSelectionExpr : StmtNode<Expr>;
+def PseudoObjectExpr : StmtNode<Expr>;
+def SourceLocExpr : StmtNode<Expr>;
 
 // Wrapper expressions
-def FullExpr : DStmt<Expr, 1>;
-def ConstantExpr : DStmt<FullExpr>;
+def FullExpr : StmtNode<Expr, 1>;
+def ConstantExpr : StmtNode<FullExpr>;
 
 // Atomic expressions
-def AtomicExpr : DStmt<Expr>;
+def AtomicExpr : StmtNode<Expr>;
 
 // GNU Extensions.
-def AddrLabelExpr : DStmt<Expr>;
-def StmtExpr : DStmt<Expr>;
-def ChooseExpr : DStmt<Expr>;
-def GNUNullExpr : DStmt<Expr>;
+def AddrLabelExpr : StmtNode<Expr>;
+def StmtExpr : StmtNode<Expr>;
+def ChooseExpr : StmtNode<Expr>;
+def GNUNullExpr : StmtNode<Expr>;
 
 // C++ Expressions.
-def CXXOperatorCallExpr : DStmt<CallExpr>;
-def CXXMemberCallExpr : DStmt<CallExpr>;
-def CXXRewrittenBinaryOperator : DStmt<Expr>;
-def CXXNamedCastExpr : DStmt<ExplicitCastExpr, 1>;
-def CXXStaticCastExpr : DStmt<CXXNamedCastExpr>;
-def CXXDynamicCastExpr : DStmt<CXXNamedCastExpr>;
-def CXXReinterpretCastExpr : DStmt<CXXNamedCastExpr>;
-def CXXConstCastExpr : DStmt<CXXNamedCastExpr>;
-def CXXFunctionalCastExpr : DStmt<ExplicitCastExpr>;
-def CXXTypeidExpr : DStmt<Expr>;
-def UserDefinedLiteral : DStmt<CallExpr>;
-def CXXBoolLiteralExpr : DStmt<Expr>;
-def CXXNullPtrLiteralExpr : DStmt<Expr>;
-def CXXThisExpr : DStmt<Expr>;
-def CXXThrowExpr : DStmt<Expr>;
-def CXXDefaultArgExpr : DStmt<Expr>;
-def CXXDefaultInitExpr : DStmt<Expr>;
-def CXXScalarValueInitExpr : DStmt<Expr>;
-def CXXStdInitializerListExpr : DStmt<Expr>;
-def CXXNewExpr : DStmt<Expr>;
-def CXXDeleteExpr : DStmt<Expr>;
-def CXXPseudoDestructorExpr : DStmt<Expr>;
-def TypeTraitExpr : DStmt<Expr>;
-def ArrayTypeTraitExpr : DStmt<Expr>;
-def ExpressionTraitExpr : DStmt<Expr>;
-def DependentScopeDeclRefExpr : DStmt<Expr>;
-def CXXConstructExpr : DStmt<Expr>;
-def CXXInheritedCtorInitExpr : DStmt<Expr>;
-def CXXBindTemporaryExpr : DStmt<Expr>;
-def ExprWithCleanups : DStmt<FullExpr>;
-def CXXTemporaryObjectExpr : DStmt<CXXConstructExpr>;
-def CXXUnresolvedConstructExpr : DStmt<Expr>;
-def CXXDependentScopeMemberExpr : DStmt<Expr>;
-def OverloadExpr : DStmt<Expr, 1>;
-def UnresolvedLookupExpr : DStmt<OverloadExpr>;
-def UnresolvedMemberExpr : DStmt<OverloadExpr>;
-def CXXNoexceptExpr : DStmt<Expr>;
-def PackExpansionExpr : DStmt<Expr>;
-def SizeOfPackExpr : DStmt<Expr>;
-def SubstNonTypeTemplateParmExpr : DStmt<Expr>;
-def SubstNonTypeTemplateParmPackExpr : DStmt<Expr>;
-def FunctionParmPackExpr : DStmt<Expr>;
-def MaterializeTemporaryExpr : DStmt<Expr>;
-def LambdaExpr : DStmt<Expr>;
-def CXXFoldExpr : DStmt<Expr>;
+def CXXOperatorCallExpr : StmtNode<CallExpr>;
+def CXXMemberCallExpr : StmtNode<CallExpr>;
+def CXXRewrittenBinaryOperator : StmtNode<Expr>;
+def CXXNamedCastExpr : StmtNode<ExplicitCastExpr, 1>;
+def CXXStaticCastExpr : StmtNode<CXXNamedCastExpr>;
+def CXXDynamicCastExpr : StmtNode<CXXNamedCastExpr>;
+def CXXReinterpretCastExpr : StmtNode<CXXNamedCastExpr>;
+def CXXConstCastExpr : StmtNode<CXXNamedCastExpr>;
+def CXXFunctionalCastExpr : StmtNode<ExplicitCastExpr>;
+def CXXTypeidExpr : StmtNode<Expr>;
+def UserDefinedLiteral : StmtNode<CallExpr>;
+def CXXBoolLiteralExpr : StmtNode<Expr>;
+def CXXNullPtrLiteralExpr : StmtNode<Expr>;
+def CXXThisExpr : StmtNode<Expr>;
+def CXXThrowExpr : StmtNode<Expr>;
+def CXXDefaultArgExpr : StmtNode<Expr>;
+def CXXDefaultInitExpr : StmtNode<Expr>;
+def CXXScalarValueInitExpr : StmtNode<Expr>;
+def CXXStdInitializerListExpr : StmtNode<Expr>;
+def CXXNewExpr : StmtNode<Expr>;
+def CXXDeleteExpr : StmtNode<Expr>;
+def CXXPseudoDestructorExpr : StmtNode<Expr>;
+def TypeTraitExpr : StmtNode<Expr>;
+def ArrayTypeTraitExpr : StmtNode<Expr>;
+def ExpressionTraitExpr : StmtNode<Expr>;
+def DependentScopeDeclRefExpr : StmtNode<Expr>;
+def CXXConstructExpr : StmtNode<Expr>;
+def CXXInheritedCtorInitExpr : StmtNode<Expr>;
+def CXXBindTemporaryExpr : StmtNode<Expr>;
+def ExprWithCleanups : StmtNode<FullExpr>;
+def CXXTemporaryObjectExpr : StmtNode<CXXConstructExpr>;
+def CXXUnresolvedConstructExpr : StmtNode<Expr>;
+def CXXDependentScopeMemberExpr : StmtNode<Expr>;
+def OverloadExpr : StmtNode<Expr, 1>;
+def UnresolvedLookupExpr : StmtNode<OverloadExpr>;
+def UnresolvedMemberExpr : StmtNode<OverloadExpr>;
+def CXXNoexceptExpr : StmtNode<Expr>;
+def PackExpansionExpr : StmtNode<Expr>;
+def SizeOfPackExpr : StmtNode<Expr>;
+def SubstNonTypeTemplateParmExpr : StmtNode<Expr>;
+def SubstNonTypeTemplateParmPackExpr : StmtNode<Expr>;
+def FunctionParmPackExpr : StmtNode<Expr>;
+def MaterializeTemporaryExpr : StmtNode<Expr>;
+def LambdaExpr : StmtNode<Expr>;
+def CXXFoldExpr : StmtNode<Expr>;
 
 // C++ Coroutines TS expressions
-def CoroutineSuspendExpr : DStmt<Expr, 1>;
-def CoawaitExpr : DStmt<CoroutineSuspendExpr>;
-def DependentCoawaitExpr : DStmt<Expr>;
-def CoyieldExpr : DStmt<CoroutineSuspendExpr>;
+def CoroutineSuspendExpr : StmtNode<Expr, 1>;
+def CoawaitExpr : StmtNode<CoroutineSuspendExpr>;
+def DependentCoawaitExpr : StmtNode<Expr>;
+def CoyieldExpr : StmtNode<CoroutineSuspendExpr>;
 
 // C++2a Concepts expressions
-def ConceptSpecializationExpr : DStmt<Expr>;
+def ConceptSpecializationExpr : StmtNode<Expr>;
 
 // Obj-C Expressions.
-def ObjCStringLiteral : DStmt<Expr>;
-def ObjCBoxedExpr : DStmt<Expr>;
-def ObjCArrayLiteral : DStmt<Expr>;
-def ObjCDictionaryLiteral : DStmt<Expr>;
-def ObjCEncodeExpr : DStmt<Expr>;
-def ObjCMessageExpr : DStmt<Expr>;
-def ObjCSelectorExpr : DStmt<Expr>;
-def ObjCProtocolExpr : DStmt<Expr>;
-def ObjCIvarRefExpr : DStmt<Expr>;
-def ObjCPropertyRefExpr : DStmt<Expr>;
-def ObjCIsaExpr : DStmt<Expr>;
-def ObjCIndirectCopyRestoreExpr : DStmt<Expr>;
-def ObjCBoolLiteralExpr : DStmt<Expr>;
-def ObjCSubscriptRefExpr : DStmt<Expr>;
-def ObjCAvailabilityCheckExpr : DStmt<Expr>;
+def ObjCStringLiteral : StmtNode<Expr>;
+def ObjCBoxedExpr : StmtNode<Expr>;
+def ObjCArrayLiteral : StmtNode<Expr>;
+def ObjCDictionaryLiteral : StmtNode<Expr>;
+def ObjCEncodeExpr : StmtNode<Expr>;
+def ObjCMessageExpr : StmtNode<Expr>;
+def ObjCSelectorExpr : StmtNode<Expr>;
+def ObjCProtocolExpr : StmtNode<Expr>;
+def ObjCIvarRefExpr : StmtNode<Expr>;
+def ObjCPropertyRefExpr : StmtNode<Expr>;
+def ObjCIsaExpr : StmtNode<Expr>;
+def ObjCIndirectCopyRestoreExpr : StmtNode<Expr>;
+def ObjCBoolLiteralExpr : StmtNode<Expr>;
+def ObjCSubscriptRefExpr : StmtNode<Expr>;
+def ObjCAvailabilityCheckExpr : StmtNode<Expr>;
 
 // Obj-C ARC Expressions.
-def ObjCBridgedCastExpr : DStmt<ExplicitCastExpr>;
+def ObjCBridgedCastExpr : StmtNode<ExplicitCastExpr>;
 
 // CUDA Expressions.
-def CUDAKernelCallExpr : DStmt<CallExpr>;
+def CUDAKernelCallExpr : StmtNode<CallExpr>;
 
 // Clang Extensions.
-def ShuffleVectorExpr : DStmt<Expr>;
-def ConvertVectorExpr : DStmt<Expr>;
-def BlockExpr : DStmt<Expr>;
-def OpaqueValueExpr : DStmt<Expr>;
-def TypoExpr : DStmt<Expr>;
-def BuiltinBitCastExpr : DStmt<ExplicitCastExpr>;
+def ShuffleVectorExpr : StmtNode<Expr>;
+def ConvertVectorExpr : StmtNode<Expr>;
+def BlockExpr : StmtNode<Expr>;
+def OpaqueValueExpr : StmtNode<Expr>;
+def TypoExpr : StmtNode<Expr>;
+def BuiltinBitCastExpr : StmtNode<ExplicitCastExpr>;
 
 // Microsoft Extensions.
-def MSPropertyRefExpr : DStmt<Expr>;
-def MSPropertySubscriptExpr : DStmt<Expr>;
-def CXXUuidofExpr : DStmt<Expr>;
-def SEHTryStmt : Stmt;
-def SEHExceptStmt : Stmt;
-def SEHFinallyStmt : Stmt;
-def SEHLeaveStmt : Stmt;
-def MSDependentExistsStmt : Stmt;
+def MSPropertyRefExpr : StmtNode<Expr>;
+def MSPropertySubscriptExpr : StmtNode<Expr>;
+def CXXUuidofExpr : StmtNode<Expr>;
+def SEHTryStmt : StmtNode<Stmt>;
+def SEHExceptStmt : StmtNode<Stmt>;
+def SEHFinallyStmt : StmtNode<Stmt>;
+def SEHLeaveStmt : StmtNode<Stmt>;
+def MSDependentExistsStmt : StmtNode<Stmt>;
 
 // OpenCL Extensions.
-def AsTypeExpr : DStmt<Expr>;
+def AsTypeExpr : StmtNode<Expr>;
 
 // OpenMP Directives.
-def OMPExecutableDirective : Stmt<1>;
-def OMPLoopDirective : DStmt<OMPExecutableDirective, 1>;
-def OMPParallelDirective : DStmt<OMPExecutableDirective>;
-def OMPSimdDirective : DStmt<OMPLoopDirective>;
-def OMPForDirective : DStmt<OMPLoopDirective>;
-def OMPForSimdDirective : DStmt<OMPLoopDirective>;
-def OMPSectionsDirective : DStmt<OMPExecutableDirective>;
-def OMPSectionDirective : DStmt<OMPExecutableDirective>;
-def OMPSingleDirective : DStmt<OMPExecutableDirective>;
-def OMPMasterDirective : DStmt<OMPExecutableDirective>;
-def OMPCriticalDirective : DStmt<OMPExecutableDirective>;
-def OMPParallelForDirective : DStmt<OMPLoopDirective>;
-def OMPParallelForSimdDirective : DStmt<OMPLoopDirective>;
-def OMPParallelSectionsDirective : DStmt<OMPExecutableDirective>;
-def OMPTaskDirective : DStmt<OMPExecutableDirective>;
-def OMPTaskyieldDirective : DStmt<OMPExecutableDirective>;
-def OMPBarrierDirective : DStmt<OMPExecutableDirective>;
-def OMPTaskwaitDirective : DStmt<OMPExecutableDirective>;
-def OMPTaskgroupDirective : DStmt<OMPExecutableDirective>;
-def OMPFlushDirective : DStmt<OMPExecutableDirective>;
-def OMPOrderedDirective : DStmt<OMPExecutableDirective>;
-def OMPAtomicDirective : DStmt<OMPExecutableDirective>;
-def OMPTargetDirective : DStmt<OMPExecutableDirective>;
-def OMPTargetDataDirective : DStmt<OMPExecutableDirective>;
-def OMPTargetEnterDataDirective : DStmt<OMPExecutableDirective>;
-def OMPTargetExitDataDirective : DStmt<OMPExecutableDirective>;
-def OMPTargetParallelDirective : DStmt<OMPExecutableDirective>;
-def OMPTargetParallelForDirective : DStmt<OMPExecutableDirective>;
-def OMPTargetUpdateDirective : DStmt<OMPExecutableDirective>;
-def OMPTeamsDirective : DStmt<OMPExecutableDirective>;
-def OMPCancellationPointDirective : DStmt<OMPExecutableDirective>;
-def OMPCancelDirective : DStmt<OMPExecutableDirective>;
-def OMPTaskLoopDirective : DStmt<OMPLoopDirective>;
-def OMPTaskLoopSimdDirective : DStmt<OMPLoopDirective>;
-def OMPMasterTaskLoopDirective : DStmt<OMPLoopDirective>;
-def OMPMasterTaskLoopSimdDirective : DStmt<OMPLoopDirective>;
-def OMPParallelMasterTaskLoopDirective : DStmt<OMPLoopDirective>;
-def OMPDistributeDirective : DStmt<OMPLoopDirective>;
-def OMPDistributeParallelForDirective : DStmt<OMPLoopDirective>;
-def OMPDistributeParallelForSimdDirective : DStmt<OMPLoopDirective>;
-def OMPDistributeSimdDirective : DStmt<OMPLoopDirective>;
-def OMPTargetParallelForSimdDirective : DStmt<OMPLoopDirective>;
-def OMPTargetSimdDirective : DStmt<OMPLoopDirective>;
-def OMPTeamsDistributeDirective : DStmt<OMPLoopDirective>;
-def OMPTeamsDistributeSimdDirective : DStmt<OMPLoopDirective>;
-def OMPTeamsDistributeParallelForSimdDirective : DStmt<OMPLoopDirective>;
-def OMPTeamsDistributeParallelForDirective : DStmt<OMPLoopDirective>;
-def OMPTargetTeamsDirective : DStmt<OMPExecutableDirective>;
-def OMPTargetTeamsDistributeDirective : DStmt<OMPLoopDirective>;
-def OMPTargetTeamsDistributeParallelForDirective : DStmt<OMPLoopDirective>;
-def OMPTargetTeamsDistributeParallelForSimdDirective : DStmt<OMPLoopDirective>;
-def OMPTargetTeamsDistributeSimdDirective : DStmt<OMPLoopDirective>;
+def OMPExecutableDirective : StmtNode<Stmt, 1>;
+def OMPLoopDirective : StmtNode<OMPExecutableDirective, 1>;
+def OMPParallelDirective : StmtNode<OMPExecutableDirective>;
+def OMPSimdDirective : StmtNode<OMPLoopDirective>;
+def OMPForDirective : StmtNode<OMPLoopDirective>;
+def OMPForSimdDirective : StmtNode<OMPLoopDirective>;
+def OMPSectionsDirective : StmtNode<OMPExecutableDirective>;
+def OMPSectionDirective : StmtNode<OMPExecutableDirective>;
+def OMPSingleDirective : StmtNode<OMPExecutableDirective>;
+def OMPMasterDirective : StmtNode<OMPExecutableDirective>;
+def OMPCriticalDirective : StmtNode<OMPExecutableDirective>;
+def OMPParallelForDirective : StmtNode<OMPLoopDirective>;
+def OMPParallelForSimdDirective : StmtNode<OMPLoopDirective>;
+def OMPParallelSectionsDirective : StmtNode<OMPExecutableDirective>;
+def OMPTaskDirective : StmtNode<OMPExecutableDirective>;
+def OMPTaskyieldDirective : StmtNode<OMPExecutableDirective>;
+def OMPBarrierDirective : StmtNode<OMPExecutableDirective>;
+def OMPTaskwaitDirective : StmtNode<OMPExecutableDirective>;
+def OMPTaskgroupDirective : StmtNode<OMPExecutableDirective>;
+def OMPFlushDirective : StmtNode<OMPExecutableDirective>;
+def OMPOrderedDirective : StmtNode<OMPExecutableDirective>;
+def OMPAtomicDirective : StmtNode<OMPExecutableDirective>;
+def OMPTargetDirective : StmtNode<OMPExecutableDirective>;
+def OMPTargetDataDirective : StmtNode<OMPExecutableDirective>;
+def OMPTargetEnterDataDirective : StmtNode<OMPExecutableDirective>;
+def OMPTargetExitDataDirective : StmtNode<OMPExecutableDirective>;
+def OMPTargetParallelDirective : StmtNode<OMPExecutableDirective>;
+def OMPTargetParallelForDirective : StmtNode<OMPExecutableDirective>;
+def OMPTargetUpdateDirective : StmtNode<OMPExecutableDirective>;
+def OMPTeamsDirective : StmtNode<OMPExecutableDirective>;
+def OMPCancellationPointDirective : StmtNode<OMPExecutableDirective>;
+def OMPCancelDirective : StmtNode<OMPExecutableDirective>;
+def OMPTaskLoopDirective : StmtNode<OMPLoopDirective>;
+def OMPTaskLoopSimdDirective : StmtNode<OMPLoopDirective>;
+def OMPMasterTaskLoopDirective : StmtNode<OMPLoopDirective>;
+def OMPMasterTaskLoopSimdDirective : StmtNode<OMPLoopDirective>;
+def OMPParallelMasterTaskLoopDirective : StmtNode<OMPLoopDirective>;
+def OMPDistributeDirective : StmtNode<OMPLoopDirective>;
+def OMPDistributeParallelForDirective : StmtNode<OMPLoopDirective>;
+def OMPDistributeParallelForSimdDirective : StmtNode<OMPLoopDirective>;
+def OMPDistributeSimdDirective : StmtNode<OMPLoopDirective>;
+def OMPTargetParallelForSimdDirective : StmtNode<OMPLoopDirective>;
+def OMPTargetSimdDirective : StmtNode<OMPLoopDirective>;
+def OMPTeamsDistributeDirective : StmtNode<OMPLoopDirective>;
+def OMPTeamsDistributeSimdDirective : StmtNode<OMPLoopDirective>;
+def OMPTeamsDistributeParallelForSimdDirective : StmtNode<OMPLoopDirective>;
+def OMPTeamsDistributeParallelForDirective : StmtNode<OMPLoopDirective>;
+def OMPTargetTeamsDirective : StmtNode<OMPExecutableDirective>;
+def OMPTargetTeamsDistributeDirective : StmtNode<OMPLoopDirective>;
+def OMPTargetTeamsDistributeParallelForDirective : StmtNode<OMPLoopDirective>;
+def OMPTargetTeamsDistributeParallelForSimdDirective : StmtNode<OMPLoopDirective>;
+def OMPTargetTeamsDistributeSimdDirective : StmtNode<OMPLoopDirective>;

diff  --git a/clang/include/clang/Basic/TypeNodes.td b/clang/include/clang/Basic/TypeNodes.td
index b2554de24aaf..835db0b73170 100644
--- a/clang/include/clang/Basic/TypeNodes.td
+++ b/clang/include/clang/Basic/TypeNodes.td
@@ -1,11 +1,8 @@
-class Type<bit abstract = 0> {
+class TypeNode<TypeNode base, bit abstract = 0> {
+	TypeNode Base = base;
   bit Abstract = abstract;
 } 
 
-class DerivedType<Type base, bit abstract = 0> : Type<abstract> {
-	Type Base = base;
-}
-
 /// A type node that is only used to represent dependent types in C++.  For
 /// example, DependentTemplateSpecializationType is used to represent types
 /// where the base template-id is dependent (such as `T::foo<U>`).  Code
@@ -51,56 +48,57 @@ class NeverCanonicalUnlessDependent {}
 /// to types that may not be leaves should not declare this.
 class LeafType {}
 
-def BuiltinType : Type, LeafType;
-def ComplexType : Type;
-def PointerType : Type;
-def BlockPointerType : Type;
-def ReferenceType : Type<1>;
-def LValueReferenceType : DerivedType<ReferenceType>;
-def RValueReferenceType : DerivedType<ReferenceType>;
-def MemberPointerType : Type;
-def ArrayType : Type<1>;
-def ConstantArrayType : DerivedType<ArrayType>;
-def IncompleteArrayType : DerivedType<ArrayType>;
-def VariableArrayType : DerivedType<ArrayType>;
-def DependentSizedArrayType : DerivedType<ArrayType>, AlwaysDependent;
-def DependentSizedExtVectorType : Type, AlwaysDependent;
-def DependentAddressSpaceType : Type, AlwaysDependent;
-def VectorType : Type;
-def DependentVectorType : Type, AlwaysDependent;
-def ExtVectorType : DerivedType<VectorType>;
-def FunctionType : Type<1>;
-def FunctionProtoType : DerivedType<FunctionType>;
-def FunctionNoProtoType : DerivedType<FunctionType>;
-def UnresolvedUsingType : Type, AlwaysDependent;
-def ParenType : Type, NeverCanonical;
-def TypedefType : Type, NeverCanonical;
-def MacroQualifiedType : Type, NeverCanonical;
-def AdjustedType : Type, NeverCanonical;
-def DecayedType : DerivedType<AdjustedType>, NeverCanonical;
-def TypeOfExprType : Type, NeverCanonicalUnlessDependent;
-def TypeOfType : Type, NeverCanonicalUnlessDependent;
-def DecltypeType : Type, NeverCanonicalUnlessDependent;
-def UnaryTransformType : Type, NeverCanonicalUnlessDependent;
-def TagType : Type<1>;
-def RecordType : DerivedType<TagType>, LeafType;
-def EnumType : DerivedType<TagType>, LeafType;
-def ElaboratedType : Type, NeverCanonical;
-def AttributedType : Type, NeverCanonical;
-def TemplateTypeParmType : Type, AlwaysDependent, LeafType;
-def SubstTemplateTypeParmType : Type, NeverCanonical;
-def SubstTemplateTypeParmPackType : Type, AlwaysDependent;
-def TemplateSpecializationType : Type, NeverCanonicalUnlessDependent;
-def DeducedType : Type<1>;
-def AutoType : DerivedType<DeducedType>;
-def DeducedTemplateSpecializationType : DerivedType<DeducedType>;
-def InjectedClassNameType : Type, AlwaysDependent, LeafType;
-def DependentNameType : Type, AlwaysDependent;
-def DependentTemplateSpecializationType : Type, AlwaysDependent;
-def PackExpansionType : Type, NeverCanonicalUnlessDependent;
-def ObjCTypeParamType : Type, NeverCanonical;
-def ObjCObjectType : Type;
-def ObjCInterfaceType : DerivedType<ObjCObjectType>, LeafType;
-def ObjCObjectPointerType : Type;
-def PipeType : Type;
-def AtomicType : Type;
+def Type : TypeNode<?, 1>;
+def BuiltinType : TypeNode<Type>, LeafType;
+def ComplexType : TypeNode<Type>;
+def PointerType : TypeNode<Type>;
+def BlockPointerType : TypeNode<Type>;
+def ReferenceType : TypeNode<Type, 1>;
+def LValueReferenceType : TypeNode<ReferenceType>;
+def RValueReferenceType : TypeNode<ReferenceType>;
+def MemberPointerType : TypeNode<Type>;
+def ArrayType : TypeNode<Type, 1>;
+def ConstantArrayType : TypeNode<ArrayType>;
+def IncompleteArrayType : TypeNode<ArrayType>;
+def VariableArrayType : TypeNode<ArrayType>;
+def DependentSizedArrayType : TypeNode<ArrayType>, AlwaysDependent;
+def DependentSizedExtVectorType : TypeNode<Type>, AlwaysDependent;
+def DependentAddressSpaceType : TypeNode<Type>, AlwaysDependent;
+def VectorType : TypeNode<Type>;
+def DependentVectorType : TypeNode<Type>, AlwaysDependent;
+def ExtVectorType : TypeNode<VectorType>;
+def FunctionType : TypeNode<Type, 1>;
+def FunctionProtoType : TypeNode<FunctionType>;
+def FunctionNoProtoType : TypeNode<FunctionType>;
+def UnresolvedUsingType : TypeNode<Type>, AlwaysDependent;
+def ParenType : TypeNode<Type>, NeverCanonical;
+def TypedefType : TypeNode<Type>, NeverCanonical;
+def MacroQualifiedType : TypeNode<Type>, NeverCanonical;
+def AdjustedType : TypeNode<Type>, NeverCanonical;
+def DecayedType : TypeNode<AdjustedType>, NeverCanonical;
+def TypeOfExprType : TypeNode<Type>, NeverCanonicalUnlessDependent;
+def TypeOfType : TypeNode<Type>, NeverCanonicalUnlessDependent;
+def DecltypeType : TypeNode<Type>, NeverCanonicalUnlessDependent;
+def UnaryTransformType : TypeNode<Type>, NeverCanonicalUnlessDependent;
+def TagType : TypeNode<Type, 1>;
+def RecordType : TypeNode<TagType>, LeafType;
+def EnumType : TypeNode<TagType>, LeafType;
+def ElaboratedType : TypeNode<Type>, NeverCanonical;
+def AttributedType : TypeNode<Type>, NeverCanonical;
+def TemplateTypeParmType : TypeNode<Type>, AlwaysDependent, LeafType;
+def SubstTemplateTypeParmType : TypeNode<Type>, NeverCanonical;
+def SubstTemplateTypeParmPackType : TypeNode<Type>, AlwaysDependent;
+def TemplateSpecializationType : TypeNode<Type>, NeverCanonicalUnlessDependent;
+def DeducedType : TypeNode<Type, 1>;
+def AutoType : TypeNode<DeducedType>;
+def DeducedTemplateSpecializationType : TypeNode<DeducedType>;
+def InjectedClassNameType : TypeNode<Type>, AlwaysDependent, LeafType;
+def DependentNameType : TypeNode<Type>, AlwaysDependent;
+def DependentTemplateSpecializationType : TypeNode<Type>, AlwaysDependent;
+def PackExpansionType : TypeNode<Type>, NeverCanonicalUnlessDependent;
+def ObjCTypeParamType : TypeNode<Type>, NeverCanonical;
+def ObjCObjectType : TypeNode<Type>;
+def ObjCInterfaceType : TypeNode<ObjCObjectType>, LeafType;
+def ObjCObjectPointerType : TypeNode<Type>;
+def PipeType : TypeNode<Type>;
+def AtomicType : TypeNode<Type>;

diff  --git a/clang/utils/TableGen/ClangASTEmitters.h b/clang/utils/TableGen/ClangASTEmitters.h
new file mode 100644
index 000000000000..942c85f1613a
--- /dev/null
+++ b/clang/utils/TableGen/ClangASTEmitters.h
@@ -0,0 +1,39 @@
+//=== ClangASTEmitters.h - Definitions for AST node emitters ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_AST_EMITTERS
+#define CLANG_AST_EMITTERS
+
+#include "llvm/TableGen/Record.h"
+#include "llvm/ADT/STLExtras.h"
+
+// These are spellings in the tblgen files.
+
+// The field name for the base-node property.
+// Fortunately, this is common across all the hierarchies.
+#define BaseFieldName "Base"
+
+// Comment node hierarchy.
+#define CommentNodeClassName "CommentNode"
+
+// Decl node hierarchy.
+#define DeclNodeClassName "DeclNode"
+#define DeclContextNodeClassName "DeclContext"
+
+// Stmt node hierarchy.
+#define StmtNodeClassName "StmtNode"
+
+// Type node hierarchy.
+#define TypeNodeClassName "TypeNode"
+#define AlwaysDependentClassName "AlwaysDependent"
+#define NeverCanonicalClassName "NeverCanonical"
+#define NeverCanonicalUnlessDependentClassName "NeverCanonicalUnlessDependent"
+#define LeafTypeClassName "LeafType"
+#define AbstractFieldName "Abstract"
+
+#endif

diff  --git a/clang/utils/TableGen/ClangASTNodesEmitter.cpp b/clang/utils/TableGen/ClangASTNodesEmitter.cpp
index 3ece9be6a5c7..704ccda9bbd1 100644
--- a/clang/utils/TableGen/ClangASTNodesEmitter.cpp
+++ b/clang/utils/TableGen/ClangASTNodesEmitter.cpp
@@ -10,8 +10,10 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "ClangASTEmitters.h"
 #include "TableGenBackends.h"
 
+#include "llvm/TableGen/Error.h"
 #include "llvm/TableGen/Record.h"
 #include "llvm/TableGen/TableGenBackend.h"
 #include <cctype>
@@ -30,8 +32,11 @@ class ClangASTNodesEmitter {
   typedef ChildMap::const_iterator ChildIterator;
 
   RecordKeeper &Records;
-  Record Root;
+  Record *Root = nullptr;
+  const std::string &NodeClassName;
   const std::string &BaseSuffix;
+  std::string MacroHierarchyName;
+  ChildMap Tree;
 
   // Create a macro-ized version of a name
   static std::string macroName(std::string S) {
@@ -41,23 +46,30 @@ class ClangASTNodesEmitter {
     return S;
   }
 
+  const std::string &macroHierarchyName() {
+    assert(Root && "root node not yet derived!");
+    if (MacroHierarchyName.empty())
+      MacroHierarchyName = macroName(Root->getName());
+    return MacroHierarchyName;
+  }
+
   // Return the name to be printed in the base field. Normally this is
   // the record's name plus the base suffix, but if it is the root node and
   // the suffix is non-empty, it's just the suffix.
   std::string baseName(Record &R) {
-    if (&R == &Root && !BaseSuffix.empty())
+    if (&R == Root && !BaseSuffix.empty())
       return BaseSuffix;
 
     return R.getName().str() + BaseSuffix;
   }
 
-  std::pair<Record *, Record *> EmitNode (const ChildMap &Tree, raw_ostream& OS,
-                                          Record *Base);
+  void deriveChildTree();
+
+  std::pair<Record *, Record *> EmitNode(raw_ostream& OS, Record *Base);
 public:
   explicit ClangASTNodesEmitter(RecordKeeper &R, const std::string &N,
                                 const std::string &S)
-    : Records(R), Root(N, SMLoc(), R), BaseSuffix(S)
-    {}
+    : Records(R), NodeClassName(N), BaseSuffix(S) {}
 
   // run - Output the .inc file contents
   void run(raw_ostream &OS);
@@ -70,23 +82,19 @@ class ClangASTNodesEmitter {
 
 // Returns the first and last non-abstract subrecords
 // Called recursively to ensure that nodes remain contiguous
-std::pair<Record *, Record *> ClangASTNodesEmitter::EmitNode(
-                                                           const ChildMap &Tree,
-                                                           raw_ostream &OS,
-                                                           Record *Base) {
+std::pair<Record *, Record *> ClangASTNodesEmitter::EmitNode(raw_ostream &OS,
+                                                             Record *Base) {
   std::string BaseName = macroName(Base->getName());
 
   ChildIterator i = Tree.lower_bound(Base), e = Tree.upper_bound(Base);
 
   Record *First = nullptr, *Last = nullptr;
-  // This might be the pseudo-node for Stmt; don't assume it has an Abstract
-  // bit
-  if (Base->getValue("Abstract") && !Base->getValueAsBit("Abstract"))
+  if (!Base->getValueAsBit(AbstractFieldName))
     First = Last = Base;
 
   for (; i != e; ++i) {
     Record *R = i->second;
-    bool Abstract = R->getValueAsBit("Abstract");
+    bool Abstract = R->getValueAsBit(AbstractFieldName);
     std::string NodeName = macroName(R->getName());
 
     OS << "#ifndef " << NodeName << "\n";
@@ -95,7 +103,7 @@ std::pair<Record *, Record *> ClangASTNodesEmitter::EmitNode(
     OS << "#endif\n";
 
     if (Abstract)
-      OS << "ABSTRACT_" << macroName(Root.getName()) << "(" << NodeName << "("
+      OS << "ABSTRACT_" << macroHierarchyName() << "(" << NodeName << "("
           << R->getName() << ", " << baseName(*Base) << "))\n";
     else
       OS << NodeName << "(" << R->getName() << ", "
@@ -103,7 +111,7 @@ std::pair<Record *, Record *> ClangASTNodesEmitter::EmitNode(
 
     if (Tree.find(R) != Tree.end()) {
       const std::pair<Record *, Record *> &Result
-        = EmitNode(Tree, OS, R);
+        = EmitNode(OS, R);
       if (!First && Result.first)
         First = Result.first;
       if (Result.second)
@@ -122,10 +130,10 @@ std::pair<Record *, Record *> ClangASTNodesEmitter::EmitNode(
 
   if (First) {
     assert (Last && "Got a first node but not a last node for a range!");
-    if (Base == &Root)
-      OS << "LAST_" << macroName(Root.getName()) << "_RANGE(";
+    if (Base == Root)
+      OS << "LAST_" << macroHierarchyName() << "_RANGE(";
     else
-      OS << macroName(Root.getName()) << "_RANGE(";
+      OS << macroHierarchyName() << "_RANGE(";
     OS << Base->getName() << ", " << First->getName() << ", "
        << Last->getName() << ")\n\n";
   }
@@ -133,46 +141,58 @@ std::pair<Record *, Record *> ClangASTNodesEmitter::EmitNode(
   return std::make_pair(First, Last);
 }
 
+void ClangASTNodesEmitter::deriveChildTree() {
+  assert(Root == nullptr && "already computed tree");
+
+  // Emit statements
+  const std::vector<Record*> Stmts
+    = Records.getAllDerivedDefinitions(NodeClassName);
+
+  for (unsigned i = 0, e = Stmts.size(); i != e; ++i) {
+    Record *R = Stmts[i];
+
+    if (auto B = R->getValueAsOptionalDef(BaseFieldName))
+      Tree.insert(std::make_pair(B, R));
+    else if (Root)
+      PrintFatalError(R->getLoc(),
+                      Twine("multiple root nodes in \"") + NodeClassName
+                        + "\" hierarchy");
+    else
+      Root = R;
+  }
+
+  if (!Root)
+    PrintFatalError(Twine("didn't find root node in \"") + NodeClassName
+                      + "\" hierarchy");
+}
+
 void ClangASTNodesEmitter::run(raw_ostream &OS) {
+  deriveChildTree();
+
   emitSourceFileHeader("List of AST nodes of a particular kind", OS);
 
   // Write the preamble
-  OS << "#ifndef ABSTRACT_" << macroName(Root.getName()) << "\n";
-  OS << "#  define ABSTRACT_" << macroName(Root.getName()) << "(Type) Type\n";
+  OS << "#ifndef ABSTRACT_" << macroHierarchyName() << "\n";
+  OS << "#  define ABSTRACT_" << macroHierarchyName() << "(Type) Type\n";
   OS << "#endif\n";
 
-  OS << "#ifndef " << macroName(Root.getName()) << "_RANGE\n";
+  OS << "#ifndef " << macroHierarchyName() << "_RANGE\n";
   OS << "#  define "
-     << macroName(Root.getName()) << "_RANGE(Base, First, Last)\n";
+     << macroHierarchyName() << "_RANGE(Base, First, Last)\n";
   OS << "#endif\n\n";
 
-  OS << "#ifndef LAST_" << macroName(Root.getName()) << "_RANGE\n";
+  OS << "#ifndef LAST_" << macroHierarchyName() << "_RANGE\n";
   OS << "#  define LAST_" 
-     << macroName(Root.getName()) << "_RANGE(Base, First, Last) " 
-     << macroName(Root.getName()) << "_RANGE(Base, First, Last)\n";
+     << macroHierarchyName() << "_RANGE(Base, First, Last) " 
+     << macroHierarchyName() << "_RANGE(Base, First, Last)\n";
   OS << "#endif\n\n";
- 
-  // Emit statements
-  const std::vector<Record*> Stmts
-    = Records.getAllDerivedDefinitions(Root.getName());
-
-  ChildMap Tree;
-
-  for (unsigned i = 0, e = Stmts.size(); i != e; ++i) {
-    Record *R = Stmts[i];
-
-    if (R->getValue("Base"))
-      Tree.insert(std::make_pair(R->getValueAsDef("Base"), R));
-    else
-      Tree.insert(std::make_pair(&Root, R));
-  }
 
-  EmitNode(Tree, OS, &Root);
+  EmitNode(OS, Root);
 
-  OS << "#undef " << macroName(Root.getName()) << "\n";
-  OS << "#undef " << macroName(Root.getName()) << "_RANGE\n";
-  OS << "#undef LAST_" << macroName(Root.getName()) << "_RANGE\n";
-  OS << "#undef ABSTRACT_" << macroName(Root.getName()) << "\n";
+  OS << "#undef " << macroHierarchyName() << "\n";
+  OS << "#undef " << macroHierarchyName() << "_RANGE\n";
+  OS << "#undef LAST_" << macroHierarchyName() << "_RANGE\n";
+  OS << "#undef ABSTRACT_" << macroHierarchyName() << "\n";
 }
 
 void clang::EmitClangASTNodes(RecordKeeper &RK, raw_ostream &OS,
@@ -199,15 +219,14 @@ void clang::EmitClangDeclContext(RecordKeeper &Records, raw_ostream &OS) {
   typedef std::vector<Record*> RecordVector;
   
   RecordVector DeclContextsVector
-    = Records.getAllDerivedDefinitions("DeclContext");
-  RecordVector Decls = Records.getAllDerivedDefinitions("Decl");
+    = Records.getAllDerivedDefinitions(DeclContextNodeClassName);
+  RecordVector Decls = Records.getAllDerivedDefinitions(DeclNodeClassName);
   RecordSet DeclContexts (DeclContextsVector.begin(), DeclContextsVector.end());
    
   for (RecordVector::iterator i = Decls.begin(), e = Decls.end(); i != e; ++i) {
     Record *R = *i;
 
-    if (R->getValue("Base")) {
-      Record *B = R->getValueAsDef("Base");
+    if (Record *B = R->getValueAsOptionalDef(BaseFieldName)) {
       if (DeclContexts.find(B) != DeclContexts.end()) {
         OS << "DECL_CONTEXT_BASE(" << B->getName() << ")\n";
         DeclContexts.erase(B);

diff  --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index 0d92a321c747..f9f285c0d4fa 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "TableGenBackends.h"
+#include "ClangASTEmitters.h"
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
@@ -1808,7 +1809,7 @@ struct PragmaClangAttributeSupport {
 } // end anonymous namespace
 
 static bool doesDeclDeriveFrom(const Record *D, const Record *Base) {
-  const Record *CurrentBase = D->getValueAsDef("Base");
+  const Record *CurrentBase = D->getValueAsOptionalDef(BaseFieldName);
   if (!CurrentBase)
     return false;
   if (CurrentBase == Base)
@@ -1849,7 +1850,8 @@ PragmaClangAttributeSupport::PragmaClangAttributeSupport(
 
   std::vector<Record *> Aggregates =
       Records.getAllDerivedDefinitions("AttrSubjectMatcherAggregateRule");
-  std::vector<Record *> DeclNodes = Records.getAllDerivedDefinitions("DDecl");
+  std::vector<Record *> DeclNodes =
+    Records.getAllDerivedDefinitions(DeclNodeClassName);
   for (const auto *Aggregate : Aggregates) {
     Record *SubjectDecl = Aggregate->getValueAsDef("Subject");
 
@@ -3303,9 +3305,8 @@ static std::string GetDiagnosticSpelling(const Record &R) {
   // If we couldn't find the DiagSpelling in this object, we can check to see
   // if the object is one that has a base, and if it is, loop up to the Base
   // member recursively.
-  std::string Super = R.getSuperClasses().back().first->getName();
-  if (Super == "DDecl" || Super == "DStmt")
-    return GetDiagnosticSpelling(*R.getValueAsDef("Base"));
+  if (auto Base = R.getValueAsOptionalDef(BaseFieldName))
+    return GetDiagnosticSpelling(*Base);
 
   return "";
 }
@@ -3385,7 +3386,8 @@ static std::string GenerateCustomAppertainsTo(const Record &Subject,
   if (I != CustomSubjectSet.end())
     return *I;
 
-  Record *Base = Subject.getValueAsDef("Base");
+  // This only works with non-root Decls.
+  Record *Base = Subject.getValueAsDef(BaseFieldName);
 
   // Not currently support custom subjects within custom subjects.
   if (Base->isSubClassOf("SubsetSubject")) {

diff  --git a/clang/utils/TableGen/ClangTypeNodesEmitter.cpp b/clang/utils/TableGen/ClangTypeNodesEmitter.cpp
index c9986c8fa496..764095393514 100644
--- a/clang/utils/TableGen/ClangTypeNodesEmitter.cpp
+++ b/clang/utils/TableGen/ClangTypeNodesEmitter.cpp
@@ -45,6 +45,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "ClangASTEmitters.h"
+#include "TableGenBackends.h"
+
 #include "llvm/ADT/StringRef.h"
 #include "llvm/TableGen/Error.h"
 #include "llvm/TableGen/Record.h"
@@ -52,7 +55,6 @@
 #include <set>
 #include <string>
 #include <vector>
-#include "TableGenBackends.h"
 
 using namespace llvm;
 
@@ -66,16 +68,7 @@ using namespace llvm;
 #define LastTypeMacroName "LAST_TYPE"
 #define LeafTypeMacroName "LEAF_TYPE"
 
-// These are spellings in the tblgen file.
-// (Type is also used for the spelling of the AST class.)
 #define TypeClassName "Type"
-#define DerivedTypeClassName "DerivedType"
-#define AlwaysDependentClassName "AlwaysDependent"
-#define NeverCanonicalClassName "NeverCanonical"
-#define NeverCanonicalUnlessDependentClassName "NeverCanonicalUnlessDependent"
-#define LeafTypeClassName "LeafType"
-#define AbstractFieldName "Abstract"
-#define BaseFieldName "Base"
 
 static StringRef getIdForType(Record *type) {
 	// The record name is expected to be the full C++ class name,
@@ -96,7 +89,7 @@ class TypeNodeEmitter {
 public:
 	TypeNodeEmitter(RecordKeeper &records, raw_ostream &out)
 		: Records(records), Out(out),
-			Types(Records.getAllDerivedDefinitions("Type")) {
+			Types(Records.getAllDerivedDefinitions(TypeNodeClassName)) {
 	}
 
 	void emit();
@@ -151,9 +144,12 @@ void TypeNodeEmitter::emitFallbackDefine(StringRef macroName,
 
 void TypeNodeEmitter::emitNodeInvocations() {
 	for (auto type : Types) {
-		// The name with the Type suffix.
+		// The name without the Type suffix.
 		StringRef id = getIdForType(type);
 
+		// If this is the Type node itself, skip it.
+		if (id.empty()) continue;
+
 		// Figure out which macro to use.
 		StringRef macroName;
 		auto setMacroName = [&](StringRef newName) {
@@ -177,8 +173,8 @@ void TypeNodeEmitter::emitNodeInvocations() {
 
 		// Compute the base class.
 		StringRef baseName = TypeClassName;
-		if (type->isSubClassOf(DerivedTypeClassName))
-			baseName = type->getValueAsDef(BaseFieldName)->getName();
+		if (auto base = type->getValueAsOptionalDef(BaseFieldName))
+			baseName = base->getName();
 
 		// Generate the invocation line.
 		Out << macroName << "(" << id << ", " << baseName << ")\n";

diff  --git a/clang/utils/TableGen/TableGen.cpp b/clang/utils/TableGen/TableGen.cpp
index 29c6d76f73ec..c988a580f298 100644
--- a/clang/utils/TableGen/TableGen.cpp
+++ b/clang/utils/TableGen/TableGen.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "TableGenBackends.h" // Declares all backends.
+#include "ClangASTEmitters.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/Support/Signals.h"
@@ -263,14 +264,14 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
     EmitClangDiagsIndexName(Records, OS);
     break;
   case GenClangCommentNodes:
-    EmitClangASTNodes(Records, OS, "Comment", "");
+    EmitClangASTNodes(Records, OS, CommentNodeClassName, "");
     break;
   case GenClangDeclNodes:
-    EmitClangASTNodes(Records, OS, "Decl", "Decl");
+    EmitClangASTNodes(Records, OS, DeclNodeClassName, "Decl");
     EmitClangDeclContext(Records, OS);
     break;
   case GenClangStmtNodes:
-    EmitClangASTNodes(Records, OS, "Stmt", "");
+    EmitClangASTNodes(Records, OS, StmtNodeClassName, "");
     break;
   case GenClangTypeNodes:
     EmitClangTypeNodes(Records, OS);


        


More information about the cfe-commits mailing list