r373407 - Emit TypeNodes.def with tblgen.

John McCall via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 1 18:25:07 PDT 2019


On 1 Oct 2019, at 21:20, Nico Weber wrote:
> All other tablegen outputs are called .inc instead of .def. Any reason 
> this
> one's different?

This was an existing file; it’s just generated now instead of written
in source.  I was deliberately not changing anything about the existing
use sites.  That said, I could certainly go rename it as a follow-up
just to re-establish that consistent naming convention.

John.

>
> On Tue, Oct 1, 2019 at 7:10 PM John McCall via cfe-commits <
> cfe-commits at 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 &macroName : 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 at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>




More information about the cfe-commits mailing list