On Wed, Oct 2, 2019 at 2:33 AM John McCall <rjmcc...@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 <rjmcc...@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@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@lists.llvm.org > >>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > >>>> > >> > >> > >> > > >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits