diff options
Diffstat (limited to 'lib/Driver/UniversalDriver.cpp')
| -rw-r--r-- | lib/Driver/UniversalDriver.cpp | 71 |
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); |
