r373407 - Emit TypeNodes.def with tblgen.
Nico Weber via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 1 18:20:29 PDT 2019
All other tablegen outputs are called .inc instead of .def. Any reason this
one's different?
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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191001/c51d7418/attachment-0001.html>
More information about the cfe-commits
mailing list