diff --git a/clang/utils/TableGen/TableGen.cpp b/clang/utils/TableGen/TableGen.cpp --- a/clang/utils/TableGen/TableGen.cpp +++ b/clang/utils/TableGen/TableGen.cpp @@ -489,6 +489,7 @@ int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(argv[0]); PrettyStackTraceProgram X(argc, argv); + registerTableGenOptions(); cl::ParseCommandLineOptions(argc, argv); llvm_shutdown_obj Y; diff --git a/libc/utils/HdrGen/Main.cpp b/libc/utils/HdrGen/Main.cpp --- a/libc/utils/HdrGen/Main.cpp +++ b/libc/utils/HdrGen/Main.cpp @@ -56,6 +56,7 @@ } // namespace llvm_libc int main(int argc, char *argv[]) { + llvm::registerTableGenOptions(); llvm::cl::ParseCommandLineOptions(argc, argv); - return TableGenMain(argv[0], &llvm_libc::HeaderGeneratorMain); + return llvm::TableGenMain(argv[0], &llvm_libc::HeaderGeneratorMain); } diff --git a/libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp b/libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp --- a/libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp +++ b/libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp @@ -100,6 +100,7 @@ } int main(int argc, char *argv[]) { + llvm::registerTableGenOptions(); llvm::cl::ParseCommandLineOptions(argc, argv); - return TableGenMain(argv[0], TestGeneratorMain); + return llvm::TableGenMain(argv[0], TestGeneratorMain); } diff --git a/libc/utils/tools/WrapperGen/Main.cpp b/libc/utils/tools/WrapperGen/Main.cpp --- a/libc/utils/tools/WrapperGen/Main.cpp +++ b/libc/utils/tools/WrapperGen/Main.cpp @@ -193,6 +193,7 @@ } int main(int argc, char *argv[]) { + llvm::registerTableGenOptions(); llvm::cl::ParseCommandLineOptions(argc, argv); - return TableGenMain(argv[0], wrapperGenMain); + return llvm::TableGenMain(argv[0], wrapperGenMain); } diff --git a/lldb/utils/TableGen/LLDBTableGen.cpp b/lldb/utils/TableGen/LLDBTableGen.cpp --- a/lldb/utils/TableGen/LLDBTableGen.cpp +++ b/lldb/utils/TableGen/LLDBTableGen.cpp @@ -66,6 +66,7 @@ int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(argv[0]); PrettyStackTraceProgram X(argc, argv); + registerTableGenOptions(); cl::ParseCommandLineOptions(argc, argv); llvm_shutdown_obj Y; diff --git a/llvm/include/llvm/TableGen/Main.h b/llvm/include/llvm/TableGen/Main.h --- a/llvm/include/llvm/TableGen/Main.h +++ b/llvm/include/llvm/TableGen/Main.h @@ -18,6 +18,8 @@ class raw_ostream; class RecordKeeper; +void registerTableGenOptions(); + /// Perform the action using Records, and write output to OS. /// Returns true on error, false otherwise. using TableGenMainFn = bool (raw_ostream &OS, RecordKeeper &Records); diff --git a/llvm/lib/TableGen/Main.cpp b/llvm/lib/TableGen/Main.cpp --- a/llvm/lib/TableGen/Main.cpp +++ b/llvm/lib/TableGen/Main.cpp @@ -26,36 +26,45 @@ #include using namespace llvm; -static cl::opt -OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), - cl::init("-")); +namespace { -static cl::opt -DependFilename("d", - cl::desc("Dependency filename"), - cl::value_desc("filename"), - cl::init("")); +struct TableGenOptions { + cl::opt OutputFilename{"o", cl::desc("Output filename"), + cl::value_desc("filename"), + cl::init("-")}; -static cl::opt -InputFilename(cl::Positional, cl::desc(""), cl::init("-")); + cl::opt DependFilename{"d", cl::desc("Dependency filename"), + cl::value_desc("filename"), cl::init("")}; -static cl::list -IncludeDirs("I", cl::desc("Directory of include files"), - cl::value_desc("directory"), cl::Prefix); + cl::opt InputFilename{cl::Positional, cl::desc(""), + cl::init("-")}; -static cl::list -MacroNames("D", cl::desc("Name of the macro to be defined"), - cl::value_desc("macro name"), cl::Prefix); + cl::list IncludeDirs{"I", cl::desc("Directory of include files"), + cl::value_desc("directory"), cl::Prefix}; -static cl::opt -WriteIfChanged("write-if-changed", cl::desc("Only write output if it changed")); + cl::list MacroNames{"D", + cl::desc("Name of the macro to be defined"), + cl::value_desc("macro name"), cl::Prefix}; -static cl::opt -TimePhases("time-phases", cl::desc("Time phases of parser and backend")); + cl::opt WriteIfChanged{"write-if-changed", + cl::desc("Only write output if it changed")}; -static cl::opt NoWarnOnUnusedTemplateArgs( - "no-warn-on-unused-template-args", - cl::desc("Disable unused template argument warnings.")); + cl::opt TimePhases{"time-phases", + cl::desc("Time phases of parser and backend")}; + + cl::opt NoWarnOnUnusedTemplateArgs{ + "no-warn-on-unused-template-args", + cl::desc("Disable unused template argument warnings.")}; +}; + +TableGenOptions &getOpts() { + static TableGenOptions Opts; + return Opts; +} + +} // anonymous namespace + +void llvm::registerTableGenOptions() { (void)getOpts(); } static int reportError(const char *ProgName, Twine Msg) { errs() << ProgName << ": " << Msg; @@ -68,15 +77,15 @@ /// This functionality is really only for the benefit of the build system. /// It is similar to GCC's `-M*` family of options. static int createDependencyFile(const TGParser &Parser, const char *argv0) { - if (OutputFilename == "-") + if (getOpts().OutputFilename == "-") return reportError(argv0, "the option -d must be used together with -o\n"); std::error_code EC; - ToolOutputFile DepOut(DependFilename, EC, sys::fs::OF_Text); + ToolOutputFile DepOut(getOpts().DependFilename, EC, sys::fs::OF_Text); if (EC) - return reportError(argv0, "error opening " + DependFilename + ":" + - EC.message() + "\n"); - DepOut.os() << OutputFilename << ":"; + return reportError(argv0, "error opening " + getOpts().DependFilename + + ":" + EC.message() + "\n"); + DepOut.os() << getOpts().OutputFilename << ":"; for (const auto &Dep : Parser.getDependencies()) { DepOut.os() << ' ' << Dep; } @@ -88,28 +97,31 @@ int llvm::TableGenMain(const char *argv0, TableGenMainFn *MainFn) { RecordKeeper Records; - if (TimePhases) + if (getOpts().TimePhases) Records.startPhaseTiming(); // Parse the input file. Records.startTimer("Parse, build records"); ErrorOr> FileOrErr = - MemoryBuffer::getFileOrSTDIN(InputFilename, /*IsText=*/true); - if (std::error_code EC = FileOrErr.getError()) - return reportError(argv0, "Could not open input file '" + InputFilename + + MemoryBuffer::getFileOrSTDIN(getOpts().InputFilename, /*IsText=*/true); + if (std::error_code EC = FileOrErr.getError()) { + return reportError(argv0, "Could not open input file '" + + getOpts().InputFilename + "': " + EC.message() + "\n"); + } - Records.saveInputFilename(InputFilename); + Records.saveInputFilename(getOpts().InputFilename); // Tell SrcMgr about this buffer, which is what TGParser will pick up. SrcMgr.AddNewSourceBuffer(std::move(*FileOrErr), SMLoc()); // Record the location of the include directory so that the lexer can find // it later. - SrcMgr.setIncludeDirs(IncludeDirs); + SrcMgr.setIncludeDirs(getOpts().IncludeDirs); - TGParser Parser(SrcMgr, MacroNames, Records, NoWarnOnUnusedTemplateArgs); + TGParser Parser(SrcMgr, getOpts().MacroNames, Records, + getOpts().NoWarnOnUnusedTemplateArgs); if (Parser.ParseFile()) return 1; @@ -128,28 +140,28 @@ // If it's missing, Ninja considers the output dirty. If this was below // the early exit below and someone deleted the .inc.d file but not the .inc // file, tablegen would never write the depfile. - if (!DependFilename.empty()) { + if (!getOpts().DependFilename.empty()) { if (int Ret = createDependencyFile(Parser, argv0)) return Ret; } Records.startTimer("Write output"); bool WriteFile = true; - if (WriteIfChanged) { + if (getOpts().WriteIfChanged) { // Only updates the real output file if there are any differences. // This prevents recompilation of all the files depending on it if there // aren't any. if (auto ExistingOrErr = - MemoryBuffer::getFile(OutputFilename, /*IsText=*/true)) + MemoryBuffer::getFile(getOpts().OutputFilename, /*IsText=*/true)) if (std::move(ExistingOrErr.get())->getBuffer() == Out.str()) WriteFile = false; } if (WriteFile) { std::error_code EC; - ToolOutputFile OutFile(OutputFilename, EC, sys::fs::OF_Text); + ToolOutputFile OutFile(getOpts().OutputFilename, EC, sys::fs::OF_Text); if (EC) - return reportError(argv0, "error opening " + OutputFilename + ": " + - EC.message() + "\n"); + return reportError(argv0, "error opening " + getOpts().OutputFilename + + ": " + EC.message() + "\n"); OutFile.os() << Out.str(); if (ErrorsPrinted == 0) OutFile.keep(); diff --git a/llvm/tools/llvm-shlib/CMakeLists.txt b/llvm/tools/llvm-shlib/CMakeLists.txt --- a/llvm/tools/llvm-shlib/CMakeLists.txt +++ b/llvm/tools/llvm-shlib/CMakeLists.txt @@ -19,7 +19,6 @@ # Exclude libLLVMTableGen for the following reasons: # - it is only used by internal *-tblgen utilities; - # - it pollutes the global options space. list(REMOVE_ITEM LIB_NAMES "LLVMTableGen") if(LLVM_DYLIB_EXPORTED_SYMBOL_FILE) diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp --- a/llvm/utils/TableGen/TableGen.cpp +++ b/llvm/utils/TableGen/TableGen.cpp @@ -286,6 +286,7 @@ int main(int argc, char **argv) { InitLLVM X(argc, argv); + registerTableGenOptions(); cl::ParseCommandLineOptions(argc, argv); return TableGenMain(argv[0], &LLVMTableGenMain); diff --git a/mlir/lib/Tools/mlir-tblgen/MlirTblgenMain.cpp b/mlir/lib/Tools/mlir-tblgen/MlirTblgenMain.cpp --- a/mlir/lib/Tools/mlir-tblgen/MlirTblgenMain.cpp +++ b/mlir/lib/Tools/mlir-tblgen/MlirTblgenMain.cpp @@ -129,6 +129,7 @@ llvm::cl::opt generator( "", llvm::cl::desc("Generator to run"), cl::location(::generator)); + llvm::registerTableGenOptions(); cl::ParseCommandLineOptions(argc, argv); return TableGenMain(argv[0], &mlirTableGenMain);