TableGen.cpp revision 224145
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 "Error.h" 30#include "FastISelEmitter.h" 31#include "InstrInfoEmitter.h" 32#include "IntrinsicEmitter.h" 33#include "LLVMCConfigurationEmitter.h" 34#include "NeonEmitter.h" 35#include "OptParserEmitter.h" 36#include "PseudoLoweringEmitter.h" 37#include "Record.h" 38#include "RegisterInfoEmitter.h" 39#include "ARMDecoderEmitter.h" 40#include "SubtargetEmitter.h" 41#include "SetTheory.h" 42#include "TGParser.h" 43#include "llvm/ADT/OwningPtr.h" 44#include "llvm/Support/CommandLine.h" 45#include "llvm/Support/MemoryBuffer.h" 46#include "llvm/Support/PrettyStackTrace.h" 47#include "llvm/Support/ToolOutputFile.h" 48#include "llvm/Support/Signals.h" 49#include "llvm/Support/system_error.h" 50#include <algorithm> 51#include <cstdio> 52using namespace llvm; 53 54enum ActionType { 55 PrintRecords, 56 GenEmitter, 57 GenRegisterInfo, 58 GenInstrInfo, 59 GenAsmWriter, 60 GenAsmMatcher, 61 GenARMDecoder, 62 GenDisassembler, 63 GenPseudoLowering, 64 GenCallingConv, 65 GenClangAttrClasses, 66 GenClangAttrImpl, 67 GenClangAttrList, 68 GenClangAttrPCHRead, 69 GenClangAttrPCHWrite, 70 GenClangAttrSpellingList, 71 GenClangDiagsDefs, 72 GenClangDiagGroups, 73 GenClangDiagsIndexName, 74 GenClangDeclNodes, 75 GenClangStmtNodes, 76 GenClangSACheckers, 77 GenDAGISel, 78 GenFastISel, 79 GenOptParserDefs, GenOptParserImpl, 80 GenSubtarget, 81 GenIntrinsic, 82 GenTgtIntrinsic, 83 GenLLVMCConf, 84 GenEDInfo, 85 GenArmNeon, 86 GenArmNeonSema, 87 GenArmNeonTest, 88 PrintEnums, 89 PrintSets 90}; 91 92namespace { 93 cl::opt<ActionType> 94 Action(cl::desc("Action to perform:"), 95 cl::values(clEnumValN(PrintRecords, "print-records", 96 "Print all records to stdout (default)"), 97 clEnumValN(GenEmitter, "gen-emitter", 98 "Generate machine code emitter"), 99 clEnumValN(GenRegisterInfo, "gen-register-info", 100 "Generate registers and register classes info"), 101 clEnumValN(GenInstrInfo, "gen-instr-info", 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(GenPseudoLowering, "gen-pseudo-lowering", 112 "Generate pseudo instruction lowering"), 113 clEnumValN(GenAsmMatcher, "gen-asm-matcher", 114 "Generate assembly instruction matcher"), 115 clEnumValN(GenDAGISel, "gen-dag-isel", 116 "Generate a DAG instruction selector"), 117 clEnumValN(GenFastISel, "gen-fast-isel", 118 "Generate a \"fast\" instruction selector"), 119 clEnumValN(GenOptParserDefs, "gen-opt-parser-defs", 120 "Generate option definitions"), 121 clEnumValN(GenOptParserImpl, "gen-opt-parser-impl", 122 "Generate option parser implementation"), 123 clEnumValN(GenSubtarget, "gen-subtarget", 124 "Generate subtarget enumerations"), 125 clEnumValN(GenIntrinsic, "gen-intrinsic", 126 "Generate intrinsic information"), 127 clEnumValN(GenTgtIntrinsic, "gen-tgt-intrinsic", 128 "Generate target intrinsic information"), 129 clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes", 130 "Generate clang attribute clases"), 131 clEnumValN(GenClangAttrImpl, "gen-clang-attr-impl", 132 "Generate clang attribute implementations"), 133 clEnumValN(GenClangAttrList, "gen-clang-attr-list", 134 "Generate a clang attribute list"), 135 clEnumValN(GenClangAttrPCHRead, "gen-clang-attr-pch-read", 136 "Generate clang PCH attribute reader"), 137 clEnumValN(GenClangAttrPCHWrite, "gen-clang-attr-pch-write", 138 "Generate clang PCH attribute writer"), 139 clEnumValN(GenClangAttrSpellingList, 140 "gen-clang-attr-spelling-list", 141 "Generate a clang attribute spelling list"), 142 clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs", 143 "Generate Clang diagnostics definitions"), 144 clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups", 145 "Generate Clang diagnostic groups"), 146 clEnumValN(GenClangDiagsIndexName, 147 "gen-clang-diags-index-name", 148 "Generate Clang diagnostic name index"), 149 clEnumValN(GenClangDeclNodes, "gen-clang-decl-nodes", 150 "Generate Clang AST declaration nodes"), 151 clEnumValN(GenClangStmtNodes, "gen-clang-stmt-nodes", 152 "Generate Clang AST statement nodes"), 153 clEnumValN(GenClangSACheckers, "gen-clang-sa-checkers", 154 "Generate Clang Static Analyzer checkers"), 155 clEnumValN(GenLLVMCConf, "gen-llvmc", 156 "Generate LLVMC configuration library"), 157 clEnumValN(GenEDInfo, "gen-enhanced-disassembly-info", 158 "Generate enhanced disassembly info"), 159 clEnumValN(GenArmNeon, "gen-arm-neon", 160 "Generate arm_neon.h for clang"), 161 clEnumValN(GenArmNeonSema, "gen-arm-neon-sema", 162 "Generate ARM NEON sema support for clang"), 163 clEnumValN(GenArmNeonTest, "gen-arm-neon-test", 164 "Generate ARM NEON tests for clang"), 165 clEnumValN(PrintEnums, "print-enums", 166 "Print enum values for a class"), 167 clEnumValN(PrintSets, "print-sets", 168 "Print expanded sets for testing DAG exprs"), 169 clEnumValEnd)); 170 171 cl::opt<std::string> 172 Class("class", cl::desc("Print Enum list for this class"), 173 cl::value_desc("class name")); 174 175 cl::opt<std::string> 176 OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), 177 cl::init("-")); 178 179 cl::opt<std::string> 180 DependFilename("d", cl::desc("Dependency filename"), cl::value_desc("filename"), 181 cl::init("")); 182 183 cl::opt<std::string> 184 InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-")); 185 186 cl::list<std::string> 187 IncludeDirs("I", cl::desc("Directory of include files"), 188 cl::value_desc("directory"), cl::Prefix); 189 190 cl::opt<std::string> 191 ClangComponent("clang-component", 192 cl::desc("Only use warnings from specified component"), 193 cl::value_desc("component"), cl::Hidden); 194} 195 196 197int main(int argc, char **argv) { 198 RecordKeeper Records; 199 200 sys::PrintStackTraceOnErrorSignal(); 201 PrettyStackTraceProgram X(argc, argv); 202 cl::ParseCommandLineOptions(argc, argv); 203 204 205 try { 206 // Parse the input file. 207 OwningPtr<MemoryBuffer> File; 208 if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), File)) { 209 errs() << "Could not open input file '" << InputFilename << "': " 210 << ec.message() <<"\n"; 211 return 1; 212 } 213 MemoryBuffer *F = File.take(); 214 215 // Tell SrcMgr about this buffer, which is what TGParser will pick up. 216 SrcMgr.AddNewSourceBuffer(F, SMLoc()); 217 218 // Record the location of the include directory so that the lexer can find 219 // it later. 220 SrcMgr.setIncludeDirs(IncludeDirs); 221 222 TGParser Parser(SrcMgr, Records); 223 224 if (Parser.ParseFile()) 225 return 1; 226 227 std::string Error; 228 tool_output_file Out(OutputFilename.c_str(), Error); 229 if (!Error.empty()) { 230 errs() << argv[0] << ": error opening " << OutputFilename 231 << ":" << Error << "\n"; 232 return 1; 233 } 234 if (!DependFilename.empty()) { 235 if (OutputFilename == "-") { 236 errs() << argv[0] << ": the option -d must be used together with -o\n"; 237 return 1; 238 } 239 tool_output_file DepOut(DependFilename.c_str(), Error); 240 if (!Error.empty()) { 241 errs() << argv[0] << ": error opening " << DependFilename 242 << ":" << Error << "\n"; 243 return 1; 244 } 245 DepOut.os() << DependFilename << ":"; 246 const std::vector<std::string> &Dependencies = Parser.getDependencies(); 247 for (std::vector<std::string>::const_iterator I = Dependencies.begin(), 248 E = Dependencies.end(); 249 I != E; ++I) { 250 DepOut.os() << " " << (*I); 251 } 252 DepOut.os() << "\n"; 253 DepOut.keep(); 254 } 255 256 switch (Action) { 257 case PrintRecords: 258 Out.os() << Records; // No argument, dump all contents 259 break; 260 case GenEmitter: 261 CodeEmitterGen(Records).run(Out.os()); 262 break; 263 case GenRegisterInfo: 264 RegisterInfoEmitter(Records).run(Out.os()); 265 break; 266 case GenInstrInfo: 267 InstrInfoEmitter(Records).run(Out.os()); 268 break; 269 case GenCallingConv: 270 CallingConvEmitter(Records).run(Out.os()); 271 break; 272 case GenAsmWriter: 273 AsmWriterEmitter(Records).run(Out.os()); 274 break; 275 case GenARMDecoder: 276 ARMDecoderEmitter(Records).run(Out.os()); 277 break; 278 case GenAsmMatcher: 279 AsmMatcherEmitter(Records).run(Out.os()); 280 break; 281 case GenClangAttrClasses: 282 ClangAttrClassEmitter(Records).run(Out.os()); 283 break; 284 case GenClangAttrImpl: 285 ClangAttrImplEmitter(Records).run(Out.os()); 286 break; 287 case GenClangAttrList: 288 ClangAttrListEmitter(Records).run(Out.os()); 289 break; 290 case GenClangAttrPCHRead: 291 ClangAttrPCHReadEmitter(Records).run(Out.os()); 292 break; 293 case GenClangAttrPCHWrite: 294 ClangAttrPCHWriteEmitter(Records).run(Out.os()); 295 break; 296 case GenClangAttrSpellingList: 297 ClangAttrSpellingListEmitter(Records).run(Out.os()); 298 break; 299 case GenClangDiagsDefs: 300 ClangDiagsDefsEmitter(Records, ClangComponent).run(Out.os()); 301 break; 302 case GenClangDiagGroups: 303 ClangDiagGroupsEmitter(Records).run(Out.os()); 304 break; 305 case GenClangDiagsIndexName: 306 ClangDiagsIndexNameEmitter(Records).run(Out.os()); 307 break; 308 case GenClangDeclNodes: 309 ClangASTNodesEmitter(Records, "Decl", "Decl").run(Out.os()); 310 ClangDeclContextEmitter(Records).run(Out.os()); 311 break; 312 case GenClangStmtNodes: 313 ClangASTNodesEmitter(Records, "Stmt", "").run(Out.os()); 314 break; 315 case GenClangSACheckers: 316 ClangSACheckersEmitter(Records).run(Out.os()); 317 break; 318 case GenDisassembler: 319 DisassemblerEmitter(Records).run(Out.os()); 320 break; 321 case GenPseudoLowering: 322 PseudoLoweringEmitter(Records).run(Out.os()); 323 break; 324 case GenOptParserDefs: 325 OptParserEmitter(Records, true).run(Out.os()); 326 break; 327 case GenOptParserImpl: 328 OptParserEmitter(Records, false).run(Out.os()); 329 break; 330 case GenDAGISel: 331 DAGISelEmitter(Records).run(Out.os()); 332 break; 333 case GenFastISel: 334 FastISelEmitter(Records).run(Out.os()); 335 break; 336 case GenSubtarget: 337 SubtargetEmitter(Records).run(Out.os()); 338 break; 339 case GenIntrinsic: 340 IntrinsicEmitter(Records).run(Out.os()); 341 break; 342 case GenTgtIntrinsic: 343 IntrinsicEmitter(Records, true).run(Out.os()); 344 break; 345 case GenLLVMCConf: 346 LLVMCConfigurationEmitter(Records).run(Out.os()); 347 break; 348 case GenEDInfo: 349 EDEmitter(Records).run(Out.os()); 350 break; 351 case GenArmNeon: 352 NeonEmitter(Records).run(Out.os()); 353 break; 354 case GenArmNeonSema: 355 NeonEmitter(Records).runHeader(Out.os()); 356 break; 357 case GenArmNeonTest: 358 NeonEmitter(Records).runTests(Out.os()); 359 break; 360 case PrintEnums: 361 { 362 std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class); 363 for (unsigned i = 0, e = Recs.size(); i != e; ++i) 364 Out.os() << Recs[i]->getName() << ", "; 365 Out.os() << "\n"; 366 break; 367 } 368 case PrintSets: 369 { 370 SetTheory Sets; 371 Sets.addFieldExpander("Set", "Elements"); 372 std::vector<Record*> Recs = Records.getAllDerivedDefinitions("Set"); 373 for (unsigned i = 0, e = Recs.size(); i != e; ++i) { 374 Out.os() << Recs[i]->getName() << " = ["; 375 const std::vector<Record*> *Elts = Sets.expand(Recs[i]); 376 assert(Elts && "Couldn't expand Set instance"); 377 for (unsigned ei = 0, ee = Elts->size(); ei != ee; ++ei) 378 Out.os() << ' ' << (*Elts)[ei]->getName(); 379 Out.os() << " ]\n"; 380 } 381 break; 382 } 383 default: 384 assert(1 && "Invalid Action"); 385 return 1; 386 } 387 388 // Declare success. 389 Out.keep(); 390 return 0; 391 392 } catch (const TGError &Error) { 393 PrintError(Error); 394 } catch (const std::string &Error) { 395 PrintError(Error); 396 } catch (const char *Error) { 397 PrintError(Error); 398 } catch (...) { 399 errs() << argv[0] << ": Unknown unexpected exception occurred.\n"; 400 } 401 402 return 1; 403} 404