<div dir="ltr"><div dir="ltr">On Wed, Oct 2, 2019 at 2:33 AM John McCall <<a href="mailto:rjmccall@apple.com">rjmccall@apple.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 1 Oct 2019, at 21:31, Nico Weber wrote:<br>
> I think that'd be nice; I believe I renamed one .def output with the <br>
> same<br>
> history for the same reason a while ago.<br>
<br>
r373425<br></blockquote><div><br></div><div>Thanks!</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
John.<br>
<br>
><br>
> On Tue, Oct 1, 2019 at 9:25 PM John McCall <<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>> wrote:<br>
><br>
>> On 1 Oct 2019, at 21:20, Nico Weber wrote:<br>
>>> All other tablegen outputs are called .inc instead of .def. Any <br>
>>> reason<br>
>>> this<br>
>>> one's different?<br>
>><br>
>> This was an existing file; it’s just generated now instead of <br>
>> written<br>
>> in source.  I was deliberately not changing anything about the <br>
>> existing<br>
>> use sites.  That said, I could certainly go rename it as a follow-up<br>
>> just to re-establish that consistent naming convention.<br>
>><br>
>> John.<br>
>><br>
>>><br>
>>> On Tue, Oct 1, 2019 at 7:10 PM John McCall via cfe-commits <<br>
>>> <a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br>
>>><br>
>>>> Author: rjmccall<br>
>>>> Date: Tue Oct  1 16:13:03 2019<br>
>>>> New Revision: 373407<br>
>>>><br>
>>>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=373407&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=373407&view=rev</a><br>
>>>> Log:<br>
>>>> Emit TypeNodes.def with tblgen.<br>
>>>><br>
>>>> The primary goal here is to make the type node hierarchy available <br>
>>>> to<br>
>>>> other tblgen backends, although it should also make it easier to<br>
>>>> generate<br>
>>>> more selective x-macros in the future.<br>
>>>><br>
>>>> Because tblgen doesn't seem to allow backends to preserve the <br>
>>>> source<br>
>>>> order of defs, this is not NFC because it significantly re-orders<br>
>>>> IDs.<br>
>>>> I've fixed the one (fortunately obvious) place where we relied on<br>
>>>> the old order.  Unfortunately, I wasn't able to share code with the<br>
>>>> existing AST-node x-macro generators because the x-macro schema we<br>
>>>> use<br>
>>>> for types is different in a number of ways.  The main loss is that<br>
>>>> subclasses aren't ordered together, which doesn't seem important <br>
>>>> for<br>
>>>> types because the hierarchy is generally very shallow with little<br>
>>>> clustering.<br>
>>>><br>
>>>> Added:<br>
>>>>     cfe/trunk/include/clang/Basic/TypeNodes.td<br>
>>>>     cfe/trunk/utils/TableGen/ClangTypeNodesEmitter.cpp<br>
>>>> Removed:<br>
>>>>     cfe/trunk/include/clang/AST/TypeNodes.def<br>
>>>> Modified:<br>
>>>>     cfe/trunk/include/clang/AST/CMakeLists.txt<br>
>>>>     cfe/trunk/include/clang/AST/Type.h<br>
>>>>     cfe/trunk/utils/TableGen/CMakeLists.txt<br>
>>>>     cfe/trunk/utils/TableGen/TableGen.cpp<br>
>>>>     cfe/trunk/utils/TableGen/TableGenBackends.h<br>
>>>><br>
>>>> Modified: cfe/trunk/include/clang/AST/CMakeLists.txt<br>
>>>> URL:<br>
>>>><br>
>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CMakeLists.txt?rev=373407&r1=373406&r2=373407&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CMakeLists.txt?rev=373407&r1=373406&r2=373407&view=diff</a><br>
>>>><br>
>>>><br>
>> ==============================================================================<br>
>>>> --- cfe/trunk/include/clang/AST/CMakeLists.txt (original)<br>
>>>> +++ cfe/trunk/include/clang/AST/CMakeLists.txt Tue Oct  1 16:13:03<br>
>>>> 2019<br>
>>>> @@ -31,6 +31,10 @@ clang_tablegen(DeclNodes.inc -gen-clang-<br>
>>>>    SOURCE ../Basic/DeclNodes.td<br>
>>>>    TARGET ClangDeclNodes)<br>
>>>><br>
>>>> +clang_tablegen(TypeNodes.def -gen-clang-type-nodes<br>
>>>> +  SOURCE ../Basic/TypeNodes.td<br>
>>>> +  TARGET ClangTypeNodes)<br>
>>>> +<br>
>>>>  clang_tablegen(CommentNodes.inc -gen-clang-comment-nodes<br>
>>>>    SOURCE ../Basic/CommentNodes.td<br>
>>>>    TARGET ClangCommentNodes)<br>
>>>><br>
>>>> Modified: cfe/trunk/include/clang/AST/Type.h<br>
>>>> URL:<br>
>>>><br>
>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=373407&r1=373406&r2=373407&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=373407&r1=373406&r2=373407&view=diff</a><br>
>>>><br>
>>>><br>
>> ==============================================================================<br>
>>>> --- cfe/trunk/include/clang/AST/Type.h (original)<br>
>>>> +++ cfe/trunk/include/clang/AST/Type.h Tue Oct  1 16:13:03 2019<br>
>>>> @@ -1437,10 +1437,9 @@ class alignas(8) Type : public ExtQualsT<br>
>>>>  public:<br>
>>>>    enum TypeClass {<br>
>>>>  #define TYPE(Class, Base) Class,<br>
>>>> -#define LAST_TYPE(Class) TypeLast = Class,<br>
>>>> +#define LAST_TYPE(Class) TypeLast = Class<br>
>>>>  #define ABSTRACT_TYPE(Class, Base)<br>
>>>>  #include "clang/AST/TypeNodes.def"<br>
>>>> -    TagFirst = Record, TagLast = Enum<br>
>>>>    };<br>
>>>><br>
>>>>  private:<br>
>>>> @@ -4436,7 +4435,7 @@ public:<br>
>>>>    bool isBeingDefined() const;<br>
>>>><br>
>>>>    static bool classof(const Type *T) {<br>
>>>> -    return T->getTypeClass() >= TagFirst && T->getTypeClass() <=<br>
>>>> TagLast;<br>
>>>> +    return T->getTypeClass() == Enum || T->getTypeClass() == <br>
>>>> Record;<br>
>>>>    }<br>
>>>>  };<br>
>>>><br>
>>>><br>
>>>> Removed: cfe/trunk/include/clang/AST/TypeNodes.def<br>
>>>> URL:<br>
>>>><br>
>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=373406&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=373406&view=auto</a><br>
>>>><br>
>>>><br>
>> ==============================================================================<br>
>>>> --- cfe/trunk/include/clang/AST/TypeNodes.def (original)<br>
>>>> +++ cfe/trunk/include/clang/AST/TypeNodes.def (removed)<br>
>>>> @@ -1,135 +0,0 @@<br>
>>>> -//===-- TypeNodes.def - Metadata about Type AST nodes <br>
>>>> -----------*-<br>
>>>> C++<br>
>>>> -*-===//<br>
>>>> -//<br>
>>>> -// Part of the LLVM Project, under the Apache License v2.0 with <br>
>>>> LLVM<br>
>>>> Exceptions.<br>
>>>> -// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
>>>> -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
>>>> -//<br>
>>>><br>
>>>><br>
>> -//===----------------------------------------------------------------------===//<br>
>>>> -//<br>
>>>> -//  This file defines the AST type info database. Each type node <br>
>>>> is<br>
>>>> -//  enumerated by providing its name (e.g., "Builtin" or "Enum") <br>
>>>> and<br>
>>>> -//  base class (e.g., "Type" or "TagType"). Depending on where in<br>
>>>> the<br>
>>>> -//  abstract syntax tree the type will show up, the enumeration <br>
>>>> uses<br>
>>>> -//  one of five different macros:<br>
>>>> -//<br>
>>>> -//    TYPE(Class, Base) - A type that can show up anywhere in the<br>
>>>> AST,<br>
>>>> -//    and might be dependent, canonical, or non-canonical. All<br>
>>>> clients<br>
>>>> -//    will need to understand these types.<br>
>>>> -//<br>
>>>> -//    ABSTRACT_TYPE(Class, Base) - An abstract class that shows up<br>
>>>> in<br>
>>>> -//    the type hierarchy but has no concrete instances.<br>
>>>> -//<br>
>>>> -//    NON_CANONICAL_TYPE(Class, Base) - A type that can show up<br>
>>>> -//    anywhere in the AST but will never be a part of a canonical<br>
>>>> -//    type. Clients that only need to deal with canonical types<br>
>>>> -//    (ignoring, e.g., typedefs and other type aliases used for<br>
>>>> -//    pretty-printing) can ignore these types.<br>
>>>> -//<br>
>>>> -//    DEPENDENT_TYPE(Class, Base) - A type that will only show up<br>
>>>> -//    within a C++ template that has not been instantiated, e.g., <br>
>>>> a<br>
>>>> -//    type that is always dependent. Clients that do not need to<br>
>>>> deal<br>
>>>> -//    with uninstantiated C++ templates can ignore these types.<br>
>>>> -//<br>
>>>> -//    NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) - A type <br>
>>>> that<br>
>>>> -//    is non-canonical unless it is dependent.  Defaults to TYPE<br>
>>>> because<br>
>>>> -//    it is neither reliably dependent nor reliably non-canonical.<br>
>>>> -//<br>
>>>> -//  There is a sixth macro, independent of the others.  Most <br>
>>>> clients<br>
>>>> -//  will not need to use it.<br>
>>>> -//<br>
>>>> -//    LEAF_TYPE(Class) - A type that never has inner types.  <br>
>>>> Clients<br>
>>>> -//    which can operate on such types more efficiently may wish to<br>
>>>> do so.<br>
>>>> -//<br>
>>>><br>
>>>><br>
>> -//===----------------------------------------------------------------------===//<br>
>>>> -<br>
>>>> -#ifndef ABSTRACT_TYPE<br>
>>>> -#  define ABSTRACT_TYPE(Class, Base) TYPE(Class, Base)<br>
>>>> -#endif<br>
>>>> -<br>
>>>> -#ifndef NON_CANONICAL_TYPE<br>
>>>> -#  define NON_CANONICAL_TYPE(Class, Base) TYPE(Class, Base)<br>
>>>> -#endif<br>
>>>> -<br>
>>>> -#ifndef DEPENDENT_TYPE<br>
>>>> -#  define DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)<br>
>>>> -#endif<br>
>>>> -<br>
>>>> -#ifndef NON_CANONICAL_UNLESS_DEPENDENT_TYPE<br>
>>>> -#  define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)<br>
>>>> TYPE(Class,<br>
>>>> Base)<br>
>>>> -#endif<br>
>>>> -<br>
>>>> -TYPE(Builtin, Type)<br>
>>>> -TYPE(Complex, Type)<br>
>>>> -TYPE(Pointer, Type)<br>
>>>> -TYPE(BlockPointer, Type)<br>
>>>> -ABSTRACT_TYPE(Reference, Type)<br>
>>>> -TYPE(LValueReference, ReferenceType)<br>
>>>> -TYPE(RValueReference, ReferenceType)<br>
>>>> -TYPE(MemberPointer, Type)<br>
>>>> -ABSTRACT_TYPE(Array, Type)<br>
>>>> -TYPE(ConstantArray, ArrayType)<br>
>>>> -TYPE(IncompleteArray, ArrayType)<br>
>>>> -TYPE(VariableArray, ArrayType)<br>
>>>> -DEPENDENT_TYPE(DependentSizedArray, ArrayType)<br>
>>>> -DEPENDENT_TYPE(DependentSizedExtVector, Type)<br>
>>>> -DEPENDENT_TYPE(DependentAddressSpace, Type)<br>
>>>> -TYPE(Vector, Type)<br>
>>>> -DEPENDENT_TYPE(DependentVector, Type)<br>
>>>> -TYPE(ExtVector, VectorType)<br>
>>>> -ABSTRACT_TYPE(Function, Type)<br>
>>>> -TYPE(FunctionProto, FunctionType)<br>
>>>> -TYPE(FunctionNoProto, FunctionType)<br>
>>>> -DEPENDENT_TYPE(UnresolvedUsing, Type)<br>
>>>> -NON_CANONICAL_TYPE(Paren, Type)<br>
>>>> -NON_CANONICAL_TYPE(Typedef, Type)<br>
>>>> -NON_CANONICAL_TYPE(MacroQualified, Type)<br>
>>>> -NON_CANONICAL_TYPE(Adjusted, Type)<br>
>>>> -NON_CANONICAL_TYPE(Decayed, AdjustedType)<br>
>>>> -NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)<br>
>>>> -NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)<br>
>>>> -NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type)<br>
>>>> -NON_CANONICAL_UNLESS_DEPENDENT_TYPE(UnaryTransform, Type)<br>
>>>> -ABSTRACT_TYPE(Tag, Type)<br>
>>>> -TYPE(Record, TagType)<br>
>>>> -TYPE(Enum, TagType)<br>
>>>> -NON_CANONICAL_TYPE(Elaborated, Type)<br>
>>>> -NON_CANONICAL_TYPE(Attributed, Type)<br>
>>>> -DEPENDENT_TYPE(TemplateTypeParm, Type)<br>
>>>> -NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)<br>
>>>> -DEPENDENT_TYPE(SubstTemplateTypeParmPack, Type)<br>
>>>> -NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)<br>
>>>> -ABSTRACT_TYPE(Deduced, Type)<br>
>>>> -TYPE(Auto, DeducedType)<br>
>>>> -TYPE(DeducedTemplateSpecialization, DeducedType)<br>
>>>> -DEPENDENT_TYPE(InjectedClassName, Type)<br>
>>>> -DEPENDENT_TYPE(DependentName, Type)<br>
>>>> -DEPENDENT_TYPE(DependentTemplateSpecialization, Type)<br>
>>>> -NON_CANONICAL_UNLESS_DEPENDENT_TYPE(PackExpansion, Type)<br>
>>>> -NON_CANONICAL_TYPE(ObjCTypeParam, Type)<br>
>>>> -TYPE(ObjCObject, Type)<br>
>>>> -TYPE(ObjCInterface, ObjCObjectType)<br>
>>>> -TYPE(ObjCObjectPointer, Type)<br>
>>>> -TYPE(Pipe, Type)<br>
>>>> -TYPE(Atomic, Type)<br>
>>>> -<br>
>>>> -#ifdef LAST_TYPE<br>
>>>> -LAST_TYPE(Atomic)<br>
>>>> -#undef LAST_TYPE<br>
>>>> -#endif<br>
>>>> -<br>
>>>> -// These types are always leaves in the type hierarchy.<br>
>>>> -#ifdef LEAF_TYPE<br>
>>>> -LEAF_TYPE(Enum)<br>
>>>> -LEAF_TYPE(Builtin)<br>
>>>> -LEAF_TYPE(Record)<br>
>>>> -LEAF_TYPE(InjectedClassName)<br>
>>>> -LEAF_TYPE(ObjCInterface)<br>
>>>> -LEAF_TYPE(TemplateTypeParm)<br>
>>>> -#undef LEAF_TYPE<br>
>>>> -#endif<br>
>>>> -<br>
>>>> -#undef NON_CANONICAL_UNLESS_DEPENDENT_TYPE<br>
>>>> -#undef DEPENDENT_TYPE<br>
>>>> -#undef NON_CANONICAL_TYPE<br>
>>>> -#undef ABSTRACT_TYPE<br>
>>>> -#undef TYPE<br>
>>>><br>
>>>> Added: cfe/trunk/include/clang/Basic/TypeNodes.td<br>
>>>> URL:<br>
>>>><br>
>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TypeNodes.td?rev=373407&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TypeNodes.td?rev=373407&view=auto</a><br>
>>>><br>
>>>><br>
>> ==============================================================================<br>
>>>> --- cfe/trunk/include/clang/Basic/TypeNodes.td (added)<br>
>>>> +++ cfe/trunk/include/clang/Basic/TypeNodes.td Tue Oct  1 16:13:03<br>
>>>> 2019<br>
>>>> @@ -0,0 +1,106 @@<br>
>>>> +class Type<bit abstract = 0> {<br>
>>>> +  bit Abstract = abstract;<br>
>>>> +}<br>
>>>> +<br>
>>>> +class DerivedType<Type base, bit abstract = 0> : Type<abstract> {<br>
>>>> +       Type Base = base;<br>
>>>> +}<br>
>>>> +<br>
>>>> +/// A type node that is only used to represent dependent types in<br>
>>>> C++.<br>
>>>> For<br>
>>>> +/// example, DependentTemplateSpecializationType is used to<br>
>>>> represent<br>
>>>> types<br>
>>>> +/// where the base template-id is dependent (such as `T::foo<U>`).<br>
>>>> Code<br>
>>>> +/// that only works with non-dependent types can ignore these type<br>
>>>> nodes.<br>
>>>> +class AlwaysDependent {}<br>
>>>> +<br>
>>>> +/// A type node that is never used to represent a canonical type,<br>
>>>> which<br>
>>>> is to<br>
>>>> +/// say that it always represents some sort of type "sugar" which<br>
>>>> can<br>
>>>> +/// (supposedly) be erased without affecting the formal behavior <br>
>>>> of<br>
>>>> the<br>
>>>> +/// language.  For example, in standard C/C++, typedefs do not<br>
>>>> introduce<br>
>>>> new<br>
>>>> +/// types and do not affect the semantics of the program.  Code <br>
>>>> that<br>
>>>> only<br>
>>>> +/// works with canonical types can ignore these type nodes.<br>
>>>> +///<br>
>>>> +/// Note that this simple story about non-canonical types is not <br>
>>>> the<br>
>>>> whole<br>
>>>> +/// truth.  Languages and extensions often have formation rules<br>
>>>> which<br>
>>>> differ<br>
>>>> +/// based on how a type is spelled and which therefore are not<br>
>>>> consistent<br>
>>>> +/// with immediately stipping away type sugar.  More critically,<br>
>>>> attributes on<br>
>>>> +/// typedefs can have semantic impacts in ways that are only<br>
>>>> reflected in<br>
>>>> our<br>
>>>> +/// AST by preserving the typedef sugar; for example, we do not<br>
>>>> otherwise<br>
>>>> +/// represent the alignment attribute on typedefs, and so it is<br>
>>>> necessary<br>
>>>> to<br>
>>>> +/// preserve typedef structure into most parts of IR generation.<br>
>>>> +class NeverCanonical {}<br>
>>>> +<br>
>>>> +/// A type node that only represents a canonical type in some<br>
>>>> dependent<br>
>>>> cases.<br>
>>>> +/// For example, `std::vector<int>` (a TemplateSpecializationType)<br>
>>>> is<br>
>>>> +/// considered to be a non-canonical representation for the<br>
>>>> RecordType<br>
>>>> +/// referencing the concrete ClassTemplateSpecializationDecl; but<br>
>>>> +/// `std::vector<T>` cannot be resolved to a concrete <br>
>>>> specialization<br>
>>>> +/// and so remains canonical.  Code which only works with<br>
>>>> non-dependent<br>
>>>> +/// canonical types can ignore these nodes.<br>
>>>> +class NeverCanonicalUnlessDependent {}<br>
>>>> +<br>
>>>> +/// A type node which never has component type structure.  Some <br>
>>>> code<br>
>>>> may<br>
>>>> be<br>
>>>> +/// able to operate on leaf types faster than they can on non-leaf<br>
>>>> types.<br>
>>>> +///<br>
>>>> +/// For example, the function type `void (int)` is not a leaf type<br>
>>>> because it<br>
>>>> +/// is structurally composed of component types (`void` and <br>
>>>> `int`).<br>
>>>> +///<br>
>>>> +/// A struct type is a leaf type because its field types are not<br>
>>>> part of<br>
>>>> its<br>
>>>> +/// type-expression.<br>
>>>> +///<br>
>>>> +/// Nodes like `TypedefType` which are syntactically leaves but <br>
>>>> can<br>
>>>> desugar<br>
>>>> +/// to types that may not be leaves should not declare this.<br>
>>>> +class LeafType {}<br>
>>>> +<br>
>>>> +def BuiltinType : Type, LeafType;<br>
>>>> +def ComplexType : Type;<br>
>>>> +def PointerType : Type;<br>
>>>> +def BlockPointerType : Type;<br>
>>>> +def ReferenceType : Type<1>;<br>
>>>> +def LValueReferenceType : DerivedType<ReferenceType>;<br>
>>>> +def RValueReferenceType : DerivedType<ReferenceType>;<br>
>>>> +def MemberPointerType : Type;<br>
>>>> +def ArrayType : Type<1>;<br>
>>>> +def ConstantArrayType : DerivedType<ArrayType>;<br>
>>>> +def IncompleteArrayType : DerivedType<ArrayType>;<br>
>>>> +def VariableArrayType : DerivedType<ArrayType>;<br>
>>>> +def DependentSizedArrayType : DerivedType<ArrayType>,<br>
>>>> AlwaysDependent;<br>
>>>> +def DependentSizedExtVectorType : Type, AlwaysDependent;<br>
>>>> +def DependentAddressSpaceType : Type, AlwaysDependent;<br>
>>>> +def VectorType : Type;<br>
>>>> +def DependentVectorType : Type, AlwaysDependent;<br>
>>>> +def ExtVectorType : DerivedType<VectorType>;<br>
>>>> +def FunctionType : Type<1>;<br>
>>>> +def FunctionProtoType : DerivedType<FunctionType>;<br>
>>>> +def FunctionNoProtoType : DerivedType<FunctionType>;<br>
>>>> +def UnresolvedUsingType : Type, AlwaysDependent;<br>
>>>> +def ParenType : Type, NeverCanonical;<br>
>>>> +def TypedefType : Type, NeverCanonical;<br>
>>>> +def MacroQualifiedType : Type, NeverCanonical;<br>
>>>> +def AdjustedType : Type, NeverCanonical;<br>
>>>> +def DecayedType : DerivedType<AdjustedType>, NeverCanonical;<br>
>>>> +def TypeOfExprType : Type, NeverCanonicalUnlessDependent;<br>
>>>> +def TypeOfType : Type, NeverCanonicalUnlessDependent;<br>
>>>> +def DecltypeType : Type, NeverCanonicalUnlessDependent;<br>
>>>> +def UnaryTransformType : Type, NeverCanonicalUnlessDependent;<br>
>>>> +def TagType : Type<1>;<br>
>>>> +def RecordType : DerivedType<TagType>, LeafType;<br>
>>>> +def EnumType : DerivedType<TagType>, LeafType;<br>
>>>> +def ElaboratedType : Type, NeverCanonical;<br>
>>>> +def AttributedType : Type, NeverCanonical;<br>
>>>> +def TemplateTypeParmType : Type, AlwaysDependent, LeafType;<br>
>>>> +def SubstTemplateTypeParmType : Type, NeverCanonical;<br>
>>>> +def SubstTemplateTypeParmPackType : Type, AlwaysDependent;<br>
>>>> +def TemplateSpecializationType : Type,<br>
>>>> NeverCanonicalUnlessDependent;<br>
>>>> +def DeducedType : Type<1>;<br>
>>>> +def AutoType : DerivedType<DeducedType>;<br>
>>>> +def DeducedTemplateSpecializationType : DerivedType<DeducedType>;<br>
>>>> +def InjectedClassNameType : Type, AlwaysDependent, LeafType;<br>
>>>> +def DependentNameType : Type, AlwaysDependent;<br>
>>>> +def DependentTemplateSpecializationType : Type, AlwaysDependent;<br>
>>>> +def PackExpansionType : Type, NeverCanonicalUnlessDependent;<br>
>>>> +def ObjCTypeParamType : Type, NeverCanonical;<br>
>>>> +def ObjCObjectType : Type;<br>
>>>> +def ObjCInterfaceType : DerivedType<ObjCObjectType>, LeafType;<br>
>>>> +def ObjCObjectPointerType : Type;<br>
>>>> +def PipeType : Type;<br>
>>>> +def AtomicType : Type;<br>
>>>><br>
>>>> Modified: cfe/trunk/utils/TableGen/CMakeLists.txt<br>
>>>> URL:<br>
>>>><br>
>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/CMakeLists.txt?rev=373407&r1=373406&r2=373407&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/CMakeLists.txt?rev=373407&r1=373406&r2=373407&view=diff</a><br>
>>>><br>
>>>><br>
>> ==============================================================================<br>
>>>> --- cfe/trunk/utils/TableGen/CMakeLists.txt (original)<br>
>>>> +++ cfe/trunk/utils/TableGen/CMakeLists.txt Tue Oct  1 16:13:03 <br>
>>>> 2019<br>
>>>> @@ -12,6 +12,7 @@ add_tablegen(clang-tblgen CLANG<br>
>>>>    ClangOpenCLBuiltinEmitter.cpp<br>
>>>>    ClangOptionDocEmitter.cpp<br>
>>>>    ClangSACheckersEmitter.cpp<br>
>>>> +  ClangTypeNodesEmitter.cpp<br>
>>>>    NeonEmitter.cpp<br>
>>>>    TableGen.cpp<br>
>>>>    )<br>
>>>><br>
>>>> Added: cfe/trunk/utils/TableGen/ClangTypeNodesEmitter.cpp<br>
>>>> URL:<br>
>>>><br>
>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangTypeNodesEmitter.cpp?rev=373407&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangTypeNodesEmitter.cpp?rev=373407&view=auto</a><br>
>>>><br>
>>>><br>
>> ==============================================================================<br>
>>>> --- cfe/trunk/utils/TableGen/ClangTypeNodesEmitter.cpp (added)<br>
>>>> +++ cfe/trunk/utils/TableGen/ClangTypeNodesEmitter.cpp Tue Oct  1<br>
>>>> 16:13:03<br>
>>>> 2019<br>
>>>> @@ -0,0 +1,220 @@<br>
>>>> +//=== ClangTypeNodesEmitter.cpp - Generate type node tables <br>
>>>> -----*-<br>
>>>> C++<br>
>>>> -*-===//<br>
>>>> +//<br>
>>>> +// Part of the LLVM Project, under the Apache License v2.0 with <br>
>>>> LLVM<br>
>>>> Exceptions.<br>
>>>> +// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
>>>> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
>>>> +//<br>
>>>><br>
>>>><br>
>> +//===----------------------------------------------------------------------===//<br>
>>>> +//<br>
>>>> +// This tblgen backend emits the node table (the .def file) for<br>
>>>> Clang<br>
>>>> +// type nodes.<br>
>>>> +//<br>
>>>> +// This file defines the AST type info database. Each type node is<br>
>>>> +// enumerated by providing its name (e.g., "Builtin" or "Enum") <br>
>>>> and<br>
>>>> +// base class (e.g., "Type" or "TagType"). Depending on where in <br>
>>>> the<br>
>>>> +// abstract syntax tree the type will show up, the enumeration <br>
>>>> uses<br>
>>>> +// one of five different macros:<br>
>>>> +//<br>
>>>> +//    TYPE(Class, Base) - A type that can show up anywhere in the<br>
>>>> AST,<br>
>>>> +//    and might be dependent, canonical, or non-canonical. All<br>
>>>> clients<br>
>>>> +//    will need to understand these types.<br>
>>>> +//<br>
>>>> +//    ABSTRACT_TYPE(Class, Base) - An abstract class that shows up<br>
>>>> in<br>
>>>> +//    the type hierarchy but has no concrete instances.<br>
>>>> +//<br>
>>>> +//    NON_CANONICAL_TYPE(Class, Base) - A type that can show up<br>
>>>> +//    anywhere in the AST but will never be a part of a canonical<br>
>>>> +//    type. Clients that only need to deal with canonical types<br>
>>>> +//    (ignoring, e.g., typedefs and other type aliases used for<br>
>>>> +//    pretty-printing) can ignore these types.<br>
>>>> +//<br>
>>>> +//    DEPENDENT_TYPE(Class, Base) - A type that will only show up<br>
>>>> +//    within a C++ template that has not been instantiated, e.g., <br>
>>>> a<br>
>>>> +//    type that is always dependent. Clients that do not need to<br>
>>>> deal<br>
>>>> +//    with uninstantiated C++ templates can ignore these types.<br>
>>>> +//<br>
>>>> +//    NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) - A type <br>
>>>> that<br>
>>>> +//    is non-canonical unless it is dependent.  Defaults to TYPE<br>
>>>> because<br>
>>>> +//    it is neither reliably dependent nor reliably non-canonical.<br>
>>>> +//<br>
>>>> +// There is a sixth macro, independent of the others.  Most <br>
>>>> clients<br>
>>>> +// will not need to use it.<br>
>>>> +//<br>
>>>> +//    LEAF_TYPE(Class) - A type that never has inner types.  <br>
>>>> Clients<br>
>>>> +//    which can operate on such types more efficiently may wish to<br>
>>>> do so.<br>
>>>> +//<br>
>>>><br>
>>>><br>
>> +//===----------------------------------------------------------------------===//<br>
>>>> +<br>
>>>> +#include "llvm/ADT/StringRef.h"<br>
>>>> +#include "llvm/TableGen/Error.h"<br>
>>>> +#include "llvm/TableGen/Record.h"<br>
>>>> +#include "llvm/TableGen/TableGenBackend.h"<br>
>>>> +#include <set><br>
>>>> +#include <string><br>
>>>> +#include <vector><br>
>>>> +#include "TableGenBackends.h"<br>
>>>> +<br>
>>>> +using namespace llvm;<br>
>>>> +<br>
>>>> +// These are spellings in the generated output.<br>
>>>> +#define TypeMacroName "TYPE"<br>
>>>> +#define AbstractTypeMacroName "ABSTRACT_TYPE"<br>
>>>> +#define DependentTypeMacroName "DEPENDENT_TYPE"<br>
>>>> +#define NonCanonicalTypeMacroName "NON_CANONICAL_TYPE"<br>
>>>> +#define NonCanonicalUnlessDependentTypeMacroName<br>
>>>> "NON_CANONICAL_UNLESS_DEPENDENT_TYPE"<br>
>>>> +#define TypeMacroArgs "(Class, Base)"<br>
>>>> +#define LastTypeMacroName "LAST_TYPE"<br>
>>>> +#define LeafTypeMacroName "LEAF_TYPE"<br>
>>>> +<br>
>>>> +// These are spellings in the tblgen file.<br>
>>>> +// (Type is also used for the spelling of the AST class.)<br>
>>>> +#define TypeClassName "Type"<br>
>>>> +#define DerivedTypeClassName "DerivedType"<br>
>>>> +#define AlwaysDependentClassName "AlwaysDependent"<br>
>>>> +#define NeverCanonicalClassName "NeverCanonical"<br>
>>>> +#define NeverCanonicalUnlessDependentClassName<br>
>>>> "NeverCanonicalUnlessDependent"<br>
>>>> +#define LeafTypeClassName "LeafType"<br>
>>>> +#define AbstractFieldName "Abstract"<br>
>>>> +#define BaseFieldName "Base"<br>
>>>> +<br>
>>>> +static StringRef getIdForType(Record *type) {<br>
>>>> +       // The record name is expected to be the full C++ class <br>
>>>> name,<br>
>>>> +       // including "Type".  Check for that and strip it off.<br>
>>>> +       auto fullName = type->getName();<br>
>>>> +       if (!fullName.endswith("Type"))<br>
>>>> +               PrintFatalError(type->getLoc(), "name of Type node<br>
>>>> doesn't<br>
>>>> end in Type");<br>
>>>> +       return fullName.drop_back(4);<br>
>>>> +}<br>
>>>> +<br>
>>>> +namespace {<br>
>>>> +class TypeNodeEmitter {<br>
>>>> +       RecordKeeper &Records;<br>
>>>> +       raw_ostream &Out;<br>
>>>> +       const std::vector<Record*> Types;<br>
>>>> +       std::vector<StringRef> MacrosToUndef;<br>
>>>> +<br>
>>>> +public:<br>
>>>> +       TypeNodeEmitter(RecordKeeper &records, raw_ostream &out)<br>
>>>> +               : Records(records), Out(out),<br>
>>>> +<br>
>>>> Types(Records.getAllDerivedDefinitions("Type")) {<br>
>>>> +       }<br>
>>>> +<br>
>>>> +       void emit();<br>
>>>> +<br>
>>>> +private:<br>
>>>> +       void emitFallbackDefine(StringRef macroName, StringRef<br>
>>>> fallbackMacroName,<br>
>>>> +<br>
>>>>                              StringRef args);<br>
>>>> +<br>
>>>> +       void emitNodeInvocations();<br>
>>>> +       void emitLastNodeInvocation();<br>
>>>> +       void emitLeafNodeInvocations();<br>
>>>> +<br>
>>>> +       void addMacroToUndef(StringRef macroName);<br>
>>>> +       void emitUndefs();<br>
>>>> +};<br>
>>>> +}<br>
>>>> +<br>
>>>> +void TypeNodeEmitter::emit() {<br>
>>>> +       if (Types.empty())<br>
>>>> +               PrintFatalError("no Type records in input!");<br>
>>>> +<br>
>>>> +       emitSourceFileHeader("An x-macro database of Clang type<br>
>>>> nodes",<br>
>>>> Out);<br>
>>>> +<br>
>>>> +       // Preamble<br>
>>>> +       addMacroToUndef(TypeMacroName);<br>
>>>> +       addMacroToUndef(AbstractTypeMacroName);<br>
>>>> +       emitFallbackDefine(AbstractTypeMacroName, TypeMacroName,<br>
>>>> TypeMacroArgs);<br>
>>>> +       emitFallbackDefine(NonCanonicalTypeMacroName, <br>
>>>> TypeMacroName,<br>
>>>> TypeMacroArgs);<br>
>>>> +       emitFallbackDefine(DependentTypeMacroName, TypeMacroName,<br>
>>>> TypeMacroArgs);<br>
>>>> +       <br>
>>>> emitFallbackDefine(NonCanonicalUnlessDependentTypeMacroName,<br>
>>>> TypeMacroName,<br>
>>>> +<br>
>>>>       TypeMacroArgs);<br>
>>>> +<br>
>>>> +       // Invocations.<br>
>>>> +       emitNodeInvocations();<br>
>>>> +       emitLastNodeInvocation();<br>
>>>> +       emitLeafNodeInvocations();<br>
>>>> +<br>
>>>> +       // Postmatter<br>
>>>> +       emitUndefs();<br>
>>>> +}<br>
>>>> +<br>
>>>> +void TypeNodeEmitter::emitFallbackDefine(StringRef macroName,<br>
>>>> +<br>
>>>><br>
>>>>           StringRef fallbackMacroName,<br>
>>>> +<br>
>>>><br>
>>>>           StringRef args) {<br>
>>>> +  Out << "#ifndef " << macroName << "\n";<br>
>>>> +  Out << "#  define " << macroName << args<br>
>>>> +         << " " << fallbackMacroName << args << "\n";<br>
>>>> +  Out << "#endif\n";<br>
>>>> +<br>
>>>> +  addMacroToUndef(macroName);<br>
>>>> +}<br>
>>>> +<br>
>>>> +void TypeNodeEmitter::emitNodeInvocations() {<br>
>>>> +       for (auto type : Types) {<br>
>>>> +               // The name with the Type suffix.<br>
>>>> +               StringRef id = getIdForType(type);<br>
>>>> +<br>
>>>> +               // Figure out which macro to use.<br>
>>>> +               StringRef macroName;<br>
>>>> +               auto setMacroName = [&](StringRef newName) {<br>
>>>> +                       if (!macroName.empty())<br>
>>>> +                               PrintFatalError(type->getLoc(),<br>
>>>> +<br>
>>>>                      Twine("conflict when computing macro name for <br>
>>>> "<br>
>>>> +<br>
>>>>                                              "Type node: trying to<br>
>>>> use both<br>
>>>> \"")<br>
>>>> +<br>
>>>>                              + macroName + "\" and \"" + newName +<br>
>>>> "\"");<br>
>>>> +                       macroName = newName;<br>
>>>> +               };<br>
>>>> +               if (type->isSubClassOf(AlwaysDependentClassName))<br>
>>>> +                       setMacroName(DependentTypeMacroName);<br>
>>>> +               if (type->isSubClassOf(NeverCanonicalClassName))<br>
>>>> +                       setMacroName(NonCanonicalTypeMacroName);<br>
>>>> +               if<br>
>>>> (type->isSubClassOf(NeverCanonicalUnlessDependentClassName))<br>
>>>> +<br>
>>>>  setMacroName(NonCanonicalUnlessDependentTypeMacroName);<br>
>>>> +               if (type->getValueAsBit(AbstractFieldName))<br>
>>>> +                       setMacroName(AbstractTypeMacroName);<br>
>>>> +               if (macroName.empty())<br>
>>>> +                       macroName = TypeMacroName;<br>
>>>> +<br>
>>>> +               // Compute the base class.<br>
>>>> +               StringRef baseName = TypeClassName;<br>
>>>> +               if (type->isSubClassOf(DerivedTypeClassName))<br>
>>>> +                       baseName =<br>
>>>> type->getValueAsDef(BaseFieldName)->getName();<br>
>>>> +<br>
>>>> +               // Generate the invocation line.<br>
>>>> +               Out << macroName << "(" << id << ", " << baseName <br>
>>>> <<<br>
>>>> ")\n";<br>
>>>> +       }<br>
>>>> +}<br>
>>>> +<br>
>>>> +void TypeNodeEmitter::emitLastNodeInvocation() {<br>
>>>> +       // We check that this is non-empty earlier.<br>
>>>> +       Out << "#ifdef " LastTypeMacroName "\n"<br>
>>>> +              LastTypeMacroName "(" << getIdForType(Types.back()) <br>
>>>> <<<br>
>>>> ")\n"<br>
>>>> +                                "#undef " LastTypeMacroName "\n"<br>
>>>> +                                "#endif\n";<br>
>>>> +}<br>
>>>> +<br>
>>>> +void TypeNodeEmitter::emitLeafNodeInvocations() {<br>
>>>> +       Out << "#ifdef " LeafTypeMacroName "\n";<br>
>>>> +<br>
>>>> +       for (auto type : Types) {<br>
>>>> +               if (!type->isSubClassOf(LeafTypeClassName)) <br>
>>>> continue;<br>
>>>> +               Out << LeafTypeMacroName "(" << getIdForType(type) <br>
>>>> <<<br>
>>>> ")\n";<br>
>>>> +       }<br>
>>>> +<br>
>>>> +       Out << "#undef " LeafTypeMacroName "\n"<br>
>>>> +                                "#endif\n";<br>
>>>> +}<br>
>>>> +<br>
>>>> +void TypeNodeEmitter::addMacroToUndef(StringRef macroName) {<br>
>>>> +       MacrosToUndef.push_back(macroName);<br>
>>>> +}<br>
>>>> +<br>
>>>> +void TypeNodeEmitter::emitUndefs() {<br>
>>>> +       for (auto &macroName : MacrosToUndef) {<br>
>>>> +               Out << "#undef " << macroName << "\n";<br>
>>>> +       }<br>
>>>> +}<br>
>>>> +<br>
>>>> +void clang::EmitClangTypeNodes(RecordKeeper &records, raw_ostream<br>
>>>> &out) {<br>
>>>> +       TypeNodeEmitter(records, out).emit();<br>
>>>> +}<br>
>>>><br>
>>>> Modified: cfe/trunk/utils/TableGen/TableGen.cpp<br>
>>>> URL:<br>
>>>><br>
>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGen.cpp?rev=373407&r1=373406&r2=373407&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGen.cpp?rev=373407&r1=373406&r2=373407&view=diff</a><br>
>>>><br>
>>>><br>
>> ==============================================================================<br>
>>>> --- cfe/trunk/utils/TableGen/TableGen.cpp (original)<br>
>>>> +++ cfe/trunk/utils/TableGen/TableGen.cpp Tue Oct  1 16:13:03 2019<br>
>>>> @@ -47,6 +47,7 @@ enum ActionType {<br>
>>>>    GenClangCommentNodes,<br>
>>>>    GenClangDeclNodes,<br>
>>>>    GenClangStmtNodes,<br>
>>>> +  GenClangTypeNodes,<br>
>>>>    GenClangOpcodes,<br>
>>>>    GenClangSACheckers,<br>
>>>>    GenClangCommentHTMLTags,<br>
>>>> @@ -130,6 +131,8 @@ cl::opt<ActionType> Action(<br>
>>>>                     "Generate Clang AST declaration nodes"),<br>
>>>>          clEnumValN(GenClangStmtNodes, "gen-clang-stmt-nodes",<br>
>>>>                     "Generate Clang AST statement nodes"),<br>
>>>> +        clEnumValN(GenClangTypeNodes, "gen-clang-type-nodes",<br>
>>>> +                   "Generate Clang AST type nodes"),<br>
>>>>          clEnumValN(GenClangOpcodes, "gen-clang-opcodes",<br>
>>>>                     "Generate Clang constexpr interpreter <br>
>>>> opcodes"),<br>
>>>>          clEnumValN(GenClangSACheckers, "gen-clang-sa-checkers",<br>
>>>> @@ -254,6 +257,9 @@ bool ClangTableGenMain(raw_ostream &OS,<br>
>>>>    case GenClangStmtNodes:<br>
>>>>      EmitClangASTNodes(Records, OS, "Stmt", "");<br>
>>>>      break;<br>
>>>> +  case GenClangTypeNodes:<br>
>>>> +    EmitClangTypeNodes(Records, OS);<br>
>>>> +    break;<br>
>>>>    case GenClangOpcodes:<br>
>>>>      EmitClangOpcodes(Records, OS);<br>
>>>>      break;<br>
>>>><br>
>>>> Modified: cfe/trunk/utils/TableGen/TableGenBackends.h<br>
>>>> URL:<br>
>>>><br>
>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGenBackends.h?rev=373407&r1=373406&r2=373407&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGenBackends.h?rev=373407&r1=373406&r2=373407&view=diff</a><br>
>>>><br>
>>>><br>
>> ==============================================================================<br>
>>>> --- cfe/trunk/utils/TableGen/TableGenBackends.h (original)<br>
>>>> +++ cfe/trunk/utils/TableGen/TableGenBackends.h Tue Oct  1 16:13:03<br>
>>>> 2019<br>
>>>> @@ -27,6 +27,7 @@ namespace clang {<br>
>>>>  void EmitClangDeclContext(llvm::RecordKeeper &RK, <br>
>>>> llvm::raw_ostream<br>
>>>> &OS);<br>
>>>>  void EmitClangASTNodes(llvm::RecordKeeper &RK, llvm::raw_ostream<br>
>>>> &OS,<br>
>>>>                         const std::string &N, const std::string <br>
>>>> &S);<br>
>>>> +void EmitClangTypeNodes(llvm::RecordKeeper &Records,<br>
>>>> llvm::raw_ostream<br>
>>>> &OS);<br>
>>>><br>
>>>>  void EmitClangAttrParserStringSwitches(llvm::RecordKeeper <br>
>>>> &Records,<br>
>>>>                                         llvm::raw_ostream &OS);<br>
>>>><br>
>>>><br>
>>>> _______________________________________________<br>
>>>> cfe-commits mailing list<br>
>>>> <a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
>>>> <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
>>>><br>
>><br>
>><br>
>><br>
<br>
<br>
</blockquote></div></div>