Factor out more code to Common/Args.cpp.

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

llvm-svn: 319211
This commit is contained in:
Rui Ueyama 2017-11-28 19:58:45 +00:00
parent 230b0a1477
commit 3e03944f02
5 changed files with 123 additions and 112 deletions

62
lld/Common/Args.cpp Normal file
View File

@ -0,0 +1,62 @@
//===- Args.cpp -----------------------------------------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lld/Common/Args.h"
#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Option/ArgList.h"
using namespace llvm;
using namespace lld;
int lld::args::getInteger(opt::InputArgList &Args, unsigned Key, int Default) {
int V = Default;
if (auto *Arg = Args.getLastArg(Key)) {
StringRef S = Arg->getValue();
if (!to_integer(S, V, 10))
error(Arg->getSpelling() + ": number expected, but got '" + S + "'");
}
return V;
}
std::vector<StringRef> lld::args::getStrings(opt::InputArgList &Args, int Id) {
std::vector<StringRef> V;
for (auto *Arg : Args.filtered(Id))
V.push_back(Arg->getValue());
return V;
}
uint64_t lld::args::getZOptionValue(opt::InputArgList &Args, int Id, StringRef Key,
uint64_t Default) {
for (auto *Arg : Args.filtered(Id)) {
std::pair<StringRef, StringRef> KV = StringRef(Arg->getValue()).split('=');
if (KV.first == Key) {
uint64_t Result = Default;
if (!to_integer(KV.second, Result))
error("invalid " + Key + ": " + KV.second);
return Result;
}
}
return Default;
}
std::vector<StringRef> lld::args::getLines(MemoryBufferRef MB) {
SmallVector<StringRef, 0> Arr;
MB.getBuffer().split(Arr, '\n');
std::vector<StringRef> Ret;
for (StringRef S : Arr) {
S = S.trim();
if (!S.empty() && S[0] != '#')
Ret.push_back(S);
}
return Ret;
}

View File

