r373407 - Emit TypeNodes.def with tblgen.

Nico Weber via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 2 02:43:00 PDT 2019


On Wed, Oct 2, 2019 at 2:33 AM John McCall <rjmccall at apple.com> wrote:

> On 1 Oct 2019, at 21:31, Nico Weber wrote:
> > I think that'd be nice; I believe I renamed one .def output with the
> > same
> > history for the same reason a while ago.
>
> r373425
>

Thanks!


>
> John.
>
> >
> > 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/20191002/1695053e/attachment-0001.html>


More information about the cfe-commits mailing list