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