<div dir="ltr">All other tablegen outputs are called .inc instead of .def. Any reason this one's different?</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Oct 1, 2019 at 7:10 PM John McCall via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: rjmccall<br>
Date: Tue Oct  1 16:13:03 2019<br>
New Revision: 373407<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=373407&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=373407&view=rev</a><br>
Log:<br>
Emit TypeNodes.def with tblgen.<br>
<br>
The primary goal here is to make the type node hierarchy available to<br>
other tblgen backends, although it should also make it easier to generate<br>
more selective x-macros in the future.<br>
<br>
Because tblgen doesn't seem to allow backends to preserve the source<br>
order of defs, this is not NFC because it significantly re-orders IDs.<br>
I've fixed the one (fortunately obvious) place where we relied on<br>
the old order.  Unfortunately, I wasn't able to share code with the<br>
existing AST-node x-macro generators because the x-macro schema we use<br>
for types is different in a number of ways.  The main loss is that<br>
subclasses aren't ordered together, which doesn't seem important for<br>
types because the hierarchy is generally very shallow with little<br>
clustering.<br>
<br>
Added:<br>
    cfe/trunk/include/clang/Basic/TypeNodes.td<br>
    cfe/trunk/utils/TableGen/ClangTypeNodesEmitter.cpp<br>
Removed:<br>
    cfe/trunk/include/clang/AST/TypeNodes.def<br>
Modified:<br>
    cfe/trunk/include/clang/AST/CMakeLists.txt<br>
    cfe/trunk/include/clang/AST/Type.h<br>
    cfe/trunk/utils/TableGen/CMakeLists.txt<br>
    cfe/trunk/utils/TableGen/TableGen.cpp<br>
    cfe/trunk/utils/TableGen/TableGenBackends.h<br>
<br>
Modified: cfe/trunk/include/clang/AST/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CMakeLists.txt?rev=373407&r1=373406&r2=373407&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CMakeLists.txt?rev=373407&r1=373406&r2=373407&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/CMakeLists.txt (original)<br>
+++ cfe/trunk/include/clang/AST/CMakeLists.txt Tue Oct  1 16:13:03 2019<br>
@@ -31,6 +31,10 @@ clang_tablegen(DeclNodes.inc -gen-clang-<br>
   SOURCE ../Basic/DeclNodes.td<br>
   TARGET ClangDeclNodes)<br>
<br>
+clang_tablegen(TypeNodes.def -gen-clang-type-nodes<br>
+  SOURCE ../Basic/TypeNodes.td<br>
+  TARGET ClangTypeNodes)<br>
+<br>
 clang_tablegen(CommentNodes.inc -gen-clang-comment-nodes<br>
   SOURCE ../Basic/CommentNodes.td<br>
   TARGET ClangCommentNodes)<br>
<br>
Modified: cfe/trunk/include/clang/AST/Type.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=373407&r1=373406&r2=373407&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=373407&r1=373406&r2=373407&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/Type.h (original)<br>
+++ cfe/trunk/include/clang/AST/Type.h Tue Oct  1 16:13:03 2019<br>
@@ -1437,10 +1437,9 @@ class alignas(8) Type : public ExtQualsT<br>
 public:<br>
   enum TypeClass {<br>
 #define TYPE(Class, Base) Class,<br>
-#define LAST_TYPE(Class) TypeLast = Class,<br>
+#define LAST_TYPE(Class) TypeLast = Class<br>
 #define ABSTRACT_TYPE(Class, Base)<br>
 #include "clang/AST/TypeNodes.def"<br>
-    TagFirst = Record, TagLast = Enum<br>
   };<br>
<br>
 private:<br>
@@ -4436,7 +4435,7 @@ public:<br>
   bool isBeingDefined() const;<br>
<br>
   static bool classof(const Type *T) {<br>
-    return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;<br>
+    return T->getTypeClass() == Enum || T->getTypeClass() == Record;<br>
   }<br>
 };<br>
