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.cpp338
1 files changed, 191 insertions, 147 deletions
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 7f9ed9a..01c6623 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -14,10 +14,10 @@
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
-#include "clang/Driver/ObjCRuntime.h"
#include "clang/Driver/OptTable.h"
#include "clang/Driver/Option.h"
#include "clang/Driver/Options.h"
+#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Version.h"
#include "llvm/ADT/SmallString.h"
@@ -42,9 +42,7 @@ using namespace clang;
/// Darwin - Darwin tool chain for i386 and x86_64.
Darwin::Darwin(const Driver &D, const llvm::Triple& Triple)
- : ToolChain(D, Triple), TargetInitialized(false),
- ARCRuntimeForSimulator(ARCSimulator_None),
- LibCXXForSimulator(LibCXXSimulator_None)
+ : ToolChain(D, Triple), TargetInitialized(false)
{
// Compute the initial Darwin version from the triple
unsigned Major, Minor, Micro;
@@ -59,6 +57,11 @@ Darwin::Darwin(const Driver &D, const llvm::Triple& Triple)
DarwinVersion[0] = Minor + 4;
DarwinVersion[1] = Micro;
DarwinVersion[2] = 0;
+
+ // Compute the initial iOS version from the triple
+ Triple.getiOSVersion(Major, Minor, Micro);
+ llvm::raw_string_ostream(iOSVersionMin)
+ << Major << '.' << Minor << '.' << Micro;
}
types::ID Darwin::LookupTypeForExtension(const char *Ext) const {
@@ -75,42 +78,19 @@ bool Darwin::HasNativeLLVMSupport() const {
return true;
}
-bool Darwin::hasARCRuntime() const {
- // FIXME: Remove this once there is a proper way to detect an ARC runtime
- // for the simulator.
- switch (ARCRuntimeForSimulator) {
- case ARCSimulator_None:
- break;
- case ARCSimulator_HasARCRuntime:
- return true;
- case ARCSimulator_NoARCRuntime:
- return false;
- }
-
- if (isTargetIPhoneOS())
- return !isIPhoneOSVersionLT(5);
- else
- return !isMacosxVersionLT(10, 7);
-}
-
-bool Darwin::hasSubscriptingRuntime() const {
- return !isTargetIPhoneOS() && !isMacosxVersionLT(10, 8);
-}
-
/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
-void Darwin::configureObjCRuntime(ObjCRuntime &runtime) const {
- if (runtime.getKind() != ObjCRuntime::NeXT)
- return ToolChain::configureObjCRuntime(runtime);
-
- runtime.HasARC = runtime.HasWeak = hasARCRuntime();
- runtime.HasSubscripting = hasSubscriptingRuntime();
-
- // So far, objc_terminate is only available in iOS 5.
- // FIXME: do the simulator logic properly.
- if (!ARCRuntimeForSimulator && isTargetIPhoneOS())
- runtime.HasTerminate = !isIPhoneOSVersionLT(5);
- else
- runtime.HasTerminate = false;
+ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {
+ if (isTargetIPhoneOS()) {
+ return ObjCRuntime(ObjCRuntime::iOS, TargetVersion);
+ } else if (TargetSimulatorVersionFromDefines != VersionTuple()) {
+ return ObjCRuntime(ObjCRuntime::iOS, TargetSimulatorVersionFromDefines);
+ } else {
+ if (isNonFragile) {
+ return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion);
+ } else {
+ return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion);
+ }
+ }
}
/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
@@ -194,21 +174,25 @@ void Generic_ELF::anchor() {}
Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const {
- Action::ActionClass Key;
+ Action::ActionClass Key = JA.getKind();
+ bool useClang = false;
if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) {
+ useClang = true;
// Fallback to llvm-gcc for i386 kext compiles, we don't support that ABI.
- if (Inputs.size() == 1 &&
+ if (!getDriver().shouldForceClangUse() &&
+ Inputs.size() == 1 &&
types::isCXX(Inputs[0]->getType()) &&
getTriple().isOSDarwin() &&
getTriple().getArch() == llvm::Triple::x86 &&
(C.getArgs().getLastArg(options::OPT_fapple_kext) ||
C.getArgs().getLastArg(options::OPT_mkernel)))
- Key = JA.getKind();
- else
- Key = Action::AnalyzeJobClass;
- } else
- Key = JA.getKind();
+ useClang = false;
+ }
+
+ // FIXME: This seems like a hacky way to choose clang frontend.
+ if (useClang)
+ Key = Action::AnalyzeJobClass;
bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
options::OPT_no_integrated_as,
@@ -287,76 +271,6 @@ void DarwinClang::AddGCCLibexecPath(unsigned darwinVersion) {
getProgramPaths().push_back(Path);
}
-void DarwinClang::AddLinkSearchPathArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const {
- // The Clang toolchain uses explicit paths for internal libraries.
-
- // Unfortunately, we still might depend on a few of the libraries that are
- // only available in the gcc library directory (in particular
- // libstdc++.dylib). For now, hardcode the path to the known install location.
- // FIXME: This should get ripped out someday. However, when building on
- // 10.6 (darwin10), we're still relying on this to find libstdc++.dylib.
- llvm::sys::Path P(getDriver().Dir);
- P.eraseComponent(); // .../usr/bin -> ../usr
- P.appendComponent("llvm-gcc-4.2");
- P.appendComponent("lib");
- P.appendComponent("gcc");
- switch (getTriple().getArch()) {
- default:
- llvm_unreachable("Invalid Darwin arch!");
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- P.appendComponent("i686-apple-darwin10");
- break;
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- P.appendComponent("arm-apple-darwin10");
- break;
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- P.appendComponent("powerpc-apple-darwin10");
- break;
- }
- P.appendComponent("4.2.1");
-
- // Determine the arch specific GCC subdirectory.
- const char *ArchSpecificDir = 0;
- switch (getTriple().getArch()) {
- default:
- break;
- case llvm::Triple::arm:
- case llvm::Triple::thumb: {
- std::string Triple = ComputeLLVMTriple(Args);
- StringRef TripleStr = Triple;
- if (TripleStr.startswith("armv5") || TripleStr.startswith("thumbv5"))
- ArchSpecificDir = "v5";
- else if (TripleStr.startswith("armv6") || TripleStr.startswith("thumbv6"))
- ArchSpecificDir = "v6";
- else if (TripleStr.startswith("armv7") || TripleStr.startswith("thumbv7"))
- ArchSpecificDir = "v7";
- break;
- }
- case llvm::Triple::ppc64:
- ArchSpecificDir = "ppc64";
- break;
- case llvm::Triple::x86_64:
- ArchSpecificDir = "x86_64";
- break;
- }
-
- if (ArchSpecificDir) {
- P.appendComponent(ArchSpecificDir);
- bool Exists;
- if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
- CmdArgs.push_back(Args.MakeArgString("-L" + P.str()));
- P.eraseComponent();
- }
-
- bool Exists;
- if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
- CmdArgs.push_back(Args.MakeArgString("-L" + P.str()));
-}
-
void DarwinClang::AddLinkARCArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
@@ -374,7 +288,7 @@ void DarwinClang::AddLinkARCArgs(const ArgList &Args,
else if (isTargetIPhoneOS())
s += "iphoneos";
// FIXME: Remove this once we depend fully on -mios-simulator-version-min.
- else if (ARCRuntimeForSimulator != ARCSimulator_None)
+ else if (TargetSimulatorVersionFromDefines != VersionTuple())
s += "iphonesimulator";
else
s += "macosx";
@@ -545,11 +459,13 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
unsigned Major = 0, Minor = 0, Micro = 0;
if (GetVersionFromSimulatorDefine(define, Major, Minor, Micro) &&
Major < 10 && Minor < 100 && Micro < 100) {
- ARCRuntimeForSimulator = Major < 5 ? ARCSimulator_NoARCRuntime
- : ARCSimulator_HasARCRuntime;
- LibCXXForSimulator = Major < 5 ? LibCXXSimulator_NotAvailable
- : LibCXXSimulator_Available;
+ TargetSimulatorVersionFromDefines = VersionTuple(Major, Minor, Micro);
}
+ // When using the define to indicate the simulator, we force
+ // 10.6 macosx target.
+ const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
+ OSXVersion = Args.MakeJoinedArg(0, O, "10.6");
+ Args.append(OSXVersion);
break;
}
}
@@ -593,9 +509,9 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
// If no OSX or iOS target has been specified and we're compiling for armv7,
// go ahead as assume we're targeting iOS.
- if (OSXTarget.empty() && iOSTarget.empty())
- if (getDarwinArchName(Args) == "armv7")
- iOSTarget = "0.0";
+ if (OSXTarget.empty() && iOSTarget.empty() &&
+ getDarwinArchName(Args) == "armv7")
+ iOSTarget = iOSVersionMin;
// Handle conflicting deployment targets
//
@@ -956,27 +872,27 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
// Add an explicit version min argument for the deployment target. We do this
// after argument translation because -Xarch_ arguments may add a version min
// argument.
- AddDeploymentTarget(*DAL);
+ if (BoundArch)
+ AddDeploymentTarget(*DAL);
// Validate the C++ standard library choice.
CXXStdlibType Type = GetCXXStdlibType(*DAL);
if (Type == ToolChain::CST_Libcxx) {
- switch (LibCXXForSimulator) {
- case LibCXXSimulator_None:
- // Handle non-simulator cases.
- if (isTargetIPhoneOS()) {
- if (isIPhoneOSVersionLT(5, 0)) {
- getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment)
- << "iOS 5.0";
- }
- }
- break;
- case LibCXXSimulator_NotAvailable:
+ // Check whether the target provides libc++.
+ StringRef where;
+
+ // Complain about targetting iOS < 5.0 in any way.
+ if (TargetSimulatorVersionFromDefines != VersionTuple()) {
+ if (TargetSimulatorVersionFromDefines < VersionTuple(5, 0))
+ where = "iOS 5.0";
+ } else if (isTargetIPhoneOS()) {
+ if (isIPhoneOSVersionLT(5, 0))
+ where = "iOS 5.0";
+ }
+
+ if (where != StringRef()) {
getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment)
- << "iOS 5.0";
- break;
- case LibCXXSimulator_Available:
- break;
+ << where;
}
}
@@ -1187,6 +1103,9 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
"arm-linux-gnueabi",
"arm-linux-androideabi"
};
+ static const char *const ARMHFTriples[] = {
+ "arm-linux-gnueabihf",
+ };
static const char *const X86_64LibDirs[] = { "/lib64", "/lib" };
static const char *const X86_64Triples[] = {
@@ -1210,7 +1129,8 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
"i586-redhat-linux",
"i386-redhat-linux",
"i586-suse-linux",
- "i486-slackware-linux"
+ "i486-slackware-linux",
+ "i686-montavista-linux"
};
static const char *const MIPSLibDirs[] = { "/lib" };
@@ -1218,11 +1138,17 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
static const char *const MIPSELLibDirs[] = { "/lib" };
static const char *const MIPSELTriples[] = { "mipsel-linux-gnu" };
+ static const char *const MIPS64LibDirs[] = { "/lib64", "/lib" };
+ static const char *const MIPS64Triples[] = { "mips64-linux-gnu" };
+ static const char *const MIPS64ELLibDirs[] = { "/lib64", "/lib" };
+ static const char *const MIPS64ELTriples[] = { "mips64el-linux-gnu" };
+
static const char *const PPCLibDirs[] = { "/lib32", "/lib" };
static const char *const PPCTriples[] = {
"powerpc-linux-gnu",
"powerpc-unknown-linux-gnu",
- "powerpc-suse-linux"
+ "powerpc-suse-linux",
+ "powerpc-montavista-linuxspe"
};
static const char *const PPC64LibDirs[] = { "/lib64", "/lib" };
static const char *const PPC64Triples[] = {
@@ -1236,8 +1162,13 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
case llvm::Triple::arm:
case llvm::Triple::thumb:
LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs));
- TripleAliases.append(
- ARMTriples, ARMTriples + llvm::array_lengthof(ARMTriples));
+ if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
+ TripleAliases.append(
+ ARMHFTriples, ARMHFTriples + llvm::array_lengthof(ARMHFTriples));
+ } else {
+ TripleAliases.append(
+ ARMTriples, ARMTriples + llvm::array_lengthof(ARMTriples));
+ }
break;
case llvm::Triple::x86_64:
LibDirs.append(
@@ -1263,12 +1194,40 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
MIPSLibDirs, MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs));
TripleAliases.append(
MIPSTriples, MIPSTriples + llvm::array_lengthof(MIPSTriples));
+ MultiarchLibDirs.append(
+ MIPS64LibDirs, MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs));
+ MultiarchTripleAliases.append(
+ MIPS64Triples, MIPS64Triples + llvm::array_lengthof(MIPS64Triples));
break;
case llvm::Triple::mipsel:
LibDirs.append(
MIPSELLibDirs, MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs));
TripleAliases.append(
MIPSELTriples, MIPSELTriples + llvm::array_lengthof(MIPSELTriples));
+ MultiarchLibDirs.append(
+ MIPS64ELLibDirs, MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs));
+ MultiarchTripleAliases.append(
+ MIPS64ELTriples, MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples));
+ break;
+ case llvm::Triple::mips64:
+ LibDirs.append(
+ MIPS64LibDirs, MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs));
+ TripleAliases.append(
+ MIPS64Triples, MIPS64Triples + llvm::array_lengthof(MIPS64Triples));
+ MultiarchLibDirs.append(
+ MIPSLibDirs, MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs));
+ MultiarchTripleAliases.append(
+ MIPSTriples, MIPSTriples + llvm::array_lengthof(MIPSTriples));
+ break;
+ case llvm::Triple::mips64el:
+ LibDirs.append(
+ MIPS64ELLibDirs, MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs));
+ TripleAliases.append(
+ MIPS64ELTriples, MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples));
+ MultiarchLibDirs.append(
+ MIPSELLibDirs, MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs));
+ MultiarchTripleAliases.append(
+ MIPSELTriples, MIPSELTriples + llvm::array_lengthof(MIPSELTriples));
break;
case llvm::Triple::ppc:
LibDirs.append(PPCLibDirs, PPCLibDirs + llvm::array_lengthof(PPCLibDirs));
@@ -1350,7 +1309,9 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
// crtbegin.o without the subdirectory.
StringRef MultiarchSuffix
= (TargetArch == llvm::Triple::x86_64 ||
- TargetArch == llvm::Triple::ppc64) ? "/64" : "/32";
+ TargetArch == llvm::Triple::ppc64 ||
+ TargetArch == llvm::Triple::mips64 ||
+ TargetArch == llvm::Triple::mips64el) ? "/64" : "/32";
if (llvm::sys::fs::exists(LI->path() + MultiarchSuffix + "/crtbegin.o")) {
GCCMultiarchSuffix = MultiarchSuffix.str();
} else {
@@ -1606,6 +1567,67 @@ Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA,
return *T;
}
+/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly.
+
+Bitrig::Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
+ : Generic_ELF(D, Triple, Args) {
+ getFilePaths().push_back(getDriver().Dir + "/../lib");
+ getFilePaths().push_back("/usr/lib");
+}
+
+Tool &Bitrig::SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const {
+ Action::ActionClass Key;
+ if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+ Key = Action::AnalyzeJobClass;
+ else
+ Key = JA.getKind();
+
+ bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
+ options::OPT_no_integrated_as,
+ IsIntegratedAssemblerDefault());
+
+ Tool *&T = Tools[Key];
+ if (!T) {
+ switch (Key) {
+ case Action::AssembleJobClass: {
+ if (UseIntegratedAs)
+ T = new tools::ClangAs(*this);
+ else
+ T = new tools::bitrig::Assemble(*this);
+ break;
+ }
+ case Action::LinkJobClass:
+ T = new tools::bitrig::Link(*this); break;
+ default:
+ T = &Generic_GCC::SelectTool(C, JA, Inputs);
+ }
+ }
+
+ return *T;
+}
+
+void Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
+ DriverArgs.hasArg(options::OPT_nostdincxx))
+ return;
+
+ std::string Triple = getTriple().str();
+ if (Triple.substr(0, 5) == "amd64")
+ Triple.replace(0, 5, "x86_64");
+
+ addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/4.6.2");
+ addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/4.6.2/backward");
+ addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/4.6.2/" + Triple);
+
+}
+
+void Bitrig::AddCXXStdlibLibArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ CmdArgs.push_back("-lstdc++");
+}
+
/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
FreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
@@ -1957,6 +1979,16 @@ static std::string getMultiarchTriple(const llvm::Triple TargetTriple,
// common linux triples that don't quite match the Clang triple for both
// 32-bit and 64-bit targets. Multiarch fixes its install triples to these
// regardless of what the actual target triple is.
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
+ if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabihf"))
+ return "arm-linux-gnueabihf";
+ } else {
+ if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabi"))
+ return "arm-linux-gnueabi";
+ }
+ return TargetTriple.str();
case llvm::Triple::x86:
if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu"))
return "i386-linux-gnu";
@@ -2139,6 +2171,12 @@ Tool &Linux::SelectTool(const Compilation &C, const JobAction &JA,
return *T;
}
+void Linux::addClangTargetOptions(ArgStringList &CC1Args) const {
+ const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion();
+ if (V >= Generic_GCC::GCCVersion::Parse("4.7.0"))
+ CC1Args.push_back("-fuse-init-array");
+}
+
void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
const Driver &D = getDriver();
@@ -2197,6 +2235,9 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
const StringRef ARMMultiarchIncludeDirs[] = {
"/usr/include/arm-linux-gnueabi"
};
+ const StringRef ARMHFMultiarchIncludeDirs[] = {
+ "/usr/include/arm-linux-gnueabihf"
+ };
const StringRef MIPSMultiarchIncludeDirs[] = {
"/usr/include/mips-linux-gnu"
};
@@ -2215,7 +2256,10 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
} else if (getTriple().getArch() == llvm::Triple::x86) {
MultiarchIncludeDirs = X86MultiarchIncludeDirs;
} else if (getTriple().getArch() == llvm::Triple::arm) {
- MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
+ if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
+ MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs;
+ else
+ MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
} else if (getTriple().getArch() == llvm::Triple::mips) {
MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
} else if (getTriple().getArch() == llvm::Triple::mipsel) {
@@ -2281,7 +2325,7 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
// equivalent to '/usr/include/c++/X.Y' in almost all cases.
StringRef LibDir = GCCInstallation.getParentLibPath();
StringRef InstallDir = GCCInstallation.getInstallPath();
- StringRef Version = GCCInstallation.getVersion();
+ StringRef Version = GCCInstallation.getVersion().Text;
if (!addLibStdCXXIncludePaths(LibDir + "/../include/c++/" + Version,
(GCCInstallation.getTriple().str() +
GCCInstallation.getMultiarchSuffix()),
OpenPOWER on IntegriCloud