r373407 - Emit TypeNodes.def with tblgen.

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


I think that'd be nice; I believe I renamed one .def output with the same
history for the same reason a while ago.

On Tue, Oct 1, 2019 at 9:25 PM John McCall <rjmccall at apple.com> wrote:

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


More information about the cfe-commits mailing list