<br>
<br>
Removed: cfe/trunk/include/clang/AST/TypeNodes.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=373406&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=373406&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/TypeNodes.def (original)<br>
+++ cfe/trunk/include/clang/AST/TypeNodes.def (removed)<br>
@@ -1,135 +0,0 @@<br>
-//===-- TypeNodes.def - Metadata about Type AST nodes -----------*- C++ -*-===//<br>
-//<br>
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
-// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-//<br>
-//  This file defines the AST type info database. Each type node is<br>
-//  enumerated by providing its name (e.g., "Builtin" or "Enum") and<br>
-//  base class (e.g., "Type" or "TagType"). Depending on where in the<br>
-//  abstract syntax tree the type will show up, the enumeration uses<br>
-//  one of five different macros:<br>
-//<br>
-//    TYPE(Class, Base) - A type that can show up anywhere in the AST,<br>
-//    and might be dependent, canonical, or non-canonical. All clients<br>
-//    will need to understand these types.<br>
-//<br>
-//    ABSTRACT_TYPE(Class, Base) - An abstract class that shows up in<br>
-//    the type hierarchy but has no concrete instances.<br>
-//<br>
-//    NON_CANONICAL_TYPE(Class, Base) - A type that can show up<br>
-//    anywhere in the AST but will never be a part of a canonical<br>
-//    type. Clients that only need to deal with canonical types<br>
-//    (ignoring, e.g., typedefs and other type aliases used for<br>
-//    pretty-printing) can ignore these types.<br>
-//<br>
-//    DEPENDENT_TYPE(Class, Base) - A type that will only show up<br>
-//    within a C++ template that has not been instantiated, e.g., a<br>
-//    type that is always dependent. Clients that do not need to deal<br>
-//    with uninstantiated C++ templates can ignore these types.<br>
-//<br>
-//    NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) - A type that<br>
-//    is non-canonical unless it is dependent.  Defaults to TYPE because<br>
-//    it is neither reliably dependent nor reliably non-canonical.<br>
-//<br>
-//  There is a sixth macro, independent of the others.  Most clients<br>
-//  will not need to use it.<br>
-//<br>
-//    LEAF_TYPE(Class) - A type that never has inner types.  Clients<br>
-//    which can operate on such types more efficiently may wish to do so.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#ifndef ABSTRACT_TYPE<br>
-#  define ABSTRACT_TYPE(Class, Base) TYPE(Class, Base)<br>
-#endif<br>
-<br>
-#ifndef NON_CANONICAL_TYPE<br>
-#  define NON_CANONICAL_TYPE(Class, Base) TYPE(Class, Base)<br>
-#endif<br>
-<br>
-#ifndef DEPENDENT_TYPE<br>
-#  define DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)<br>
-#endif<br>
-<br>
-#ifndef NON_CANONICAL_UNLESS_DEPENDENT_TYPE<br>
-#  define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)<br>
-#endif<br>
-<br>
-TYPE(Builtin, Type)<br>
-TYPE(Complex, Type)<br>
-TYPE(Pointer, Type)<br>
-TYPE(BlockPointer, Type)<br>
-ABSTRACT_TYPE(Reference, Type)<br>
-TYPE(LValueReference, ReferenceType)<br>
-TYPE(RValueReference, ReferenceType)<br>
-TYPE(MemberPointer, Type)<br>
-ABSTRACT_TYPE(Array, Type)<br>
-TYPE(ConstantArray, ArrayType)<br>
-TYPE(IncompleteArray, ArrayType)<br>
-TYPE(VariableArray, ArrayType)<br>
-DEPENDENT_TYPE(DependentSizedArray, ArrayType)<br>
-DEPENDENT_TYPE(DependentSizedExtVector, Type)<br>
-DEPENDENT_TYPE(DependentAddressSpace, Type)<br>
-TYPE(Vector, Type)<br>
-DEPENDENT_TYPE(DependentVector, Type)<br>
-TYPE(ExtVector, VectorType)<br>
-ABSTRACT_TYPE(Function, Type)<br>
-TYPE(FunctionProto, FunctionType)<br>
-TYPE(FunctionNoProto, FunctionType)<br>
-DEPENDENT_TYPE(UnresolvedUsing, Type)<br>
-NON_CANONICAL_TYPE(Paren, Type)<br>
-NON_CANONICAL_TYPE(Typedef, Type)<br>
-NON_CANONICAL_TYPE(MacroQualified, Type)<br>
-NON_CANONICAL_TYPE(Adjusted, Type)<br>
-NON_CANONICAL_TYPE(Decayed, AdjustedType)<br>
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)<br>
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)<br>
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type)<br>
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(UnaryTransform, Type)<br>
-ABSTRACT_TYPE(Tag, Type)<br>
-TYPE(Record, TagType)<br>
-TYPE(Enum, TagType)<br>
-NON_CANONICAL_TYPE(Elaborated, Type)<br>
-NON_CANONICAL_TYPE(Attributed, Type)<br>
-DEPENDENT_TYPE(TemplateTypeParm, Type)<br>
-NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)<br>
-DEPENDENT_TYPE(SubstTemplateTypeParmPack, Type)<br>
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)<br>
-ABSTRACT_TYPE(Deduced, Type)<br>
-TYPE(Auto, DeducedType)<br>
-TYPE(DeducedTemplateSpecialization, DeducedType)<br>
-DEPENDENT_TYPE(InjectedClassName, Type)<br>
-DEPENDENT_TYPE(DependentName, Type)<br>
-DEPENDENT_TYPE(DependentTemplateSpecialization, Type)<br>
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(PackExpansion, Type)<br>
-NON_CANONICAL_TYPE(ObjCTypeParam, Type)<br>
-TYPE(ObjCObject, Type)<br>
-TYPE(ObjCInterface, ObjCObjectType)<br>
-TYPE(ObjCObjectPointer, Type)<br>
-TYPE(Pipe, Type)<br>
-TYPE(Atomic, Type)<br>
-<br>
-#ifdef LAST_TYPE<br>
-LAST_TYPE(Atomic)<br>
-#undef LAST_TYPE<br>
-#endif<br>
-<br>
-// These types are always leaves in the type hierarchy.<br>
-#ifdef LEAF_TYPE<br>
-LEAF_TYPE(Enum)<br>
-LEAF_TYPE(Builtin)<br>
-LEAF_TYPE(Record)<br>
-LEAF_TYPE(InjectedClassName)<br>
-LEAF_TYPE(ObjCInterface)<br>
-LEAF_TYPE(TemplateTypeParm)<br>
-#undef LEAF_TYPE<br>
-#endif<br>
-<br>
-#undef NON_CANONICAL_UNLESS_DEPENDENT_TYPE<br>
-#undef DEPENDENT_TYPE<br>
-#undef NON_CANONICAL_TYPE<br>
-#undef ABSTRACT_TYPE<br>
-#undef TYPE<br>
<br>
Added: cfe/trunk/include/clang/Basic/TypeNodes.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TypeNodes.td?rev=373407&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TypeNodes.td?rev=373407&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/TypeNodes.td (added)<br>
+++ cfe/trunk/include/clang/Basic/TypeNodes.td Tue Oct  1 16:13:03 2019<br>
@@ -0,0 +1,106 @@<br>
+class Type<bit abstract = 0> {<br>
+  bit Abstract = abstract;<br>
+} <br>
+<br>
+class DerivedType<Type base, bit abstract = 0> : Type<abstract> {<br>
+       Type Base = base;<br>
+}<br>
+<br>
+/// A type node that is only used to represent dependent types in C++.  For<br>
+/// example, DependentTemplateSpecializationType is used to represent types<br>
+/// where the base template-id is dependent (such as `T::foo<U>`).  Code<br>
+/// that only works with non-dependent types can ignore these type nodes.<br>
+class AlwaysDependent {}<br>
+<br>
+/// A type node that is never used to represent a canonical type, which is to<br>
+/// say that it always represents some sort of type "sugar" which can<br>
+/// (supposedly) be erased without affecting the formal behavior of the<br>
+/// language.  For example, in standard C/C++, typedefs do not introduce new<br>
+/// types and do not affect the semantics of the program.  Code that only<br>
+/// works with canonical types can ignore these type nodes.<br>
+///<br>
+/// Note that this simple story about non-canonical types is not the whole<br>
+/// truth.  Languages and extensions often have formation rules which differ<br>
+/// based on how a type is spelled and which therefore are not consistent<br>
+/// with immediately stipping away type sugar.  More critically, attributes on<br>
+/// typedefs can have semantic impacts in ways that are only reflected in our<br>
+/// AST by preserving the typedef sugar; for example, we do not otherwise<br>
+/// represent the alignment attribute on typedefs, and so it is necessary to<br>
+/// preserve typedef structure into most parts of IR generation.<br>
+class NeverCanonical {}<br>
+<br>
+/// A type node that only represents a canonical type in some dependent cases.<br>
+/// For example, `std::vector<int>` (a TemplateSpecializationType) is<br>
+/// considered to be a non-canonical representation for the RecordType<br>
+/// referencing the concrete ClassTemplateSpecializationDecl; but<br>
+/// `std::vector<T>` cannot be resolved to a concrete specialization<br>
+/// and so remains canonical.  Code which only works with non-dependent<br>
+/// canonical types can ignore these nodes.<br>
+class NeverCanonicalUnlessDependent {}<br>
+<br>
+/// A type node which never has component type structure.  Some code may be<br>
+/// able to operate on leaf types faster than they can on non-leaf types.<br>
+///<br>
+/// For example, the function type `void (int)` is not a leaf type because it<br>
+/// is structurally composed of component types (`void` and `int`).<br>
+///<br>
+/// A struct type is a leaf type because its field types are not part of its<br>
+/// type-expression.<br>
+///<br>
+/// Nodes like `TypedefType` which are syntactically leaves but can desugar<br>
+/// to types that may not be leaves should not declare this.<br>
+class LeafType {}<br>
+<br>
+def BuiltinType : Type, LeafType;<br>
+def ComplexType : Type;<br>
+def PointerType : Type;<br>
+def BlockPointerType : Type;<br>
+def ReferenceType : Type<1>;<br>
+def LValueReferenceType : DerivedType<ReferenceType>;<br>
+def RValueReferenceType : DerivedType<ReferenceType>;<br>
+def MemberPointerType : Type;<br>
+def ArrayType : Type<1>;<br>
+def ConstantArrayType : DerivedType<ArrayType>;<br>
+def IncompleteArrayType : DerivedType<ArrayType>;<br>
+def VariableArrayType : DerivedType<ArrayType>;<br>
+def DependentSizedArrayType : DerivedType<ArrayType>, AlwaysDependent;<br>
+def DependentSizedExtVectorType : Type, AlwaysDependent;<br>
+def DependentAddressSpaceType : Type, AlwaysDependent;<br>
+def VectorType : Type;<br>
+def DependentVectorType : Type, AlwaysDependent;<br>
+def ExtVectorType : DerivedType<VectorType>;<br>
+def FunctionType : Type<1>;<br>
+def FunctionProtoType : DerivedType<FunctionType>;<br>
+def FunctionNoProtoType : DerivedType<FunctionType>;<br>
+def UnresolvedUsingType : Type, AlwaysDependent;<br>
+def ParenType : Type, NeverCanonical;<br>
+def TypedefType : Type, NeverCanonical;<br>
+def MacroQualifiedType : Type, NeverCanonical;<br>
+def AdjustedType : Type, NeverCanonical;<br>
+def DecayedType : DerivedType<AdjustedType>, NeverCanonical;<br>
+def TypeOfExprType : Type, NeverCanonicalUnlessDependent;<br>
+def TypeOfType : Type, NeverCanonicalUnlessDependent;<br>
+def DecltypeType : Type, NeverCanonicalUnlessDependent;<br>
+def UnaryTransformType : Type, NeverCanonicalUnlessDependent;<br>
+def TagType : Type<1>;<br>
+def RecordType : DerivedType<TagType>, LeafType;<br>
+def EnumType : DerivedType<TagType>, LeafType;<br>
+def ElaboratedType : Type, NeverCanonical;<br>
+def AttributedType : Type, NeverCanonical;<br>
+def TemplateTypeParmType : Type, AlwaysDependent, LeafType;<br>
+def SubstTemplateTypeParmType : Type, NeverCanonical;<br>
+def SubstTemplateTypeParmPackType : Type, AlwaysDependent;<br>
+def TemplateSpecializationType : Type, NeverCanonicalUnlessDependent;<br>
+def DeducedType : Type<1>;<br>
+def AutoType : DerivedType<DeducedType>;<br>
+def DeducedTemplateSpecializationType : DerivedType<DeducedType>;<br>
+def InjectedClassNameType : Type, AlwaysDependent, LeafType;<br>
+def DependentNameType : Type, AlwaysDependent;<br>
+def DependentTemplateSpecializationType : Type, AlwaysDependent;<br>
+def PackExpansionType : Type, NeverCanonicalUnlessDependent;<br>
+def ObjCTypeParamType : Type, NeverCanonical;<br>
+def ObjCObjectType : Type;<br>
+def ObjCInterfaceType : DerivedType<ObjCObjectType>, LeafType;<br>
+def ObjCObjectPointerType : Type;<br>
+def PipeType : Type;<br>
+def AtomicType : Type;<br>
<br>
Modified: cfe/trunk/utils/TableGen/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/CMakeLists.txt?rev=373407&r1=373406&r2=373407&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/CMakeLists.txt?rev=373407&r1=373406&r2=373407&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/utils/TableGen/CMakeLists.txt (original)<br>
+++ cfe/trunk/utils/TableGen/CMakeLists.txt Tue Oct  1 16:13:03 2019<br>
@@ -12,6 +12,7 @@ add_tablegen(clang-tblgen CLANG<br>
   ClangOpenCLBuiltinEmitter.cpp<br>
   ClangOptionDocEmitter.cpp<br>
   ClangSACheckersEmitter.cpp<br>
+  ClangTypeNodesEmitter.cpp<br>
   NeonEmitter.cpp<br>
   TableGen.cpp<br>
   )<br>
