[llvm-cxxfilt] Switch command line parsing from llvm::cl to OptTable
authorFangrui Song <i@maskray.me>
Fri, 9 Jul 2021 17:10:45 +0000 (10:10 -0700)
committerFangrui Song <i@maskray.me>
Fri, 9 Jul 2021 17:10:45 +0000 (10:10 -0700)
Similar to D104889. The tool is very simple and its long options are uncommon,
so just drop the one-dash form in this patch.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D105605

llvm/docs/CommandGuide/llvm-cxxfilt.rst
llvm/test/tools/llvm-cxxfilt/help.test
llvm/tools/llvm-cxxfilt/CMakeLists.txt
llvm/tools/llvm-cxxfilt/Opts.td [new file with mode: 0644]
llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
llvm/utils/gn/secondary/llvm/tools/llvm-cxxfilt/BUILD.gn
utils/bazel/llvm-project-overlay/llvm/BUILD.bazel

index b50252a..3f7deb1 100644 (file)
@@ -48,10 +48,6 @@ OPTIONS
 
   Print a summary of command line options.
 
-.. option:: --help-list
-
-  Print an uncategorized summary of command line options.
-
 .. option:: --no-strip-underscore, -n
 
   Do not strip a leading underscore. This is the default for all platforms
index 78bfad4..eede117 100644 (file)
@@ -1,7 +1,7 @@
 RUN: llvm-cxxfilt -h | FileCheck %s
 RUN: llvm-cxxfilt --help | FileCheck %s
 
-CHECK: OVERVIEW: llvm symbol undecoration tool
-CHECK: USAGE: llvm-cxxfilt{{(.exe)?}} [options] <mangled>{{$}}
+CHECK: OVERVIEW: LLVM symbol undecoration tool
+CHECK: USAGE: {{.*}}llvm-cxxfilt{{(.exe)?}} [options] <mangled>{{$}}
 CHECK: OPTIONS:
 CHECK: @FILE
index 2a78aca..07ba9f9 100644 (file)
@@ -1,10 +1,18 @@
 set(LLVM_LINK_COMPONENTS
   Demangle
+  Option
   Support
   )
 
+set(LLVM_TARGET_DEFINITIONS Opts.td)
+tablegen(LLVM Opts.inc -gen-opt-parser-defs)
+add_public_tablegen_target(CxxfiltOptsTableGen)
+
 add_llvm_tool(llvm-cxxfilt
   llvm-cxxfilt.cpp
+
+  DEPENDS
+  CxxfiltOptsTableGen
   )
 
 if(LLVM_INSTALL_BINUTILS_SYMLINKS)
