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