[llvm] 480dcdc - [ifs] Switch to using OptTable

Alex Brachet via llvm-commits llvm-commits at lists.llvm.org
Fri May 20 08:29:15 PDT 2022


Author: Alex Brachet
Date: 2022-05-20T15:29:05Z
New Revision: 480dcdc8975d895ebb1f35ccf324900c816a0d6d

URL: https://github.com/llvm/llvm-project/commit/480dcdc8975d895ebb1f35ccf324900c816a0d6d
DIFF: https://github.com/llvm/llvm-project/commit/480dcdc8975d895ebb1f35ccf324900c816a0d6d.diff

LOG: [ifs] Switch to using OptTable

Differential revision: https://reviews.llvm.org/D125658

Added: 
    llvm/tools/llvm-ifs/Opts.td

Modified: 
    llvm/test/tools/llvm-ifs/help.test
    llvm/tools/llvm-ifs/CMakeLists.txt
    llvm/tools/llvm-ifs/llvm-ifs.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-ifs/help.test b/llvm/test/tools/llvm-ifs/help.test
index 1cfdbd25cca43..76c15bdf7b665 100644
--- a/llvm/test/tools/llvm-ifs/help.test
+++ b/llvm/test/tools/llvm-ifs/help.test
@@ -1,6 +1,5 @@
 # RUN: llvm-ifs --help | FileCheck %s --check-prefix HELP --implicit-check-not='{{[Oo]}}ptions:'
 
-# HELP: USAGE
-# HELP: Color Options
-# HELP: Generic Options
-# HELP: Ifs Options
+# HELP: OVERVIEW:
+# HELP: USAGE:
+# HELP: OPTIONS:

diff  --git a/llvm/tools/llvm-ifs/CMakeLists.txt b/llvm/tools/llvm-ifs/CMakeLists.txt
index 5a0cfb9138381..483610dce94a0 100644
--- a/llvm/tools/llvm-ifs/CMakeLists.txt
+++ b/llvm/tools/llvm-ifs/CMakeLists.txt
@@ -5,9 +5,17 @@ set(LLVM_LINK_COMPONENTS
   Support
   TextAPI
   ObjectYAML
+  Option
   )
 
+set(LLVM_TARGET_DEFINITIONS Opts.td)
+tablegen(LLVM Opts.inc -gen-opt-parser-defs)
+add_public_tablegen_target(IFSOptsTableGen)
+
 add_llvm_tool(llvm-ifs
   ErrorCollector.cpp
   llvm-ifs.cpp
+
+DEPENDS
+  IFSOptsTableGen
   )

