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