1 //===- TableGen.cpp - Top-Level TableGen implementation -------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // TableGen is a tool which can be used to build up a description of something, 11 // then invoke one or more "tablegen backends" to emit information about the 12 // description in some predefined format. In practice, this is used by the LLVM 13 // code generators to automate generation of a code generator through a 14 // high-level description of the target. 15 // 16 //===----------------------------------------------------------------------===// 17 18 #include "AsmMatcherEmitter.h" 19 #include "AsmWriterEmitter.h" 20 #include "CallingConvEmitter.h" 21 #include "ClangASTNodesEmitter.h" 22 #include "ClangAttrEmitter.h" 23 #include "ClangDiagnosticsEmitter.h" 24 #include "ClangSACheckersEmitter.h" 25 #include "CodeEmitterGen.h" 26 #include "DAGISelEmitter.h" 27 #include "DisassemblerEmitter.h" 28 #include "EDEmitter.h" 29 #include "FastISelEmitter.h" 30 #include "InstrEnumEmitter.h" 31 #include "InstrInfoEmitter.h" 32 #include "IntrinsicEmitter.h" 33 #include "LLVMCConfigurationEmitter.h" 34 #include "NeonEmitter.h" 35 #include "OptParserEmitter.h" 36 #include "Record.h" 37 #include "RegisterInfoEmitter.h" 38 #include "ARMDecoderEmitter.h" 39 #include "SubtargetEmitter.h" 40 #include "TGParser.h" 41 #include "llvm/ADT/OwningPtr.h" 42 #include "llvm/Support/CommandLine.h" 43 #include "llvm/Support/MemoryBuffer.h" 44 #include "llvm/Support/PrettyStackTrace.h" 45 #include "llvm/Support/ToolOutputFile.h" 46 #include "llvm/Support/Signals.h" 47 #include "llvm/Support/system_error.h" 48 #include <algorithm> 49 #include <cstdio> 50 using namespace llvm; 51 52 enum ActionType { 53 PrintRecords, 54 GenEmitter, 55 GenRegisterEnums, GenRegister, GenRegisterHeader, 56 GenInstrEnums, GenInstrs, GenAsmWriter, GenAsmMatcher, 57 GenARMDecoder, 58 GenDisassembler, 59 GenCallingConv, 60 GenClangAttrClasses, 61 GenClangAttrImpl, 62 GenClangAttrList, 63 GenClangAttrPCHRead, 64 GenClangAttrPCHWrite, 65 GenClangAttrSpellingList, 66 GenClangDiagsDefs, 67 GenClangDiagGroups, 68 GenClangDiagsIndexName, 69 GenClangDeclNodes, 70 GenClangStmtNodes, 71 GenClangSACheckers, 72 GenDAGISel, 73 GenFastISel, 74 GenOptParserDefs, GenOptParserImpl, 75 GenSubtarget, 76 GenIntrinsic, 77 GenTgtIntrinsic, 78 GenLLVMCConf, 79 GenEDInfo, 80 GenArmNeon, 81 GenArmNeonSema, 82 GenArmNeonTest, 83 PrintEnums 84 }; 85 86 namespace { 87 cl::opt<ActionType> 88 Action(cl::desc("Action to perform:"), 89 cl::values(clEnumValN(PrintRecords, "print-records", 90 "Print all records to stdout (default)"), 91 clEnumValN(GenEmitter, "gen-emitter", 92 "Generate machine code emitter"), 93 clEnumValN(GenRegisterEnums, "gen-register-enums", 94 "Generate enum values for registers"), 95 clEnumValN(GenRegister, "gen-register-desc", 96 "Generate a register info description"), 97 clEnumValN(GenRegisterHeader, "gen-register-desc-header", 98 "Generate a register info description header"), 99 clEnumValN(GenInstrEnums, "gen-instr-enums", 100 "Generate enum values for instructions"), 101 clEnumValN(GenInstrs, "gen-instr-desc", 102 "Generate instruction descriptions"), 103 clEnumValN(GenCallingConv, "gen-callingconv", 104 "Generate calling convention descriptions"), 105 clEnumValN(GenAsmWriter, "gen-asm-writer", 106 "Generate assembly writer"), 107 clEnumValN(GenARMDecoder, "gen-arm-decoder", 108 "Generate decoders for ARM/Thumb"), 109 clEnumValN(GenDisassembler, "gen-disassembler", 110 "Generate disassembler"), 111 clEnumValN(GenAsmMatcher, "gen-asm-matcher", 112 "Generate assembly instruction matcher"), 113 clEnumValN(GenDAGISel, "gen-dag-isel", 114 "Generate a DAG instruction selector"), 115 clEnumValN(GenFastISel, "gen-fast-isel", 116 "Generate a \"fast\" instruction selector"), 117 clEnumValN(GenOptParserDefs, "gen-opt-parser-defs", 118 "Generate option definitions"), 119 clEnumValN(GenOptParserImpl, "gen-opt-parser-impl", 120 "Generate option parser implementation"), 121 clEnumValN(GenSubtarget, "gen-subtarget", 122 "Generate subtarget enumerations"), 123 clEnumValN(GenIntrinsic, "gen-intrinsic", 124 "Generate intrinsic information"), 125 clEnumValN(GenTgtIntrinsic, "gen-tgt-intrinsic", 126 "Generate target intrinsic information"), 127 clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes", 128 "Generate clang attribute clases"), 129 clEnumValN(GenClangAttrImpl, "gen-clang-attr-impl", 130 "Generate clang attribute implementations"), 131 clEnumValN(GenClangAttrList, "gen-clang-attr-list", 132 "Generate a clang attribute list"), 133 clEnumValN(GenClangAttrPCHRead, "gen-clang-attr-pch-read", 134 "Generate clang PCH attribute reader"), 135 clEnumValN(GenClangAttrPCHWrite, "gen-clang-attr-pch-write", 136 "Generate clang PCH attribute writer"), 137 clEnumValN(GenClangAttrSpellingList, 138 "gen-clang-attr-spelling-list", 139 "Generate a clang attribute spelling list"), 140 clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs", 141 "Generate Clang diagnostics definitions"), 142 clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups", 143 "Generate Clang diagnostic groups"), 144 clEnumValN(GenClangDiagsIndexName, 145 "gen-clang-diags-index-name", 146 "Generate Clang diagnostic name index"), 147 clEnumValN(GenClangDeclNodes, "gen-clang-decl-nodes", 148 "Generate Clang AST declaration nodes"), 149 clEnumValN(GenClangStmtNodes, "gen-clang-stmt-nodes", 150 "Generate Clang AST statement nodes"), 151 clEnumValN(GenClangSACheckers, "gen-clang-sa-checkers", 152 "Generate Clang Static Analyzer checkers"), 153 clEnumValN(GenLLVMCConf, "gen-llvmc", 154 "Generate LLVMC configuration library"), 155 clEnumValN(GenEDInfo, "gen-enhanced-disassembly-info", 156 "Generate enhanced disassembly info"), 157 clEnumValN(GenArmNeon, "gen-arm-neon", 158 "Generate arm_neon.h for clang"), 159 clEnumValN(GenArmNeonSema, "gen-arm-neon-sema", 160 "Generate ARM NEON sema support for clang"), 161 clEnumValN(GenArmNeonTest, "gen-arm-neon-test", 162 "Generate ARM NEON tests for clang"), 163 clEnumValN(PrintEnums, "print-enums", 164 "Print enum values for a class"), 165 clEnumValEnd)); 166 167 cl::opt<std::string> 168 Class("class", cl::desc("Print Enum list for this class"), 169 cl::value_desc("class name")); 170 171 cl::opt<std::string> 172 OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), 173 cl::init("-")); 174 175 cl::opt<std::string> 176 InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-")); 177 178 cl::list<std::string> 179 IncludeDirs("I", cl::desc("Directory of include files"), 180 cl::value_desc("directory"), cl::Prefix); 181 182 cl::opt<std::string> 183 ClangComponent("clang-component", 184 cl::desc("Only use warnings from specified component"), 185 cl::value_desc("component"), cl::Hidden); 186 } 187 188 189 static SourceMgr SrcMgr; 190 191 void llvm::PrintError(SMLoc ErrorLoc, const Twine &Msg) { 192 SrcMgr.PrintMessage(ErrorLoc, Msg, "error"); 193 } 194 195 196 197 /// ParseFile - this function begins the parsing of the specified tablegen 198 /// file. 199 static bool ParseFile(const std::string &Filename, 200 const std::vector<std::string> &IncludeDirs, 201 SourceMgr &SrcMgr, 202 RecordKeeper &Records) { 203 OwningPtr<MemoryBuffer> File; 204 if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File)) { 205 errs() << "Could not open input file '" << Filename << "': " 206 << ec.message() <<"\n"; 207 return true; 208 } 209 MemoryBuffer *F = File.take(); 210 211 // Tell SrcMgr about this buffer, which is what TGParser will pick up. 212 SrcMgr.AddNewSourceBuffer(F, SMLoc()); 213 214 // Record the location of the include directory so that the lexer can find 215 // it later. 216 SrcMgr.setIncludeDirs(IncludeDirs); 217 218 TGParser Parser(SrcMgr, Records); 219 220 return Parser.ParseFile(); 221 } 222 223 int main(int argc, char **argv) { 224 RecordKeeper Records; 225 226 sys::PrintStackTraceOnErrorSignal(); 227 PrettyStackTraceProgram X(argc, argv); 228 cl::ParseCommandLineOptions(argc, argv); 229 230 231 // Parse the input file. 232 if (ParseFile(InputFilename, IncludeDirs, SrcMgr, Records)) 233 return 1; 234 235 std::string Error; 236 tool_output_file Out(OutputFilename.c_str(), Error); 237 if (!Error.empty()) { 238 errs() << argv[0] << ": error opening " << OutputFilename 239 << ":" << Error << "\n"; 240 return 1; 241 } 242 243 try { 244 switch (Action) { 245 case PrintRecords: 246 Out.os() << Records; // No argument, dump all contents 247 break; 248 case GenEmitter: 249 CodeEmitterGen(Records).run(Out.os()); 250 break; 251 252 case GenRegisterEnums: 253 RegisterInfoEmitter(Records).runEnums(Out.os()); 254 break; 255 case GenRegister: 256 RegisterInfoEmitter(Records).run(Out.os()); 257 break; 258 case GenRegisterHeader: 259 RegisterInfoEmitter(Records).runHeader(Out.os()); 260 break; 261 case GenInstrEnums: 262 InstrEnumEmitter(Records).run(Out.os()); 263 break; 264 case GenInstrs: 265 InstrInfoEmitter(Records).run(Out.os()); 266 break; 267 case GenCallingConv: 268 CallingConvEmitter(Records).run(Out.os()); 269 break; 270 case GenAsmWriter: 271 AsmWriterEmitter(Records).run(Out.os()); 272 break; 273 case GenARMDecoder: 274 ARMDecoderEmitter(Records).run(Out.os()); 275 break; 276 case GenAsmMatcher: 277 AsmMatcherEmitter(Records).run(Out.os()); 278 break; 279 case GenClangAttrClasses: 280 ClangAttrClassEmitter(Records).run(Out.os()); 281 break; 282 case GenClangAttrImpl: 283 ClangAttrImplEmitter(Records).run(Out.os()); 284 break; 285 case GenClangAttrList: 286 ClangAttrListEmitter(Records).run(Out.os()); 287 break; 288 case GenClangAttrPCHRead: 289 ClangAttrPCHReadEmitter(Records).run(Out.os()); 290 break; 291 case GenClangAttrPCHWrite: 292 ClangAttrPCHWriteEmitter(Records).run(Out.os()); 293 break; 294 case GenClangAttrSpellingList: 295 ClangAttrSpellingListEmitter(Records).run(Out.os()); 296 break; 297 case GenClangDiagsDefs: 298 ClangDiagsDefsEmitter(Records, ClangComponent).run(Out.os()); 299 break; 300 case GenClangDiagGroups: 301 ClangDiagGroupsEmitter(Records).run(Out.os()); 302 break; 303 case GenClangDiagsIndexName: 304 ClangDiagsIndexNameEmitter(Records).run(Out.os()); 305 break; 306 case GenClangDeclNodes: 307 ClangASTNodesEmitter(Records, "Decl", "Decl").run(Out.os()); 308 ClangDeclContextEmitter(Records).run(Out.os()); 309 break; 310 case GenClangStmtNodes: 311 ClangASTNodesEmitter(Records, "Stmt", "").run(Out.os()); 312 break; 313 case GenClangSACheckers: 314 ClangSACheckersEmitter(Records).run(Out.os()); 315 break; 316 case GenDisassembler: 317 DisassemblerEmitter(Records).run(Out.os()); 318 break; 319 case GenOptParserDefs: 320 OptParserEmitter(Records, true).run(Out.os()); 321 break; 322 case GenOptParserImpl: 323 OptParserEmitter(Records, false).run(Out.os()); 324 break; 325 case GenDAGISel: 326 DAGISelEmitter(Records).run(Out.os()); 327 break; 328 case GenFastISel: 329 FastISelEmitter(Records).run(Out.os()); 330 break; 331 case GenSubtarget: 332 SubtargetEmitter(Records).run(Out.os()); 333 break; 334 case GenIntrinsic: 335 IntrinsicEmitter(Records).run(Out.os()); 336 break; 337 case GenTgtIntrinsic: 338 IntrinsicEmitter(Records, true).run(Out.os()); 339 break; 340 case GenLLVMCConf: 341 LLVMCConfigurationEmitter(Records).run(Out.os()); 342 break; 343 case GenEDInfo: 344 EDEmitter(Records).run(Out.os()); 345 break; 346 case GenArmNeon: 347 NeonEmitter(Records).run(Out.os()); 348 break; 349 case GenArmNeonSema: 350 NeonEmitter(Records).runHeader(Out.os()); 351 break; 352 case GenArmNeonTest: 353 NeonEmitter(Records).runTests(Out.os()); 354 break; 355 case PrintEnums: 356 { 357 std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class); 358 for (unsigned i = 0, e = Recs.size(); i != e; ++i) 359 Out.os() << Recs[i]->getName() << ", "; 360 Out.os() << "\n"; 361 break; 362 } 363 default: 364 assert(1 && "Invalid Action"); 365 return 1; 366 } 367 368 // Declare success. 369 Out.keep(); 370 return 0; 371 372 } catch (const TGError &Error) { 373 errs() << argv[0] << ": error:\n"; 374 PrintError(Error.getLoc(), Error.getMessage()); 375 376 } catch (const std::string &Error) { 377 errs() << argv[0] << ": " << Error << "\n"; 378 } catch (const char *Error) { 379 errs() << argv[0] << ": " << Error << "\n"; 380 } catch (...) { 381 errs() << argv[0] << ": Unknown unexpected exception occurred.\n"; 382 } 383 384 return 1; 385 } 386