summaryrefslogtreecommitdiff
path: root/lib/Driver/UniversalDriver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Driver/UniversalDriver.cpp')
-rw-r--r--lib/Driver/UniversalDriver.cpp71
1 files changed, 39 insertions, 32 deletions
diff --git a/lib/Driver/UniversalDriver.cpp b/lib/Driver/UniversalDriver.cpp
index 7d42ad7b4bfc0..3dea7ebfae894 100644
--- a/lib/Driver/UniversalDriver.cpp
+++ b/lib/Driver/UniversalDriver.cpp
@@ -63,15 +63,16 @@ static const llvm::opt::OptTable::Info infoTable[] = {
class UniversalDriverOptTable : public llvm::opt::OptTable {
public:
UniversalDriverOptTable()
- : OptTable(infoTable, llvm::array_lengthof(infoTable)) {}
+ : OptTable(infoTable) {}
};
enum class Flavor {
invalid,
- gnu_ld, // -flavor gnu
- win_link, // -flavor link
- darwin_ld, // -flavor darwin
- core // -flavor core OR -core
+ old_gnu_ld, // -flavor old-gnu
+ gnu_ld, // -flavor gnu
+ win_link, // -flavor link
+ darwin_ld, // -flavor darwin
+ core // -flavor core OR -core
};
struct ProgramNameParts {
@@ -83,7 +84,9 @@ struct ProgramNameParts {
static Flavor strToFlavor(StringRef str) {
return llvm::StringSwitch<Flavor>(str)
+ .Case("old-gnu", Flavor::old_gnu_ld)
.Case("gnu", Flavor::gnu_ld)
+ .Case("ld.lld", Flavor::gnu_ld)
.Case("link", Flavor::win_link)
.Case("lld-link", Flavor::win_link)
.Case("darwin", Flavor::darwin_ld)
@@ -124,27 +127,27 @@ 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,
- std::unique_ptr<llvm::opt::InputArgList> &parsedArgs) {
- if (llvm::opt::Arg *argCore = parsedArgs->getLastArg(OPT_core)) {
- removeArg(argCore, argc, argv);
+static Flavor getFlavor(llvm::MutableArrayRef<const char *> &args,
+ const llvm::opt::InputArgList &parsedArgs) {
+ if (llvm::opt::Arg *argCore = parsedArgs.getLastArg(OPT_core)) {
+ removeArg(argCore, args);
return Flavor::core;
}
- if (llvm::opt::Arg *argFlavor = parsedArgs->getLastArg(OPT_flavor)) {
- removeArg(argFlavor, argc, argv);
+ if (llvm::opt::Arg *argFlavor = parsedArgs.getLastArg(OPT_flavor)) {
+ 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;
@@ -154,59 +157,63 @@ static Flavor getFlavor(int &argc, const char **&argv,
}
#endif
- StringRef name = llvm::sys::path::stem(argv[0]);
+ StringRef name = llvm::sys::path::filename(args[0]);
+ if (name.endswith_lower(".exe"))
+ name = llvm::sys::path::stem(name);
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;
UniversalDriverOptTable table;
unsigned missingIndex;
unsigned missingCount;
// Program name
- StringRef programName = llvm::sys::path::stem(argv[0]);
+ StringRef programName = llvm::sys::path::stem(args[0]);
- parsedArgs.reset(
- table.ParseArgs(&argv[1], &argv[argc], missingIndex, missingCount));
+ llvm::opt::InputArgList parsedArgs =
+ table.ParseArgs(args.slice(1), missingIndex, missingCount);
if (missingCount) {
diagnostics << "error: missing arg value for '"
- << parsedArgs->getArgString(missingIndex) << "' expected "
+ << parsedArgs.getArgString(missingIndex) << "' expected "
<< missingCount << " argument(s).\n";
return false;
}
// Handle -help
- if (parsedArgs->getLastArg(OPT_help)) {
+ if (parsedArgs.getLastArg(OPT_help)) {
table.PrintHelp(llvm::outs(), programName.data(), "LLVM Linker", false);
return true;
}
// Handle -version
- if (parsedArgs->getLastArg(OPT_version)) {
+ if (parsedArgs.getLastArg(OPT_version)) {
diagnostics << "LLVM Linker Version: " << getLLDVersion()
<< getLLDRepositoryVersion() << "\n";
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::old_gnu_ld:
+ return GnuLdDriver::linkELF(args, diagnostics);
case Flavor::gnu_ld:
- return GnuLdDriver::linkELF(args.size(), args.data(), diagnostics);
+ elf2::link(args);
+ return true;
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);
+ coff::link(args);
+ return true;
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);