diff  --git a/llvm/tools/llvm-ifs/Opts.td b/llvm/tools/llvm-ifs/Opts.td
new file mode 100644
index 0000000000000..7288cf0123a72
--- /dev/null
+++ b/llvm/tools/llvm-ifs/Opts.td
@@ -0,0 +1,37 @@
+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 Eq<string name, string help> {
+  def NAME #_EQ : Joined<["--"], name #"=">, HelpText<help>;
+  def : Separate<["--"], name>, Alias<!cast<Joined>(NAME #_EQ)>;
+}
+
+defm arch : Eq<"arch", "Specify the architecture, e.g. x86_64">;
+defm bitwidth : Eq<"bitwidth", "Specify the bit width">;
+defm endianness : Eq<"endianness", "Specify the endianness">;
+defm exclude : Eq<"exclude", "Remove symbols which match the pattern. Can be specified multiple times">;
+def help : FF<"help", "Display this help">;
+def : F<"h", "Alias for --help">, Alias<help>;
+defm hint_ifs_target : Eq<"hint-ifs-target", "When --output-format is 'IFS', this flag will hint the expected target triple for IFS output">;
+defm input : Eq<"input", "input">;
+defm input_format : Eq<"input-format", "Specify the input file format">;
+defm output : Eq<"output", "Output file **DEPRECATED**">;
+def : Separate<["-"], "o">, HelpText<"Alias for --output">, Alias<output_EQ>;
+defm output_elf : Eq<"output-elf", "Output path for ELF file">;
+defm output_format : Eq<"output-format", "Specify the output file format **DEPRECATED**">;
+defm output_ifs : Eq<"output-ifs", "Output path for IFS file">;
+defm output_tbd : Eq<"output-tbd", "Output path for TBD file">;
+defm soname : Eq<"soname", "name">;
+def strip_ifs_arch : FF<"strip-ifs-arch", "Strip target architecture information away from IFS output">;
+def strip_ifs_bitwidth : FF<"strip-ifs-bitwidth", "Strip target bit width information away from IFS output">;
+def strip_ifs_endianness : FF<"strip-ifs-endianness", "Strip target endianness information away from IFS output">;
+def strip_ifs_target : FF<"strip-ifs-target", "Strip all target information away from IFS output">;
+def strip_needed : FF<"strip-needed", "Strip needed libs from output">;
+def strip_size : FF<"strip-size", "Remove object size from the output">;
+def strip_undefined : FF<"strip-undefined", "Strip undefined symbols from IFS output">;
+defm target : Eq<"target", "Specify the target triple, e.g. x86_64-linux-gnu">;
+def version : FF<"version", "Display the version">;
+def : F<"V", "Alias for --version">, Alias<version>;
+def write_if_changed : FF<"write-if-changed", "Write the output file only if it is new or has changed">;

diff  --git a/llvm/tools/llvm-ifs/llvm-ifs.cpp b/llvm/tools/llvm-ifs/llvm-ifs.cpp
index 444a6d2dd58a5..b1026042e23ec 100644
--- a/llvm/tools/llvm-ifs/llvm-ifs.cpp
+++ b/llvm/tools/llvm-ifs/llvm-ifs.cpp
@@ -15,6 +15,9 @@
 #include "llvm/InterfaceStub/IFSHandler.h"
 #include "llvm/InterfaceStub/IFSStub.h"
 #include "llvm/ObjectYAML/yaml2obj.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Errc.h"
@@ -46,100 +49,68 @@ const VersionTuple IfsVersionCurrent(3, 0);
 enum class FileFormat { IFS, ELF, TBD };
 } // end anonymous namespace
 
