Driver: move non-positional parameters out of switch. NFC.

llvm-svn: 228743
This commit is contained in:
Rui Ueyama 2015-02-10 20:57:43 +00:00
parent 1d966eff08
commit c008539736
1 changed files with 172 additions and 198 deletions

View File

@ -349,6 +349,14 @@ GnuLdDriver::createELFLinkingContext(llvm::Triple triple) {
return nullptr;
}
static llvm::Optional<bool>
getBool(const llvm::opt::InputArgList &parsedArgs,
unsigned yesFlag, unsigned noFlag) {
if (auto *arg = parsedArgs.getLastArg(yesFlag, noFlag))
return arg->getOption().getID() == yesFlag;
return llvm::None;
}
bool GnuLdDriver::parse(int argc, const char *argv[],
std::unique_ptr<ELFLinkingContext> &context,
raw_ostream &diag) {
@ -368,17 +376,18 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
}
// Handle --help
if (parsedArgs->getLastArg(OPT_help)) {
if (parsedArgs->hasArg(OPT_help)) {
table.PrintHelp(llvm::outs(), argv[0], "LLVM Linker", false);
return true;
}
// Use -target or use default target triple to instantiate LinkingContext
llvm::Triple baseTriple;
if (llvm::opt::Arg *trip = parsedArgs->getLastArg(OPT_target))
baseTriple = llvm::Triple(trip->getValue());
else
if (auto *arg = parsedArgs->getLastArg(OPT_target)) {
baseTriple = llvm::Triple(arg->getValue());
} else {
baseTriple = getDefaultTarget(argv[0]);
}
llvm::Triple triple(baseTriple);
if (!applyEmulation(triple, *parsedArgs, diag))
@ -391,11 +400,9 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
return false;
}
std::stack<int> groupStack;
int numfiles = 0;
bool asNeeded = false;
bool wholeArchive = false;
bool hasNoStdLib = false;
// Copy mllvm
for (auto *arg : parsedArgs->filtered(OPT_mllvm))
ctx->appendLLVMOption(arg->getValue());
// Ignore unknown arguments.
for (auto unknownArg : parsedArgs->filtered(OPT_UNKNOWN))
@ -403,63 +410,53 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
<< unknownArg->getValue() << "\n";
// Set sys root path.
if (llvm::opt::Arg *sysRootPath = parsedArgs->getLastArg(OPT_sysroot))
ctx->setSysroot(sysRootPath->getValue());
// Add all search paths.
for (auto libDir : parsedArgs->filtered(OPT_L))
ctx->addSearchPath(libDir->getValue());
if (auto *arg = parsedArgs->getLastArg(OPT_sysroot))
ctx->setSysroot(arg->getValue());
// Add the default search directory specific to the target.
if (!(hasNoStdLib = parsedArgs->hasArg(OPT_nostdlib)))
if (!parsedArgs->hasArg(OPT_nostdlib))
addPlatformSearchDirs(*ctx, triple, baseTriple);
// Handle --demangle option(For compatibility)
if (parsedArgs->getLastArg(OPT_demangle))
if (parsedArgs->hasArg(OPT_demangle))
ctx->setDemangleSymbols(true);
// Handle --no-demangle option.
if (parsedArgs->getLastArg(OPT_no_demangle))
if (parsedArgs->hasArg(OPT_no_demangle))
ctx->setDemangleSymbols(false);
// Figure out output kind ( -r, -static, -shared)
if (llvm::opt::Arg *kind =
parsedArgs->getLastArg(OPT_relocatable, OPT_static, OPT_shared,
OPT_nmagic, OPT_omagic, OPT_no_omagic)) {
switch (kind->getOption().getID()) {
case OPT_relocatable:
ctx->setOutputELFType(llvm::ELF::ET_REL);
ctx->setPrintRemainingUndefines(false);
ctx->setAllowRemainingUndefines(true);
break;
case OPT_static:
ctx->setOutputELFType(llvm::ELF::ET_EXEC);
ctx->setIsStaticExecutable(true);
break;
case OPT_shared:
ctx->setOutputELFType(llvm::ELF::ET_DYN);
ctx->setAllowShlibUndefines(true);
ctx->setUseShlibUndefines(false);
ctx->setPrintRemainingUndefines(false);
ctx->setAllowRemainingUndefines(true);
break;
}
// Figure out output kind (-r, -static, -shared)
if (parsedArgs->hasArg(OPT_relocatable)) {
ctx->setOutputELFType(llvm::ELF::ET_REL);
ctx->setPrintRemainingUndefines(false);
ctx->setAllowRemainingUndefines(true);
}
if (parsedArgs->hasArg(OPT_static)) {
ctx->setOutputELFType(llvm::ELF::ET_EXEC);
ctx->setIsStaticExecutable(true);
}
if (parsedArgs->hasArg(OPT_shared)) {
ctx->setOutputELFType(llvm::ELF::ET_DYN);
ctx->setAllowShlibUndefines(true);
ctx->setUseShlibUndefines(false);
ctx->setPrintRemainingUndefines(false);
ctx->setAllowRemainingUndefines(true);
}
// Figure out if the output type is nmagic/omagic
if (llvm::opt::Arg *kind =
parsedArgs->getLastArg(OPT_nmagic, OPT_omagic, OPT_no_omagic)) {
switch (kind->getOption().getID()) {
if (auto *arg = parsedArgs->getLastArg(
OPT_nmagic, OPT_omagic, OPT_no_omagic)) {
switch (arg->getOption().getID()) {
case OPT_nmagic:
ctx->setOutputMagic(ELFLinkingContext::OutputMagic::NMAGIC);
ctx->setIsStaticExecutable(true);
break;
case OPT_omagic:
ctx->setOutputMagic(ELFLinkingContext::OutputMagic::OMAGIC);
ctx->setIsStaticExecutable(true);
break;
case OPT_no_omagic:
ctx->setOutputMagic(ELFLinkingContext::OutputMagic::DEFAULT);
ctx->setNoAllowDynamicLibraries();
@ -467,24 +464,125 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
}
}
for (auto inputArg : *parsedArgs) {
switch (inputArg->getOption().getID()) {
case OPT_merge_strings:
ctx->setMergeCommonStrings(true);
break;
case OPT_t:
ctx->setLogInputFiles(true);
break;
case OPT_use_shlib_undefs:
ctx->setUseShlibUndefines(true);
break;
case OPT_no_allow_shlib_undefs:
ctx->setAllowShlibUndefines(false);
break;
case OPT_allow_shlib_undefs:
ctx->setAllowShlibUndefines(true);
break;
if (parsedArgs->hasArg(OPT_strip_all))
ctx->setStripSymbols(true);
if (auto *arg = parsedArgs->getLastArg(OPT_soname))
ctx->setSharedObjectName(arg->getValue());
if (parsedArgs->hasArg(OPT_rosegment))
ctx->setCreateSeparateROSegment();
if (parsedArgs->hasArg(OPT_no_align_segments))
ctx->setAlignSegments(false);
if (auto *arg = parsedArgs->getLastArg(OPT_image_base)) {
uint64_t baseAddress = 0;
StringRef inputValue = arg->getValue();
if (inputValue.getAsInteger(0, baseAddress) || !baseAddress) {
diag << "invalid value for image base " << inputValue << "\n";
return false;
}
ctx->setBaseAddress(baseAddress);
}
if (parsedArgs->hasArg(OPT_merge_strings))
ctx->setMergeCommonStrings(true);
if (parsedArgs->hasArg(OPT_t))
ctx->setLogInputFiles(true);
if (parsedArgs->hasArg(OPT_use_shlib_undefs))
ctx->setUseShlibUndefines(true);
if (auto val = getBool(*parsedArgs, OPT_allow_shlib_undefs,
OPT_no_allow_shlib_undefs))
ctx->setAllowShlibUndefines(*val);
if (auto *arg = parsedArgs->getLastArg(OPT_e))
ctx->setEntrySymbolName(arg->getValue());
if (auto *arg = parsedArgs->getLastArg(OPT_output))
ctx->setOutputPath(arg->getValue());
if (parsedArgs->hasArg(OPT_noinhibit_exec))
ctx->setAllowRemainingUndefines(true);
if (parsedArgs->hasArg(OPT_export_dynamic))
ctx->setExportDynamic(true);
if (parsedArgs->hasArg(OPT_allow_multiple_definition))
ctx->setAllowDuplicates(true);
if (auto *arg = parsedArgs->getLastArg(OPT_dynamic_linker))
ctx->setInterpreter(arg->getValue());
if (auto *arg = parsedArgs->getLastArg(OPT_init))
ctx->setInitFunction(arg->getValue());
if (auto *arg = parsedArgs->getLastArg(OPT_fini))
ctx->setFiniFunction(arg->getValue());
if (auto *arg = parsedArgs->getLastArg(OPT_output_filetype))
ctx->setOutputFileType(arg->getValue());
for (auto *arg : parsedArgs->filtered(OPT_L))
ctx->addSearchPath(arg->getValue());
for (auto *arg : parsedArgs->filtered(OPT_u))
ctx->addInitialUndefinedSymbol(arg->getValue());
for (auto *arg : parsedArgs->filtered(OPT_defsym)) {
StringRef sym, target;
uint64_t addr;
if (parseDefsymAsAbsolute(arg->getValue(), sym, addr)) {
ctx->addInitialAbsoluteSymbol(sym, addr);
} else if (parseDefsymAsAlias(arg->getValue(), sym, target)) {
ctx->addAlias(sym, target);
} else {
diag << "invalid --defsym: " << arg->getValue() << "\n";
return false;
}
}
for (auto *arg : parsedArgs->filtered(OPT_z)) {
StringRef opt = arg->getValue();
if (opt == "muldefs") {
ctx->setAllowDuplicates(true);
} else if (opt.startswith("max-page-size")) {
// Parse -z max-page-size option.
// The default page size is considered the minimum page size the user
// can set, check the user input if its atleast the minimum page size
// and does not exceed the maximum page size allowed for the target.
uint64_t maxPageSize = 0;
// Error if the page size user set is less than the maximum page size
// and greather than the default page size and the user page size is a
// modulo of the default page size.
if ((!parseZOption(opt, maxPageSize)) ||
(maxPageSize < ctx->getPageSize()) ||
(maxPageSize % ctx->getPageSize())) {
diag << "invalid option: " << opt << "\n";
return false;
}
ctx->setMaxPageSize(maxPageSize);
} else {
diag << "warning: ignoring unknown argument for -z: " << opt << "\n";
}
}
for (auto *arg : parsedArgs->filtered(OPT_rpath)) {
SmallVector<StringRef, 2> rpaths;
StringRef(arg->getValue()).split(rpaths, ":");
for (auto path : rpaths)
ctx->addRpath(path);
}
for (auto *arg : parsedArgs->filtered(OPT_rpath_link)) {
SmallVector<StringRef, 2> rpaths;
StringRef(arg->getValue()).split(rpaths, ":");
for (auto path : rpaths)
ctx->addRpathLink(path);
}
// Register possible input file parsers.
@ -498,52 +596,14 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
ctx->registry().addSupportELFDynamicSharedObjects(
ctx->useShlibUndefines(), ctx->targetHandler());
// Process all the arguments and create input files.
for (auto inputArg : *parsedArgs) {
switch (inputArg->getOption().getID()) {
case OPT_mllvm:
ctx->appendLLVMOption(inputArg->getValue());
break;
case OPT_e:
ctx->setEntrySymbolName(inputArg->getValue());
break;
case OPT_output:
ctx->setOutputPath(inputArg->getValue());
break;
case OPT_noinhibit_exec:
ctx->setAllowRemainingUndefines(true);
break;
case OPT_export_dynamic:
ctx->setExportDynamic(true);
break;
case OPT_allow_multiple_definition:
ctx->setAllowDuplicates(true);
break;
case OPT_dynamic_linker:
ctx->setInterpreter(inputArg->getValue());
break;
case OPT_u:
ctx->addInitialUndefinedSymbol(inputArg->getValue());
break;
case OPT_init:
ctx->setInitFunction(inputArg->getValue());
break;
case OPT_fini:
ctx->setFiniFunction(inputArg->getValue());
break;
case OPT_output_filetype:
ctx->setOutputFileType(inputArg->getValue());
break;
std::stack<int> groupStack;
int numfiles = 0;
bool asNeeded = false;
bool wholeArchive = false;
// Process files
for (auto arg : *parsedArgs) {
switch (arg->getOption().getID()) {
case OPT_no_whole_archive:
wholeArchive = false;
break;
@ -560,20 +620,6 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
asNeeded = false;
break;
case OPT_defsym: {
StringRef sym, target;
uint64_t addr;
if (parseDefsymAsAbsolute(inputArg->getValue(), sym, addr)) {
ctx->addInitialAbsoluteSymbol(sym, addr);
} else if (parseDefsymAsAlias(inputArg->getValue(), sym, target)) {
ctx->addAlias(sym, target);
} else {
diag << "invalid --defsym: " << inputArg->getValue() << "\n";
return false;
}
break;
}
case OPT_start_group:
groupStack.push(numfiles);
break;
@ -590,36 +636,10 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
break;
}
case OPT_z: {
StringRef extOpt = inputArg->getValue();
if (extOpt == "muldefs")
ctx->setAllowDuplicates(true);
else if (extOpt.startswith("max-page-size")) {
// Parse -z max-page-size option.
// The default page size is considered the minimum page size the user
// can set, check the user input if its atleast the minimum page size
// and does not exceed the maximum page size allowed for the target.
uint64_t maxPageSize = 0;
// Error if the page size user set is less than the maximum page size
// and greather than the default page size and the user page size is a
// modulo of the default page size.
if ((!parseZOption(extOpt, maxPageSize)) ||
(maxPageSize < ctx->getPageSize()) ||
(maxPageSize % ctx->getPageSize())) {
diag << "invalid option: " << extOpt << "\n";
return false;
}
ctx->setMaxPageSize(maxPageSize);
} else
diag << "warning: ignoring unknown argument for -z: " << extOpt << "\n";
break;
}
case OPT_INPUT:
case OPT_l: {
bool dashL = (inputArg->getOption().getID() == OPT_l);
StringRef path = inputArg->getValue();
bool dashL = (arg->getOption().getID() == OPT_l);
StringRef path = arg->getValue();
ErrorOr<StringRef> pathOrErr = findFile(*ctx, path, dashL);
if (std::error_code ec = pathOrErr.getError()) {
@ -642,8 +662,9 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
diag << "Cannot open " << path << ": " << ec.message() << "\n";
return false;
}
bool nostdlib = parsedArgs->hasArg(OPT_nostdlib);
std::error_code ec =
evalLinkerScript(*ctx, std::move(mb.get()), diag, hasNoStdLib);
evalLinkerScript(*ctx, std::move(mb.get()), diag, nostdlib);
if (ec) {
diag << path << ": Error parsing linker script: "
<< ec.message() << "\n";
@ -663,55 +684,8 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
numfiles += files.size();
break;
}
case OPT_rpath: {
SmallVector<StringRef, 2> rpaths;
StringRef(inputArg->getValue()).split(rpaths, ":");
for (auto path : rpaths)
ctx->addRpath(path);
break;
}
case OPT_rpath_link: {
SmallVector<StringRef, 2> rpaths;
StringRef(inputArg->getValue()).split(rpaths, ":");
for (auto path : rpaths)
ctx->addRpathLink(path);
break;
}
case OPT_strip_all: {
ctx->setStripSymbols(true);
break;
}
case OPT_soname:
ctx->setSharedObjectName(inputArg->getValue());
break;
case OPT_rosegment:
ctx->setCreateSeparateROSegment();
break;
case OPT_no_align_segments:
ctx->setAlignSegments(false);
break;
case OPT_image_base: {
uint64_t baseAddress = 0;
StringRef inputValue = inputArg->getValue();
if ((inputValue.getAsInteger(0, baseAddress)) || !baseAddress) {
diag << "invalid value for image base " << inputValue << "\n";
return false;
}
ctx->setBaseAddress(baseAddress);
break;
}
default:
break;
} // end switch on option ID
} // end for
}
if (ctx->getNodes().empty()) {
diag << "No input files\n";