<br>
Added: cfe/trunk/utils/TableGen/ClangTypeNodesEmitter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangTypeNodesEmitter.cpp?rev=373407&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangTypeNodesEmitter.cpp?rev=373407&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/utils/TableGen/ClangTypeNodesEmitter.cpp (added)<br>
+++ cfe/trunk/utils/TableGen/ClangTypeNodesEmitter.cpp Tue Oct  1 16:13:03 2019<br>
@@ -0,0 +1,220 @@<br>
+//=== ClangTypeNodesEmitter.cpp - Generate type node tables -----*- C++ -*-===//<br>
+//<br>
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
+// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This tblgen backend emits the node table (the .def file) for Clang<br>
+// type nodes.<br>
+//<br>
+// This file defines the AST type info database. Each type node is<br>
+// enumerated by providing its name (e.g., "Builtin" or "Enum") and<br>
+// base class (e.g., "Type" or "TagType"). Depending on where in the<br>
+// abstract syntax tree the type will show up, the enumeration uses<br>
+// one of five different macros:<br>
+//<br>
+//    TYPE(Class, Base) - A type that can show up anywhere in the AST,<br>
+//    and might be dependent, canonical, or non-canonical. All clients<br>
+//    will need to understand these types.<br>
+//<br>
+//    ABSTRACT_TYPE(Class, Base) - An abstract class that shows up in<br>
+//    the type hierarchy but has no concrete instances.<br>
+//<br>
+//    NON_CANONICAL_TYPE(Class, Base) - A type that can show up<br>
+//    anywhere in the AST but will never be a part of a canonical<br>
+//    type. Clients that only need to deal with canonical types<br>
+//    (ignoring, e.g., typedefs and other type aliases used for<br>
+//    pretty-printing) can ignore these types.<br>
+//<br>
+//    DEPENDENT_TYPE(Class, Base) - A type that will only show up<br>
+//    within a C++ template that has not been instantiated, e.g., a<br>
+//    type that is always dependent. Clients that do not need to deal<br>
+//    with uninstantiated C++ templates can ignore these types.<br>
+//<br>
+//    NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) - A type that<br>
+//    is non-canonical unless it is dependent.  Defaults to TYPE because<br>
+//    it is neither reliably dependent nor reliably non-canonical.<br>
+//<br>
+// There is a sixth macro, independent of the others.  Most clients<br>
+// will not need to use it.<br>
+//<br>
+//    LEAF_TYPE(Class) - A type that never has inner types.  Clients<br>
+//    which can operate on such types more efficiently may wish to do so.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "llvm/ADT/StringRef.h"<br>
+#include "llvm/TableGen/Error.h"<br>
+#include "llvm/TableGen/Record.h"<br>
+#include "llvm/TableGen/TableGenBackend.h"<br>
+#include <set><br>
+#include <string><br>
+#include <vector><br>
+#include "TableGenBackends.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+// These are spellings in the generated output.<br>
+#define TypeMacroName "TYPE"<br>
+#define AbstractTypeMacroName "ABSTRACT_TYPE"<br>
+#define DependentTypeMacroName "DEPENDENT_TYPE"<br>
+#define NonCanonicalTypeMacroName "NON_CANONICAL_TYPE"<br>
+#define NonCanonicalUnlessDependentTypeMacroName "NON_CANONICAL_UNLESS_DEPENDENT_TYPE"<br>
+#define TypeMacroArgs "(Class, Base)"<br>
+#define LastTypeMacroName "LAST_TYPE"<br>
+#define LeafTypeMacroName "LEAF_TYPE"<br>
+<br>
+// These are spellings in the tblgen file.<br>
+// (Type is also used for the spelling of the AST class.)<br>
+#define TypeClassName "Type"<br>
+#define DerivedTypeClassName "DerivedType"<br>
+#define AlwaysDependentClassName "AlwaysDependent"<br>
+#define NeverCanonicalClassName "NeverCanonical"<br>
+#define NeverCanonicalUnlessDependentClassName "NeverCanonicalUnlessDependent"<br>
+#define LeafTypeClassName "LeafType"<br>
+#define AbstractFieldName "Abstract"<br>
+#define BaseFieldName "Base"<br>
+<br>
+static StringRef getIdForType(Record *type) {<br>
+       // The record name is expected to be the full C++ class name,<br>
+       // including "Type".  Check for that and strip it off.<br>
+       auto fullName = type->getName();<br>
+       if (!fullName.endswith("Type"))<br>
+               PrintFatalError(type->getLoc(), "name of Type node doesn't end in Type");<br>
+       return fullName.drop_back(4);<br>
+}<br>
+<br>
+namespace {<br>
+class TypeNodeEmitter {<br>
+       RecordKeeper &Records;<br>
+       raw_ostream &Out;<br>
+       const std::vector<Record*> Types;<br>
+       std::vector<StringRef> MacrosToUndef;<br>
+<br>
+public:<br>
+       TypeNodeEmitter(RecordKeeper &records, raw_ostream &out)<br>
+               : Records(records), Out(out),<br>
+                       Types(Records.getAllDerivedDefinitions("Type")) {<br>
+       }<br>
+<br>
+       void emit();<br>
+<br>
+private:<br>
+       void emitFallbackDefine(StringRef macroName, StringRef fallbackMacroName,<br>
+                                                                                                       StringRef args);<br>
+<br>
+       void emitNodeInvocations();<br>
+       void emitLastNodeInvocation();<br>
+       void emitLeafNodeInvocations();<br>
+<br>
+       void addMacroToUndef(StringRef macroName);<br>
+       void emitUndefs();<br>
+};<br>
+}<br>
+<br>
+void TypeNodeEmitter::emit() {<br>
+       if (Types.empty())<br>
+               PrintFatalError("no Type records in input!");<br>
+<br>
+       emitSourceFileHeader("An x-macro database of Clang type nodes", Out);<br>
+<br>
+       // Preamble<br>
+       addMacroToUndef(TypeMacroName);<br>
+       addMacroToUndef(AbstractTypeMacroName);<br>
+       emitFallbackDefine(AbstractTypeMacroName, TypeMacroName, TypeMacroArgs);<br>
+       emitFallbackDefine(NonCanonicalTypeMacroName, TypeMacroName, TypeMacroArgs);<br>
+       emitFallbackDefine(DependentTypeMacroName, TypeMacroName, TypeMacroArgs);<br>
+       emitFallbackDefine(NonCanonicalUnlessDependentTypeMacroName, TypeMacroName, <br>
+                                                                                TypeMacroArgs);<br>
+<br>
+       // Invocations.<br>
+       emitNodeInvocations();<br>
+       emitLastNodeInvocation();<br>
+       emitLeafNodeInvocations();<br>
+<br>
+       // Postmatter<br>
+       emitUndefs();<br>
+}<br>
+<br>
+void TypeNodeEmitter::emitFallbackDefine(StringRef macroName,<br>
+                                                                                                                                                                StringRef fallbackMacroName,<br>
+                                                                                                                                                                StringRef args) {<br>
+  Out << "#ifndef " << macroName << "\n";<br>
+  Out << "#  define " << macroName << args<br>
+         << " " << fallbackMacroName << args << "\n";<br>
+  Out << "#endif\n";<br>
+<br>
+  addMacroToUndef(macroName);<br>
+}<br>
+<br>
+void TypeNodeEmitter::emitNodeInvocations() {<br>
+       for (auto type : Types) {<br>
+               // The name with the Type suffix.<br>
+               StringRef id = getIdForType(type);<br>
+<br>
+               // Figure out which macro to use.<br>
+               StringRef macroName;<br>
+               auto setMacroName = [&](StringRef newName) {<br>
+                       if (!macroName.empty())<br>
+                               PrintFatalError(type->getLoc(),<br>
+                                                                                               Twine("conflict when computing macro name for "<br>
+                                                                                                                       "Type node: trying to use both \"")<br>
+                                                                                                       + macroName + "\" and \"" + newName + "\"");<br>
+                       macroName = newName;<br>
+               };<br>
+               if (type->isSubClassOf(AlwaysDependentClassName))<br>
+                       setMacroName(DependentTypeMacroName);<br>
+               if (type->isSubClassOf(NeverCanonicalClassName))<br>
+                       setMacroName(NonCanonicalTypeMacroName);<br>
+               if (type->isSubClassOf(NeverCanonicalUnlessDependentClassName))<br>
+                       setMacroName(NonCanonicalUnlessDependentTypeMacroName);<br>
+               if (type->getValueAsBit(AbstractFieldName))<br>
+                       setMacroName(AbstractTypeMacroName);<br>
+               if (macroName.empty())<br>
+                       macroName = TypeMacroName;<br>
+<br>
+               // Compute the base class.<br>
+               StringRef baseName = TypeClassName;<br>
+               if (type->isSubClassOf(DerivedTypeClassName))<br>
+                       baseName = type->getValueAsDef(BaseFieldName)->getName();<br>
+<br>
+               // Generate the invocation line.<br>
+               Out << macroName << "(" << id << ", " << baseName << ")\n";<br>
+       }<br>
+}<br>
+<br>
+void TypeNodeEmitter::emitLastNodeInvocation() {<br>
+       // We check that this is non-empty earlier.<br>
+       Out << "#ifdef " LastTypeMacroName "\n"<br>
+              LastTypeMacroName "(" << getIdForType(Types.back()) << ")\n"<br>
+                                "#undef " LastTypeMacroName "\n"<br>
+                                "#endif\n";<br>
+}<br>
+<br>
+void TypeNodeEmitter::emitLeafNodeInvocations() {<br>
+       Out << "#ifdef " LeafTypeMacroName "\n";<br>
+<br>
+       for (auto type : Types) {<br>
+               if (!type->isSubClassOf(LeafTypeClassName)) continue;<br>
+               Out << LeafTypeMacroName "(" << getIdForType(type) << ")\n";<br>
+       }<br>
+<br>
+       Out << "#undef " LeafTypeMacroName "\n"<br>
+                                "#endif\n";<br>
+}<br>
+<br>
+void TypeNodeEmitter::addMacroToUndef(StringRef macroName) {<br>
+       MacrosToUndef.push_back(macroName);<br>
+}<br>
+<br>
+void TypeNodeEmitter::emitUndefs() {<br>
+       for (auto &macroName : MacrosToUndef) {<br>
+               Out << "#undef " << macroName << "\n";<br>
+       }<br>
+}<br>
+<br>
+void clang::EmitClangTypeNodes(RecordKeeper &records, raw_ostream &out) {<br>
+       TypeNodeEmitter(records, out).emit();<br>
+}<br>
<br>
Modified: cfe/trunk/utils/TableGen/TableGen.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGen.cpp?rev=373407&r1=373406&r2=373407&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGen.cpp?rev=373407&r1=373406&r2=373407&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/utils/TableGen/TableGen.cpp (original)<br>
+++ cfe/trunk/utils/TableGen/TableGen.cpp Tue Oct  1 16:13:03 2019<br>
@@ -47,6 +47,7 @@ enum ActionType {<br>
   GenClangCommentNodes,<br>
   GenClangDeclNodes,<br>
   GenClangStmtNodes,<br>
+  GenClangTypeNodes,<br>
   GenClangOpcodes,<br>
   GenClangSACheckers,<br>
   GenClangCommentHTMLTags,<br>
@@ -130,6 +131,8 @@ cl::opt<ActionType> Action(<br>
                    "Generate Clang AST declaration nodes"),<br>
         clEnumValN(GenClangStmtNodes, "gen-clang-stmt-nodes",<br>
                    "Generate Clang AST statement nodes"),<br>
+        clEnumValN(GenClangTypeNodes, "gen-clang-type-nodes",<br>
+                   "Generate Clang AST type nodes"),<br>
         clEnumValN(GenClangOpcodes, "gen-clang-opcodes",<br>
                    "Generate Clang constexpr interpreter opcodes"),<br>
         clEnumValN(GenClangSACheckers, "gen-clang-sa-checkers",<br>
@@ -254,6 +257,9 @@ bool ClangTableGenMain(raw_ostream &OS,<br>
   case GenClangStmtNodes:<br>
     EmitClangASTNodes(Records, OS, "Stmt", "");<br>
     break;<br>
+  case GenClangTypeNodes:<br>
+    EmitClangTypeNodes(Records, OS);<br>
+    break;<br>
   case GenClangOpcodes:<br>
     EmitClangOpcodes(Records, OS);<br>
     break;<br>
<br>
Modified: cfe/trunk/utils/TableGen/TableGenBackends.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGenBackends.h?rev=373407&r1=373406&r2=373407&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGenBackends.h?rev=373407&r1=373406&r2=373407&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/utils/TableGen/TableGenBackends.h (original)<br>
+++ cfe/trunk/utils/TableGen/TableGenBackends.h Tue Oct  1 16:13:03 2019<br>
@@ -27,6 +27,7 @@ namespace clang {<br>
 void EmitClangDeclContext(llvm::RecordKeeper &RK, llvm::raw_ostream &OS);<br>
 void EmitClangASTNodes(llvm::RecordKeeper &RK, llvm::raw_ostream &OS,<br>
                        const std::string &N, const std::string &S);<br>
+void EmitClangTypeNodes(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);<br>
<br>
 void EmitClangAttrParserStringSwitches(llvm::RecordKeeper &Records,<br>
                                        llvm::raw_ostream &OS);<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>