diff --git a/llvm/test/tools/llvm-dwp/help.test b/llvm/test/tools/llvm-dwp/help.test --- a/llvm/test/tools/llvm-dwp/help.test +++ b/llvm/test/tools/llvm-dwp/help.test @@ -2,6 +2,4 @@ # HELP: OVERVIEW # HELP: USAGE -# HELP: Color Options -# HELP: Generic Options -# HELP: Specific Options +# HELP: OPTIONS diff --git a/llvm/tools/llvm-dwp/CMakeLists.txt b/llvm/tools/llvm-dwp/CMakeLists.txt --- a/llvm/tools/llvm-dwp/CMakeLists.txt +++ b/llvm/tools/llvm-dwp/CMakeLists.txt @@ -6,15 +6,21 @@ DWP MC Object + Option Support TargetParser ) +set(LLVM_TARGET_DEFINITIONS Opts.td) +tablegen(LLVM Opts.inc -gen-opt-parser-defs) +add_public_tablegen_target(DwpOptsTableGen) + add_llvm_tool(llvm-dwp llvm-dwp.cpp DEPENDS intrinsics_gen + DwpOptsTableGen ) if(LLVM_INSTALL_BINUTILS_SYMLINKS) diff --git a/llvm/tools/llvm-dwp/Opts.td b/llvm/tools/llvm-dwp/Opts.td new file mode 100644 --- /dev/null +++ b/llvm/tools/llvm-dwp/Opts.td @@ -0,0 +1,13 @@ +include "llvm/Option/OptParser.td" + +class F : Flag<["-", "--"], name>, HelpText; +class S : Separate<["-", "--"], name>, HelpText; + +def help : F<"help", "Display this help">; +def : F<"h", "Alias for --help">, Alias; +def version : F<"version", "Display the version of this program">; + +def execFileNames : S<"e", "Specify the executable/library files to get the list of *.dwo from.">, MetaVarName<"">; +def outputFileName : S<"o", "Specify the output file.">, MetaVarName<"">; +def continueOnCuIndexOverflow: F<"continue-on-cu-index-overflow", "This turns an error when offset for .debug_*.dwo sections " + "overfolws into a warning.">, MetaVarName<"">; diff --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp --- a/llvm/tools/llvm-dwp/llvm-dwp.cpp +++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp @@ -23,6 +23,8 @@ #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCTargetOptionsCommandFlags.h" #include "llvm/MC/TargetRegistry.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Option/Option.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/InitLLVM.h" @@ -36,26 +38,46 @@ static mc::RegisterMCTargetOptionsFlags MCTargetOptionsFlags; -cl::OptionCategory DwpCategory("Specific Options"); -static cl::list - InputFiles(cl::Positional, cl::desc(""), cl::cat(DwpCategory)); +// Command-line option boilerplate. +namespace { +enum ID { + OPT_INVALID = 0, // This is not an option ID. +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES) \ + OPT_##ID, +#include "Opts.inc" +#undef OPTION +}; -static cl::list ExecFilenames( - "e", - cl::desc( - "Specify the executable/library files to get the list of *.dwo from"), - cl::value_desc("filename"), cl::cat(DwpCategory)); +#define PREFIX(NAME, VALUE) \ + static constexpr StringLiteral NAME##_init[] = VALUE; \ + static constexpr ArrayRef NAME(NAME##_init, \ + std::size(NAME##_init) - 1); +#include "Opts.inc" +#undef PREFIX -static cl::opt OutputFilename(cl::Required, "o", - cl::desc("Specify the output file."), - cl::value_desc("filename"), - cl::cat(DwpCategory)); +static constexpr opt::OptTable::Info InfoTable[] = { +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES) \ + { \ + PREFIX, NAME, HELPTEXT, \ + METAVAR, OPT_##ID, opt::Option::KIND##Class, \ + PARAM, FLAGS, OPT_##GROUP, \ + OPT_##ALIAS, ALIASARGS, VALUES}, +#include "Opts.inc" +#undef OPTION +}; -static cl::opt ContinueOnCuIndexOverflow( - "continue-on-cu-index-overflow", - cl::desc("This turns an error when offset for .debug_*.dwo sections " - "overfolws into a warning."), - cl::cat(DwpCategory)); +class DwpOptTable : public opt::GenericOptTable { +public: + DwpOptTable() : GenericOptTable(InfoTable) {} +}; +} // end anonymous namespace + +// Options +static std::vector ExecFilenames; +static std::string OutputFilename; +static bool ContinueOnCuIndexOverflow; static Expected> getDWOFilenames(StringRef ExecFilename) { @@ -106,15 +128,41 @@ int main(int argc, char **argv) { InitLLVM X(argc, argv); - cl::HideUnrelatedOptions({&DwpCategory, &getColorCategory()}); - cl::ParseCommandLineOptions(argc, argv, "merge split dwarf (.dwo) files\n"); + DwpOptTable Tbl; + llvm::BumpPtrAllocator A; + llvm::StringSaver Saver{A}; + opt::InputArgList Args = + Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) { + llvm::errs() << Msg << '\n'; + std::exit(1); + }); + + if (Args.hasArg(OPT_help)) { + Tbl.printHelp(llvm::outs(), "llvm-dwp [options] ", + "merge split dwarf (.dwo) files"); + std::exit(0); + } + + if (Args.hasArg(OPT_version)) { + llvm::cl::PrintVersionMessage(); + std::exit(0); + } + + OutputFilename = Args.getLastArgValue(OPT_outputFileName, ""); + ContinueOnCuIndexOverflow = Args.hasArg(OPT_continueOnCuIndexOverflow); + + for (const llvm::opt::Arg *A : Args.filtered(OPT_execFileNames)) + ExecFilenames.emplace_back(A->getValue()); + + std::vector DWOFilenames; + for (const llvm::opt::Arg *A : Args.filtered(OPT_INPUT)) + DWOFilenames.emplace_back(A->getValue()); llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllTargets(); llvm::InitializeAllAsmPrinters(); - std::vector DWOFilenames = InputFiles; for (const auto &ExecFilename : ExecFilenames) { auto DWOs = getDWOFilenames(ExecFilename); if (!DWOs) { diff --git a/llvm/utils/gn/secondary/llvm/tools/llvm-dwp/BUILD.gn b/llvm/utils/gn/secondary/llvm/tools/llvm-dwp/BUILD.gn --- a/llvm/utils/gn/secondary/llvm/tools/llvm-dwp/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/tools/llvm-dwp/BUILD.gn @@ -1,5 +1,11 @@ import("//llvm/tools/binutils_symlinks.gni") import("//llvm/utils/gn/build/symlink_or_copy.gni") +import("//llvm/utils/TableGen/tablegen.gni") + +tablegen("Opts") { + visibility = [ ":llvm-dwp" ] + args = [ "-gen-opt-parser-defs" ] +} if (llvm_install_binutils_symlinks) { symlink_or_copy("dwp") { @@ -19,10 +25,12 @@ executable("llvm-dwp") { deps = [ + ":Opts", "//llvm/lib/DWP", "//llvm/lib/DebugInfo/DWARF", "//llvm/lib/MC", "//llvm/lib/Object", + "//llvm/lib/Option", "//llvm/lib/Support", "//llvm/lib/Target:TargetsToBuild", "//llvm/lib/TargetParser", diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel --- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel @@ -3490,6 +3490,18 @@ ], ) +gentbl( + name = "DwpOptionsTableGen", + strip_include_prefix = "tools/llvm-dwp", + tbl_outs = [( + "-gen-opt-parser-defs", + "tools/llvm-dwp/Opts.inc", + )], + tblgen = ":llvm-tblgen", + td_file = "tools/llvm-dwp/Opts.td", + td_srcs = ["include/llvm/Option/OptParser.td"], +) + cc_binary( name = "llvm-dwp", srcs = glob([ @@ -3501,7 +3513,9 @@ deps = [ ":AllTargetsCodeGens", ":DWP", + ":DwpOptionsTableGen", ":MC", + ":Option", ":Support", ], )