@ -3,6 +3,7 @@ if(NOT LLD_BUILT_STANDALONE)
endif()
add_lld_library(lldCommon
Args.cpp
ErrorHandler.cpp
Reproduce.cpp
Strings.cpp

View File

@ -38,6 +38,7 @@
#include "SyntheticSections.h"
#include "Target.h"
#include "Writer.h"
#include "lld/Common/Args.h"
#include "lld/Common/Driver.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Threads.h"
@ -293,16 +294,6 @@ static void checkOptions(opt::InputArgList &Args) {
}
}
static int getInteger(opt::InputArgList &Args, unsigned Key, int Default) {
int V = Default;
if (auto *Arg = Args.getLastArg(Key)) {
StringRef S = Arg->getValue();
if (!to_integer(S, V, 10))
error(Arg->getSpelling() + ": number expected, but got '" + S + "'");
}
return V;
}
static const char *getReproduceOption(opt::InputArgList &Args) {
if (auto *Arg = Args.getLastArg(OPT_reproduce))
return Arg->getValue();
@ -316,26 +307,12 @@ static bool hasZOption(opt::InputArgList &Args, StringRef Key) {
return false;
}
static uint64_t getZOptionValue(opt::InputArgList &Args, StringRef Key,
uint64_t Default) {
for (auto *Arg : Args.filtered(OPT_z)) {
std::pair<StringRef, StringRef> KV = StringRef(Arg->getValue()).split('=');
if (KV.first == Key) {
uint64_t Result = Default;
if (!to_integer(KV.second, Result))
error("invalid " + Key + ": " + KV.second);
return Result;
}
}
return Default;
}
void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) {
ELFOptTable Parser;
opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
// Interpret this flag early because error() depends on them.
errorHandler().ErrorLimit = getInteger(Args, OPT_error_limit, 20);
errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20);
// Handle -help
if (Args.hasArg(OPT_help)) {
@ -413,15 +390,8 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) {
}
}
static std::vector<StringRef> getArgs(opt::InputArgList &Args, int Id) {
std::vector<StringRef> V;
for (auto *Arg : Args.filtered(Id))
V.push_back(Arg->getValue());
return V;
}
static std::string getRpath(opt::InputArgList &Args) {
std::vector<StringRef> V = getArgs(Args, OPT_rpath);
std::vector<StringRef> V = args::getStrings(Args, OPT_rpath);
return llvm::join(V.begin(), V.end(), ":");
}
@ -596,19 +566,6 @@ getBuildId(opt::InputArgList &Args) {
return {BuildIdKind::None, {}};
}
static std::vector<StringRef> getLines(MemoryBufferRef MB) {
SmallVector<StringRef, 0> Arr;
MB.getBuffer().split(Arr, '\n');
std::vector<StringRef> Ret;
for (StringRef S : Arr) {
S = S.trim();
if (!S.empty())
Ret.push_back(S);
}
return Ret;
}
static bool getCompressDebugSections(opt::InputArgList &Args) {
StringRef S = Args.getLastArgValue(OPT_compress_debug_sections, "none");
if (S == "none")
@ -631,7 +588,7 @@ static int parseInt(StringRef S, opt::Arg *Arg) {
void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->AllowMultipleDefinition =
Args.hasArg(OPT_allow_multiple_definition) || hasZOption(Args, "muldefs");
Config->AuxiliaryList = getArgs(Args, OPT_auxiliary);
Config->AuxiliaryList = args::getStrings(Args, OPT_auxiliary);
Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic);
Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions);
Config->Chroot = Args.getLastArgValue(OPT_chroot);
@ -651,7 +608,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false);
errorHandler().FatalWarnings =
Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
Config->FilterList = getArgs(Args, OPT_filter);
Config->FilterList = args::getStrings(Args, OPT_filter);
Config->Fini = Args.getLastArgValue(OPT_fini, "_fini");
Config->GcSections = Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false);
Config->GdbIndex = Args.hasFlag(OPT_gdb_index, OPT_no_gdb_index, false);
@ -659,8 +616,8 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->Init = Args.getLastArgValue(OPT_init, "_init");
Config->LTOAAPipeline = Args.getLastArgValue(OPT_lto_aa_pipeline);
Config->LTONewPmPasses = Args.getLastArgValue(OPT_lto_newpm_passes);
Config->LTOO = getInteger(Args, OPT_lto_O, 2);
Config->LTOPartitions = getInteger(Args, OPT_lto_partitions, 1);
Config->LTOO = args::getInteger(Args, OPT_lto_O, 2);
Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1);
Config->MapFile = Args.getLastArgValue(OPT_Map);
Config->NoGnuUnique = Args.hasArg(OPT_no_gnu_unique);
Config->NoUndefinedVersion = Args.hasArg(OPT_no_undefined_version);
@ -670,7 +627,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->Omagic = Args.hasFlag(OPT_omagic, OPT_no_omagic, false);
Config->OptRemarksFilename = Args.getLastArgValue(OPT_opt_remarks_filename);
Config->OptRemarksWithHotness = Args.hasArg(OPT_opt_remarks_with_hotness);
Config->Optimize = getInteger(Args, OPT_O, 1);
Config->Optimize = args::getInteger(Args, OPT_O, 1);
Config->OrphanHandling = getOrphanHandling(Args);
Config->OutputFile = Args.getLastArgValue(OPT_o);
Config->Pie = Args.hasFlag(OPT_pie, OPT_nopie, false);
@ -679,7 +636,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->Rpath = getRpath(Args);
Config->Relocatable = Args.hasArg(OPT_relocatable);
Config->SaveTemps = Args.hasArg(OPT_save_temps);
Config->SearchPaths = getArgs(Args, OPT_library_path);
Config->SearchPaths = args::getStrings(Args, OPT_library_path);
Config->SectionStartMap = getSectionStartMap(Args);
Config->Shared = Args.hasArg(OPT_shared);
Config->SingleRoRx = Args.hasArg(OPT_no_rosegment);
@ -693,10 +650,10 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->ThinLTOCachePolicy = check(
parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)),
"--thinlto-cache-policy: invalid cache policy");
Config->ThinLTOJobs = getInteger(Args, OPT_thinlto_jobs, -1u);
Config->ThinLTOJobs = args::getInteger(Args, OPT_thinlto_jobs, -1u);
ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true);
Config->Trace = Args.hasArg(OPT_trace);
Config->Undefined = getArgs(Args, OPT_undefined);
Config->Undefined = args::getStrings(Args, OPT_undefined);
Config->UnresolvedSymbols = getUnresolvedSymbolPolicy(Args);
Config->Verbose = Args.hasArg(OPT_verbose);
errorHandler().Verbose = Config->Verbose;
@ -710,7 +667,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->ZOrigin = hasZOption(Args, "origin");
Config->ZRelro = !hasZOption(Args, "norelro");
Config->ZRodynamic = hasZOption(Args, "rodynamic");
Config->ZStackSize = getZOptionValue(Args, "stack-size", 0);
Config->ZStackSize = args::getZOptionValue(Args, OPT_z, "stack-size", 0);
Config->ZText = !hasZOption(Args, "notext");
Config->ZWxneeded = hasZOption(Args, "wxneeded");
@ -785,14 +742,14 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
if (auto *Arg = Args.getLastArg(OPT_symbol_ordering_file))
if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
Config->SymbolOrderingFile = getLines(*Buffer);
Config->SymbolOrderingFile = args::getLines(*Buffer);
// If --retain-symbol-file is used, we'll keep only the symbols listed in
// the file and discard all others.
if (auto *Arg = Args.getLastArg(OPT_retain_symbols_file)) {
Config->DefaultSymbolVersion = VER_NDX_LOCAL;
if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
for (StringRef S : getLines(*Buffer))
for (StringRef S : args::getLines(*Buffer))
Config->VersionScriptGlobals.push_back(
{S, /*IsExternCpp*/ false, /*HasWildcard*/ false});
}
@ -923,8 +880,8 @@ void LinkerDriver::inferMachineType() {
// Parse -z max-page-size=<value>. The default value is defined by
// each target.
static uint64_t getMaxPageSize(opt::InputArgList &Args) {
uint64_t Val =
getZOptionValue(Args, "max-page-size", Target->DefaultMaxPageSize);
uint64_t Val = args::getZOptionValue(Args, OPT_z, "max-page-size",
Target->DefaultMaxPageSize);
if (!isPowerOf2_64(Val))
error("max-page-size: value isn't a power of 2");
return Val;

View File

@ -0,0 +1,35 @@
//===- Args.h ---------------------------------------------------*- C++ -*-===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLD_ARGS_H
#define LLD_ARGS_H
#include "lld/Common/LLVM.h"
#include "llvm/Support/MemoryBuffer.h"
#include <vector>
namespace llvm {
namespace opt {
class InputArgList;
}
} // namespace llvm
namespace lld {
namespace args {
int getInteger(llvm::opt::InputArgList &Args, unsigned Key, int Default);
std::vector<StringRef> getStrings(llvm::opt::InputArgList &Args, int Id);
uint64_t getZOptionValue(llvm::opt::InputArgList &Args, int Id, StringRef Key,
uint64_t Default);
std::vector<StringRef> getLines(MemoryBufferRef MB);
} // namespace args
} // namespace lld
#endif

View File

@ -12,6 +12,7 @@
#include "Memory.h"
#include "SymbolTable.h"
#include "Writer.h"
#include "lld/Common/Args.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Threads.h"
#include "lld/Common/Version.h"
@ -104,52 +105,6 @@ static const opt::OptTable::Info OptInfo[] = {
#undef OPTION
};
static std::vector<StringRef> getArgs(opt::InputArgList &Args, int Id) {
std::vector<StringRef> V;
for (auto *Arg : Args.filtered(Id))
V.push_back(Arg->getValue());
return V;
}
static int getInteger(opt::InputArgList &Args, unsigned Key, int Default) {
int V = Default;
if (auto *Arg = Args.getLastArg(Key)) {
StringRef S = Arg->getValue();
if (S.getAsInteger(10, V))
error(Arg->getSpelling() + ": number expected, but got " + S);
}
return V;
}
static uint64_t getZOptionValue(opt::InputArgList &Args, StringRef Key,
uint64_t Default) {
for (auto *Arg : Args.filtered(OPT_z)) {
StringRef Value = Arg->getValue();
size_t Pos = Value.find("=");
if (Pos != StringRef::npos && Key == Value.substr(0, Pos)) {
Value = Value.substr(Pos + 1);
uint64_t Res;
if (Value.getAsInteger(0, Res))
error("invalid " + Key + ": " + Value);
return Res;
}
}
return Default;
}
static std::vector<StringRef> getLines(MemoryBufferRef MB) {
SmallVector<StringRef, 0> Arr;
MB.getBuffer().split(Arr, '\n');
std::vector<StringRef> Ret;
for (StringRef S : Arr) {
S = S.trim();
if (!S.empty() && S[0] != '#')
Ret.push_back(S);
}
return Ret;
}
// Set color diagnostics according to -color-diagnostics={auto,always,never}
// or -no-color-diagnostics flags.
static void handleColorDiagnostics(opt::InputArgList &Args) {
@ -283,7 +238,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
V.push_back(Arg->getValue());
cl::ParseCommandLineOptions(V.size(), V.data());
errorHandler().ErrorLimit = getInteger(Args, OPT_error_limit, 20);
errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20);
if (Args.hasArg(OPT_version) || Args.hasArg(OPT_v)) {
outs() << getLLDVersion() << "\n";
@ -296,21 +251,22 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
Config->ImportMemory = Args.hasArg(OPT_import_memory);
Config->OutputFile = Args.getLastArgValue(OPT_o);
Config->Relocatable = Args.hasArg(OPT_relocatable);
Config->SearchPaths = getArgs(Args, OPT_L);
Config->SearchPaths = args::getStrings(Args, OPT_L);
Config->StripAll = Args.hasArg(OPT_strip_all);
Config->StripDebug = Args.hasArg(OPT_strip_debug);
Config->Sysroot = Args.getLastArgValue(OPT_sysroot);
errorHandler().Verbose = Args.hasArg(OPT_verbose);
ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true);
Config->InitialMemory = getInteger(Args, OPT_initial_memory, 0);
Config->GlobalBase = getInteger(Args, OPT_global_base, 1024);
Config->MaxMemory = getInteger(Args, OPT_max_memory, 0);
Config->ZStackSize = getZOptionValue(Args, "stack-size", WasmPageSize);
Config->InitialMemory = args::getInteger(Args, OPT_initial_memory, 0);
Config->GlobalBase = args::getInteger(Args, OPT_global_base, 1024);
Config->MaxMemory = args::getInteger(Args, OPT_max_memory, 0);
Config->ZStackSize =
args::getZOptionValue(Args, OPT_z, "stack-size", WasmPageSize);
if (auto *Arg = Args.getLastArg(OPT_allow_undefined_file))
if (Optional<MemoryBufferRef> Buf = readFile(Arg->getValue()))
for (StringRef Sym : getLines(*Buf))
for (StringRef Sym : args::getLines(*Buf))
Config->AllowUndefinedSymbols.insert(Sym);
if (Config->OutputFile.empty())