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.cpp225
1 files changed, 0 insertions, 225 deletions
diff --git a/lib/Driver/UniversalDriver.cpp b/lib/Driver/UniversalDriver.cpp
deleted file mode 100644
index 3dea7ebfae89..000000000000
--- a/lib/Driver/UniversalDriver.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-//===- lib/Driver/UniversalDriver.cpp -------------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-///
-/// Driver for "universal" lld tool which can mimic any linker command line
-/// parsing once it figures out which command line flavor to use.
-///
-//===----------------------------------------------------------------------===//
-
-#include "lld/Driver/Driver.h"
-#include "lld/Config/Version.h"
-#include "lld/Core/LLVM.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Option/Arg.h"
-#include "llvm/Option/Option.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace lld;
-
-namespace {
-
-// Create enum with OPT_xxx values for each option in GnuLdOptions.td
-enum {
- OPT_INVALID = 0,
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELP, META) \
- OPT_##ID,
-#include "UniversalDriverOptions.inc"
-#undef OPTION
-};
-
-// Create prefix string literals used in GnuLdOptions.td
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
-#include "UniversalDriverOptions.inc"
-#undef PREFIX
-
-// Create table mapping all options defined in GnuLdOptions.td
-static const llvm::opt::OptTable::Info infoTable[] = {
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR) \
- { \
- PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
- PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS \
- } \
- ,
-#include "UniversalDriverOptions.inc"
-#undef OPTION
-};
-
-// Create OptTable class for parsing actual command line arguments
-class UniversalDriverOptTable : public llvm::opt::OptTable {
-public:
- UniversalDriverOptTable()
- : OptTable(infoTable) {}
-};
-
-enum class Flavor {
- invalid,
- 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 {
- StringRef _target;
- StringRef _flavor;
-};
-
-} // anonymous namespace
-
-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)
- .Case("core", Flavor::core)
- .Case("ld", Flavor::gnu_ld)
- .Default(Flavor::invalid);
-}
-
-static ProgramNameParts parseProgramName(StringRef programName) {
- SmallVector<StringRef, 3> components;
- llvm::SplitString(programName, components, "-");
- ProgramNameParts ret;
-
- using std::begin;
- using std::end;
-
- // Erase any lld components.
- components.erase(std::remove(components.begin(), components.end(), "lld"),
- components.end());
-
- // Find the flavor component.
- auto flIter = std::find_if(components.begin(), components.end(),
- [](StringRef str) -> bool {
- return strToFlavor(str) != Flavor::invalid;
- });
-
- if (flIter != components.end()) {
- ret._flavor = *flIter;
- components.erase(flIter);
- }
-
- // Any remaining component must be the target.
- if (components.size() == 1)
- ret._target = components[0];
-
- return ret;
-}
-
-// Removes the argument from argv along with its value, if exists, and updates
-// argc.
-static void removeArg(llvm::opt::Arg *arg,
- llvm::MutableArrayRef<const char *> &args) {
- unsigned int numToRemove = arg->getNumValues() + 1;
- auto sub = args.slice(arg->getIndex() + 1);
- std::rotate(sub.begin(), sub.begin() + numToRemove, sub.end());
- args = args.drop_back(numToRemove);
-}
-
-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, args);
- return strToFlavor(argFlavor->getValue());
- }
-
-#if LLVM_ON_UNIX
- 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;
-#endif
- // On a ELF based systems, if linker binary is named "ld", use gnu driver.
- return Flavor::gnu_ld;
- }
-#endif
-
- 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(llvm::MutableArrayRef<const char *> args,
- raw_ostream &diagnostics) {
- // Parse command line options using GnuLdOptions.td
- UniversalDriverOptTable table;
- unsigned missingIndex;
- unsigned missingCount;
-
- // Program name
- StringRef programName = llvm::sys::path::stem(args[0]);
-
- llvm::opt::InputArgList parsedArgs =
- table.ParseArgs(args.slice(1), missingIndex, missingCount);
-
- if (missingCount) {
- diagnostics << "error: missing arg value for '"
- << parsedArgs.getArgString(missingIndex) << "' expected "
- << missingCount << " argument(s).\n";
- return false;
- }
-
- // Handle -help
- if (parsedArgs.getLastArg(OPT_help)) {
- table.PrintHelp(llvm::outs(), programName.data(), "LLVM Linker", false);
- return true;
- }
-
- // Handle -version
- if (parsedArgs.getLastArg(OPT_version)) {
- diagnostics << "LLVM Linker Version: " << getLLDVersion()
- << getLLDRepositoryVersion() << "\n";
- return true;
- }
-
- 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:
- elf2::link(args);
- return true;
- case Flavor::darwin_ld:
- return DarwinLdDriver::linkMachO(args, diagnostics);
- case Flavor::win_link:
- coff::link(args);
- return true;
- case Flavor::core:
- return CoreDriver::link(args, diagnostics);
- case Flavor::invalid:
- diagnostics << "Select the appropriate flavor\n";
- table.PrintHelp(llvm::outs(), programName.data(), "LLVM Linker", false);
- return false;
- }
- llvm_unreachable("Unrecognised flavor");
-}
-
-} // end namespace lld