diff --git a/llvm/tools/llvm-cxxfilt/Opts.td b/llvm/tools/llvm-cxxfilt/Opts.td
new file mode 100644 (file)
index 0000000..93f8652
--- /dev/null
@@ -0,0 +1,28 @@
+include "llvm/Option/OptParser.td"
+
+class F<string letter, string help> : Flag<["-"], letter>, HelpText<help>;
+class FF<string name, string help> : Flag<["--"], name>, HelpText<help>;
+
+multiclass BB<string name, string help1, string help2> {
+  def NAME: Flag<["--"], name>, HelpText<help1>;
+  def no_ # NAME: Flag<["--"], "no-" # name>, HelpText<help2>;
+}
+
+multiclass Eq<string name, string help> {
+  def NAME #_EQ : Joined<["--"], name #"=">,
+                  HelpText<help>;
+  def : Separate<["--"], name>, Alias<!cast<Joined>(NAME #_EQ)>;
+}
+
+def help : FF<"help", "Display this help">;
+defm strip_underscore : BB<"strip-underscore", "Strip the leading underscore", "Don't strip the leading underscore">;
+def types : FF<"types", "">;
+def version : FF<"version", "Display the version">;
+
+defm : Eq<"format", "Specify mangling format. Currently ignored because only 'gnu' is supported">;
+def : F<"s", "Alias for --format">;
+
+def : F<"_", "Alias for --strip-underscore">, Alias<strip_underscore>;
+def : F<"h", "Alias for --help">, Alias<help>;
+def : F<"n", "Alias for --no-strip-underscore">, Alias<no_strip_underscore>;
+def : F<"t", "Alias for --types">, Alias<types>;
index ac569ab..d8bf8db 100644 (file)
@@ -9,69 +9,59 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Demangle/Demangle.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/WithColor.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdlib>
 #include <iostream>
 
 using namespace llvm;
 
-enum Style {
-  Auto,  ///< auto-detect mangling
-  GNU,   ///< GNU
-  Lucid, ///< Lucid compiler (lcc)
-  ARM,
-  HP,    ///< HP compiler (xCC)
-  EDG,   ///< EDG compiler
-  GNUv3, ///< GNU C++ v3 ABI
-  Java,  ///< Java (gcj)
-  GNAT   ///< ADA compiler (gnat)
+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::opt<Style>
-    Format("format", cl::desc("decoration style"),
-           cl::values(clEnumValN(Auto, "auto", "auto-detect style"),
-                      clEnumValN(GNU, "gnu", "GNU (itanium) style")),
-           cl::init(Auto));
-static cl::alias FormatShort("s", cl::desc("alias for --format"),
-                             cl::aliasopt(Format));
-
-static cl::opt<bool> StripUnderscore("strip-underscore",
-                                     cl::desc("strip the leading underscore"),
-                                     cl::init(false));
-static cl::alias StripUnderscoreShort("_",
-                                      cl::desc("alias for --strip-underscore"),
-                                      cl::aliasopt(StripUnderscore));
-static cl::opt<bool>
-    NoStripUnderscore("no-strip-underscore",
-                      cl::desc("do not strip the leading underscore"),
-                      cl::init(false));
-static cl::alias
-    NoStripUnderscoreShort("n", cl::desc("alias for --no-strip-underscore"),
-                           cl::aliasopt(NoStripUnderscore));
-
-static cl::opt<bool>
-    Types("types",
-          cl::desc("attempt to demangle types as well as function names"),
-          cl::init(false));
-static cl::alias TypesShort("t", cl::desc("alias for --types"),
-                            cl::aliasopt(Types));
-
-static cl::list<std::string>
-Decorated(cl::Positional, cl::desc("<mangled>"), cl::ZeroOrMore);
-
-static cl::extrahelp
-    HelpResponse("\nPass @FILE as argument to read options from FILE.\n");
-
-static bool shouldStripUnderscore() {
-  if (StripUnderscore)
-    return true;
-  if (NoStripUnderscore)
-    return false;
-  // If none of them are set, use the default value for platform.
-  // macho has symbols prefix with "_" so strip by default.
-  return Triple(sys::getProcessTriple()).isOSBinFormatMachO();
+
+#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
+#include "Opts.inc"
+#undef PREFIX
+
+const 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
+};
+
+class CxxfiltOptTable : public opt::OptTable {
+public:
+  CxxfiltOptTable() : OptTable(InfoTable) { setGroupedShortOptions(true); }
+};
+} // namespace
+
+static bool StripUnderscore;
+static bool Types;
+
+static StringRef ToolName;
+
+static void error(const Twine &Message) {
+  WithColor::error(errs(), ToolName) << Message << '\n';
+  exit(1);
 }
 
 static std::string demangle(const std::string &Mangled) {
@@ -79,7 +69,7 @@ static std::string demangle(const std::string &Mangled) {
   std::string Prefix;
 
   const char *DecoratedStr = Mangled.c_str();
-  if (shouldStripUnderscore())
+  if (StripUnderscore)
     if (DecoratedStr[0] == '_')
       ++DecoratedStr;
   size_t DecoratedLength = strlen(DecoratedStr);
@@ -159,9 +149,37 @@ static void demangleLine(llvm::raw_ostream &OS, StringRef Mangled, bool Split) {
 
 int main(int argc, char **argv) {
   InitLLVM X(argc, argv);
+  BumpPtrAllocator A;
+  StringSaver Saver(A);
+  CxxfiltOptTable Tbl;
+  ToolName = argv[0];
+  opt::InputArgList Args = Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver,
+                                         [&](StringRef Msg) { error(Msg); });
+  if (Args.hasArg(OPT_help)) {
+    Tbl.printHelp(outs(),
+                  (Twine(ToolName) + " [options] <mangled>").str().c_str(),
+                  "LLVM symbol undecoration tool");
+    // TODO Replace this with OptTable API once it adds extrahelp support.
+    outs() << "\nPass @FILE as argument to read options from FILE.\n";
+    return 0;
+  }
+  if (Args.hasArg(OPT_version)) {
+    outs() << ToolName << '\n';
+    cl::PrintVersionMessage();
+    return 0;
+  }
+
+  // The default value depends on the default triple. Mach-O has symbols
+  // prefixed with "_", so strip by default.
+  if (opt::Arg *A =
+          Args.getLastArg(OPT_strip_underscore, OPT_no_strip_underscore))
+    StripUnderscore = A->getOption().matches(OPT_strip_underscore);
+  else
+    StripUnderscore = Triple(sys::getProcessTriple()).isOSBinFormatMachO();
 
-  cl::ParseCommandLineOptions(argc, argv, "llvm symbol undecoration tool\n");
+  Types = Args.hasArg(OPT_types);
 
+  std::vector<std::string> Decorated = Args.getAllArgValues(OPT_INPUT);
   if (Decorated.empty())
     for (std::string Mangled; std::getline(std::cin, Mangled);)
       demangleLine(llvm::outs(), Mangled, true);
index 1f419ac..081f77d 100644 (file)
@@ -1,6 +1,12 @@
 import("//llvm/tools/binutils_symlinks.gni")
+import("//llvm/utils/TableGen/tablegen.gni")
 import("//llvm/utils/gn/build/symlink_or_copy.gni")
 
+tablegen("Opts") {
+  visibility = [ ":llvm-cxxfilt" ]
+  args = [ "-gen-opt-parser-defs" ]
+}
+
 if (llvm_install_binutils_symlinks) {
   symlink_or_copy("cxxfilt") {  # Can't have '+' in target name.
     deps = [ ":llvm-cxxfilt" ]
@@ -19,7 +25,9 @@ group("symlinks") {
 
 executable("llvm-cxxfilt") {
   deps = [
+    ":Opts",
     "//llvm/lib/Demangle",
+    "//llvm/lib/Option",
     "//llvm/lib/Support",
   ]
   sources = [ "llvm-cxxfilt.cpp" ]
index f5d0ece..d4397d5 100644 (file)
@@ -2653,6 +2653,18 @@ cc_binary(
     ],
 )
 
+gentbl(
+    name = "CxxfiltOptsTableGen",
+    strip_include_prefix = "tools/llvm-cxxfilt",
+    tbl_outs = [(
+        "-gen-opt-parser-defs",
+        "tools/llvm-cxxfilt/Opts.inc",
+    )],
+    tblgen = ":llvm-tblgen",
+    td_file = "tools/llvm-cxxfilt/Opts.td",
+    td_srcs = ["include/llvm/Option/OptParser.td"],
+)
+
 cc_binary(
     name = "llvm-cxxfilt",
     srcs = glob([
@@ -2662,7 +2674,9 @@ cc_binary(
     copts = llvm_copts,
     stamp = 0,
     deps = [
+        ":CxxfiltOptsTableGen",
         ":Demangle",
+        ":Option",
         ":Support",
     ],
 )