summaryrefslogtreecommitdiffstats
path: root/lld
diff options
context:
space:
mode:
Diffstat (limited to 'lld')
-rw-r--r--lld/include/lld/Driver/Driver.h14
-rw-r--r--lld/lib/Driver/UniversalDriver.cpp144
-rw-r--r--lld/unittests/CMakeLists.txt10
-rw-r--r--lld/unittests/CoreTests/CMakeLists.txt3
-rw-r--r--lld/unittests/CoreTests/RangeTest.cpp (renamed from lld/unittests/RangeTest.cpp)0
-rw-r--r--lld/unittests/DriverTests/CMakeLists.txt7
-rw-r--r--lld/unittests/DriverTests/UniversalDriverTest.cpp35
7 files changed, 134 insertions, 79 deletions
diff --git a/lld/include/lld/Driver/Driver.h b/lld/include/lld/Driver/Driver.h
index 8259e71bd8c..99fdde5b3cd 100644
--- a/lld/include/lld/Driver/Driver.h
+++ b/lld/include/lld/Driver/Driver.h
@@ -48,21 +48,11 @@ 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(int argc, const char *argv[],
+ raw_ostream &diagnostics = llvm::errs());
private:
UniversalDriver() LLVM_DELETED_FUNCTION;
-
- enum class Flavor {
- invalid,
- gnu_ld, // -flavor gnu
- win_link, // -flavor link
- darwin_ld, // -flavor darwin
- core // -flavor core OR -core
- };
-
- static Flavor selectFlavor(std::vector<const char*> &args);
- static Flavor strToFlavor(StringRef str);
};
diff --git a/lld/lib/Driver/UniversalDriver.cpp b/lld/lib/Driver/UniversalDriver.cpp
index 5164f9da69c..001c354d309 100644
--- a/lld/lib/Driver/UniversalDriver.cpp
+++ b/lld/lib/Driver/UniversalDriver.cpp
@@ -14,96 +14,120 @@
//===----------------------------------------------------------------------===//
#include "lld/Driver/Driver.h"
-#include "lld/ReaderWriter/MachOTargetInfo.h"
-#include "llvm/ADT/ArrayRef.h"
+#include "lld/Core/LLVM.h"
+
#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Option/Arg.h"
-#include "llvm/Option/Option.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/FileSystem.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Host.h"
-#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Signals.h"
-
-#include <memory>
-namespace lld {
+using namespace lld;
+namespace {
+enum class Flavor {
+ invalid,
+ gnu_ld, // -flavor gnu
+ win_link, // -flavor link
+ darwin_ld, // -flavor darwin
+ core // -flavor core OR -core
+};
-bool UniversalDriver::link(int argc, const char *argv[]) {
- // Convert argv[] C-array to vector.
- std::vector<const char *> args;
- args.assign(&argv[0], &argv[argc]);
-
- // Determine flavor of link based on command name or -flavor argument.
- // Note: 'args' is modified to remove -flavor option.
- Flavor flavor = selectFlavor(args);
-
- // Switch to appropriate driver.
- switch (flavor) {
- case Flavor::gnu_ld:
- return GnuLdDriver::linkELF(args.size(), &args[0]);
- case Flavor::darwin_ld:
- return DarwinLdDriver::linkMachO(args.size(), &args[0]);
- case Flavor::core:
- return CoreDriver::link(args.size(), &args[0]);
- case Flavor::win_link:
- llvm_unreachable("Unsupported flavor");
- case Flavor::invalid:
- return true;
- }
+Flavor strToFlavor(StringRef str) {
+ return llvm::StringSwitch<Flavor>(str)
+ .Case("gnu", Flavor::gnu_ld)
+ .Case("link", Flavor::win_link)
+ .Case("darwin", Flavor::darwin_ld)
+ .Case("core", Flavor::core)
+ .Case("ld", Flavor::gnu_ld) // deprecated
+ .Default(Flavor::invalid);
}
+struct ProgramNameParts {
+ StringRef _target;
+ StringRef _flavor;
+};
+
+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;
+}
-/// Pick the flavor of driver to use based on the command line and
-/// host environment.
-UniversalDriver::Flavor UniversalDriver::selectFlavor(
- std::vector<const char*> &args) {
+Flavor selectFlavor(std::vector<const char *> &args, raw_ostream &diag) {
// -core as first arg is shorthand for -flavor core.
- if (args.size() >= 1 && StringRef(args[1]) == "-core") {
+ if (args.size() > 1 && StringRef(args[1]) == "-core") {
args.erase(args.begin() + 1);
return Flavor::core;
}
// Handle -flavor as first arg.
- if (args.size() >= 2 && StringRef(args[1]) == "-flavor") {
+ if (args.size() > 2 && StringRef(args[1]) == "-flavor") {
Flavor flavor = strToFlavor(args[2]);
args.erase(args.begin() + 1);
args.erase(args.begin() + 1);
if (flavor == Flavor::invalid)
- llvm::errs() << "error: '" << args[2] << "' invalid value for -flavor.\n";
+ diag << "error: '" << args[2] << "' invalid value for -flavor.\n";
return flavor;
}
- // Check if flavor is at end of program name (e.g. "lld-gnu");
- SmallVector<StringRef, 3> components;
- llvm::SplitString(args[0], components, "-");
- Flavor flavor = strToFlavor(components.back());
-
+ Flavor flavor =
+ strToFlavor(parseProgramName(llvm::sys::path::stem(args[0]))._flavor);
+
// If flavor still undetermined, then error out.
if (flavor == Flavor::invalid)
- llvm::errs() << "error: failed to determine driver flavor from program name"
- " '" << args[0] << "'.\n";
+ diag << "error: failed to determine driver flavor from program name"
+ " '" << args[0] << "'.\n";
return flavor;
}
-
-/// Maps flavor strings to Flavor enum values.
-UniversalDriver::Flavor UniversalDriver::strToFlavor(StringRef str) {
- return llvm::StringSwitch<Flavor>(str)
- .Case("gnu", Flavor::gnu_ld)
- .Case("darwin", Flavor::darwin_ld)
- .Case("link", Flavor::win_link)
- .Case("core", Flavor::core)
- .Case("ld", Flavor::gnu_ld) // deprecated
- .Default(Flavor::invalid);
}
+namespace lld {
+bool UniversalDriver::link(int argc, const char *argv[],
+ raw_ostream &diagnostics) {
+ // Convert argv[] C-array to vector.
+ std::vector<const char *> args(argv, argv + argc);
+
+ // Determine flavor of link based on command name or -flavor argument.
+ // Note: 'args' is modified to remove -flavor option.
+ Flavor flavor = selectFlavor(args, diagnostics);
-} // namespace lld
+ // Switch to appropriate driver.
+ switch (flavor) {
+ case Flavor::gnu_ld:
+ return GnuLdDriver::linkELF(args.size(), args.data(), diagnostics);
+ case Flavor::darwin_ld:
+ return DarwinLdDriver::linkMachO(args.size(), args.data(), diagnostics);
+ case Flavor::core:
+ return CoreDriver::link(args.size(), args.data(), diagnostics);
+ case Flavor::win_link:
+ llvm_unreachable("Unsupported flavor");
+ case Flavor::invalid:
+ return true;
+ }
+}
+} // end namespace lld
diff --git a/lld/unittests/CMakeLists.txt b/lld/unittests/CMakeLists.txt
index d2535e371d9..53b699f111e 100644
--- a/lld/unittests/CMakeLists.txt
+++ b/lld/unittests/CMakeLists.txt
@@ -7,12 +7,8 @@ set_target_properties(LLDUnitTests PROPERTIES FOLDER "lld tests")
# Produces a binary named 'basename(test_dirname)'.
function(add_lld_unittest test_dirname)
add_unittest(LLDUnitTests ${test_dirname} ${ARGN})
+ target_link_libraries(${test_dirname} ${LLVM_COMMON_LIBS})
endfunction()
-set(LLVM_LINK_COMPONENTS
- support
- )
-
-add_lld_unittest(CoreTests
- RangeTest.cpp
- )
+add_subdirectory(CoreTests)
+add_subdirectory(DriverTests)
diff --git a/lld/unittests/CoreTests/CMakeLists.txt b/lld/unittests/CoreTests/CMakeLists.txt
new file mode 100644
index 00000000000..5da6ee3800c
--- /dev/null
+++ b/lld/unittests/CoreTests/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_lld_unittest(CoreTests
+ RangeTest.cpp
+ )
diff --git a/lld/unittests/RangeTest.cpp b/lld/unittests/CoreTests/RangeTest.cpp
index eb446a68b46..eb446a68b46 100644
--- a/lld/unittests/RangeTest.cpp
+++ b/lld/unittests/CoreTests/RangeTest.cpp
diff --git a/lld/unittests/DriverTests/CMakeLists.txt b/lld/unittests/DriverTests/CMakeLists.txt
new file mode 100644
index 00000000000..bb7fa9701f1
--- /dev/null
+++ b/lld/unittests/DriverTests/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_lld_unittest(DriverTests
+ UniversalDriverTest.cpp
+ )
+
+target_link_libraries(DriverTests
+ lldDriver
+ )
diff --git a/lld/unittests/DriverTests/UniversalDriverTest.cpp b/lld/unittests/DriverTests/UniversalDriverTest.cpp
new file mode 100644
index 00000000000..e2fb1f25e21
--- /dev/null
+++ b/lld/unittests/DriverTests/UniversalDriverTest.cpp
@@ -0,0 +1,35 @@
+//===- lld/unittest/UniversalDriverTest.cpp -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Universal driver tests that depend on the value of argv[0].
+///
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include "lld/Driver/Driver.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+using namespace lld;
+
+TEST(UniversalDriver, flavor) {
+ const char *args[] = { "ld" };
+
+ std::string diags;
+ raw_string_ostream os(diags);
+ UniversalDriver::link(array_lengthof(args), args, os);
+ EXPECT_EQ(os.str().find("failed to determine driver flavor"),
+ std::string::npos);
+ EXPECT_NE(os.str().find("No input files"),
+ std::string::npos);
+}
OpenPOWER on IntegriCloud