<div dir="ltr">I think that'd be nice; I believe I renamed one .def output with the same history for the same reason a while ago.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Oct 1, 2019 at 9:25 PM John McCall <<a href="mailto:rjmccall@apple.com">rjmccall@apple.com</a>> wrote:<br></div><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:20, Nico Weber wrote:<br>
> All other tablegen outputs are called .inc instead of .def. Any reason <br>
> this<br>
> one's different?<br>
<br>
This was an existing file; it’s just generated now instead of written<br>
in source. I was deliberately not changing anything about the 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 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 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 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>
>> <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>
>> --- 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>
>> <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>
>> --- 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() == Record;<br>
>> }<br>
>> };<br>
>><br>
>><br>
>> Removed: cfe/trunk/include/clang/AST/TypeNodes.def<br>
>> URL:<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>
>> --- 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>
>> C++<br>
>> -*-===//<br>
>> -//<br>
>> -// Part of the LLVM Project, under the Apache License v2.0 with 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>
>> -// This file defines the AST type info database. Each type node is<br>
>> -// enumerated by providing its name (e.g., "Builtin" or "Enum") 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 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., 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 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 clients<br>
>> -// will not need to use it.<br>
>> -//<br>
>> -// LEAF_TYPE(Class) - A type that never has inner types. Clients<br>
>> -// which can operate on such types more efficiently may wish to <br>
>> do so.<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>
>> <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>
>> --- 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 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 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 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 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 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 `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 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>
>> <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>
>> --- cfe/trunk/utils/TableGen/CMakeLists.txt (original)<br>
>> +++ cfe/trunk/utils/TableGen/CMakeLists.txt Tue Oct 1 16:13:03 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>
>> <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>
>> --- 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>
>> C++<br>
>> -*-===//<br>
>> +//<br>
>> +// Part of the LLVM Project, under the Apache License v2.0 with 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>
>> +// 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") and<br>
>> +// base class (e.g., "Type" or "TagType"). Depending on where in the<br>
>> +// abstract syntax tree the type will show up, the enumeration 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., 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 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 clients<br>
>> +// will not need to use it.<br>
>> +//<br>
>> +// LEAF_TYPE(Class) - A type that never has inner types. Clients<br>
>> +// which can operate on such types more efficiently may wish to <br>
>> do so.<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 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, TypeMacroName,<br>
>> TypeMacroArgs);<br>
>> + emitFallbackDefine(DependentTypeMacroName, TypeMacroName,<br>
>> TypeMacroArgs);<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>
>> "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>
>> ")\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>
>> ")\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)) continue;<br>
>> + Out << LeafTypeMacroName "(" << getIdForType(type) <<<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 ¯oName : 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>
>> <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>
>> --- 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 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>
>> <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>
>> --- 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, llvm::raw_ostream <br>
>> &OS);<br>
>> void EmitClangASTNodes(llvm::RecordKeeper &RK, llvm::raw_ostream <br>
>> &OS,<br>
>> const std::string &N, const std::string &S);<br>
>> +void EmitClangTypeNodes(llvm::RecordKeeper &Records, <br>
>> llvm::raw_ostream<br>
>> &OS);<br>
>><br>
>> void EmitClangAttrParserStringSwitches(llvm::RecordKeeper &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>
</blockquote></div>