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 ¯oName : 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