1//===- Main.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 "TGParser.h" 19#include "llvm/ADT/OwningPtr.h" 20#include "llvm/Support/CommandLine.h" 21#include "llvm/Support/MemoryBuffer.h" 22#include "llvm/Support/ToolOutputFile.h" 23#include "llvm/Support/system_error.h" 24#include "llvm/TableGen/Error.h" 25#include "llvm/TableGen/Record.h" 26#include "llvm/TableGen/TableGenAction.h" 27#include <algorithm> 28#include <cstdio> 29using namespace llvm; 30 31namespace { 32 cl::opt<std::string> 33 OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), 34 cl::init("-")); 35 36 cl::opt<std::string> 37 DependFilename("d", 38 cl::desc("Dependency filename"), 39 cl::value_desc("filename"), 40 cl::init("")); 41 42 cl::opt<std::string> 43 InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-")); 44 45 cl::list<std::string> 46 IncludeDirs("I", cl::desc("Directory of include files"), 47 cl::value_desc("directory"), cl::Prefix); 48} 49 50namespace llvm { 51 52int TableGenMain(char *argv0, TableGenAction &Action) { 53 RecordKeeper Records; 54 55 try { 56 // Parse the input file. 57 OwningPtr<MemoryBuffer> File; 58 if (error_code ec = 59 MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), File)) { 60 errs() << "Could not open input file '" << InputFilename << "': " 61 << ec.message() <<"\n"; 62 return 1; 63 } 64 MemoryBuffer *F = File.take(); 65 66 // Tell SrcMgr about this buffer, which is what TGParser will pick up. 67 SrcMgr.AddNewSourceBuffer(F, SMLoc()); 68 69 // Record the location of the include directory so that the lexer can find 70 // it later. 71 SrcMgr.setIncludeDirs(IncludeDirs); 72 73 TGParser Parser(SrcMgr, Records); 74 75 if (Parser.ParseFile()) 76 return 1; 77 78 std::string Error; 79 tool_output_file Out(OutputFilename.c_str(), Error); 80 if (!Error.empty()) { 81 errs() << argv0 << ": error opening " << OutputFilename 82 << ":" << Error << "\n"; 83 return 1; 84 } 85 if (!DependFilename.empty()) { 86 if (OutputFilename == "-") { 87 errs() << argv0 << ": the option -d must be used together with -o\n"; 88 return 1; 89 } 90 tool_output_file DepOut(DependFilename.c_str(), Error); 91 if (!Error.empty()) { 92 errs() << argv0 << ": error opening " << DependFilename 93 << ":" << Error << "\n"; 94 return 1; 95 } 96 DepOut.os() << OutputFilename << ":"; 97 const std::vector<std::string> &Dependencies = Parser.getDependencies(); 98 for (std::vector<std::string>::const_iterator I = Dependencies.begin(), 99 E = Dependencies.end(); 100 I != E; ++I) { 101 DepOut.os() << " " << (*I); 102 } 103 DepOut.os() << "\n"; 104 DepOut.keep(); 105 } 106 107 if (Action(Out.os(), Records)) 108 return 1; 109 110 // Declare success. 111 Out.keep(); 112 return 0; 113 114 } catch (const TGError &Error) { 115 PrintError(Error); 116 } catch (const std::string &Error) { 117 PrintError(Error); 118 } catch (const char *Error) { 119 PrintError(Error); 120 } catch (...) { 121 errs() << argv0 << ": Unknown unexpected exception occurred.\n"; 122 } 123 124 return 1; 125} 126 127} 128