[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