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