r373407 - Emit TypeNodes.def with tblgen.

John McCall via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 1 16:13:03 PDT 2019


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 &macroName : 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);




More information about the cfe-commits mailing list