TableGen.cpp revision 210299
1214501Srpaulo//===- TableGen.cpp - Top-Level TableGen implementation -------------------===//
2214501Srpaulo//
3214501Srpaulo//                     The LLVM Compiler Infrastructure
4214501Srpaulo//
5214501Srpaulo// This file is distributed under the University of Illinois Open Source
6214501Srpaulo// License. See LICENSE.TXT for details.
7214501Srpaulo//
8214501Srpaulo//===----------------------------------------------------------------------===//
9214501Srpaulo//
10214501Srpaulo// TableGen is a tool which can be used to build up a description of something,
11214501Srpaulo// then invoke one or more "tablegen backends" to emit information about the
12214501Srpaulo// description in some predefined format.  In practice, this is used by the LLVM
13214501Srpaulo// code generators to automate generation of a code generator through a
14214501Srpaulo// high-level description of the target.
15214501Srpaulo//
16214501Srpaulo//===----------------------------------------------------------------------===//
17214501Srpaulo
18214501Srpaulo#include "AsmMatcherEmitter.h"
19214501Srpaulo#include "AsmWriterEmitter.h"
20214501Srpaulo#include "CallingConvEmitter.h"
21214501Srpaulo#include "ClangASTNodesEmitter.h"
22214501Srpaulo#include "ClangAttrEmitter.h"
23214501Srpaulo#include "ClangDiagnosticsEmitter.h"
24214501Srpaulo#include "CodeEmitterGen.h"
25214501Srpaulo#include "DAGISelEmitter.h"
26214501Srpaulo#include "DisassemblerEmitter.h"
27214501Srpaulo#include "EDEmitter.h"
28214501Srpaulo#include "FastISelEmitter.h"
29214501Srpaulo#include "InstrEnumEmitter.h"
30214501Srpaulo#include "InstrInfoEmitter.h"
31214501Srpaulo#include "IntrinsicEmitter.h"
32214501Srpaulo#include "LLVMCConfigurationEmitter.h"
33214501Srpaulo#include "NeonEmitter.h"
34214501Srpaulo#include "OptParserEmitter.h"
35214501Srpaulo#include "Record.h"
36214501Srpaulo#include "RegisterInfoEmitter.h"
37214501Srpaulo#include "ARMDecoderEmitter.h"
38214501Srpaulo#include "SubtargetEmitter.h"
39214501Srpaulo#include "TGParser.h"
40214501Srpaulo#include "llvm/Support/CommandLine.h"
41214501Srpaulo#include "llvm/Support/MemoryBuffer.h"
42214501Srpaulo#include "llvm/Support/PrettyStackTrace.h"
43214501Srpaulo#include "llvm/Support/raw_ostream.h"
44214501Srpaulo#include "llvm/System/Signals.h"
45214501Srpaulo#include <algorithm>
46214501Srpaulo#include <cstdio>
47214501Srpaulousing namespace llvm;
48214501Srpaulo
49214501Srpauloenum ActionType {
50214501Srpaulo  PrintRecords,
51214501Srpaulo  GenEmitter,
52214501Srpaulo  GenRegisterEnums, GenRegister, GenRegisterHeader,
53214501Srpaulo  GenInstrEnums, GenInstrs, GenAsmWriter, GenAsmMatcher,
54214501Srpaulo  GenARMDecoder,
55214501Srpaulo  GenDisassembler,
56214501Srpaulo  GenCallingConv,
57214501Srpaulo  GenClangAttrClasses,
58214501Srpaulo  GenClangAttrList,
59  GenClangDiagsDefs,
60  GenClangDiagGroups,
61  GenClangDeclNodes,
62  GenClangStmtNodes,
63  GenDAGISel,
64  GenFastISel,
65  GenOptParserDefs, GenOptParserImpl,
66  GenSubtarget,
67  GenIntrinsic,
68  GenTgtIntrinsic,
69  GenLLVMCConf,
70  GenEDHeader, GenEDInfo,
71  GenArmNeon,
72  GenArmNeonSema,
73  PrintEnums
74};
75
76namespace {
77  cl::opt<ActionType>
78  Action(cl::desc("Action to perform:"),
79         cl::values(clEnumValN(PrintRecords, "print-records",
80                               "Print all records to stdout (default)"),
81                    clEnumValN(GenEmitter, "gen-emitter",
82                               "Generate machine code emitter"),
83                    clEnumValN(GenRegisterEnums, "gen-register-enums",
84                               "Generate enum values for registers"),
85                    clEnumValN(GenRegister, "gen-register-desc",
86                               "Generate a register info description"),
87                    clEnumValN(GenRegisterHeader, "gen-register-desc-header",
88                               "Generate a register info description header"),
89                    clEnumValN(GenInstrEnums, "gen-instr-enums",
90                               "Generate enum values for instructions"),
91                    clEnumValN(GenInstrs, "gen-instr-desc",
92                               "Generate instruction descriptions"),
93                    clEnumValN(GenCallingConv, "gen-callingconv",
94                               "Generate calling convention descriptions"),
95                    clEnumValN(GenAsmWriter, "gen-asm-writer",
96                               "Generate assembly writer"),
97                    clEnumValN(GenARMDecoder, "gen-arm-decoder",
98                               "Generate decoders for ARM/Thumb"),
99                    clEnumValN(GenDisassembler, "gen-disassembler",
100                               "Generate disassembler"),
101                    clEnumValN(GenAsmMatcher, "gen-asm-matcher",
102                               "Generate assembly instruction matcher"),
103                    clEnumValN(GenDAGISel, "gen-dag-isel",
104                               "Generate a DAG instruction selector"),
105                    clEnumValN(GenFastISel, "gen-fast-isel",
106                               "Generate a \"fast\" instruction selector"),
107                    clEnumValN(GenOptParserDefs, "gen-opt-parser-defs",
108                               "Generate option definitions"),
109                    clEnumValN(GenOptParserImpl, "gen-opt-parser-impl",
110                               "Generate option parser implementation"),
111                    clEnumValN(GenSubtarget, "gen-subtarget",
112                               "Generate subtarget enumerations"),
113                    clEnumValN(GenIntrinsic, "gen-intrinsic",
114                               "Generate intrinsic information"),
115                    clEnumValN(GenTgtIntrinsic, "gen-tgt-intrinsic",
116                               "Generate target intrinsic information"),
117                    clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes",
118                               "Generate clang attribute clases"),
119                    clEnumValN(GenClangAttrList, "gen-clang-attr-list",
120                               "Generate a clang attribute list"),
121                    clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs",
122                               "Generate Clang diagnostics definitions"),
123                    clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups",
124                               "Generate Clang diagnostic groups"),
125                    clEnumValN(GenClangDeclNodes, "gen-clang-decl-nodes",
126                               "Generate Clang AST statement nodes"),
127                    clEnumValN(GenClangStmtNodes, "gen-clang-stmt-nodes",
128                               "Generate Clang AST statement nodes"),
129                    clEnumValN(GenLLVMCConf, "gen-llvmc",
130                               "Generate LLVMC configuration library"),
131                    clEnumValN(GenEDHeader, "gen-enhanced-disassembly-header",
132                               "Generate enhanced disassembly info header"),
133                    clEnumValN(GenEDInfo, "gen-enhanced-disassembly-info",
134                               "Generate enhanced disassembly info"),
135                    clEnumValN(GenArmNeon, "gen-arm-neon",
136                               "Generate arm_neon.h for clang"),
137                    clEnumValN(GenArmNeonSema, "gen-arm-neon-sema",
138                               "Generate ARM NEON sema support for clang"),
139                    clEnumValN(PrintEnums, "print-enums",
140                               "Print enum values for a class"),
141                    clEnumValEnd));
142
143  cl::opt<std::string>
144  Class("class", cl::desc("Print Enum list for this class"),
145        cl::value_desc("class name"));
146
147  cl::opt<std::string>
148  OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"),
149                 cl::init("-"));
150
151  cl::opt<std::string>
152  InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
153
154  cl::list<std::string>
155  IncludeDirs("I", cl::desc("Directory of include files"),
156              cl::value_desc("directory"), cl::Prefix);
157
158  cl::opt<std::string>
159  ClangComponent("clang-component",
160                 cl::desc("Only use warnings from specified component"),
161                 cl::value_desc("component"), cl::Hidden);
162}
163
164
165// FIXME: Eliminate globals from tblgen.
166RecordKeeper llvm::Records;
167
168static SourceMgr SrcMgr;
169
170void llvm::PrintError(SMLoc ErrorLoc, const std::string &Msg) {
171  SrcMgr.PrintMessage(ErrorLoc, Msg, "error");
172}
173
174
175
176/// ParseFile - this function begins the parsing of the specified tablegen
177/// file.
178static bool ParseFile(const std::string &Filename,
179                      const std::vector<std::string> &IncludeDirs,
180                      SourceMgr &SrcMgr) {
181  std::string ErrorStr;
182  MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrorStr);
183  if (F == 0) {
184    errs() << "Could not open input file '" << Filename << "': "
185           << ErrorStr <<"\n";
186    return true;
187  }
188
189  // Tell SrcMgr about this buffer, which is what TGParser will pick up.
190  SrcMgr.AddNewSourceBuffer(F, SMLoc());
191
192  // Record the location of the include directory so that the lexer can find
193  // it later.
194  SrcMgr.setIncludeDirs(IncludeDirs);
195
196  TGParser Parser(SrcMgr);
197
198  return Parser.ParseFile();
199}
200
201int main(int argc, char **argv) {
202  sys::PrintStackTraceOnErrorSignal();
203  PrettyStackTraceProgram X(argc, argv);
204  cl::ParseCommandLineOptions(argc, argv);
205
206
207  // Parse the input file.
208  if (ParseFile(InputFilename, IncludeDirs, SrcMgr))
209    return 1;
210
211  std::string Error;
212  raw_fd_ostream Out(OutputFilename.c_str(), Error);
213  if (!Error.empty()) {
214    errs() << argv[0] << ": error opening " << OutputFilename
215           << ":" << Error << "\n";
216    return 1;
217  }
218
219  // Make sure the file gets removed if *gasp* tablegen crashes...
220  sys::RemoveFileOnSignal(sys::Path(OutputFilename));
221
222  try {
223    switch (Action) {
224    case PrintRecords:
225      Out << Records;           // No argument, dump all contents
226      break;
227    case GenEmitter:
228      CodeEmitterGen(Records).run(Out);
229      break;
230
231    case GenRegisterEnums:
232      RegisterInfoEmitter(Records).runEnums(Out);
233      break;
234    case GenRegister:
235      RegisterInfoEmitter(Records).run(Out);
236      break;
237    case GenRegisterHeader:
238      RegisterInfoEmitter(Records).runHeader(Out);
239      break;
240    case GenInstrEnums:
241      InstrEnumEmitter(Records).run(Out);
242      break;
243    case GenInstrs:
244      InstrInfoEmitter(Records).run(Out);
245      break;
246    case GenCallingConv:
247      CallingConvEmitter(Records).run(Out);
248      break;
249    case GenAsmWriter:
250      AsmWriterEmitter(Records).run(Out);
251      break;
252    case GenARMDecoder:
253      ARMDecoderEmitter(Records).run(Out);
254      break;
255    case GenAsmMatcher:
256      AsmMatcherEmitter(Records).run(Out);
257      break;
258    case GenClangAttrClasses:
259      ClangAttrClassEmitter(Records).run(Out);
260      break;
261    case GenClangAttrList:
262      ClangAttrListEmitter(Records).run(Out);
263      break;
264    case GenClangDiagsDefs:
265      ClangDiagsDefsEmitter(Records, ClangComponent).run(Out);
266      break;
267    case GenClangDiagGroups:
268      ClangDiagGroupsEmitter(Records).run(Out);
269      break;
270    case GenClangDeclNodes:
271      ClangASTNodesEmitter(Records, "Decl", "Decl").run(Out);
272      ClangDeclContextEmitter(Records).run(Out);
273      break;
274    case GenClangStmtNodes:
275      ClangASTNodesEmitter(Records, "Stmt", "").run(Out);
276      break;
277    case GenDisassembler:
278      DisassemblerEmitter(Records).run(Out);
279      break;
280    case GenOptParserDefs:
281      OptParserEmitter(Records, true).run(Out);
282      break;
283    case GenOptParserImpl:
284      OptParserEmitter(Records, false).run(Out);
285      break;
286    case GenDAGISel:
287      DAGISelEmitter(Records).run(Out);
288      break;
289    case GenFastISel:
290      FastISelEmitter(Records).run(Out);
291      break;
292    case GenSubtarget:
293      SubtargetEmitter(Records).run(Out);
294      break;
295    case GenIntrinsic:
296      IntrinsicEmitter(Records).run(Out);
297      break;
298    case GenTgtIntrinsic:
299      IntrinsicEmitter(Records, true).run(Out);
300      break;
301    case GenLLVMCConf:
302      LLVMCConfigurationEmitter(Records).run(Out);
303      break;
304    case GenEDHeader:
305      EDEmitter(Records).runHeader(Out);
306      break;
307    case GenEDInfo:
308      EDEmitter(Records).run(Out);
309      break;
310    case GenArmNeon:
311      NeonEmitter(Records).run(Out);
312      break;
313    case GenArmNeonSema:
314      NeonEmitter(Records).runHeader(Out);
315      break;
316    case PrintEnums:
317    {
318      std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
319      for (unsigned i = 0, e = Recs.size(); i != e; ++i)
320        Out << Recs[i]->getName() << ", ";
321      Out << "\n";
322      break;
323    }
324    default:
325      assert(1 && "Invalid Action");
326      return 1;
327    }
328
329    return 0;
330
331  } catch (const TGError &Error) {
332    errs() << argv[0] << ": error:\n";
333    PrintError(Error.getLoc(), Error.getMessage());
334
335  } catch (const std::string &Error) {
336    errs() << argv[0] << ": " << Error << "\n";
337  } catch (const char *Error) {
338    errs() << argv[0] << ": " << Error << "\n";
339  } catch (...) {
340    errs() << argv[0] << ": Unknown unexpected exception occurred.\n";
341  }
342
343  if (OutputFilename != "-")
344    std::remove(OutputFilename.c_str());    // Remove the file, it's broken
345  return 1;
346}
347