r373407 - Emit TypeNodes.def with tblgen.

Nico Weber via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 1 18:20:29 PDT 2019


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 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191001/c51d7418/attachment-0001.html>


More information about the cfe-commits mailing list