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 "llvm/ADT/StringRef.h" 49 #include "llvm/TableGen/Error.h" 50 #include "llvm/TableGen/Record.h" 51 #include "llvm/TableGen/TableGenBackend.h" 52 #include <set> 53 #include <string> 54 #include <vector> 55 #include "TableGenBackends.h" 56 57 using namespace llvm; 58 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" 68 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" 79 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); 87 } 88 89 namespace { 90 class TypeNodeEmitter { 91 RecordKeeper &Records; 92 raw_ostream &Out; 93 const std::vector<Record*> Types; 94 std::vector<StringRef> MacrosToUndef; 95 96 public: 97 TypeNodeEmitter(RecordKeeper &records, raw_ostream &out) 98 : Records(records), Out(out), 99 Types(Records.getAllDerivedDefinitions("Type")) { 100 } 101 102 void emit(); 103 104 private: 105 void emitFallbackDefine(StringRef macroName, StringRef fallbackMacroName, 106 StringRef args); 107 108 void emitNodeInvocations(); 109 void emitLastNodeInvocation(); 110 void emitLeafNodeInvocations(); 111 112 void addMacroToUndef(StringRef macroName); 113 void emitUndefs(); 114 }; 115 } 116 117 void TypeNodeEmitter::emit() { 118 if (Types.empty()) 119 PrintFatalError("no Type records in input!"); 120 121 emitSourceFileHeader("An x-macro database of Clang type nodes", Out); 122 123 // Preamble 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, 130 TypeMacroArgs); 131 132 // Invocations. 133 emitNodeInvocations(); 134 emitLastNodeInvocation(); 135 emitLeafNodeInvocations(); 136 137 // Postmatter 138 emitUndefs(); 139 } 140 141 void TypeNodeEmitter::emitFallbackDefine(StringRef macroName, 142 StringRef fallbackMacroName, 143 StringRef args) { 144 Out << "#ifndef " << macroName << "\n"; 145 Out << "# define " << macroName << args 146 << " " << fallbackMacroName << args << "\n"; 147 Out << "#endif\n"; 148 149 addMacroToUndef(macroName); 150 } 151 152 void TypeNodeEmitter::emitNodeInvocations() { 153 for (auto type : Types) { 154 // The name with the Type suffix. 155 StringRef id = getIdForType(type); 156 157 // Figure out which macro to use. 158 StringRef macroName; 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 + "\""); 165 macroName = newName; 166 }; 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; 177 178 // Compute the base class. 179 StringRef baseName = TypeClassName; 180 if (type->isSubClassOf(DerivedTypeClassName)) 181 baseName = type->getValueAsDef(BaseFieldName)->getName(); 182 183 // Generate the invocation line. 184 Out << macroName << "(" << id << ", " << baseName << ")\n"; 185 } 186 } 187 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" 193 "#endif\n"; 194 } 195 196 void TypeNodeEmitter::emitLeafNodeInvocations() { 197 Out << "#ifdef " LeafTypeMacroName "\n"; 198 199 for (auto type : Types) { 200 if (!type->isSubClassOf(LeafTypeClassName)) continue; 201 Out << LeafTypeMacroName "(" << getIdForType(type) << ")\n"; 202 } 203 204 Out << "#undef " LeafTypeMacroName "\n" 205 "#endif\n"; 206 } 207 208 void TypeNodeEmitter::addMacroToUndef(StringRef macroName) { 209 MacrosToUndef.push_back(macroName); 210 } 211 212 void TypeNodeEmitter::emitUndefs() { 213 for (auto ¯oName : MacrosToUndef) { 214 Out << "#undef " << macroName << "\n"; 215 } 216 } 217 218 void clang::EmitClangTypeNodes(RecordKeeper &records, raw_ostream &out) { 219 TypeNodeEmitter(records, out).emit(); 220 } 221