ArrayRef-ify Driver::parse and related functions.

llvm-svn: 240236
This commit is contained in:
David Blaikie 2015-06-21 06:32:10 +00:00
parent 8da889f1a5
commit b2b1c7c3e1
12 changed files with 99 additions and 103 deletions

View File

@ -43,12 +43,12 @@ namespace coff {
Configuration *Config;
LinkerDriver *Driver;
bool link(int Argc, const char *Argv[]) {
bool link(llvm::ArrayRef<const char*> Args) {
auto C = make_unique<Configuration>();
Config = C.get();
auto D = make_unique<LinkerDriver>();
Driver = D.get();
return Driver->link(Argc, Argv);
return Driver->link(Args);
}
// Drop directory components and replace extension with ".exe".
@ -214,7 +214,7 @@ static WindowsSubsystem inferSubsystem() {
.Default(IMAGE_SUBSYSTEM_UNKNOWN);
}
bool LinkerDriver::link(int Argc, const char *Argv[]) {
bool LinkerDriver::link(llvm::ArrayRef<const char*> ArgsArr) {
// Needed for LTO.
llvm::InitializeAllTargetInfos();
llvm::InitializeAllTargets();
@ -225,11 +225,11 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) {
// If the first command line argument is "/lib", link.exe acts like lib.exe.
// We call our own implementation of lib.exe that understands bitcode files.
if (Argc > 1 && StringRef(Argv[1]).equals_lower("/lib"))
return llvm::libDriverMain(Argc - 1, Argv + 1) == 0;
if (ArgsArr.size() > 1 && StringRef(ArgsArr[1]).equals_lower("/lib"))
return llvm::libDriverMain(ArgsArr.slice(1)) == 0;
// Parse command line options.
auto ArgsOrErr = Parser.parse(Argc, Argv);
auto ArgsOrErr = Parser.parse(ArgsArr);
if (auto EC = ArgsOrErr.getError()) {
llvm::errs() << EC.message() << "\n";
return false;
@ -238,7 +238,7 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) {
// Handle /help
if (Args->hasArg(OPT_help)) {
printHelp(Argv[0]);
printHelp(ArgsArr[0]);
return true;
}

View File

@ -35,14 +35,14 @@ using llvm::Optional;
class InputFile;
// Entry point of the COFF linker.
bool link(int Argc, const char *Argv[]);
bool link(llvm::ArrayRef<const char*> Args);
class ArgParser {
public:
ArgParser() : Alloc(AllocAux) {}
// Parses command line options.
ErrorOr<std::unique_ptr<llvm::opt::InputArgList>> parse(int Argc,
const char *Argv[]);
ErrorOr<std::unique_ptr<llvm::opt::InputArgList>>
parse(llvm::ArrayRef<const char *> Args);
// Tokenizes a given string and then parses as command line options.
ErrorOr<std::unique_ptr<llvm::opt::InputArgList>> parse(StringRef S) {
@ -65,7 +65,7 @@ private:
class LinkerDriver {
public:
LinkerDriver() : Alloc(AllocAux) {}
bool link(int Argc, const char *Argv[]);
bool link(llvm::ArrayRef<const char*> Args);
// Used by the resolver to parse .drectve section contents.
std::error_code

View File

@ -571,8 +571,9 @@ ArgParser::parse(std::vector<const char *> Argv) {
}
ErrorOr<std::unique_ptr<llvm::opt::InputArgList>>
ArgParser::parse(int Argc, const char *Argv[]) {
std::vector<const char *> V(Argv + 1, Argv + Argc);
ArgParser::parse(llvm::ArrayRef<const char*> Args) {
Args = Args.slice(1);
std::vector<const char *> V(Args.begin(), Args.end());
return parse(V);
}

View File

@ -55,7 +55,7 @@ private:
class UniversalDriver : public Driver {
public:
/// Determine flavor and pass control to Driver for that flavor.
static bool link(int argc, const char *argv[],
static bool link(llvm::MutableArrayRef<const char*> args,
raw_ostream &diag = llvm::errs());
private:
@ -67,12 +67,12 @@ class GnuLdDriver : public Driver {
public:
/// Parses command line arguments same as gnu/binutils ld and performs link.
/// Returns true iff an error occurred.
static bool linkELF(int argc, const char *argv[],
static bool linkELF(llvm::ArrayRef<const char*> args,
raw_ostream &diag = llvm::errs());
/// Uses gnu/binutils style ld command line options to fill in options struct.
/// Returns true iff there was an error.
static bool parse(int argc, const char *argv[],
static bool parse(llvm::ArrayRef<const char*> args,
std::unique_ptr<ELFLinkingContext> &context,
raw_ostream &diag = llvm::errs());
@ -103,12 +103,12 @@ class DarwinLdDriver : public Driver {
public:
/// Parses command line arguments same as darwin's ld and performs link.
/// Returns true iff there was an error.
static bool linkMachO(int argc, const char *argv[],
static bool linkMachO(llvm::ArrayRef<const char*> args,
raw_ostream &diag = llvm::errs());
/// Uses darwin style ld command line options to update LinkingContext object.
/// Returns true iff there was an error.
static bool parse(int argc, const char *argv[], MachOLinkingContext &info,
static bool parse(llvm::ArrayRef<const char*> args, MachOLinkingContext &info,
raw_ostream &diag = llvm::errs());
private:
@ -120,20 +120,20 @@ class WinLinkDriver : public Driver {
public:
/// Parses command line arguments same as Windows link.exe and performs link.
/// Returns true iff there was an error.
static bool linkPECOFF(int argc, const char *argv[],
static bool linkPECOFF(llvm::ArrayRef<const char*> args,
raw_ostream &diag = llvm::errs());
/// Uses Windows style link command line options to fill in options struct.
/// Returns true iff there was an error.
static bool parse(int argc, const char *argv[], PECOFFLinkingContext &info,
static bool parse(llvm::ArrayRef<const char*> args, PECOFFLinkingContext &info,
raw_ostream &diag = llvm::errs(),
bool isDirective = false);
// Same as parse(), but restricted to the context of directives.
static bool parseDirectives(int argc, const char *argv[],
static bool parseDirectives(int argc, const char** argv,
PECOFFLinkingContext &info,
raw_ostream &diag = llvm::errs()) {
return parse(argc, argv, info, diag, true);
return parse(llvm::makeArrayRef(argv, argc), info, diag, true);
}
private:
@ -142,7 +142,7 @@ private:
/// Driver for Windows 'link.exe' command line options
namespace coff {
bool link(int argc, const char *argv[]);
bool link(llvm::ArrayRef<const char*> args);
}
/// Driver for lld unit tests
@ -150,12 +150,12 @@ class CoreDriver : public Driver {
public:
/// Parses command line arguments same as lld-core and performs link.
/// Returns true iff there was an error.
static bool link(int argc, const char *argv[],
static bool link(llvm::ArrayRef<const char*> args,
raw_ostream &diag = llvm::errs());
/// Uses lld-core command line options to fill in options struct.
/// Returns true iff there was an error.
static bool parse(int argc, const char *argv[], CoreLinkingContext &info,
static bool parse(llvm::ArrayRef<const char*> args, CoreLinkingContext &info,
raw_ostream &diag = llvm::errs());
private:

View File

@ -73,7 +73,7 @@ static const Registry::KindStrings coreKindStrings[] = {
LLD_KIND_STRING_END
};
bool CoreDriver::link(int argc, const char *argv[], raw_ostream &diagnostics) {
bool CoreDriver::link(llvm::ArrayRef<const char*> args, raw_ostream &diagnostics) {
CoreLinkingContext ctx;
// Register possible input file parsers.
@ -81,20 +81,19 @@ bool CoreDriver::link(int argc, const char *argv[], raw_ostream &diagnostics) {
ctx.registry().addKindTable(Reference::KindNamespace::testing,
Reference::KindArch::all, coreKindStrings);
if (!parse(argc, argv, ctx))
if (!parse(args, ctx))
return false;
return Driver::link(ctx);
}
bool CoreDriver::parse(int argc, const char *argv[], CoreLinkingContext &ctx,
bool CoreDriver::parse(llvm::ArrayRef<const char*> args, CoreLinkingContext &ctx,
raw_ostream &diagnostics) {
// Parse command line options using CoreOptions.td
std::unique_ptr<llvm::opt::InputArgList> parsedArgs;
CoreOptTable table;
unsigned missingIndex;
unsigned missingCount;
parsedArgs.reset(table.ParseArgs(llvm::makeArrayRef(argv, argc).slice(1),
missingIndex, missingCount));
parsedArgs.reset(table.ParseArgs(args.slice(1), missingIndex, missingCount));
if (missingCount) {
diagnostics << "error: missing arg value for '"
<< parsedArgs->getArgString(missingIndex) << "' expected "

View File

@ -267,17 +267,17 @@ static bool parseNumberBase16(StringRef numStr, uint64_t &baseAddress) {
namespace lld {
bool DarwinLdDriver::linkMachO(int argc, const char *argv[],
bool DarwinLdDriver::linkMachO(llvm::ArrayRef<const char*> args,
raw_ostream &diagnostics) {
MachOLinkingContext ctx;
if (!parse(argc, argv, ctx, diagnostics))
if (!parse(args, ctx, diagnostics))
return false;
if (ctx.doNothing())
return true;
return link(ctx, diagnostics);
}
bool DarwinLdDriver::parse(int argc, const char *argv[],
bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
MachOLinkingContext &ctx, raw_ostream &diagnostics) {
// Parse command line options using DarwinLdOptions.td
std::unique_ptr<llvm::opt::InputArgList> parsedArgs;
@ -285,8 +285,7 @@ bool DarwinLdDriver::parse(int argc, const char *argv[],
unsigned missingIndex;
unsigned missingCount;
bool globalWholeArchive = false;
parsedArgs.reset(table.ParseArgs(llvm::makeArrayRef(argv, argc).slice(1),
missingIndex, missingCount));
parsedArgs.reset(table.ParseArgs(args.slice(1), missingIndex, missingCount));
if (missingCount) {
diagnostics << "error: missing arg value for '"
<< parsedArgs->getArgString(missingIndex) << "' expected "
@ -344,7 +343,7 @@ bool DarwinLdDriver::parse(int argc, const char *argv[],
&& !parsedArgs->getLastArg(OPT_test_file_usage)) {
// If no -arch and no options at all, print usage message.
if (parsedArgs->size() == 0)
table.PrintHelp(llvm::outs(), argv[0], "LLVM Linker", false);
table.PrintHelp(llvm::outs(), args[0], "LLVM Linker", false);
else
diagnostics << "error: -arch not specified and could not be inferred\n";
return false;

View File

@ -82,21 +82,20 @@ public:
// at the original @file position. If file cannot be read, @file is not expanded
// and left unmodified. @file can appear in a response file, so it's a recursive
// process.
static std::tuple<int, const char **>
maybeExpandResponseFiles(int argc, const char **argv, BumpPtrAllocator &alloc) {
static llvm::ArrayRef<const char*>
maybeExpandResponseFiles(llvm::ArrayRef<const char*> args, BumpPtrAllocator &alloc) {
// Expand response files.
SmallVector<const char *, 256> smallvec;
for (int i = 0; i < argc; ++i)
smallvec.push_back(argv[i]);
for (const char *arg : args)
smallvec.push_back(arg);
llvm::BumpPtrStringSaver saver(alloc);
llvm::cl::ExpandResponseFiles(saver, llvm::cl::TokenizeGNUCommandLine, smallvec);
// Pack the results to a C-array and return it.
argc = smallvec.size();
const char **copy = alloc.Allocate<const char *>(argc + 1);
const char **copy = alloc.Allocate<const char *>(smallvec.size() + 1);
std::copy(smallvec.begin(), smallvec.end(), copy);
copy[argc] = nullptr;
return std::make_tuple(argc, copy);
copy[smallvec.size()] = nullptr;
return llvm::makeArrayRef(copy, smallvec.size() + 1);
}
// Parses an argument of --defsym=<sym>=<number>
@ -134,11 +133,11 @@ static bool parseMaxPageSize(StringRef opt, uint64_t &val) {
return true;
}
bool GnuLdDriver::linkELF(int argc, const char *argv[], raw_ostream &diag) {
bool GnuLdDriver::linkELF(llvm::ArrayRef<const char*> args, raw_ostream &diag) {
BumpPtrAllocator alloc;
std::tie(argc, argv) = maybeExpandResponseFiles(argc, argv, alloc);
args = maybeExpandResponseFiles(args, alloc);
std::unique_ptr<ELFLinkingContext> options;
if (!parse(argc, argv, options, diag))
if (!parse(args, options, diag))
return false;
if (!options)
return true;
@ -338,7 +337,7 @@ getBool(const llvm::opt::InputArgList &parsedArgs,
return llvm::None;
}
bool GnuLdDriver::parse(int argc, const char *argv[],
bool GnuLdDriver::parse(llvm::ArrayRef<const char*> args,
std::unique_ptr<ELFLinkingContext> &context,
raw_ostream &diag) {
// Parse command line options using GnuLdOptions.td
@ -347,7 +346,7 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
unsigned missingIndex;
unsigned missingCount;
parsedArgs.reset(table.ParseArgs(llvm::makeArrayRef(argv, argc).slice(1),
parsedArgs.reset(table.ParseArgs(args.slice(1),
missingIndex, missingCount));
if (missingCount) {
diag << "error: missing arg value for '"
@ -358,7 +357,7 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
// Handle --help
if (parsedArgs->hasArg(OPT_help)) {
table.PrintHelp(llvm::outs(), argv[0], "LLVM Linker", false);
table.PrintHelp(llvm::outs(), args[0], "LLVM Linker", false);
return true;
}
@ -367,7 +366,7 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
if (auto *arg = parsedArgs->getLastArg(OPT_target)) {
baseTriple = llvm::Triple(arg->getValue());
} else {
baseTriple = getDefaultTarget(argv[0]);
baseTriple = getDefaultTarget(args[0]);
}
llvm::Triple triple(baseTriple);

View File

@ -127,27 +127,26 @@ static ProgramNameParts parseProgramName(StringRef programName) {
// Removes the argument from argv along with its value, if exists, and updates
// argc.
static void removeArg(llvm::opt::Arg *arg, int &argc, const char **&argv) {
static void removeArg(llvm::opt::Arg *arg, llvm::MutableArrayRef<const char*> &args) {
unsigned int numToRemove = arg->getNumValues() + 1;
unsigned int argIndex = arg->getIndex() + 1;
std::rotate(&argv[argIndex], &argv[argIndex + numToRemove], argv + argc);
argc -= numToRemove;
auto sub = args.slice(arg->getIndex() + 1);
std::rotate(sub.begin(), sub.begin() + numToRemove, sub.end());
args = args.drop_back(numToRemove);
}
static Flavor getFlavor(int &argc, const char **&argv,
static Flavor getFlavor(llvm::MutableArrayRef<const char*> &args,
std::unique_ptr<llvm::opt::InputArgList> &parsedArgs) {
if (llvm::opt::Arg *argCore = parsedArgs->getLastArg(OPT_core)) {
removeArg(argCore, argc, argv);
removeArg(argCore, args);
return Flavor::core;
}
if (llvm::opt::Arg *argFlavor = parsedArgs->getLastArg(OPT_flavor)) {
removeArg(argFlavor, argc, argv);
removeArg(argFlavor, args);
return strToFlavor(argFlavor->getValue());
}
#if LLVM_ON_UNIX
if (llvm::sys::path::filename(argv[0]).equals("ld")) {
if (llvm::sys::path::filename(args[0]).equals("ld")) {
#if __APPLE__
// On a Darwin systems, if linker binary is named "ld", use Darwin driver.
return Flavor::darwin_ld;
@ -157,13 +156,13 @@ static Flavor getFlavor(int &argc, const char **&argv,
}
#endif
StringRef name = llvm::sys::path::stem(argv[0]);
StringRef name = llvm::sys::path::stem(args[0]);
return strToFlavor(parseProgramName(name)._flavor);
}
namespace lld {
bool UniversalDriver::link(int argc, const char *argv[],
bool UniversalDriver::link(llvm::MutableArrayRef<const char*> args,
raw_ostream &diagnostics) {
// Parse command line options using GnuLdOptions.td
std::unique_ptr<llvm::opt::InputArgList> parsedArgs;
@ -172,9 +171,9 @@ bool UniversalDriver::link(int argc, const char *argv[],
unsigned missingCount;
// Program name
StringRef programName = llvm::sys::path::stem(argv[0]);
StringRef programName = llvm::sys::path::stem(args[0]);
parsedArgs.reset(table.ParseArgs(llvm::makeArrayRef(argv, argc).slice(1),
parsedArgs.reset(table.ParseArgs(args.slice(1),
missingIndex, missingCount));
if (missingCount) {
@ -197,21 +196,20 @@ bool UniversalDriver::link(int argc, const char *argv[],
return true;
}
Flavor flavor = getFlavor(argc, argv, parsedArgs);
std::vector<const char *> args(argv, argv + argc);
Flavor flavor = getFlavor(args, parsedArgs);
// Switch to appropriate driver.
switch (flavor) {
case Flavor::gnu_ld:
return GnuLdDriver::linkELF(args.size(), args.data(), diagnostics);
return GnuLdDriver::linkELF(args, diagnostics);
case Flavor::darwin_ld:
return DarwinLdDriver::linkMachO(args.size(), args.data(), diagnostics);
return DarwinLdDriver::linkMachO(args, diagnostics);
case Flavor::win_link:
return WinLinkDriver::linkPECOFF(args.size(), args.data(), diagnostics);
return WinLinkDriver::linkPECOFF(args, diagnostics);
case Flavor::win_link2:
return coff::link(args.size(), args.data());
return coff::link(args);
case Flavor::core:
return CoreDriver::link(args.size(), args.data(), diagnostics);
return CoreDriver::link(args, diagnostics);
case Flavor::invalid:
diagnostics << "Select the appropriate flavor\n";
table.PrintHelp(llvm::outs(), programName.data(), "LLVM Linker", false);

View File

@ -666,12 +666,12 @@ handleFailIfMismatchOption(StringRef option,
// Process "LINK" environment variable. If defined, the value of the variable
// should be processed as command line arguments.
static std::vector<const char *> processLinkEnv(PECOFFLinkingContext &ctx,
int argc, const char **argv) {
llvm::ArrayRef<const char*> args) {
std::vector<const char *> ret;
// The first argument is the name of the command. This should stay at the head
// of the argument list.
assert(argc > 0);
ret.push_back(argv[0]);
assert(!args.empty());
ret.push_back(args[0]);
// Add arguments specified by the LINK environment variable.
llvm::Optional<std::string> env = llvm::sys::Process::GetEnv("LINK");
@ -680,8 +680,8 @@ static std::vector<const char *> processLinkEnv(PECOFFLinkingContext &ctx,
ret.push_back(ctx.allocate(arg).data());
// Add the rest of arguments passed via the command line.
for (int i = 1; i < argc; ++i)
ret.push_back(argv[i]);
for (const char* arg : args.slice(1))
ret.push_back(arg);
ret.push_back(nullptr);
return ret;
}
@ -713,16 +713,16 @@ static bool readResponseFile(StringRef path, PECOFFLinkingContext &ctx,
// Expand arguments starting with "@". It's an error if a specified file does
// not exist. Returns true on success.
static bool expandResponseFiles(int &argc, const char **&argv,
static bool expandResponseFiles(llvm::ArrayRef<const char*> &args,
PECOFFLinkingContext &ctx, raw_ostream &diag,
bool &expanded) {
std::vector<const char *> newArgv;
for (int i = 0; i < argc; ++i) {
if (argv[i][0] != '@') {
newArgv.push_back(argv[i]);
for (const char *arg : args) {
if (arg[0] != '@') {
newArgv.push_back(arg);
continue;
}
StringRef filename = StringRef(argv[i] + 1);
StringRef filename = StringRef(arg + 1);
if (!readResponseFile(filename, ctx, newArgv)) {
diag << "error: cannot read response file: " << filename << "\n";
return false;
@ -731,20 +731,19 @@ static bool expandResponseFiles(int &argc, const char **&argv,
}
if (!expanded)
return true;
argc = newArgv.size();
newArgv.push_back(nullptr);
argv = &ctx.allocateCopy(newArgv)[0];
args = llvm::makeArrayRef(&ctx.allocateCopy(newArgv)[0], newArgv.size() - 1);
return true;
}
// Parses the given command line options and returns the result. Returns NULL if
// there's an error in the options.
static std::unique_ptr<llvm::opt::InputArgList>
parseArgs(int argc, const char **argv, PECOFFLinkingContext &ctx,
parseArgs(llvm::ArrayRef<const char*> args, PECOFFLinkingContext &ctx,
raw_ostream &diag, bool isReadingDirectiveSection) {
// Expand arguments starting with "@".
bool expanded = false;
if (!expandResponseFiles(argc, argv, ctx, diag, expanded))
if (!expandResponseFiles(args, ctx, diag, expanded))
return nullptr;
// Parse command line options using WinLinkOptions.td
@ -752,7 +751,7 @@ parseArgs(int argc, const char **argv, PECOFFLinkingContext &ctx,
WinLinkOptTable table;
unsigned missingIndex;
unsigned missingCount;
parsedArgs.reset(table.ParseArgs(llvm::makeArrayRef(argv, argc).slice(1),
parsedArgs.reset(table.ParseArgs(args.slice(1),
missingIndex, missingCount));
if (missingCount) {
diag << "error: missing arg value for '"
@ -780,8 +779,8 @@ parseArgs(int argc, const char **argv, PECOFFLinkingContext &ctx,
if (!isReadingDirectiveSection && expanded &&
parsedArgs->getLastArg(OPT_verbose)) {
diag << "Command line:";
for (int i = 0; i < argc; ++i)
diag << " " << argv[i];
for (const char *arg : args)
diag << " " << arg;
diag << "\n\n";
}
@ -802,10 +801,10 @@ static bool hasLibrary(PECOFFLinkingContext &ctx, File *file) {
// If the first command line argument is "/lib", link.exe acts as if it's
// "lib.exe" command. This is for backward compatibility.
// http://msdn.microsoft.com/en-us/library/h34w59b3.aspx
static bool maybeRunLibCommand(int argc, const char **argv, raw_ostream &diag) {
if (argc <= 1)
static bool maybeRunLibCommand(llvm::ArrayRef<const char*> args, raw_ostream &diag) {
if (args.size() <= 1)
return false;
if (!StringRef(argv[1]).equals_lower("/lib"))
if (!StringRef(args[1]).equals_lower("/lib"))
return false;
ErrorOr<std::string> pathOrErr = llvm::sys::findProgramByName("lib.exe");
if (!pathOrErr) {
@ -817,8 +816,8 @@ static bool maybeRunLibCommand(int argc, const char **argv, raw_ostream &diag) {
// Run lib.exe
std::vector<const char *> vec;
vec.push_back(path.c_str());
for (int i = 2; i < argc; ++i)
vec.push_back(argv[i]);
for (const char *arg : args.slice(2))
vec.push_back(arg);
vec.push_back(nullptr);
if (llvm::sys::ExecuteAndWait(path.c_str(), &vec[0]) != 0)
@ -840,8 +839,8 @@ void addFiles(PECOFFLinkingContext &ctx, StringRef path, raw_ostream &diag,
// Main driver
//
bool WinLinkDriver::linkPECOFF(int argc, const char **argv, raw_ostream &diag) {
if (maybeRunLibCommand(argc, argv, diag))
bool WinLinkDriver::linkPECOFF(llvm::ArrayRef<const char*> args, raw_ostream &diag) {
if (maybeRunLibCommand(args, diag))
return true;
PECOFFLinkingContext ctx;
@ -851,9 +850,9 @@ bool WinLinkDriver::linkPECOFF(int argc, const char **argv, raw_ostream &diag) {
ctx.registry().addSupportArchives(ctx.logInputFiles());
ctx.registry().addSupportYamlFiles();
std::vector<const char *> newargv = processLinkEnv(ctx, argc, argv);
std::vector<const char *> newargv = processLinkEnv(ctx, args);
processLibEnv(ctx);
if (!parse(newargv.size() - 1, &newargv[0], ctx, diag))
if (!parse(llvm::makeArrayRef(newargv).drop_back(1), ctx, diag))
return false;
// Create the file if needed.
@ -864,7 +863,7 @@ bool WinLinkDriver::linkPECOFF(int argc, const char **argv, raw_ostream &diag) {
return link(ctx, diag);
}
bool WinLinkDriver::parse(int argc, const char *argv[],
bool WinLinkDriver::parse(llvm::ArrayRef<const char*> args,
PECOFFLinkingContext &ctx, raw_ostream &diag,
bool isReadingDirectiveSection) {
// Parse may be called from multiple threads simultaneously to parse .drectve
@ -875,7 +874,7 @@ bool WinLinkDriver::parse(int argc, const char *argv[],
std::map<StringRef, StringRef> failIfMismatchMap;
// Parse the options.
std::unique_ptr<llvm::opt::InputArgList> parsedArgs =
parseArgs(argc, argv, ctx, diag, isReadingDirectiveSection);
parseArgs(args, ctx, diag, isReadingDirectiveSection);
if (!parsedArgs)
return false;
@ -886,7 +885,7 @@ bool WinLinkDriver::parse(int argc, const char *argv[],
// Handle /help
if (parsedArgs->hasArg(OPT_help)) {
WinLinkOptTable table;
table.PrintHelp(llvm::outs(), argv[0], "LLVM Linker", false);
table.PrintHelp(llvm::outs(), args[0], "LLVM Linker", false);
return false;
}

View File

@ -32,5 +32,6 @@ int main(int argc, const char *argv[]) {
llvm::PrettyStackTraceProgram stackPrinter(argc, argv);
llvm::llvm_shutdown_obj shutdown;
return UniversalDriver::link(argc, argv) ? 0 : 1;
return !UniversalDriver::link(
llvm::MutableArrayRef<const char *>(argv, argc));
}

View File

@ -51,7 +51,7 @@ protected:
// Call the parser.
raw_string_ostream os(_errorMessage);
return D::parse(vec.size(), &vec[0], _ctx, os);
return D::parse(vec, _ctx, os);
}
T _ctx;

View File

@ -25,7 +25,7 @@ TEST(UniversalDriver, flavor) {
std::string diags;
raw_string_ostream os(diags);
UniversalDriver::link(array_lengthof(args), args, os);
UniversalDriver::link(args, os);
EXPECT_EQ(os.str().find("failed to determine driver flavor"),
std::string::npos);
EXPECT_NE(os.str().find("No input files"),