r373407 - Emit TypeNodes.def with tblgen.

John McCall via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 1 23:33:40 PDT 2019


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

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
>>>>
>>
>>
>>




More information about the cfe-commits mailing list