1 //=== ClangTypeNodesEmitter.cpp - Generate type node tables -----*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This tblgen backend emits the node table (the .def file) for Clang
12 // This file defines the AST type info database. Each type node is
13 // enumerated by providing its name (e.g., "Builtin" or "Enum") and
14 // base class (e.g., "Type" or "TagType"). Depending on where in the
15 // abstract syntax tree the type will show up, the enumeration uses
16 // one of five different macros:
18 // TYPE(Class, Base) - A type that can show up anywhere in the AST,
19 // and might be dependent, canonical, or non-canonical. All clients
20 // will need to understand these types.
22 // ABSTRACT_TYPE(Class, Base) - An abstract class that shows up in
23 // the type hierarchy but has no concrete instances.
25 // NON_CANONICAL_TYPE(Class, Base) - A type that can show up
26 // anywhere in the AST but will never be a part of a canonical
27 // type. Clients that only need to deal with canonical types
28 // (ignoring, e.g., typedefs and other type aliases used for
29 // pretty-printing) can ignore these types.
31 // DEPENDENT_TYPE(Class, Base) - A type that will only show up
32 // within a C++ template that has not been instantiated, e.g., a
33 // type that is always dependent. Clients that do not need to deal
34 // with uninstantiated C++ templates can ignore these types.
36 // NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) - A type that
37 // is non-canonical unless it is dependent. Defaults to TYPE because
38 // it is neither reliably dependent nor reliably non-canonical.
40 // There is a sixth macro, independent of the others. Most clients
41 // will not need to use it.
43 // LEAF_TYPE(Class) - A type that never has inner types. Clients
44 // which can operate on such types more efficiently may wish to do so.
46 //===----------------------------------------------------------------------===//
48 #include "llvm/ADT/StringRef.h"
49 #include "llvm/TableGen/Error.h"
50 #include "llvm/TableGen/Record.h"
51 #include "llvm/TableGen/TableGenBackend.h"
55 #include "TableGenBackends.h"
59 // These are spellings in the generated output.
60 #define TypeMacroName "TYPE"
61 #define AbstractTypeMacroName "ABSTRACT_TYPE"
62 #define DependentTypeMacroName "DEPENDENT_TYPE"
63 #define NonCanonicalTypeMacroName "NON_CANONICAL_TYPE"
64 #define NonCanonicalUnlessDependentTypeMacroName "NON_CANONICAL_UNLESS_DEPENDENT_TYPE"
65 #define TypeMacroArgs "(Class, Base)"
66 #define LastTypeMacroName "LAST_TYPE"
67 #define LeafTypeMacroName "LEAF_TYPE"
69 // These are spellings in the tblgen file.
70 // (Type is also used for the spelling of the AST class.)
71 #define TypeClassName "Type"
72 #define DerivedTypeClassName "DerivedType"
73 #define AlwaysDependentClassName "AlwaysDependent"
74 #define NeverCanonicalClassName "NeverCanonical"
75 #define NeverCanonicalUnlessDependentClassName "NeverCanonicalUnlessDependent"
76 #define LeafTypeClassName "LeafType"
77 #define AbstractFieldName "Abstract"
78 #define BaseFieldName "Base"
80 static StringRef getIdForType(Record *type) {
81 // The record name is expected to be the full C++ class name,
82 // including "Type". Check for that and strip it off.
83 auto fullName = type->getName();
84 if (!fullName.endswith("Type"))
85 PrintFatalError(type->getLoc(), "name of Type node doesn't end in Type");
86 return fullName.drop_back(4);
90 class TypeNodeEmitter {
91 RecordKeeper &Records;
93 const std::vector<Record*> Types;
94 std::vector<StringRef> MacrosToUndef;
97 TypeNodeEmitter(RecordKeeper &records, raw_ostream &out)
98 : Records(records), Out(out),
99 Types(Records.getAllDerivedDefinitions("Type")) {
105 void emitFallbackDefine(StringRef macroName, StringRef fallbackMacroName,
108 void emitNodeInvocations();
109 void emitLastNodeInvocation();
110 void emitLeafNodeInvocations();
112 void addMacroToUndef(StringRef macroName);
117 void TypeNodeEmitter::emit() {
119 PrintFatalError("no Type records in input!");
121 emitSourceFileHeader("An x-macro database of Clang type nodes", Out);
124 addMacroToUndef(TypeMacroName);
125 addMacroToUndef(AbstractTypeMacroName);
126 emitFallbackDefine(AbstractTypeMacroName, TypeMacroName, TypeMacroArgs);
127 emitFallbackDefine(NonCanonicalTypeMacroName, TypeMacroName, TypeMacroArgs);
128 emitFallbackDefine(DependentTypeMacroName, TypeMacroName, TypeMacroArgs);
129 emitFallbackDefine(NonCanonicalUnlessDependentTypeMacroName, TypeMacroName,
133 emitNodeInvocations();
134 emitLastNodeInvocation();
135 emitLeafNodeInvocations();
141 void TypeNodeEmitter::emitFallbackDefine(StringRef macroName,
142 StringRef fallbackMacroName,
144 Out << "#ifndef " << macroName << "\n";
145 Out << "# define " << macroName << args
146 << " " << fallbackMacroName << args << "\n";
149 addMacroToUndef(macroName);
152 void TypeNodeEmitter::emitNodeInvocations() {
153 for (auto type : Types) {
154 // The name with the Type suffix.
155 StringRef id = getIdForType(type);
157 // Figure out which macro to use.
159 auto setMacroName = [&](StringRef newName) {
160 if (!macroName.empty())
161 PrintFatalError(type->getLoc(),
162 Twine("conflict when computing macro name for "
163 "Type node: trying to use both \"")
164 + macroName + "\" and \"" + newName + "\"");
167 if (type->isSubClassOf(AlwaysDependentClassName))
168 setMacroName(DependentTypeMacroName);
169 if (type->isSubClassOf(NeverCanonicalClassName))
170 setMacroName(NonCanonicalTypeMacroName);
171 if (type->isSubClassOf(NeverCanonicalUnlessDependentClassName))
172 setMacroName(NonCanonicalUnlessDependentTypeMacroName);
173 if (type->getValueAsBit(AbstractFieldName))
174 setMacroName(AbstractTypeMacroName);
175 if (macroName.empty())
176 macroName = TypeMacroName;
178 // Compute the base class.
179 StringRef baseName = TypeClassName;
180 if (type->isSubClassOf(DerivedTypeClassName))
181 baseName = type->getValueAsDef(BaseFieldName)->getName();
183 // Generate the invocation line.
184 Out << macroName << "(" << id << ", " << baseName << ")\n";
188 void TypeNodeEmitter::emitLastNodeInvocation() {
189 // We check that this is non-empty earlier.
190 Out << "#ifdef " LastTypeMacroName "\n"
191 LastTypeMacroName "(" << getIdForType(Types.back()) << ")\n"
192 "#undef " LastTypeMacroName "\n"
196 void TypeNodeEmitter::emitLeafNodeInvocations() {
197 Out << "#ifdef " LeafTypeMacroName "\n";
199 for (auto type : Types) {
200 if (!type->isSubClassOf(LeafTypeClassName)) continue;
201 Out << LeafTypeMacroName "(" << getIdForType(type) << ")\n";
204 Out << "#undef " LeafTypeMacroName "\n"
208 void TypeNodeEmitter::addMacroToUndef(StringRef macroName) {
209 MacrosToUndef.push_back(macroName);
212 void TypeNodeEmitter::emitUndefs() {
213 for (auto ¯oName : MacrosToUndef) {
214 Out << "#undef " << macroName << "\n";
218 void clang::EmitClangTypeNodes(RecordKeeper &records, raw_ostream &out) {
219 TypeNodeEmitter(records, out).emit();