-cl::OptionCategory IfsCategory("Ifs Options");
-
-// TODO: Use OptTable for option parsing in the future.
-// Command line flags:
-cl::list<std::string> InputFilePaths(cl::Positional, cl::desc("input"),
-                                     cl::ZeroOrMore, cl::cat(IfsCategory));
-cl::opt<FileFormat> InputFormat(
-    "input-format", cl::desc("Specify the input file format"),
-    cl::values(clEnumValN(FileFormat::IFS, "IFS", "Text based ELF stub file"),
-               clEnumValN(FileFormat::ELF, "ELF", "ELF object file")),
-    cl::cat(IfsCategory));
-cl::opt<FileFormat> OutputFormat(
-    "output-format", cl::desc("Specify the output file format **DEPRECATED**"),
-    cl::values(clEnumValN(FileFormat::IFS, "IFS", "Text based ELF stub file"),
-               clEnumValN(FileFormat::ELF, "ELF", "ELF stub file"),
-               clEnumValN(FileFormat::TBD, "TBD", "Apple TBD text stub file")),
-    cl::cat(IfsCategory));
-cl::opt<std::string> OptArch("arch",
-                             cl::desc("Specify the architecture, e.g. x86_64"),
-                             cl::cat(IfsCategory));
-cl::opt<IFSBitWidthType>
-    OptBitWidth("bitwidth", cl::desc("Specify the bit width"),
-                cl::values(clEnumValN(IFSBitWidthType::IFS32, "32", "32 bits"),
-                           clEnumValN(IFSBitWidthType::IFS64, "64", "64 bits")),
-                cl::cat(IfsCategory));
-cl::opt<IFSEndiannessType> OptEndianness(
-    "endianness", cl::desc("Specify the endianness"),
-    cl::values(clEnumValN(IFSEndiannessType::Little, "little", "Little Endian"),
-               clEnumValN(IFSEndiannessType::Big, "big", "Big Endian")),
-    cl::cat(IfsCategory));
-cl::opt<std::string> OptTargetTriple(
-    "target", cl::desc("Specify the target triple, e.g. x86_64-linux-gnu"),
-    cl::cat(IfsCategory));
-cl::opt<std::string> OptTargetTripleHint(
-    "hint-ifs-target",
-    cl::desc("When --output-format is 'IFS', this flag will hint the expected "
-             "target triple for IFS output"),
-    cl::cat(IfsCategory));
-cl::opt<bool> StripIFSArch(
-    "strip-ifs-arch",
-    cl::desc("Strip target architecture information away from IFS output"),
-    cl::cat(IfsCategory));
-cl::opt<bool> StripIFSBitWidth(
-    "strip-ifs-bitwidth",
-    cl::desc("Strip target bit width information away from IFS output"),
-    cl::cat(IfsCategory));
-cl::opt<bool> StripIFSEndiannessWidth(
-    "strip-ifs-endianness",
-    cl::desc("Strip target endianness information away from IFS output"),
-    cl::cat(IfsCategory));
-cl::opt<bool> StripIFSTarget(
-    "strip-ifs-target",
-    cl::desc("Strip all target information away from IFS output"),
-    cl::cat(IfsCategory));
-cl::opt<bool>
-    StripUndefined("strip-undefined",
-                   cl::desc("Strip undefined symbols from IFS output"),
-                   cl::cat(IfsCategory));
-cl::opt<bool> StripNeededLibs("strip-needed",
-                              cl::desc("Strip needed libs from output"),
-                              cl::cat(IfsCategory));
-cl::opt<bool> StripSize("strip-size",
-                        cl::desc("Remove object size from the output"),
-                        cl::cat(IfsCategory));
-
-cl::list<std::string>
-    ExcludeSyms("exclude",
-                cl::desc("Remove symbols which match the pattern. Can be "
-                         "specified multiple times"),
-                cl::cat(IfsCategory));
-
-cl::opt<std::string>
-    SoName("soname",
-           cl::desc("Manually set the DT_SONAME entry of any emitted files"),
-           cl::value_desc("name"), cl::cat(IfsCategory));
-cl::opt<std::string> OutputFilePath("output",
-                                    cl::desc("Output file **DEPRECATED**"),
-                                    cl::cat(IfsCategory));
-cl::alias OutputFilePathA("o", cl::desc("Alias for --output"),
-                          cl::aliasopt(OutputFilePath), cl::cat(IfsCategory));
-cl::opt<std::string> OutputELFFilePath("output-elf",
-                                       cl::desc("Output path for ELF file"),
-                                       cl::cat(IfsCategory));
-cl::opt<std::string> OutputIFSFilePath("output-ifs",
-                                       cl::desc("Output path for IFS file"),
-                                       cl::cat(IfsCategory));
-cl::opt<std::string> OutputTBDFilePath("output-tbd",
-                                       cl::desc("Output path for TBD file"),
-                                       cl::cat(IfsCategory));
-
-cl::opt<bool> WriteIfChanged(
-    "write-if-changed",
-    cl::desc("Write the output file only if it is new or has changed."),
-    cl::cat(IfsCategory));
+using namespace llvm::opt;
+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
+};
+
+#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 IFSOptTable : public opt::OptTable {
+public:
+  IFSOptTable() : OptTable(InfoTable) { setGroupedShortOptions(true); }
+};
+
+struct DriverConfig {
+  std::vector<std::string> InputFilePaths;
+
+  Optional<FileFormat> InputFormat;
+  Optional<FileFormat> OutputFormat;
+
+  Optional<std::string> HintIfsTarget;
+  Optional<std::string> OptTargetTriple;
+  Optional<IFSArch> OverrideArch;
+  Optional<IFSBitWidthType> OverrideBitWidth;
+  Optional<IFSEndiannessType> OverrideEndianness;
+
+  bool StripIfsArch = false;
+  bool StripIfsBitwidth = false;
+  bool StripIfsEndianness = false;
+  bool StripIfsTarget = false;
+  bool StripNeeded = false;
+  bool StripSize = false;
+  bool StripUndefined = false;
+
+  std::vector<std::string> Exclude;
+
+  Optional<std::string> SoName;
+
+  Optional<std::string> Output;
+  Optional<std::string> OutputElf;
+  Optional<std::string> OutputIfs;
+  Optional<std::string> OutputTbd;
+
+  bool WriteIfChanged = false;
+};
 
 static std::string getTypeName(IFSSymbolType Type) {
   switch (Type) {
@@ -157,7 +128,8 @@ static std::string getTypeName(IFSSymbolType Type) {
   llvm_unreachable("Unexpected ifs symbol type.");
 }
 
-static Expected<std::unique_ptr<IFSStub>> readInputFile(StringRef FilePath) {
+static Expected<std::unique_ptr<IFSStub>>
+readInputFile(Optional<FileFormat> &InputFormat, StringRef FilePath) {
   // Read in file.
   ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrError =
       MemoryBuffer::getFileOrSTDIN(FilePath, /*IsText=*/true);
@@ -169,10 +141,11 @@ static Expected<std::unique_ptr<IFSStub>> readInputFile(StringRef FilePath) {
   ErrorCollector EC(/*UseFatalErrors=*/false);
 
   // First try to read as a binary (fails fast if not binary).
-  if (InputFormat.getNumOccurrences() == 0 || InputFormat == FileFormat::ELF) {
+  if (!InputFormat || *InputFormat == FileFormat::ELF) {
     Expected<std::unique_ptr<IFSStub>> StubFromELF =
         readELFFile(FileReadBuffer->getMemBufferRef());
     if (StubFromELF) {
+      InputFormat = FileFormat::ELF;
       (*StubFromELF)->IfsVersion = IfsVersionCurrent;
       return std::move(*StubFromELF);
     }
@@ -180,10 +153,11 @@ static Expected<std::unique_ptr<IFSStub>> readInputFile(StringRef FilePath) {
   }
 
   // Fall back to reading as a ifs.
-  if (InputFormat.getNumOccurrences() == 0 || InputFormat == FileFormat::IFS) {
+  if (!InputFormat || *InputFormat == FileFormat::IFS) {
     Expected<std::unique_ptr<IFSStub>> StubFromIFS =
         readIFSFromBuffer(FileReadBuffer->getBuffer());
     if (StubFromIFS) {
+      InputFormat = FileFormat::IFS;
       if ((*StubFromIFS)->IfsVersion > IfsVersionCurrent)
         EC.addError(
             createStringError(errc::not_supported,
@@ -271,9 +245,14 @@ static void fatalError(Error Err) {
   exit(1);
 }
 
+static void fatalError(Twine T) {
+  WithColor::error() << T.str() << '\n';
+  exit(1);
+}
+
 /// writeIFS() writes a Text-Based ELF stub to a file using the latest version
 /// of the YAML parser.
-static Error writeIFS(StringRef FilePath, IFSStub &Stub) {
+static Error writeIFS(StringRef FilePath, IFSStub &Stub, bool WriteIfChanged) {
   // Write IFS to memory first.
   std::string IFSStr;
   raw_string_ostream OutStr(IFSStr);
@@ -285,7 +264,8 @@ static Error writeIFS(StringRef FilePath, IFSStub &Stub) {
   if (WriteIfChanged) {
     if (ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrError =
             MemoryBuffer::getFile(FilePath)) {
-      // Compare IFS output with the existing IFS file. If unchanged, avoid changing the file.
+      // Compare IFS output with the existing IFS file. If unchanged, avoid
+      // changing the file.
       if ((*BufOrError)->getBuffer() == IFSStr)
         return Error::success();
     }
@@ -300,24 +280,119 @@ static Error writeIFS(StringRef FilePath, IFSStub &Stub) {
   return Error::success();
 }
 
+static DriverConfig parseArgs(int argc, char *const *argv) {
+  BumpPtrAllocator A;
+  StringSaver Saver(A);
+  IFSOptTable Tbl;
+  StringRef ToolName = argv[0];
+  llvm::opt::InputArgList Args = Tbl.parseArgs(
+      argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) { fatalError(Msg); });
+  if (Args.hasArg(OPT_help)) {
+    Tbl.printHelp(llvm::outs(),
+                  (Twine(ToolName) + " <input_file> <output_file> [options]")
+                      .str()
+                      .c_str(),
+                  "shared object stubbing tool");
+    std::exit(0);
+  }
+  if (Args.hasArg(OPT_version)) {
+    llvm::outs() << ToolName << '\n';
+    cl::PrintVersionMessage();
+    std::exit(0);
+  }
+
+  DriverConfig Config;
+  for (const opt::Arg *A : Args.filtered(OPT_INPUT))
+    Config.InputFilePaths.push_back(A->getValue());
+  if (const opt::Arg *A = Args.getLastArg(OPT_input_format_EQ)) {
+    Config.InputFormat = StringSwitch<Optional<FileFormat>>(A->getValue())
+                             .Case("IFS", FileFormat::IFS)
+                             .Case("ELF", FileFormat::ELF)
+                             .Default(None);
+    if (!Config.InputFormat)
+      fatalError(Twine("invalid argument '") + A->getValue());
+  }
+
+  auto OptionNotFound = [ToolName](StringRef FlagName, StringRef OptionName) {
+    fatalError(Twine(ToolName) + ": for the " + FlagName +
+               " option: Cannot find option named '" + OptionName + "'!");
+  };
+  if (const opt::Arg *A = Args.getLastArg(OPT_output_format_EQ)) {
+    Config.OutputFormat = StringSwitch<Optional<FileFormat>>(A->getValue())
+                              .Case("IFS", FileFormat::IFS)
+                              .Case("ELF", FileFormat::ELF)
+                              .Case("TBD", FileFormat::TBD)
+                              .Default(None);
+    if (!Config.OutputFormat)
+      OptionNotFound("--output-format", A->getValue());
+  }
+  if (const opt::Arg *A = Args.getLastArg(OPT_arch_EQ))
+    Config.OverrideArch = ELF::convertArchNameToEMachine(A->getValue());
+
+  if (const opt::Arg *A = Args.getLastArg(OPT_bitwidth_EQ)) {
+    size_t Width;
+    llvm::StringRef S(A->getValue());
+    if (!S.getAsInteger<size_t>(10, Width) || Width == 64 || Width == 32)
+      Config.OverrideBitWidth =
+          Width == 64 ? IFSBitWidthType::IFS64 : IFSBitWidthType::IFS32;
+    else
+      OptionNotFound("--bitwidth", A->getValue());
+  }
+  if (const opt::Arg *A = Args.getLastArg(OPT_endianness_EQ)) {
+    Config.OverrideEndianness =
+        StringSwitch<Optional<IFSEndiannessType>>(A->getValue())
+            .Case("little", IFSEndiannessType::Little)
+            .Case("big", IFSEndiannessType::Big)
+            .Default(None);
+    if (!Config.OverrideEndianness)
+      OptionNotFound("--endianness", A->getValue());
+  }
+  if (const opt::Arg *A = Args.getLastArg(OPT_target_EQ))
+    Config.OptTargetTriple = A->getValue();
+  if (const opt::Arg *A = Args.getLastArg(OPT_hint_ifs_target_EQ))
+    Config.HintIfsTarget = A->getValue();
+
+  Config.StripIfsArch = Args.hasArg(OPT_strip_ifs_arch);
+  Config.StripIfsBitwidth = Args.hasArg(OPT_strip_ifs_bitwidth);
+  Config.StripIfsEndianness = Args.hasArg(OPT_strip_ifs_endianness);
+  Config.StripIfsTarget = Args.hasArg(OPT_strip_ifs_target);
+  Config.StripUndefined = Args.hasArg(OPT_strip_undefined);
+  Config.StripNeeded = Args.hasArg(OPT_strip_needed);
+  Config.StripSize = Args.hasArg(OPT_strip_size);
+
+  for (const opt::Arg *A : Args.filtered(OPT_exclude_EQ))
+    Config.Exclude.push_back(A->getValue());
+  if (const opt::Arg *A = Args.getLastArg(OPT_soname_EQ))
+    Config.SoName = A->getValue();
+  if (const opt::Arg *A = Args.getLastArg(OPT_output_EQ))
+    Config.Output = A->getValue();
+  if (const opt::Arg *A = Args.getLastArg(OPT_output_elf_EQ))
+    Config.OutputElf = A->getValue();
+  if (const opt::Arg *A = Args.getLastArg(OPT_output_ifs_EQ))
+    Config.OutputIfs = A->getValue();
+  if (const opt::Arg *A = Args.getLastArg(OPT_output_tbd_EQ))
+    Config.OutputTbd = A->getValue();
+  Config.WriteIfChanged = Args.hasArg(OPT_write_if_changed);
+  return Config;
+}
+
 int main(int argc, char *argv[]) {
-  // Parse arguments.
-  cl::HideUnrelatedOptions({&IfsCategory, &getColorCategory()});
-  cl::ParseCommandLineOptions(argc, argv);
+  DriverConfig Config = parseArgs(argc, argv);
 
-  if (InputFilePaths.empty())
-    InputFilePaths.push_back("-");
+  if (Config.InputFilePaths.empty())
+    Config.InputFilePaths.push_back("-");
 
   // If input files are more than one, they can only be IFS files.
-  if (InputFilePaths.size() > 1)
-    InputFormat.setValue(FileFormat::IFS);
+  if (Config.InputFilePaths.size() > 1)
+    Config.InputFormat = FileFormat::IFS;
 
   // Attempt to merge input.
   IFSStub Stub;
   std::map<std::string, IFSSymbol> SymbolMap;
   std::string PreviousInputFilePath;
-  for (const std::string &InputFilePath : InputFilePaths) {
-    Expected<std::unique_ptr<IFSStub>> StubOrErr = readInputFile(InputFilePath);
+  for (const std::string &InputFilePath : Config.InputFilePaths) {
+    Expected<std::unique_ptr<IFSStub>> StubOrErr =
+        readInputFile(Config.InputFormat, InputFilePath);
     if (!StubOrErr)
       fatalError(StubOrErr.takeError());
 
@@ -411,57 +486,45 @@ int main(int argc, char *argv[]) {
     Stub.Symbols.push_back(Entry.second);
 
   // Change SoName before emitting stubs.
-  if (SoName.getNumOccurrences() == 1)
-    Stub.SoName = SoName;
-  Optional<IFSArch> OverrideArch;
-  Optional<IFSEndiannessType> OverrideEndianness;
-  Optional<IFSBitWidthType> OverrideBitWidth;
-  Optional<std::string> OverrideTriple;
-  if (OptArch.getNumOccurrences() == 1)
-    OverrideArch = ELF::convertArchNameToEMachine(OptArch.getValue());
-  if (OptEndianness.getNumOccurrences() == 1)
-    OverrideEndianness = OptEndianness.getValue();
-  if (OptBitWidth.getNumOccurrences() == 1)
-    OverrideBitWidth = OptBitWidth.getValue();
-  if (OptTargetTriple.getNumOccurrences() == 1)
-    OverrideTriple = OptTargetTriple.getValue();
-  Error OverrideError = overrideIFSTarget(
-      Stub, OverrideArch, OverrideEndianness, OverrideBitWidth, OverrideTriple);
+  if (Config.SoName)
+    Stub.SoName = *Config.SoName;
+
+  Error OverrideError =
+      overrideIFSTarget(Stub, Config.OverrideArch, Config.OverrideEndianness,
+                        Config.OverrideBitWidth, Config.OptTargetTriple);
   if (OverrideError)
     fatalError(std::move(OverrideError));
 
-  if (StripNeededLibs)
+  if (Config.StripNeeded)
     Stub.NeededLibs.clear();
 
-  if (Error E = filterIFSSyms(Stub, StripUndefined, ExcludeSyms))
+  if (Error E = filterIFSSyms(Stub, Config.StripUndefined, Config.Exclude))
     fatalError(std::move(E));
 
-  if (StripSize)
+  if (Config.StripSize)
     for (IFSSymbol &Sym : Stub.Symbols)
       Sym.Size.reset();
 
-  if (OutputELFFilePath.getNumOccurrences() == 0 &&
-      OutputIFSFilePath.getNumOccurrences() == 0 &&
-      OutputTBDFilePath.getNumOccurrences() == 0) {
-    if (OutputFormat.getNumOccurrences() == 0) {
+  if (!Config.OutputElf && !Config.OutputIfs && !Config.OutputTbd) {
+    if (!Config.OutputFormat) {
       WithColor::error() << "at least one output should be specified.";
       return -1;
     }
-  } else if (OutputFormat.getNumOccurrences() == 1) {
+  } else if (Config.OutputFormat) {
     WithColor::error() << "'--output-format' cannot be used with "
                           "'--output-{FILE_FORMAT}' options at the same time";
     return -1;
   }
-  if (OutputFormat.getNumOccurrences() == 1) {
+  if (Config.OutputFormat) {
     // TODO: Remove OutputFormat flag in the next revision.
     WithColor::warning() << "--output-format option is deprecated, please use "
                             "--output-{FILE_FORMAT} options instead\n";
-    switch (OutputFormat.getValue()) {
+    switch (Config.OutputFormat.getValue()) {
     case FileFormat::TBD: {
       std::error_code SysErr;
-      raw_fd_ostream Out(OutputFilePath, SysErr);
+      raw_fd_ostream Out(*Config.Output, SysErr);
       if (SysErr) {
-        WithColor::error() << "Couldn't open " << OutputFilePath
+        WithColor::error() << "Couldn't open " << *Config.Output
                            << " for writing.\n";
         return -1;
       }
@@ -475,10 +538,10 @@ int main(int argc, char *argv[]) {
     }
     case FileFormat::IFS: {
       Stub.IfsVersion = IfsVersionCurrent;
-      if (InputFormat.getValue() == FileFormat::ELF &&
-          OptTargetTripleHint.getNumOccurrences() == 1) {
+      if (Config.InputFormat.getValue() == FileFormat::ELF &&
+          Config.HintIfsTarget) {
         std::error_code HintEC(1, std::generic_category());
-        IFSTarget HintTarget = parseTriple(OptTargetTripleHint);
+        IFSTarget HintTarget = parseTriple(*Config.HintIfsTarget);
         if (Stub.Target.Arch.getValue() != HintTarget.Arch.getValue())
           fatalError(make_error<StringError>(
               "Triple hint does not match the actual architecture", HintEC));
@@ -491,12 +554,13 @@ int main(int argc, char *argv[]) {
               "Triple hint does not match the actual bit width", HintEC));
 
         stripIFSTarget(Stub, true, false, false, false);
-        Stub.Target.Triple = OptTargetTripleHint.getValue();
+        Stub.Target.Triple = Config.HintIfsTarget.getValue();
       } else {
-        stripIFSTarget(Stub, StripIFSTarget, StripIFSArch,
-                       StripIFSEndiannessWidth, StripIFSBitWidth);
+        stripIFSTarget(Stub, Config.StripIfsTarget, Config.StripIfsArch,
+                       Config.StripIfsEndianness, Config.StripIfsBitwidth);
       }
-      Error IFSWriteError = writeIFS(OutputFilePath.getValue(), Stub);
+      Error IFSWriteError =
+          writeIFS(Config.Output.getValue(), Stub, Config.WriteIfChanged);
       if (IFSWriteError)
         fatalError(std::move(IFSWriteError));
       break;
@@ -506,7 +570,7 @@ int main(int argc, char *argv[]) {
       if (TargetError)
         fatalError(std::move(TargetError));
       Error BinaryWriteError =
-          writeBinaryStub(OutputFilePath, Stub, WriteIfChanged);
+          writeBinaryStub(*Config.Output, Stub, Config.WriteIfChanged);
       if (BinaryWriteError)
         fatalError(std::move(BinaryWriteError));
       break;
@@ -514,21 +578,21 @@ int main(int argc, char *argv[]) {
     }
   } else {
     // Check if output path for individual format.
-    if (OutputELFFilePath.getNumOccurrences() == 1) {
+    if (Config.OutputElf) {
       Error TargetError = validateIFSTarget(Stub, true);
       if (TargetError)
         fatalError(std::move(TargetError));
       Error BinaryWriteError =
-          writeBinaryStub(OutputELFFilePath, Stub, WriteIfChanged);
+          writeBinaryStub(*Config.OutputElf, Stub, Config.WriteIfChanged);
       if (BinaryWriteError)
         fatalError(std::move(BinaryWriteError));
     }
-    if (OutputIFSFilePath.getNumOccurrences() == 1) {
+    if (Config.OutputIfs) {
       Stub.IfsVersion = IfsVersionCurrent;
-      if (InputFormat.getValue() == FileFormat::ELF &&
-          OptTargetTripleHint.getNumOccurrences() == 1) {
+      if (Config.InputFormat.getValue() == FileFormat::ELF &&
+          Config.HintIfsTarget) {
         std::error_code HintEC(1, std::generic_category());
-        IFSTarget HintTarget = parseTriple(OptTargetTripleHint);
+        IFSTarget HintTarget = parseTriple(*Config.HintIfsTarget);
         if (Stub.Target.Arch.getValue() != HintTarget.Arch.getValue())
           fatalError(make_error<StringError>(
               "Triple hint does not match the actual architecture", HintEC));
@@ -541,20 +605,21 @@ int main(int argc, char *argv[]) {
               "Triple hint does not match the actual bit width", HintEC));
 
         stripIFSTarget(Stub, true, false, false, false);
-        Stub.Target.Triple = OptTargetTripleHint.getValue();
+        Stub.Target.Triple = Config.HintIfsTarget.getValue();
       } else {
-        stripIFSTarget(Stub, StripIFSTarget, StripIFSArch,
-                       StripIFSEndiannessWidth, StripIFSBitWidth);
+        stripIFSTarget(Stub, Config.StripIfsTarget, Config.StripIfsArch,
+                       Config.StripIfsEndianness, Config.StripIfsBitwidth);
       }
-      Error IFSWriteError = writeIFS(OutputIFSFilePath.getValue(), Stub);
+      Error IFSWriteError =
+          writeIFS(Config.OutputIfs.getValue(), Stub, Config.WriteIfChanged);
       if (IFSWriteError)
         fatalError(std::move(IFSWriteError));
     }
-    if (OutputTBDFilePath.getNumOccurrences() == 1) {
+    if (Config.OutputTbd) {
       std::error_code SysErr;
-      raw_fd_ostream Out(OutputTBDFilePath, SysErr);
+      raw_fd_ostream Out(*Config.OutputTbd, SysErr);
       if (SysErr) {
-        WithColor::error() << "Couldn't open " << OutputTBDFilePath
+        WithColor::error() << "Couldn't open " << *Config.OutputTbd
                            << " for writing.\n";
         return -1;
       }


        


More information about the llvm-commits mailing list