1 //=== ClangTypeNodesEmitter.cpp - Generate type node tables -----*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This tblgen backend emits the node table (the .def file) for Clang
10 // type nodes.
11 //
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:
17 //
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.
21 //
22 //    ABSTRACT_TYPE(Class, Base) - An abstract class that shows up in
23 //    the type hierarchy but has no concrete instances.
24 //
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.
30 //
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.
35 //
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.
39 //
40 // There is a sixth macro, independent of the others.  Most clients
41 // will not need to use it.
42 //
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.
45 //
46 //===----------------------------------------------------------------------===//
47 
48 #include "ClangASTEmitters.h"
49 #include "TableGenBackends.h"
50 
51 #include "llvm/ADT/StringRef.h"
52 #include "llvm/TableGen/Error.h"
53 #include "llvm/TableGen/Record.h"
54 #include "llvm/TableGen/TableGenBackend.h"
55 #include <set>
56 #include <string>
57 #include <vector>
58 
59 using namespace llvm;
60 
61 // These are spellings in the generated output.
62 #define TypeMacroName "TYPE"
63 #define AbstractTypeMacroName "ABSTRACT_TYPE"
64 #define DependentTypeMacroName "DEPENDENT_TYPE"
65 #define NonCanonicalTypeMacroName "NON_CANONICAL_TYPE"
66 #define NonCanonicalUnlessDependentTypeMacroName "NON_CANONICAL_UNLESS_DEPENDENT_TYPE"
67 #define TypeMacroArgs "(Class, Base)"
68 #define LastTypeMacroName "LAST_TYPE"
69 #define LeafTypeMacroName "LEAF_TYPE"
70 
71 #define TypeClassName "Type"
72 
73 static StringRef getIdForType(Record *type) {
74 	// The record name is expected to be the full C++ class name,
75 	// including "Type".  Check for that and strip it off.
76 	auto fullName = type->getName();
77 	if (!fullName.endswith("Type"))
78 		PrintFatalError(type->getLoc(), "name of Type node doesn't end in Type");
79 	return fullName.drop_back(4);
80 }
81 
82 namespace {
83 class TypeNodeEmitter {
84 	RecordKeeper &Records;
85 	raw_ostream &Out;
86 	const std::vector<Record*> Types;
87 	std::vector<StringRef> MacrosToUndef;
88 
89 public:
90 	TypeNodeEmitter(RecordKeeper &records, raw_ostream &out)
91 		: Records(records), Out(out),
92 			Types(Records.getAllDerivedDefinitions(TypeNodeClassName)) {
93 	}
94 
95 	void emit();
96 
97 private:
98 	void emitFallbackDefine(StringRef macroName, StringRef fallbackMacroName,
99 													StringRef args);
100 
101 	void emitNodeInvocations();
102 	void emitLastNodeInvocation();
103 	void emitLeafNodeInvocations();
104 
105 	void addMacroToUndef(StringRef macroName);
106 	void emitUndefs();
107 };
108 }
109 
110 void TypeNodeEmitter::emit() {
111 	if (Types.empty())
112 		PrintFatalError("no Type records in input!");
113 
114 	emitSourceFileHeader("An x-macro database of Clang type nodes", Out);
115 
116 	// Preamble
117 	addMacroToUndef(TypeMacroName);
118 	addMacroToUndef(AbstractTypeMacroName);
119 	emitFallbackDefine(AbstractTypeMacroName, TypeMacroName, TypeMacroArgs);
120 	emitFallbackDefine(NonCanonicalTypeMacroName, TypeMacroName, TypeMacroArgs);
121 	emitFallbackDefine(DependentTypeMacroName, TypeMacroName, TypeMacroArgs);
122 	emitFallbackDefine(NonCanonicalUnlessDependentTypeMacroName, TypeMacroName,
123 										 TypeMacroArgs);
124 
125 	// Invocations.
126 	emitNodeInvocations();
127 	emitLastNodeInvocation();
128 	emitLeafNodeInvocations();
129 
130 	// Postmatter
131 	emitUndefs();
132 }
133 
134 void TypeNodeEmitter::emitFallbackDefine(StringRef macroName,
135 																				 StringRef fallbackMacroName,
136 																				 StringRef args) {
137   Out << "#ifndef " << macroName << "\n";
138   Out << "#  define " << macroName << args
139   	  << " " << fallbackMacroName << args << "\n";
140   Out << "#endif\n";
141 
142   addMacroToUndef(macroName);
143 }
144 
145 void TypeNodeEmitter::emitNodeInvocations() {
146 	for (auto type : Types) {
147 		// The name without the Type suffix.
148 		StringRef id = getIdForType(type);
149 
150 		// If this is the Type node itself, skip it.
151 		if (id.empty()) continue;
152 
153 		// Figure out which macro to use.
154 		StringRef macroName;
155 		auto setMacroName = [&](StringRef newName) {
156 			if (!macroName.empty())
157 				PrintFatalError(type->getLoc(),
158 												Twine("conflict when computing macro name for "
159 															"Type node: trying to use both \"")
160 													+ macroName + "\" and \"" + newName + "\"");
161 			macroName = newName;
162 		};
163 		if (type->isSubClassOf(AlwaysDependentClassName))
164 			setMacroName(DependentTypeMacroName);
165 		if (type->isSubClassOf(NeverCanonicalClassName))
166 			setMacroName(NonCanonicalTypeMacroName);
167 		if (type->isSubClassOf(NeverCanonicalUnlessDependentClassName))
168 			setMacroName(NonCanonicalUnlessDependentTypeMacroName);
169 		if (type->getValueAsBit(AbstractFieldName))
170 			setMacroName(AbstractTypeMacroName);
171 		if (macroName.empty())
172 			macroName = TypeMacroName;
173 
174 		// Compute the base class.
175 		StringRef baseName = TypeClassName;
176 		if (auto base = type->getValueAsOptionalDef(BaseFieldName))
177 			baseName = base->getName();
178 
179 		// Generate the invocation line.
180 		Out << macroName << "(" << id << ", " << baseName << ")\n";
181 	}
182 }
183 
184 void TypeNodeEmitter::emitLastNodeInvocation() {
185 	// We check that this is non-empty earlier.
186 	Out << "#ifdef " LastTypeMacroName "\n"
187 	       LastTypeMacroName "(" << getIdForType(Types.back()) << ")\n"
188 				 "#undef " LastTypeMacroName "\n"
189 				 "#endif\n";
190 }
191 
192 void TypeNodeEmitter::emitLeafNodeInvocations() {
193 	Out << "#ifdef " LeafTypeMacroName "\n";
194 
195 	for (auto type : Types) {
196 		if (!type->isSubClassOf(LeafTypeClassName)) continue;
197 		Out << LeafTypeMacroName "(" << getIdForType(type) << ")\n";
198 	}
199 
200 	Out << "#undef " LeafTypeMacroName "\n"
201 				 "#endif\n";
202 }
203 
204 void TypeNodeEmitter::addMacroToUndef(StringRef macroName) {
205 	MacrosToUndef.push_back(macroName);
206 }
207 
208 void TypeNodeEmitter::emitUndefs() {
209 	for (auto &macroName : MacrosToUndef) {
210 		Out << "#undef " << macroName << "\n";
211 	}
212 }
213 
214 void clang::EmitClangTypeNodes(RecordKeeper &records, raw_ostream &out) {
215 	TypeNodeEmitter(records, out).emit();
216 }
217