diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2011-10-01 16:41:13 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2011-10-01 16:41:13 +0000 |
commit | 7c788888872233748da10a8177a9a1eb176c1bc8 (patch) | |
tree | 2a813c66793364aeb39020c96c9510bb1c4f9cee /lib/TableGen/Main.cpp | |
parent | 2e6b97bbf86d0825a060e190189fae7f884c79c9 (diff) |
Move TableGen's parser and entry point into a library
This is the first step towards splitting LLVM and Clang's tblgen executables.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140951 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/TableGen/Main.cpp')
-rw-r--r-- | lib/TableGen/Main.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/lib/TableGen/Main.cpp b/lib/TableGen/Main.cpp new file mode 100644 index 0000000000..01bc55e989 --- /dev/null +++ b/lib/TableGen/Main.cpp @@ -0,0 +1,124 @@ +//===- Main.cpp - Top-Level TableGen implementation -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// TableGen is a tool which can be used to build up a description of something, +// then invoke one or more "tablegen backends" to emit information about the +// description in some predefined format. In practice, this is used by the LLVM +// code generators to automate generation of a code generator through a +// high-level description of the target. +// +//===----------------------------------------------------------------------===// + +#include "TGParser.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/ToolOutputFile.h" +#include "llvm/Support/system_error.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenAction.h" +#include <algorithm> +#include <cstdio> +using namespace llvm; + +namespace { + cl::opt<std::string> + OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), + cl::init("-")); + + cl::opt<std::string> + DependFilename("d", cl::desc("Dependency filename"), cl::value_desc("filename"), + cl::init("")); + + cl::opt<std::string> + InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-")); + + cl::list<std::string> + IncludeDirs("I", cl::desc("Directory of include files"), + cl::value_desc("directory"), cl::Prefix); +} + +namespace llvm { + +int TableGenMain(char *argv0, TableGenAction &Action) { + RecordKeeper Records; + + try { + // Parse the input file. + OwningPtr<MemoryBuffer> File; + if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), File)) { + errs() << "Could not open input file '" << InputFilename << "': " + << ec.message() <<"\n"; + return 1; + } + MemoryBuffer *F = File.take(); + + // Tell SrcMgr about this buffer, which is what TGParser will pick up. + SrcMgr.AddNewSourceBuffer(F, SMLoc()); + + // Record the location of the include directory so that the lexer can find + // it later. + SrcMgr.setIncludeDirs(IncludeDirs); + + TGParser Parser(SrcMgr, Records); + + if (Parser.ParseFile()) + return 1; + + std::string Error; + tool_output_file Out(OutputFilename.c_str(), Error); + if (!Error.empty()) { + errs() << argv0 << ": error opening " << OutputFilename + << ":" << Error << "\n"; + return 1; + } + if (!DependFilename.empty()) { + if (OutputFilename == "-") { + errs() << argv0 << ": the option -d must be used together with -o\n"; + return 1; + } + tool_output_file DepOut(DependFilename.c_str(), Error); + if (!Error.empty()) { + errs() << argv0 << ": error opening " << DependFilename + << ":" << Error << "\n"; + return 1; + } + DepOut.os() << OutputFilename << ":"; + const std::vector<std::string> &Dependencies = Parser.getDependencies(); + for (std::vector<std::string>::const_iterator I = Dependencies.begin(), + E = Dependencies.end(); + I != E; ++I) { + DepOut.os() << " " << (*I); + } + DepOut.os() << "\n"; + DepOut.keep(); + } + + if (Action(Out.os(), Records)) + return 1; + + // Declare success. + Out.keep(); + return 0; + + } catch (const TGError &Error) { + PrintError(Error); + } catch (const std::string &Error) { + PrintError(Error); + } catch (const char *Error) { + PrintError(Error); + } catch (...) { + errs() << argv0 << ": Unknown unexpected exception occurred.\n"; + } + + return 1; +} + +} |