summaryrefslogtreecommitdiffstats
path: root/lib/Driver/ToolChains.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Driver/ToolChains.cpp')
-rw-r--r--lib/Driver/ToolChains.cpp145
1 files changed, 111 insertions, 34 deletions
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 42657d9..a9c6a68 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -47,6 +47,69 @@ Darwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple,
IPhoneOSVersionMin = "3.0";
}
+// FIXME: Can we tablegen this?
+static const char *GetArmArchForMArch(llvm::StringRef Value) {
+ if (Value == "armv6k")
+ return "armv6";
+
+ if (Value == "armv5tej")
+ return "armv5";
+
+ if (Value == "xscale")
+ return "xscale";
+
+ if (Value == "armv4t")
+ return "armv4t";
+
+ if (Value == "armv7" || Value == "armv7-a" || Value == "armv7-r" ||
+ Value == "armv7-m" || Value == "armv7a" || Value == "armv7r" ||
+ Value == "armv7m")
+ return "armv7";
+
+ return 0;
+}
+
+// FIXME: Can we tablegen this?
+static const char *GetArmArchForMCpu(llvm::StringRef Value) {
+ if (Value == "arm10tdmi" || Value == "arm1020t" || Value == "arm9e" ||
+ Value == "arm946e-s" || Value == "arm966e-s" ||
+ Value == "arm968e-s" || Value == "arm10e" ||
+ Value == "arm1020e" || Value == "arm1022e" || Value == "arm926ej-s" ||
+ Value == "arm1026ej-s")
+ return "armv5";
+
+ if (Value == "xscale")
+ return "xscale";
+
+ if (Value == "arm1136j-s" || Value == "arm1136jf-s" ||
+ Value == "arm1176jz-s" || Value == "arm1176jzf-s")
+ return "armv6";
+
+ if (Value == "cortex-a8" || Value == "cortex-r4" || Value == "cortex-m3")
+ return "armv7";
+
+ return 0;
+}
+
+llvm::StringRef Darwin::getDarwinArchName(const ArgList &Args) const {
+ switch (getTriple().getArch()) {
+ default:
+ return getArchName();
+
+ case llvm::Triple::arm: {
+ if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
+ if (const char *Arch = GetArmArchForMArch(A->getValue(Args)))
+ return Arch;
+
+ if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+ if (const char *Arch = GetArmArchForMCpu(A->getValue(Args)))
+ return Arch;
+
+ return "arm";
+ }
+ }
+}
+
DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple,
const unsigned (&DarwinVersion)[3],
const unsigned (&_GCCVersion)[3], bool IsIPhoneOS)
@@ -118,10 +181,6 @@ DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple,
Path += ToolChainDir;
getProgramPaths().push_back(Path);
- Path = getDriver().Dir;
- Path += "/../libexec";
- getProgramPaths().push_back(Path);
-
getProgramPaths().push_back(getDriver().Dir);
}
@@ -235,13 +294,6 @@ DarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple,
bool IsIPhoneOS)
: Darwin(Host, Triple, DarwinVersion, IsIPhoneOS)
{
- // Add the relative libexec dir (for clang-cc).
- //
- // FIXME: We should sink clang-cc into libexec/clang/<version>/.
- std::string Path = getDriver().Dir;
- Path += "/../libexec";
- getProgramPaths().push_back(Path);
-
// We expect 'as', 'ld', etc. to be adjacent to our install dir.
getProgramPaths().push_back(getDriver().Dir);
}
@@ -253,12 +305,10 @@ void DarwinClang::AddLinkSearchPathArgs(const ArgList &Args,
void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
- // Check for static linking.
- if (Args.hasArg(options::OPT_static)) {
- // FIXME: We need to have compiler-rt available (perhaps as
- // libclang_static.a) to link against.
+ // Darwin doesn't support real static executables, don't link any runtime
+ // libraries with -static.
+ if (Args.hasArg(options::OPT_static))
return;
- }
// Reject -static-libgcc for now, we can deal with this when and if someone
// cares. This is useful in situations where someone wants to statically link
@@ -269,12 +319,52 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
return;
}
- // Otherwise link libSystem, which should have the support routines.
- //
- // FIXME: This is only true for 10.6 and beyond. Legacy support isn't
- // critical, but it should work... we should just link in the static
- // compiler-rt library.
+ // Otherwise link libSystem, then the dynamic runtime library, and finally any
+ // target specific static runtime library.
CmdArgs.push_back("-lSystem");
+
+ // Select the dynamic runtime library and the target specific static library.
+ const char *DarwinStaticLib = 0;
+ if (isIPhoneOS()) {
+ CmdArgs.push_back("-lgcc_s.1");
+
+ // We may need some static functions for armv6/thumb which are required to
+ // be in the same linkage unit as their caller.
+ if (getDarwinArchName(Args) == "armv6")
+ DarwinStaticLib = "libclang_rt.armv6.a";
+ } else {
+ unsigned MacosxVersionMin[3];
+ getMacosxVersionMin(Args, MacosxVersionMin);
+
+ // The dynamic runtime library was merged with libSystem for 10.6 and
+ // beyond; only 10.4 and 10.5 need an additional runtime library.
+ if (isMacosxVersionLT(MacosxVersionMin, 10, 5))
+ CmdArgs.push_back("-lgcc_s.10.4");
+ else if (isMacosxVersionLT(MacosxVersionMin, 10, 6))
+ CmdArgs.push_back("-lgcc_s.10.5");
+
+ // For OS X, we only need a static runtime library when targetting 10.4, to
+ // provide versions of the static functions which were omitted from
+ // 10.4.dylib.
+ if (isMacosxVersionLT(MacosxVersionMin, 10, 5))
+ DarwinStaticLib = "libclang_rt.10.4.a";
+ }
+
+ /// Add the target specific static library, if needed.
+ if (DarwinStaticLib) {
+ llvm::sys::Path P(getDriver().ResourceDir);
+ P.appendComponent("lib");
+ P.appendComponent("darwin");
+ P.appendComponent(DarwinStaticLib);
+
+ // For now, allow missing resource libraries to support developers who may
+ // not have compiler-rt checked out or integrated into their build.
+ if (!P.exists())
+ getDriver().Diag(clang::diag::warn_drv_missing_resource_library)
+ << P.str();
+ else
+ CmdArgs.push_back(Args.MakeArgString(P.str()));
+ }
}
void Darwin::getMacosxVersionMin(const ArgList &Args,
@@ -544,10 +634,6 @@ const char *Darwin::GetForcedPicModel() const {
Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
: ToolChain(Host, Triple) {
- std::string Path(getDriver().Dir);
- Path += "/../libexec";
- getProgramPaths().push_back(Path);
-
getProgramPaths().push_back(getDriver().Dir);
}
@@ -684,11 +770,6 @@ Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple)
: Generic_GCC(Host, Triple) {
- // Path mangling to find libexec
- std::string Path(getDriver().Dir);
-
- Path += "/../libexec";
- getProgramPaths().push_back(Path);
getProgramPaths().push_back(getDriver().Dir);
getFilePaths().push_back(getDriver().Dir + "/../lib");
@@ -753,10 +834,6 @@ DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple)
: Generic_GCC(Host, Triple) {
// Path mangling to find libexec
- std::string Path(getDriver().Dir);
-
- Path += "/../libexec";
- getProgramPaths().push_back(Path);
getProgramPaths().push_back(getDriver().Dir);
getFilePaths().push_back(getDriver().Dir + "/../lib");
OpenPOWER on IntegriCloud