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 ¯oName : 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