mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
[lld-macho] Specify the complete set of command-line options for ld64
This is a complete Options.td compiled from ld(1) dated 2018-03-07 and cross checked with ld64 source code version 512.4 dated 2018-03-18. This is the first in a series of diffs for argument handling. Follow-ups will include switch cases for all the new instances of `OPT_foo`, and parsing/validation of arguments attached to options, e.g., more code akin to `OPT_platform_version` and associated `parsePlatformVersion()`. Reviewed By: smeenai Differential Revision: https://reviews.llvm.org/D80582
This commit is contained in:
committed by
Shoaib Meenai
parent
35651fdd45
commit
7df80e3f23
+66
-15
@@ -37,6 +37,7 @@
|
||||
using namespace llvm;
|
||||
using namespace llvm::MachO;
|
||||
using namespace llvm::sys;
|
||||
using namespace llvm::opt;
|
||||
using namespace lld;
|
||||
using namespace lld::macho;
|
||||
|
||||
@@ -74,6 +75,12 @@ opt::InputArgList MachOOptTable::parse(ArrayRef<const char *> argv) {
|
||||
return args;
|
||||
}
|
||||
|
||||
void MachOOptTable::printHelp(const char *argv0, bool showHidden) const {
|
||||
PrintHelp(lld::outs(), (std::string(argv0) + " [options] file...").c_str(),
|
||||
"LLVM Linker", showHidden);
|
||||
lld::outs() << "\n";
|
||||
}
|
||||
|
||||
static Optional<std::string> findLibrary(StringRef name) {
|
||||
std::string stub = (llvm::Twine("lib") + name + ".tbd").str();
|
||||
std::string shared = (llvm::Twine("lib") + name + ".dylib").str();
|
||||
@@ -259,15 +266,41 @@ static bool markSubLibrary(StringRef searchName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static void handlePlatformVersion(opt::ArgList::iterator &it,
|
||||
const opt::ArgList::iterator &end) {
|
||||
// -platform_version takes 3 args, which LLVM's option library doesn't
|
||||
// support directly. So this explicitly handles that.
|
||||
// FIXME: stash skipped args for later use.
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
++it;
|
||||
if (it == end || (*it)->getOption().getID() != OPT_INPUT)
|
||||
fatal("usage: -platform_version platform min_version sdk_version");
|
||||
static void handlePlatformVersion(const opt::Arg *arg) {
|
||||
// TODO: implementation coming very soon ...
|
||||
}
|
||||
|
||||
static void warnIfDeprecatedOption(const opt::Option &opt) {
|
||||
if (!opt.getGroup().isValid())
|
||||
return;
|
||||
if (opt.getGroup().getID() == OPT_grp_deprecated) {
|
||||
warn("Option `" + opt.getPrefixedName() + "' is deprecated in ld64:");
|
||||
warn(opt.getHelpText());
|
||||
}
|
||||
}
|
||||
|
||||
static void warnIfUnimplementedOption(const opt::Option &opt) {
|
||||
if (!opt.getGroup().isValid())
|
||||
return;
|
||||
switch (opt.getGroup().getID()) {
|
||||
case OPT_grp_deprecated:
|
||||
// warn about deprecated options elsewhere
|
||||
break;
|
||||
case OPT_grp_undocumented:
|
||||
warn("Option `" + opt.getPrefixedName() +
|
||||
"' is undocumented. Should lld implement it?");
|
||||
break;
|
||||
case OPT_grp_obsolete:
|
||||
warn("Option `" + opt.getPrefixedName() +
|
||||
"' is obsolete. Please modernize your usage.");
|
||||
break;
|
||||
case OPT_grp_ignored:
|
||||
warn("Option `" + opt.getPrefixedName() + "' is ignored.");
|
||||
break;
|
||||
default:
|
||||
warn("Option `" + opt.getPrefixedName() +
|
||||
"' is not yet implemented. Stay tuned...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,6 +315,14 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
|
||||
MachOOptTable parser;
|
||||
opt::InputArgList args = parser.parse(argsArr.slice(1));
|
||||
|
||||
if (args.hasArg(OPT_help_hidden)) {
|
||||
parser.printHelp(argsArr[0], /*showHidden=*/true);
|
||||
return true;
|
||||
} else if (args.hasArg(OPT_help)) {
|
||||
parser.printHelp(argsArr[0], /*showHidden=*/false);
|
||||
return true;
|
||||
}
|
||||
|
||||
config = make<Configuration>();
|
||||
symtab = make<SymbolTable>();
|
||||
target = createTargetInfo(args);
|
||||
@@ -302,9 +343,9 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
|
||||
return !errorCount();
|
||||
}
|
||||
|
||||
for (opt::ArgList::iterator it = args.begin(), end = args.end(); it != end;
|
||||
++it) {
|
||||
const opt::Arg *arg = *it;
|
||||
for (const auto &arg : args) {
|
||||
const auto &opt = arg->getOption();
|
||||
warnIfDeprecatedOption(opt);
|
||||
switch (arg->getOption().getID()) {
|
||||
case OPT_INPUT:
|
||||
addFile(arg->getValue());
|
||||
@@ -318,10 +359,20 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
|
||||
error("library not found for -l" + name);
|
||||
break;
|
||||
}
|
||||
case OPT_platform_version: {
|
||||
handlePlatformVersion(it, end); // Can advance "it".
|
||||
case OPT_platform_version:
|
||||
handlePlatformVersion(arg);
|
||||
break;
|
||||
case OPT_o:
|
||||
case OPT_dylib:
|
||||
case OPT_e:
|
||||
case OPT_L:
|
||||
case OPT_Z:
|
||||
case OPT_arch:
|
||||
// handled elsewhere
|
||||
break;
|
||||
default:
|
||||
warnIfUnimplementedOption(opt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ class MachOOptTable : public llvm::opt::OptTable {
|
||||
public:
|
||||
MachOOptTable();
|
||||
llvm::opt::InputArgList parse(ArrayRef<const char *> argv);
|
||||
void printHelp(const char *argv0, bool showHidden) const;
|
||||
};
|
||||
|
||||
// Create enum with OPT_xxx values for each option in Options.td
|
||||
|
||||
+1284
-30
File diff suppressed because it is too large
Load Diff
@@ -1,16 +1,17 @@
|
||||
# RUN: not lld -flavor darwinnew -arch x86_64 -platform_version 2>&1 \
|
||||
# RUN: | FileCheck --check-prefix=FAIL %s
|
||||
# RUN: | FileCheck --check-prefix=MISSING %s
|
||||
# RUN: not lld -flavor darwinnew -arch x86_64 -platform_version macos 2>&1 \
|
||||
# RUN: | FileCheck --check-prefix=FAIL %s
|
||||
# RUN: | FileCheck --check-prefix=MISSING %s
|
||||
# RUN: not lld -flavor darwinnew -arch x86_64 -platform_version macos 10.15 2>&1 \
|
||||
# RUN: | FileCheck --check-prefix=FAIL %s
|
||||
# RUN: | FileCheck --check-prefix=MISSING %s
|
||||
# RUN: not lld -flavor darwinnew -arch x86_64 -platform_version macos -lfoo 10.15 2>&1 \
|
||||
# RUN: | FileCheck --check-prefix=FAIL %s
|
||||
# RUN: | FileCheck --check-prefix=GOOD %s
|
||||
# RUN: not lld -flavor darwinnew -arch x86_64 -platform_version macos 10.15 10.15.4 2>&1 \
|
||||
# RUN: | FileCheck --check-prefix=GOOD %s
|
||||
# RUN: not lld -flavor darwinnew -arch x86_64 -platform_version macos 10.15 10.15.4 foobar 2>&1 \
|
||||
# RUN: | FileCheck --check-prefix=FAIL_FILE %s
|
||||
|
||||
MISSING: -platform_version: missing argument
|
||||
FAIL: usage: -platform_version platform min_version sdk_version
|
||||
GOOD: undefined symbol: _main
|
||||
FAIL_FILE: cannot open foobar
|
||||
|
||||
@@ -135,6 +135,18 @@ public:
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/// Get the help text for this option.
|
||||
StringRef getHelpText() const {
|
||||
assert(Info && "Must have a valid info!");
|
||||
return Info->HelpText;
|
||||
}
|
||||
|
||||
/// Get the meta-variable list for this option.
|
||||
StringRef getMetaVar() const {
|
||||
assert(Info && "Must have a valid info!");
|
||||
return Info->MetaVar;
|
||||
}
|
||||
|
||||
unsigned getNumArgs() const { return Info->Param; }
|
||||
|
||||
bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
|
||||
|
||||
Reference in New Issue
Block a user