summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2014-03-21 17:53:59 +0000
committerdim <dim@FreeBSD.org>2014-03-21 17:53:59 +0000
commit9cedb8bb69b89b0f0c529937247a6a80cabdbaec (patch)
treec978f0e9ec1ab92dc8123783f30b08a7fd1e2a39 /contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
parent03fdc2934eb61c44c049a02b02aa974cfdd8a0eb (diff)
downloadFreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.zip
FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.tar.gz
MFC 261991:
Upgrade our copy of llvm/clang to 3.4 release. This version supports all of the features in the current working draft of the upcoming C++ standard, provisionally named C++1y. The code generator's performance is greatly increased, and the loop auto-vectorizer is now enabled at -Os and -O2 in addition to -O3. The PowerPC backend has made several major improvements to code generation quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ backends have all seen major feature work. Release notes for llvm and clang can be found here: <http://llvm.org/releases/3.4/docs/ReleaseNotes.html> <http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html> MFC 262121 (by emaste): Update lldb for clang/llvm 3.4 import This commit largely restores the lldb source to the upstream r196259 snapshot with the addition of threaded inferior support and a few bug fixes. Specific upstream lldb revisions restored include: SVN git 181387 779e6ac 181703 7bef4e2 182099 b31044e 182650 f2dcf35 182683 0d91b80 183862 15c1774 183929 99447a6 184177 0b2934b 184948 4dc3761 184954 007e7bc 186990 eebd175 Sponsored by: DARPA, AFRL MFC 262186 (by emaste): Fix mismerge in r262121 A break statement was lost in the merge. The error had no functional impact, but restore it to reduce the diff against upstream. MFC 262303: Pull in r197521 from upstream clang trunk (by rdivacky): Use the integrated assembler by default on FreeBSD/ppc and ppc64. Requested by: jhibbits MFC 262611: Pull in r196874 from upstream llvm trunk: Fix a crash that occurs when PWD is invalid. MCJIT needs to be able to run in hostile environments, even when PWD is invalid. There's no need to crash MCJIT in this case. The obvious fix is to simply leave MCContext's CompilationDir empty when PWD can't be determined. This way, MCJIT clients, and other clients that link with LLVM don't need a valid working directory. If we do want to guarantee valid CompilationDir, that should be done only for clients of getCompilationDir(). This is as simple as checking for an empty string. The only current use of getCompilationDir is EmitGenDwarfInfo, which won't conceivably run with an invalid working dir. However, in the purely hypothetically and untestable case that this happens, the AT_comp_dir will be omitted from the compilation_unit DIE. This should help fix assertions occurring with ports-mgmt/tinderbox, when it is using jails, and sometimes invalidates clang's current working directory. Reported by: decke MFC 262809: Pull in r203007 from upstream clang trunk: Don't produce an alias between destructors with different calling conventions. Fixes pr19007. (Please note that is an LLVM PR identifier, not a FreeBSD one.) This should fix Firefox and/or libxul crashes (due to problems with regparm/stdcall calling conventions) on i386. Reported by: multiple users on freebsd-current PR: bin/187103 MFC 263048: Repair recognition of "CC" as an alias for the C++ compiler, since it was silently broken by upstream for a Windows-specific use-case. Apparently some versions of CMake still rely on this archaic feature... Reported by: rakuco MFC 263049: Garbage collect the old way of adding the libstdc++ include directories in clang's InitHeaderSearch.cpp. This has been superseded by David Chisnall's commit in r255321. Moreover, if libc++ is used, the libstdc++ include directories should not be in the search path at all. These directories are now only used if you pass -stdlib=libstdc++.
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp1227
1 files changed, 733 insertions, 494 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
index dbb69ac..8a47e76 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
@@ -8,27 +8,28 @@
//===----------------------------------------------------------------------===//
#include "ToolChains.h"
-#include "SanitizerArgs.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Version.h"
-#include "clang/Driver/Arg.h"
-#include "clang/Driver/ArgList.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
-#include "clang/Driver/OptTable.h"
-#include "clang/Driver/Option.h"
#include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/OptTable.h"
+#include "llvm/Option/Option.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
+#include "llvm/Support/Program.h"
// FIXME: This needs to be listed last until we fix the broken include guards
// in these files and the LLVM config.h files.
@@ -39,6 +40,7 @@
using namespace clang::driver;
using namespace clang::driver::toolchains;
using namespace clang;
+using namespace llvm::opt;
/// Darwin - Darwin tool chain for i386 and x86_64.
@@ -122,7 +124,9 @@ static const char *GetArmArchForMCpu(StringRef Value) {
.Case("xscale", "xscale")
.Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "arm1176jzf-s", "armv6")
.Case("cortex-m0", "armv6m")
- .Cases("cortex-a8", "cortex-r4", "cortex-a9", "cortex-a15", "armv7")
+ .Cases("cortex-a5", "cortex-a7", "cortex-a8", "armv7")
+ .Cases("cortex-a9", "cortex-a12", "cortex-a15", "armv7")
+ .Cases("cortex-r4", "cortex-r5", "armv7r")
.Case("cortex-a9-mp", "armv7f")
.Case("cortex-m3", "armv7m")
.Case("cortex-m4", "armv7em")
@@ -162,10 +166,18 @@ std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
if (!isTargetInitialized())
return Triple.getTriple();
- SmallString<16> Str;
- Str += isTargetIPhoneOS() ? "ios" : "macosx";
- Str += getTargetVersion().getAsString();
- Triple.setOSName(Str);
+ if (Triple.getArchName() == "thumbv6m" ||
+ Triple.getArchName() == "thumbv7m" ||
+ Triple.getArchName() == "thumbv7em") {
+ // OS is ios or macosx unless it's the v6m or v7m.
+ Triple.setOS(llvm::Triple::Darwin);
+ Triple.setEnvironment(llvm::Triple::EABI);
+ } else {
+ SmallString<16> Str;
+ Str += isTargetIPhoneOS() ? "ios" : "macosx";
+ Str += getTargetVersion().getAsString();
+ Triple.setOSName(Str);
+ }
return Triple.getTriple();
}
@@ -217,39 +229,33 @@ void DarwinClang::AddLinkARCArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
CmdArgs.push_back("-force_load");
- llvm::sys::Path P(getDriver().ClangExecutable);
- P.eraseComponent(); // 'clang'
- P.eraseComponent(); // 'bin'
- P.appendComponent("lib");
- P.appendComponent("arc");
- P.appendComponent("libarclite_");
- std::string s = P.str();
+ SmallString<128> P(getDriver().ClangExecutable);
+ llvm::sys::path::remove_filename(P); // 'clang'
+ llvm::sys::path::remove_filename(P); // 'bin'
+ llvm::sys::path::append(P, "lib", "arc", "libarclite_");
// Mash in the platform.
if (isTargetIOSSimulator())
- s += "iphonesimulator";
+ P += "iphonesimulator";
else if (isTargetIPhoneOS())
- s += "iphoneos";
+ P += "iphoneos";
else
- s += "macosx";
- s += ".a";
+ P += "macosx";
+ P += ".a";
- CmdArgs.push_back(Args.MakeArgString(s));
+ CmdArgs.push_back(Args.MakeArgString(P));
}
void DarwinClang::AddLinkRuntimeLib(const ArgList &Args,
ArgStringList &CmdArgs,
const char *DarwinStaticLib,
bool AlwaysLink) const {
- llvm::sys::Path P(getDriver().ResourceDir);
- P.appendComponent("lib");
- P.appendComponent("darwin");
- P.appendComponent(DarwinStaticLib);
+ SmallString<128> P(getDriver().ResourceDir);
+ llvm::sys::path::append(P, "lib", "darwin", DarwinStaticLib);
// For now, allow missing resource libraries to support developers who may
// not have compiler-rt checked out or integrated into their build (unless
// we explicitly force linking with this library).
- bool Exists;
- if (AlwaysLink || (!llvm::sys::fs::exists(P.str(), Exists) && Exists))
+ if (AlwaysLink || llvm::sys::fs::exists(P.str()))
CmdArgs.push_back(Args.MakeArgString(P.str()));
}
@@ -294,10 +300,11 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
}
}
- SanitizerArgs Sanitize(*this, Args);
+ const SanitizerArgs &Sanitize = getSanitizerArgs();
// Add Ubsan runtime library, if required.
if (Sanitize.needsUbsanRt()) {
+ // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds.
if (isTargetIPhoneOS()) {
getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
<< "-fsanitize=undefined";
@@ -312,19 +319,27 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
// Add ASAN runtime library, if required. Dynamic libraries and bundles
// should not be linked with the runtime library.
if (Sanitize.needsAsanRt()) {
+ // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds.
if (isTargetIPhoneOS() && !isTargetIOSSimulator()) {
getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
<< "-fsanitize=address";
} else {
- if (Args.hasArg(options::OPT_dynamiclib) ||
- Args.hasArg(options::OPT_bundle)) {
- // Assume the binary will provide the ASan runtime.
- } else {
- AddLinkRuntimeLib(Args, CmdArgs,
- "libclang_rt.asan_osx_dynamic.dylib", true);
+ if (!Args.hasArg(options::OPT_dynamiclib) &&
+ !Args.hasArg(options::OPT_bundle)) {
// The ASAN runtime library requires C++.
AddCXXStdlibLibArgs(Args, CmdArgs);
}
+ if (isTargetMacOS()) {
+ AddLinkRuntimeLib(Args, CmdArgs,
+ "libclang_rt.asan_osx_dynamic.dylib",
+ true);
+ } else {
+ if (isTargetIOSSimulator()) {
+ AddLinkRuntimeLib(Args, CmdArgs,
+ "libclang_rt.asan_iossim_dynamic.dylib",
+ true);
+ }
+ }
}
}
@@ -376,8 +391,7 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
// isysroot.
if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
// Warn if the path does not exist.
- bool Exists;
- if (llvm::sys::fs::exists(A->getValue(), Exists) || !Exists)
+ if (!llvm::sys::fs::exists(A->getValue()))
getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
} else {
if (char *env = ::getenv("SDKROOT")) {
@@ -538,17 +552,14 @@ void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
// explicitly if we can't see an obvious -lstdc++ candidate.
// Check in the sysroot first.
- bool Exists;
if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
- llvm::sys::Path P(A->getValue());
- P.appendComponent("usr");
- P.appendComponent("lib");
- P.appendComponent("libstdc++.dylib");
-
- if (llvm::sys::fs::exists(P.str(), Exists) || !Exists) {
- P.eraseComponent();
- P.appendComponent("libstdc++.6.dylib");
- if (!llvm::sys::fs::exists(P.str(), Exists) && Exists) {
+ SmallString<128> P(A->getValue());
+ llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib");
+
+ if (!llvm::sys::fs::exists(P.str())) {
+ llvm::sys::path::remove_filename(P);
+ llvm::sys::path::append(P, "libstdc++.6.dylib");
+ if (llvm::sys::fs::exists(P.str())) {
CmdArgs.push_back(Args.MakeArgString(P.str()));
return;
}
@@ -558,8 +569,8 @@ void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
// Otherwise, look in the root.
// FIXME: This should be removed someday when we don't have to care about
// 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.
- if ((llvm::sys::fs::exists("/usr/lib/libstdc++.dylib", Exists) || !Exists)&&
- (!llvm::sys::fs::exists("/usr/lib/libstdc++.6.dylib", Exists) && Exists)){
+ if (!llvm::sys::fs::exists("/usr/lib/libstdc++.dylib") &&
+ llvm::sys::fs::exists("/usr/lib/libstdc++.6.dylib")) {
CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");
return;
}
@@ -578,22 +589,20 @@ void DarwinClang::AddCCKextLibArgs(const ArgList &Args,
// instead of the gcc-provided one (which is also incidentally
// only present in the gcc lib dir, which makes it hard to find).
- llvm::sys::Path P(getDriver().ResourceDir);
- P.appendComponent("lib");
- P.appendComponent("darwin");
+ SmallString<128> P(getDriver().ResourceDir);
+ llvm::sys::path::append(P, "lib", "darwin");
// Use the newer cc_kext for iOS ARM after 6.0.
if (!isTargetIPhoneOS() || isTargetIOSSimulator() ||
!isIPhoneOSVersionLT(6, 0)) {
- P.appendComponent("libclang_rt.cc_kext.a");
+ llvm::sys::path::append(P, "libclang_rt.cc_kext.a");
} else {
- P.appendComponent("libclang_rt.cc_kext_ios5.a");
+ llvm::sys::path::append(P, "libclang_rt.cc_kext_ios5.a");
}
// For now, allow missing resource libraries to support developers who may
// not have compiler-rt checked out or integrated into their build.
- bool Exists;
- if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
+ if (llvm::sys::fs::exists(P.str()))
CmdArgs.push_back(Args.MakeArgString(P.str()));
}
@@ -762,7 +771,7 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
else if (Name == "ppc970")
DAL->AddJoinedArg(0, MCpu, "970");
- else if (Name == "ppc64")
+ else if (Name == "ppc64" || Name == "ppc64le")
DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
else if (Name == "i386")
@@ -784,6 +793,10 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
else if (Name == "x86_64")
DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
+ else if (Name == "x86_64h") {
+ DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
+ DAL->AddJoinedArg(0, MArch, "x86_64h");
+ }
else if (Name == "arm")
DAL->AddJoinedArg(0, MArch, "armv4t");
@@ -839,6 +852,12 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
}
}
+ // Default to use libc++ on OS X 10.9+ and iOS 7+.
+ if (((isTargetMacOS() && !isMacosxVersionLT(10, 9)) ||
+ (isTargetIPhoneOS() && !isIPhoneOSVersionLT(7, 0))) &&
+ !Args.getLastArg(options::OPT_stdlib_EQ))
+ DAL->AddJoinedArg(0, Opts.getOption(options::OPT_stdlib_EQ), "libc++");
+
// Validate the C++ standard library choice.
CXXStdlibType Type = GetCXXStdlibType(*DAL);
if (Type == ToolChain::CST_Libcxx) {
@@ -917,17 +936,19 @@ Darwin_Generic_GCC::ComputeEffectiveClangTriple(const ArgList &Args,
/// This is the primary means of forming GCCVersion objects.
/*static*/
Generic_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) {
- const GCCVersion BadVersion = { VersionText.str(), -1, -1, -1, "" };
+ const GCCVersion BadVersion = { VersionText.str(), -1, -1, -1, "", "", "" };
std::pair<StringRef, StringRef> First = VersionText.split('.');
std::pair<StringRef, StringRef> Second = First.second.split('.');
- GCCVersion GoodVersion = { VersionText.str(), -1, -1, -1, "" };
+ GCCVersion GoodVersion = { VersionText.str(), -1, -1, -1, "", "", "" };
if (First.first.getAsInteger(10, GoodVersion.Major) ||
GoodVersion.Major < 0)
return BadVersion;
+ GoodVersion.MajorStr = First.first.str();
if (Second.first.getAsInteger(10, GoodVersion.Minor) ||
GoodVersion.Minor < 0)
return BadVersion;
+ GoodVersion.MinorStr = Second.first.str();
// First look for a number prefix and parse that if present. Otherwise just
// stash the entire patch string in the suffix, and leave the number
@@ -945,7 +966,7 @@ Generic_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) {
if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) ||
GoodVersion.Patch < 0)
return BadVersion;
- GoodVersion.PatchSuffix = PatchText.substr(EndNumber).str();
+ GoodVersion.PatchSuffix = PatchText.substr(EndNumber);
}
}
@@ -953,31 +974,33 @@ Generic_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) {
}
/// \brief Less-than for GCCVersion, implementing a Strict Weak Ordering.
-bool Generic_GCC::GCCVersion::operator<(const GCCVersion &RHS) const {
- if (Major != RHS.Major)
- return Major < RHS.Major;
- if (Minor != RHS.Minor)
- return Minor < RHS.Minor;
- if (Patch != RHS.Patch) {
+bool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor,
+ int RHSPatch,
+ StringRef RHSPatchSuffix) const {
+ if (Major != RHSMajor)
+ return Major < RHSMajor;
+ if (Minor != RHSMinor)
+ return Minor < RHSMinor;
+ if (Patch != RHSPatch) {
// Note that versions without a specified patch sort higher than those with
// a patch.
- if (RHS.Patch == -1)
+ if (RHSPatch == -1)
return true;
if (Patch == -1)
return false;
// Otherwise just sort on the patch itself.
- return Patch < RHS.Patch;
+ return Patch < RHSPatch;
}
- if (PatchSuffix != RHS.PatchSuffix) {
+ if (PatchSuffix != RHSPatchSuffix) {
// Sort empty suffixes higher.
- if (RHS.PatchSuffix.empty())
+ if (RHSPatchSuffix.empty())
return true;
if (PatchSuffix.empty())
return false;
// Provide a lexicographic sort to make this a total ordering.
- return PatchSuffix < RHS.PatchSuffix;
+ return PatchSuffix < RHSPatchSuffix;
}
// The versions are equal.
@@ -1002,20 +1025,19 @@ static StringRef getGCCToolchainDir(const ArgList &Args) {
/// triple.
void
Generic_GCC::GCCInstallationDetector::init(
- const Driver &D, const llvm::Triple &TargetTriple, const ArgList &Args) {
- llvm::Triple MultiarchTriple
- = TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant()
+ const llvm::Triple &TargetTriple, const ArgList &Args) {
+ llvm::Triple BiarchVariantTriple =
+ TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant()
: TargetTriple.get32BitArchVariant();
llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
// The library directories which may contain GCC installations.
- SmallVector<StringRef, 4> CandidateLibDirs, CandidateMultiarchLibDirs;
+ SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs;
// The compatible GCC triples for this particular architecture.
SmallVector<StringRef, 10> CandidateTripleAliases;
- SmallVector<StringRef, 10> CandidateMultiarchTripleAliases;
- CollectLibDirsAndTriples(TargetTriple, MultiarchTriple, CandidateLibDirs,
- CandidateTripleAliases,
- CandidateMultiarchLibDirs,
- CandidateMultiarchTripleAliases);
+ SmallVector<StringRef, 10> CandidateBiarchTripleAliases;
+ CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs,
+ CandidateTripleAliases, CandidateBiarchLibDirs,
+ CandidateBiarchTripleAliases);
// Compute the set of prefixes for our search.
SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(),
@@ -1028,9 +1050,18 @@ Generic_GCC::GCCInstallationDetector::init(
Prefixes.push_back(GCCToolchainDir);
} else {
- Prefixes.push_back(D.SysRoot);
- Prefixes.push_back(D.SysRoot + "/usr");
+ // If we have a SysRoot, try that first.
+ if (!D.SysRoot.empty()) {
+ Prefixes.push_back(D.SysRoot);
+ Prefixes.push_back(D.SysRoot + "/usr");
+ }
+
+ // Then look for gcc installed alongside clang.
Prefixes.push_back(D.InstalledDir + "/..");
+
+ // And finally in /usr.
+ if (D.SysRoot.empty())
+ Prefixes.push_back("/usr");
}
// Loop over the various components which exist and select the best GCC
@@ -1047,217 +1078,216 @@ Generic_GCC::GCCInstallationDetector::init(
ScanLibDirForGCCTriple(TargetArch, Args, LibDir,
CandidateTripleAliases[k]);
}
- for (unsigned j = 0, je = CandidateMultiarchLibDirs.size(); j < je; ++j) {
- const std::string LibDir
- = Prefixes[i] + CandidateMultiarchLibDirs[j].str();
+ for (unsigned j = 0, je = CandidateBiarchLibDirs.size(); j < je; ++j) {
+ const std::string LibDir = Prefixes[i] + CandidateBiarchLibDirs[j].str();
if (!llvm::sys::fs::exists(LibDir))
continue;
- for (unsigned k = 0, ke = CandidateMultiarchTripleAliases.size(); k < ke;
+ for (unsigned k = 0, ke = CandidateBiarchTripleAliases.size(); k < ke;
++k)
ScanLibDirForGCCTriple(TargetArch, Args, LibDir,
- CandidateMultiarchTripleAliases[k],
- /*NeedsMultiarchSuffix=*/true);
+ CandidateBiarchTripleAliases[k],
+ /*NeedsBiarchSuffix=*/ true);
}
}
}
+void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const {
+ for (std::set<std::string>::const_iterator
+ I = CandidateGCCInstallPaths.begin(),
+ E = CandidateGCCInstallPaths.end();
+ I != E; ++I)
+ OS << "Found candidate GCC installation: " << *I << "\n";
+
+ OS << "Selected GCC installation: " << GCCInstallPath << "\n";
+}
+
/*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples(
- const llvm::Triple &TargetTriple,
- const llvm::Triple &MultiarchTriple,
+ const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple,
SmallVectorImpl<StringRef> &LibDirs,
SmallVectorImpl<StringRef> &TripleAliases,
- SmallVectorImpl<StringRef> &MultiarchLibDirs,
- SmallVectorImpl<StringRef> &MultiarchTripleAliases) {
+ SmallVectorImpl<StringRef> &BiarchLibDirs,
+ SmallVectorImpl<StringRef> &BiarchTripleAliases) {
// Declare a bunch of static data sets that we'll select between below. These
// are specifically designed to always refer to string literals to avoid any
// lifetime or initialization issues.
static const char *const AArch64LibDirs[] = { "/lib" };
- static const char *const AArch64Triples[] = {
- "aarch64-none-linux-gnu",
- "aarch64-linux-gnu"
- };
+ static const char *const AArch64Triples[] = { "aarch64-none-linux-gnu",
+ "aarch64-linux-gnu" };
static const char *const ARMLibDirs[] = { "/lib" };
- static const char *const ARMTriples[] = {
- "arm-linux-gnueabi",
- "arm-linux-androideabi"
- };
- static const char *const ARMHFTriples[] = {
- "arm-linux-gnueabihf",
- "armv7hl-redhat-linux-gnueabi"
- };
+ static const char *const ARMTriples[] = { "arm-linux-gnueabi",
+ "arm-linux-androideabi" };
+ static const char *const ARMHFTriples[] = { "arm-linux-gnueabihf",
+ "armv7hl-redhat-linux-gnueabi" };
static const char *const X86_64LibDirs[] = { "/lib64", "/lib" };
static const char *const X86_64Triples[] = {
- "x86_64-linux-gnu",
- "x86_64-unknown-linux-gnu",
- "x86_64-pc-linux-gnu",
- "x86_64-redhat-linux6E",
- "x86_64-redhat-linux",
- "x86_64-suse-linux",
- "x86_64-manbo-linux-gnu",
- "x86_64-linux-gnu",
- "x86_64-slackware-linux"
+ "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", "x86_64-pc-linux-gnu",
+ "x86_64-redhat-linux6E", "x86_64-redhat-linux", "x86_64-suse-linux",
+ "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux"
};
static const char *const X86LibDirs[] = { "/lib32", "/lib" };
static const char *const X86Triples[] = {
- "i686-linux-gnu",
- "i686-pc-linux-gnu",
- "i486-linux-gnu",
- "i386-linux-gnu",
- "i386-redhat-linux6E",
- "i686-redhat-linux",
- "i586-redhat-linux",
- "i386-redhat-linux",
- "i586-suse-linux",
- "i486-slackware-linux",
+ "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu", "i386-linux-gnu",
+ "i386-redhat-linux6E", "i686-redhat-linux", "i586-redhat-linux",
+ "i386-redhat-linux", "i586-suse-linux", "i486-slackware-linux",
"i686-montavista-linux"
};
static const char *const MIPSLibDirs[] = { "/lib" };
- static const char *const MIPSTriples[] = { "mips-linux-gnu" };
+ static const char *const MIPSTriples[] = { "mips-linux-gnu",
+ "mips-mti-linux-gnu" };
static const char *const MIPSELLibDirs[] = { "/lib" };
- static const char *const MIPSELTriples[] = {
- "mipsel-linux-gnu",
- "mipsel-linux-android",
- "mips-linux-gnu"
- };
+ static const char *const MIPSELTriples[] = { "mipsel-linux-gnu",
+ "mipsel-linux-android" };
static const char *const MIPS64LibDirs[] = { "/lib64", "/lib" };
- static const char *const MIPS64Triples[] = { "mips64-linux-gnu" };
+ static const char *const MIPS64Triples[] = { "mips64-linux-gnu",
+ "mips-mti-linux-gnu" };
static const char *const MIPS64ELLibDirs[] = { "/lib64", "/lib" };
- static const char *const MIPS64ELTriples[] = { "mips64el-linux-gnu" };
+ static const char *const MIPS64ELTriples[] = { "mips64el-linux-gnu",
+ "mips-mti-linux-gnu" };
static const char *const PPCLibDirs[] = { "/lib32", "/lib" };
static const char *const PPCTriples[] = {
- "powerpc-linux-gnu",
- "powerpc-unknown-linux-gnu",
- "powerpc-linux-gnuspe",
- "powerpc-suse-linux",
- "powerpc-montavista-linuxspe"
+ "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe",
+ "powerpc-suse-linux", "powerpc-montavista-linuxspe"
};
static const char *const PPC64LibDirs[] = { "/lib64", "/lib" };
- static const char *const PPC64Triples[] = {
- "powerpc64-linux-gnu",
- "powerpc64-unknown-linux-gnu",
- "powerpc64-suse-linux",
- "ppc64-redhat-linux"
- };
+ static const char *const PPC64Triples[] = { "powerpc64-linux-gnu",
+ "powerpc64-unknown-linux-gnu",
+ "powerpc64-suse-linux",
+ "ppc64-redhat-linux" };
+ static const char *const PPC64LELibDirs[] = { "/lib64", "/lib" };
+ static const char *const PPC64LETriples[] = { "powerpc64le-linux-gnu",
+ "powerpc64le-unknown-linux-gnu",
+ "powerpc64le-suse-linux",
+ "ppc64le-redhat-linux" };
static const char *const SystemZLibDirs[] = { "/lib64", "/lib" };
static const char *const SystemZTriples[] = {
- "s390x-linux-gnu",
- "s390x-unknown-linux-gnu",
- "s390x-ibm-linux-gnu",
- "s390x-suse-linux",
- "s390x-redhat-linux"
+ "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
+ "s390x-suse-linux", "s390x-redhat-linux"
};
switch (TargetTriple.getArch()) {
case llvm::Triple::aarch64:
- LibDirs.append(AArch64LibDirs, AArch64LibDirs
- + llvm::array_lengthof(AArch64LibDirs));
- TripleAliases.append(
- AArch64Triples, AArch64Triples + llvm::array_lengthof(AArch64Triples));
- MultiarchLibDirs.append(
- AArch64LibDirs, AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs));
- MultiarchTripleAliases.append(
- AArch64Triples, AArch64Triples + llvm::array_lengthof(AArch64Triples));
+ LibDirs.append(AArch64LibDirs,
+ AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs));
+ TripleAliases.append(AArch64Triples,
+ AArch64Triples + llvm::array_lengthof(AArch64Triples));
+ BiarchLibDirs.append(AArch64LibDirs,
+ AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs));
+ BiarchTripleAliases.append(
+ AArch64Triples, AArch64Triples + llvm::array_lengthof(AArch64Triples));
break;
case llvm::Triple::arm:
case llvm::Triple::thumb:
LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs));
if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
- TripleAliases.append(
- ARMHFTriples, ARMHFTriples + llvm::array_lengthof(ARMHFTriples));
+ TripleAliases.append(ARMHFTriples,
+ ARMHFTriples + llvm::array_lengthof(ARMHFTriples));
} else {
- TripleAliases.append(
- ARMTriples, ARMTriples + llvm::array_lengthof(ARMTriples));
+ TripleAliases.append(ARMTriples,
+ ARMTriples + llvm::array_lengthof(ARMTriples));
}
break;
case llvm::Triple::x86_64:
- LibDirs.append(
- X86_64LibDirs, X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs));
- TripleAliases.append(
- X86_64Triples, X86_64Triples + llvm::array_lengthof(X86_64Triples));
- MultiarchLibDirs.append(
- X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs));
- MultiarchTripleAliases.append(
- X86Triples, X86Triples + llvm::array_lengthof(X86Triples));
+ LibDirs.append(X86_64LibDirs,
+ X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs));
+ TripleAliases.append(X86_64Triples,
+ X86_64Triples + llvm::array_lengthof(X86_64Triples));
+ BiarchLibDirs.append(X86LibDirs,
+ X86LibDirs + llvm::array_lengthof(X86LibDirs));
+ BiarchTripleAliases.append(X86Triples,
+ X86Triples + llvm::array_lengthof(X86Triples));
break;
case llvm::Triple::x86:
LibDirs.append(X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs));
- TripleAliases.append(
- X86Triples, X86Triples + llvm::array_lengthof(X86Triples));
- MultiarchLibDirs.append(
- X86_64LibDirs, X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs));
- MultiarchTripleAliases.append(
- X86_64Triples, X86_64Triples + llvm::array_lengthof(X86_64Triples));
+ TripleAliases.append(X86Triples,
+ X86Triples + llvm::array_lengthof(X86Triples));
+ BiarchLibDirs.append(X86_64LibDirs,
+ X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs));
+ BiarchTripleAliases.append(
+ X86_64Triples, X86_64Triples + llvm::array_lengthof(X86_64Triples));
break;
case llvm::Triple::mips:
- LibDirs.append(
- 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));
+ LibDirs.append(MIPSLibDirs,
+ MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs));
+ TripleAliases.append(MIPSTriples,
+ MIPSTriples + llvm::array_lengthof(MIPSTriples));
+ BiarchLibDirs.append(MIPS64LibDirs,
+ MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs));
+ BiarchTripleAliases.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));
+ LibDirs.append(MIPSELLibDirs,
+ MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs));
+ TripleAliases.append(MIPSELTriples,
+ MIPSELTriples + llvm::array_lengthof(MIPSELTriples));
+ TripleAliases.append(MIPSTriples,
+ MIPSTriples + llvm::array_lengthof(MIPSTriples));
+ BiarchLibDirs.append(
+ MIPS64ELLibDirs,
+ MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs));
+ BiarchTripleAliases.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));
+ LibDirs.append(MIPS64LibDirs,
+ MIPS64LibDirs + llvm::array_lengthof(MIPS64LibDirs));
+ TripleAliases.append(MIPS64Triples,
+ MIPS64Triples + llvm::array_lengthof(MIPS64Triples));
+ BiarchLibDirs.append(MIPSLibDirs,
+ MIPSLibDirs + llvm::array_lengthof(MIPSLibDirs));
+ BiarchTripleAliases.append(MIPSTriples,
+ MIPSTriples + llvm::array_lengthof(MIPSTriples));
break;
case llvm::Triple::mips64el:
- LibDirs.append(
- MIPS64ELLibDirs, MIPS64ELLibDirs + llvm::array_lengthof(MIPS64ELLibDirs));
+ 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));
+ MIPS64ELTriples,
+ MIPS64ELTriples + llvm::array_lengthof(MIPS64ELTriples));
+ BiarchLibDirs.append(MIPSELLibDirs,
+ MIPSELLibDirs + llvm::array_lengthof(MIPSELLibDirs));
+ BiarchTripleAliases.append(
+ MIPSELTriples, MIPSELTriples + llvm::array_lengthof(MIPSELTriples));
+ BiarchTripleAliases.append(
+ MIPSTriples, MIPSTriples + llvm::array_lengthof(MIPSTriples));
break;
case llvm::Triple::ppc:
LibDirs.append(PPCLibDirs, PPCLibDirs + llvm::array_lengthof(PPCLibDirs));
- TripleAliases.append(
- PPCTriples, PPCTriples + llvm::array_lengthof(PPCTriples));
- MultiarchLibDirs.append(
- PPC64LibDirs, PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs));
- MultiarchTripleAliases.append(
- PPC64Triples, PPC64Triples + llvm::array_lengthof(PPC64Triples));
+ TripleAliases.append(PPCTriples,
+ PPCTriples + llvm::array_lengthof(PPCTriples));
+ BiarchLibDirs.append(PPC64LibDirs,
+ PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs));
+ BiarchTripleAliases.append(
+ PPC64Triples, PPC64Triples + llvm::array_lengthof(PPC64Triples));
break;
case llvm::Triple::ppc64:
- LibDirs.append(
- PPC64LibDirs, PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs));
- TripleAliases.append(
- PPC64Triples, PPC64Triples + llvm::array_lengthof(PPC64Triples));
- MultiarchLibDirs.append(
- PPCLibDirs, PPCLibDirs + llvm::array_lengthof(PPCLibDirs));
- MultiarchTripleAliases.append(
- PPCTriples, PPCTriples + llvm::array_lengthof(PPCTriples));
+ LibDirs.append(PPC64LibDirs,
+ PPC64LibDirs + llvm::array_lengthof(PPC64LibDirs));
+ TripleAliases.append(PPC64Triples,
+ PPC64Triples + llvm::array_lengthof(PPC64Triples));
+ BiarchLibDirs.append(PPCLibDirs,
+ PPCLibDirs + llvm::array_lengthof(PPCLibDirs));
+ BiarchTripleAliases.append(PPCTriples,
+ PPCTriples + llvm::array_lengthof(PPCTriples));
+ break;
+ case llvm::Triple::ppc64le:
+ LibDirs.append(PPC64LELibDirs,
+ PPC64LELibDirs + llvm::array_lengthof(PPC64LELibDirs));
+ TripleAliases.append(PPC64LETriples,
+ PPC64LETriples + llvm::array_lengthof(PPC64LETriples));
break;
case llvm::Triple::systemz:
- LibDirs.append(
- SystemZLibDirs, SystemZLibDirs + llvm::array_lengthof(SystemZLibDirs));
- TripleAliases.append(
- SystemZTriples, SystemZTriples + llvm::array_lengthof(SystemZTriples));
+ LibDirs.append(SystemZLibDirs,
+ SystemZLibDirs + llvm::array_lengthof(SystemZLibDirs));
+ TripleAliases.append(SystemZTriples,
+ SystemZTriples + llvm::array_lengthof(SystemZTriples));
break;
default:
@@ -1271,8 +1301,8 @@ Generic_GCC::GCCInstallationDetector::init(
TripleAliases.push_back(TargetTriple.str());
// Also include the multiarch variant if it's different.
- if (TargetTriple.str() != MultiarchTriple.str())
- MultiarchTripleAliases.push_back(MultiarchTriple.str());
+ if (TargetTriple.str() != BiarchTriple.str())
+ BiarchTripleAliases.push_back(BiarchTriple.str());
}
static bool isSoftFloatABI(const ArgList &Args) {
@@ -1299,87 +1329,168 @@ static bool isMips16(const ArgList &Args) {
return A && A->getOption().matches(options::OPT_mips16);
}
+static bool isMips32r2(const ArgList &Args) {
+ Arg *A = Args.getLastArg(options::OPT_march_EQ,
+ options::OPT_mcpu_EQ);
+
+ return A && A->getValue() == StringRef("mips32r2");
+}
+
+static bool isMips64r2(const ArgList &Args) {
+ Arg *A = Args.getLastArg(options::OPT_march_EQ,
+ options::OPT_mcpu_EQ);
+
+ return A && A->getValue() == StringRef("mips64r2");
+}
+
static bool isMicroMips(const ArgList &Args) {
Arg *A = Args.getLastArg(options::OPT_mmicromips,
options::OPT_mno_micromips);
return A && A->getOption().matches(options::OPT_mmicromips);
}
+static bool isMipsFP64(const ArgList &Args) {
+ Arg *A = Args.getLastArg(options::OPT_mfp64, options::OPT_mfp32);
+ return A && A->getOption().matches(options::OPT_mfp64);
+}
+
+static bool isMipsNan2008(const ArgList &Args) {
+ Arg *A = Args.getLastArg(options::OPT_mnan_EQ);
+ return A && A->getValue() == StringRef("2008");
+}
+
// FIXME: There is the same routine in the Tools.cpp.
static bool hasMipsN32ABIArg(const ArgList &Args) {
Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
return A && (A->getValue() == StringRef("n32"));
}
-static void appendMipsTargetSuffix(std::string &Path,
+static bool hasCrtBeginObj(Twine Path) {
+ return llvm::sys::fs::exists(Path + "/crtbegin.o");
+}
+
+static bool findTargetBiarchSuffix(std::string &Suffix, StringRef Path,
llvm::Triple::ArchType TargetArch,
const ArgList &Args) {
- if (isMips16(Args))
- Path += "/mips16";
- else if (isMicroMips(Args))
- Path += "/micromips";
-
- if (isSoftFloatABI(Args))
- Path += "/soft-float";
+ // FIXME: This routine was only intended to model bi-arch toolchains which
+ // use -m32 and -m64 to swap between variants of a target. It shouldn't be
+ // doing ABI-based builtin location for MIPS.
+ if (hasMipsN32ABIArg(Args))
+ Suffix = "/n32";
+ else if (TargetArch == llvm::Triple::x86_64 ||
+ TargetArch == llvm::Triple::ppc64 ||
+ TargetArch == llvm::Triple::systemz ||
+ TargetArch == llvm::Triple::mips64 ||
+ TargetArch == llvm::Triple::mips64el)
+ Suffix = "/64";
+ else
+ Suffix = "/32";
- if (TargetArch == llvm::Triple::mipsel ||
- TargetArch == llvm::Triple::mips64el)
- Path += "/el";
+ return hasCrtBeginObj(Path + Suffix);
}
-static StringRef getMipsTargetABISuffix(llvm::Triple::ArchType TargetArch,
- const ArgList &Args) {
- if (TargetArch == llvm::Triple::mips64 ||
- TargetArch == llvm::Triple::mips64el)
- return hasMipsN32ABIArg(Args) ? "/n32" : "/64";
-
- return "/32";
-}
+void Generic_GCC::GCCInstallationDetector::findMIPSABIDirSuffix(
+ std::string &Suffix, llvm::Triple::ArchType TargetArch, StringRef Path,
+ const llvm::opt::ArgList &Args) {
+ if (!isMipsArch(TargetArch))
+ return;
-static bool findTargetMultiarchSuffix(std::string &Suffix,
- StringRef Path,
- llvm::Triple::ArchType TargetArch,
- const ArgList &Args) {
- if (isMipsArch(TargetArch)) {
- StringRef ABISuffix = getMipsTargetABISuffix(TargetArch, Args);
+ // Some MIPS toolchains put libraries and object files compiled
+ // using different options in to the sub-directoris which names
+ // reflects the flags used for compilation. For example sysroot
+ // directory might looks like the following examples:
+ //
+ // /usr
+ // /lib <= crt*.o files compiled with '-mips32'
+ // /mips16
+ // /usr
+ // /lib <= crt*.o files compiled with '-mips16'
+ // /el
+ // /usr
+ // /lib <= crt*.o files compiled with '-mips16 -EL'
+ //
+ // or
+ //
+ // /usr
+ // /lib <= crt*.o files compiled with '-mips32r2'
+ // /mips16
+ // /usr
+ // /lib <= crt*.o files compiled with '-mips32r2 -mips16'
+ // /mips32
+ // /usr
+ // /lib <= crt*.o files compiled with '-mips32'
+ //
+ // Unfortunately different toolchains use different and partially
+ // overlapped naming schemes. So we have to make a trick for detection
+ // of using toolchain. We lookup a path which unique for each toolchains.
+
+ bool IsMentorToolChain = hasCrtBeginObj(Path + "/mips16/soft-float");
+ bool IsFSFToolChain = hasCrtBeginObj(Path + "/mips32/mips16/sof");
+
+ if (IsMentorToolChain && IsFSFToolChain)
+ D.Diag(diag::err_drv_unknown_toolchain);
+
+ if (IsMentorToolChain) {
+ if (isMips16(Args))
+ Suffix += "/mips16";
+ else if (isMicroMips(Args))
+ Suffix += "/micromips";
+
+ if (isSoftFloatABI(Args))
+ Suffix += "/soft-float";
+
+ if (TargetArch == llvm::Triple::mipsel ||
+ TargetArch == llvm::Triple::mips64el)
+ Suffix += "/el";
+ } else if (IsFSFToolChain) {
+ if (TargetArch == llvm::Triple::mips ||
+ TargetArch == llvm::Triple::mipsel) {
+ if (isMicroMips(Args))
+ Suffix += "/micromips";
+ else if (isMips32r2(Args))
+ Suffix += "";
+ else
+ Suffix += "/mips32";
- // First build and check a complex path to crtbegin.o
- // depends on command line options (-mips16, -msoft-float, ...)
- // like mips-linux-gnu/4.7/mips16/soft-float/el/crtbegin.o
- appendMipsTargetSuffix(Suffix, TargetArch, Args);
+ if (isMips16(Args))
+ Suffix += "/mips16";
+ } else {
+ if (isMips64r2(Args))
+ Suffix += hasMipsN32ABIArg(Args) ? "/mips64r2" : "/mips64r2/64";
+ else
+ Suffix += hasMipsN32ABIArg(Args) ? "/mips64" : "/mips64/64";
+ }
- if (TargetArch == llvm::Triple::mips64 ||
+ if (TargetArch == llvm::Triple::mipsel ||
TargetArch == llvm::Triple::mips64el)
- Suffix += ABISuffix;
+ Suffix += "/el";
- if (llvm::sys::fs::exists(Path + Suffix + "/crtbegin.o"))
- return true;
+ if (isSoftFloatABI(Args))
+ Suffix += "/sof";
+ else {
+ if (isMipsFP64(Args))
+ Suffix += "/fp64";
- // Then fall back and probe a simple case like
- // mips-linux-gnu/4.7/32/crtbegin.o
- Suffix = ABISuffix;
- return llvm::sys::fs::exists(Path + Suffix + "/crtbegin.o");
+ if (isMipsNan2008(Args))
+ Suffix += "/nan2008";
+ }
}
- if (TargetArch == llvm::Triple::x86_64 ||
- TargetArch == llvm::Triple::ppc64 ||
- TargetArch == llvm::Triple::systemz)
- Suffix = "/64";
- else
- Suffix = "/32";
-
- return llvm::sys::fs::exists(Path + Suffix + "/crtbegin.o");
+ if (!hasCrtBeginObj(Path + Suffix))
+ Suffix.clear();
}
void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
llvm::Triple::ArchType TargetArch, const ArgList &Args,
- const std::string &LibDir,
- StringRef CandidateTriple, bool NeedsMultiarchSuffix) {
+ const std::string &LibDir, StringRef CandidateTriple,
+ bool NeedsBiarchSuffix) {
// There are various different suffixes involving the triple we
// check for. We also record what is necessary to walk from each back
// up to the lib directory.
const std::string LibSuffixes[] = {
"/gcc/" + CandidateTriple.str(),
+ // Debian puts cross-compilers in gcc-cross
+ "/gcc-cross/" + CandidateTriple.str(),
"/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(),
// The Freescale PPC SDK has the gcc libraries in
@@ -1393,14 +1504,15 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
"/i386-linux-gnu/gcc/" + CandidateTriple.str()
};
const std::string InstallSuffixes[] = {
- "/../../..",
- "/../../../..",
- "/../..",
- "/../../../.."
+ "/../../..", // gcc/
+ "/../../..", // gcc-cross/
+ "/../../../..", // <triple>/gcc/
+ "/../..", // <triple>/
+ "/../../../.." // i386-linux-gnu/gcc/<triple>/
};
// Only look at the final, weird Ubuntu suffix for i386-linux-gnu.
- const unsigned NumLibSuffixes = (llvm::array_lengthof(LibSuffixes) -
- (TargetArch != llvm::Triple::x86));
+ const unsigned NumLibSuffixes =
+ (llvm::array_lengthof(LibSuffixes) - (TargetArch != llvm::Triple::x86));
for (unsigned i = 0; i < NumLibSuffixes; ++i) {
StringRef LibSuffix = LibSuffixes[i];
llvm::error_code EC;
@@ -1408,28 +1520,34 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
!EC && LI != LE; LI = LI.increment(EC)) {
StringRef VersionText = llvm::sys::path::filename(LI->path());
GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
- static const GCCVersion MinVersion = { "4.1.1", 4, 1, 1, "" };
- if (CandidateVersion < MinVersion)
+ if (CandidateVersion.Major != -1) // Filter obviously bad entries.
+ if (!CandidateGCCInstallPaths.insert(LI->path()).second)
+ continue; // Saw this path before; no need to look at it again.
+ if (CandidateVersion.isOlderThan(4, 1, 1))
continue;
if (CandidateVersion <= Version)
continue;
+ std::string MIPSABIDirSuffix;
+ findMIPSABIDirSuffix(MIPSABIDirSuffix, TargetArch, LI->path(), Args);
+
// Some versions of SUSE and Fedora on ppc64 put 32-bit libs
// in what would normally be GCCInstallPath and put the 64-bit
// libs in a subdirectory named 64. The simple logic we follow is that
// *if* there is a subdirectory of the right name with crtbegin.o in it,
- // we use that. If not, and if not a multiarch triple, we look for
+ // we use that. If not, and if not a biarch triple alias, we look for
// crtbegin.o without the subdirectory.
- std::string MultiarchSuffix;
- if (findTargetMultiarchSuffix(MultiarchSuffix,
- LI->path(), TargetArch, Args)) {
- GCCMultiarchSuffix = MultiarchSuffix;
+ std::string BiarchSuffix;
+ if (findTargetBiarchSuffix(BiarchSuffix,
+ LI->path() + MIPSABIDirSuffix,
+ TargetArch, Args)) {
+ GCCBiarchSuffix = BiarchSuffix;
+ } else if (NeedsBiarchSuffix ||
+ !hasCrtBeginObj(LI->path() + MIPSABIDirSuffix)) {
+ continue;
} else {
- if (NeedsMultiarchSuffix ||
- !llvm::sys::fs::exists(LI->path() + "/crtbegin.o"))
- continue;
- GCCMultiarchSuffix.clear();
+ GCCBiarchSuffix.clear();
}
Version = CandidateVersion;
@@ -1439,6 +1557,7 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
// Linux.
GCCInstallPath = LibDir + LibSuffixes[i] + "/" + VersionText.str();
GCCParentLibPath = GCCInstallPath + InstallSuffixes[i];
+ GCCMIPSABIDirSuffix = MIPSABIDirSuffix;
IsValid = true;
}
}
@@ -1446,7 +1565,7 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple& Triple,
const ArgList &Args)
- : ToolChain(D, Triple, Args), GCCInstallation() {
+ : ToolChain(D, Triple, Args), GCCInstallation(getDriver()) {
getProgramPaths().push_back(getDriver().getInstalledDir());
if (getDriver().getInstalledDir() != getDriver().Dir)
getProgramPaths().push_back(getDriver().Dir);
@@ -1482,6 +1601,11 @@ Tool *Generic_GCC::buildLinker() const {
return new tools::gcc::Link(*this);
}
+void Generic_GCC::printVerboseInfo(raw_ostream &OS) const {
+ // Print the information about how we detected the GCC installation.
+ GCCInstallation.print(OS);
+}
+
bool Generic_GCC::IsUnwindTablesDefault() const {
return getArch() == llvm::Triple::x86_64;
}
@@ -1626,7 +1750,6 @@ void Hexagon_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
DriverArgs.hasArg(options::OPT_nostdlibinc))
return;
- llvm::sys::Path InstallDir(D.InstalledDir);
std::string Ver(GetGCCLibAndIncVersion());
std::string GnuDir = Hexagon_TC::GetGnuDir(D.InstalledDir);
std::string HexagonDir(GnuDir + "/lib/gcc/hexagon/" + Ver);
@@ -1644,10 +1767,10 @@ void Hexagon_TC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
const Driver &D = getDriver();
std::string Ver(GetGCCLibAndIncVersion());
- llvm::sys::Path IncludeDir(Hexagon_TC::GetGnuDir(D.InstalledDir));
+ SmallString<128> IncludeDir(Hexagon_TC::GetGnuDir(D.InstalledDir));
- IncludeDir.appendComponent("hexagon/include/c++/");
- IncludeDir.appendComponent(Ver);
+ llvm::sys::path::append(IncludeDir, "hexagon/include/c++/");
+ llvm::sys::path::append(IncludeDir, Ver);
addSystemInclude(DriverArgs, CC1Args, IncludeDir.str());
}
@@ -1666,40 +1789,47 @@ Hexagon_TC::GetCXXStdlibType(const ArgList &Args) const {
return ToolChain::CST_Libstdcxx;
}
-static Arg *GetLastHexagonArchArg(const ArgList &Args)
-{
- Arg *A = NULL;
-
- for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
- it != ie; ++it) {
- if ((*it)->getOption().matches(options::OPT_march_EQ) ||
- (*it)->getOption().matches(options::OPT_mcpu_EQ)) {
- A = *it;
- A->claim();
- } else if ((*it)->getOption().matches(options::OPT_m_Joined)) {
- StringRef Value = (*it)->getValue(0);
- if (Value.startswith("v")) {
- A = *it;
- A->claim();
- }
- }
+static int getHexagonVersion(const ArgList &Args) {
+ Arg *A = Args.getLastArg(options::OPT_march_EQ, options::OPT_mcpu_EQ);
+ // Select the default CPU (v4) if none was given.
+ if (!A)
+ return 4;
+
+ // FIXME: produce errors if we cannot parse the version.
+ StringRef WhichHexagon = A->getValue();
+ if (WhichHexagon.startswith("hexagonv")) {
+ int Val;
+ if (!WhichHexagon.substr(sizeof("hexagonv") - 1).getAsInteger(10, Val))
+ return Val;
+ }
+ if (WhichHexagon.startswith("v")) {
+ int Val;
+ if (!WhichHexagon.substr(1).getAsInteger(10, Val))
+ return Val;
}
- return A;
+
+ // FIXME: should probably be an error.
+ return 4;
}
StringRef Hexagon_TC::GetTargetCPU(const ArgList &Args)
{
- // Select the default CPU (v4) if none was given or detection failed.
- Arg *A = GetLastHexagonArchArg (Args);
- if (A) {
- StringRef WhichHexagon = A->getValue();
- if (WhichHexagon.startswith("hexagon"))
- return WhichHexagon.substr(sizeof("hexagon") - 1);
- if (WhichHexagon != "")
- return WhichHexagon;
+ int V = getHexagonVersion(Args);
+ // FIXME: We don't support versions < 4. We should error on them.
+ switch (V) {
+ default:
+ llvm_unreachable("Unexpected version");
+ case 5:
+ return "v5";
+ case 4:
+ return "v4";
+ case 3:
+ return "v3";
+ case 2:
+ return "v2";
+ case 1:
+ return "v1";
}
-
- return "v4";
}
// End Hexagon
@@ -1828,57 +1958,62 @@ FreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Arg
getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
}
-Tool *FreeBSD::buildAssembler() const {
- return new tools::freebsd::Assemble(*this);
-}
-
-Tool *FreeBSD::buildLinker() const {
- return new tools::freebsd::Link(*this);
-}
-
-bool FreeBSD::UseSjLjExceptions() const {
- // FreeBSD uses SjLj exceptions on ARM oabi.
- switch (getTriple().getEnvironment()) {
- case llvm::Triple::GNUEABI:
- case llvm::Triple::EABI:
- return false;
-
- default:
- return (getTriple().getArch() == llvm::Triple::arm ||
- getTriple().getArch() == llvm::Triple::thumb);
- }
-}
-
ToolChain::CXXStdlibType
FreeBSD::GetCXXStdlibType(const ArgList &Args) const {
if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
StringRef Value = A->getValue();
- if (Value == "libc++")
- return ToolChain::CST_Libcxx;
if (Value == "libstdc++")
return ToolChain::CST_Libstdcxx;
+ if (Value == "libc++")
+ return ToolChain::CST_Libcxx;
+
getDriver().Diag(diag::err_drv_invalid_stdlib_name)
<< A->getAsString(Args);
}
-
- return getTriple().getOSMajorVersion() >= 10 ? ToolChain::CST_Libcxx :
- ToolChain::CST_Libstdcxx;
+ if (getTriple().getOSMajorVersion() >= 10)
+ return ToolChain::CST_Libcxx;
+ return ToolChain::CST_Libstdcxx;
}
void FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
- ArgStringList &CC1Args) const {
+ ArgStringList &CC1Args) const {
if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
DriverArgs.hasArg(options::OPT_nostdincxx))
return;
- if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx)
+ switch (GetCXXStdlibType(DriverArgs)) {
+ case ToolChain::CST_Libcxx:
addSystemInclude(DriverArgs, CC1Args,
getDriver().SysRoot + "/usr/include/c++/v1");
- else
+ break;
+ case ToolChain::CST_Libstdcxx:
addSystemInclude(DriverArgs, CC1Args,
getDriver().SysRoot + "/usr/include/c++/4.2");
- return;
+ addSystemInclude(DriverArgs, CC1Args,
+ getDriver().SysRoot + "/usr/include/c++/4.2/backward");
+ break;
+ }
+}
+
+Tool *FreeBSD::buildAssembler() const {
+ return new tools::freebsd::Assemble(*this);
+}
+
+Tool *FreeBSD::buildLinker() const {
+ return new tools::freebsd::Link(*this);
+}
+bool FreeBSD::UseSjLjExceptions() const {
+ // FreeBSD uses SjLj exceptions on ARM oabi.
+ switch (getTriple().getEnvironment()) {
+ case llvm::Triple::GNUEABI:
+ case llvm::Triple::EABI:
+ return false;
+
+ default:
+ return (getTriple().getArch() == llvm::Triple::arm ||
+ getTriple().getArch() == llvm::Triple::thumb);
+ }
}
/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
@@ -1920,6 +2055,12 @@ NetBSD::GetCXXStdlibType(const ArgList &Args) const {
<< A->getAsString(Args);
}
+ unsigned Major, Minor, Micro;
+ getTriple().getOSVersion(Major, Minor, Micro);
+ if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 23) || Major == 0) {
+ if (getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64)
+ return ToolChain::CST_Libcxx;
+ }
return ToolChain::CST_Libstdcxx;
}
@@ -2019,15 +2160,8 @@ enum Distro {
RHEL4,
RHEL5,
RHEL6,
- Fedora13,
- Fedora14,
- Fedora15,
- Fedora16,
- FedoraRawhide,
- OpenSuse11_3,
- OpenSuse11_4,
- OpenSuse12_1,
- OpenSuse12_2,
+ Fedora,
+ OpenSUSE,
UbuntuHardy,
UbuntuIntrepid,
UbuntuJaunty,
@@ -2039,16 +2173,17 @@ enum Distro {
UbuntuPrecise,
UbuntuQuantal,
UbuntuRaring,
+ UbuntuSaucy,
+ UbuntuTrusty,
UnknownDistro
};
static bool IsRedhat(enum Distro Distro) {
- return (Distro >= Fedora13 && Distro <= FedoraRawhide) ||
- (Distro >= RHEL4 && Distro <= RHEL6);
+ return Distro == Fedora || (Distro >= RHEL4 && Distro <= RHEL6);
}
-static bool IsOpenSuse(enum Distro Distro) {
- return Distro >= OpenSuse11_3 && Distro <= OpenSuse12_2;
+static bool IsOpenSUSE(enum Distro Distro) {
+ return Distro == OpenSUSE;
}
static bool IsDebian(enum Distro Distro) {
@@ -2056,7 +2191,7 @@ static bool IsDebian(enum Distro Distro) {
}
static bool IsUbuntu(enum Distro Distro) {
- return Distro >= UbuntuHardy && Distro <= UbuntuRaring;
+ return Distro >= UbuntuHardy && Distro <= UbuntuTrusty;
}
static Distro DetectDistro(llvm::Triple::ArchType Arch) {
@@ -2080,23 +2215,16 @@ static Distro DetectDistro(llvm::Triple::ArchType Arch) {
.Case("precise", UbuntuPrecise)
.Case("quantal", UbuntuQuantal)
.Case("raring", UbuntuRaring)
+ .Case("saucy", UbuntuSaucy)
+ .Case("trusty", UbuntuTrusty)
.Default(UnknownDistro);
return Version;
}
if (!llvm::MemoryBuffer::getFile("/etc/redhat-release", File)) {
StringRef Data = File.get()->getBuffer();
- if (Data.startswith("Fedora release 16"))
- return Fedora16;
- else if (Data.startswith("Fedora release 15"))
- return Fedora15;
- else if (Data.startswith("Fedora release 14"))
- return Fedora14;
- else if (Data.startswith("Fedora release 13"))
- return Fedora13;
- else if (Data.startswith("Fedora release") &&
- Data.find("Rawhide") != StringRef::npos)
- return FedoraRawhide;
+ if (Data.startswith("Fedora release"))
+ return Fedora;
else if (Data.startswith("Red Hat Enterprise Linux") &&
Data.find("release 6") != StringRef::npos)
return RHEL6;
@@ -2124,19 +2252,13 @@ static Distro DetectDistro(llvm::Triple::ArchType Arch) {
return UnknownDistro;
}
- if (!llvm::MemoryBuffer::getFile("/etc/SuSE-release", File))
- return llvm::StringSwitch<Distro>(File.get()->getBuffer())
- .StartsWith("openSUSE 11.3", OpenSuse11_3)
- .StartsWith("openSUSE 11.4", OpenSuse11_4)
- .StartsWith("openSUSE 12.1", OpenSuse12_1)
- .StartsWith("openSUSE 12.2", OpenSuse12_2)
- .Default(UnknownDistro);
+ if (llvm::sys::fs::exists("/etc/SuSE-release"))
+ return OpenSUSE;
- bool Exists;
- if (!llvm::sys::fs::exists("/etc/exherbo-release", Exists) && Exists)
+ if (llvm::sys::fs::exists("/etc/exherbo-release"))
return Exherbo;
- if (!llvm::sys::fs::exists("/etc/arch-release", Exists) && Exists)
+ if (llvm::sys::fs::exists("/etc/arch-release"))
return ArchLinux;
return UnknownDistro;
@@ -2181,6 +2303,7 @@ static std::string getMultiarchTriple(const llvm::Triple TargetTriple,
case llvm::Triple::aarch64:
if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64-linux-gnu"))
return "aarch64-linux-gnu";
+ return TargetTriple.str();
case llvm::Triple::mips:
if (llvm::sys::fs::exists(SysRoot + "/lib/mips-linux-gnu"))
return "mips-linux-gnu";
@@ -2198,6 +2321,9 @@ static std::string getMultiarchTriple(const llvm::Triple TargetTriple,
case llvm::Triple::ppc64:
if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64-linux-gnu"))
return "powerpc64-linux-gnu";
+ case llvm::Triple::ppc64le:
+ if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64le-linux-gnu"))
+ return "powerpc64le-linux-gnu";
return TargetTriple.str();
}
}
@@ -2206,34 +2332,28 @@ static void addPathIfExists(Twine Path, ToolChain::path_list &Paths) {
if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str());
}
-static bool isMipsR2Arch(llvm::Triple::ArchType Arch,
- const ArgList &Args) {
- if (Arch != llvm::Triple::mips &&
- Arch != llvm::Triple::mipsel)
- return false;
-
- Arg *A = Args.getLastArg(options::OPT_march_EQ,
- options::OPT_mcpu_EQ,
- options::OPT_mips_CPUs_Group);
-
- if (!A)
- return false;
-
- if (A->getOption().matches(options::OPT_mips_CPUs_Group))
- return A->getOption().matches(options::OPT_mips32r2);
-
- return A->getValue() == StringRef("mips32r2");
-}
-
static StringRef getMultilibDir(const llvm::Triple &Triple,
const ArgList &Args) {
- if (!isMipsArch(Triple.getArch()))
- return Triple.isArch32Bit() ? "lib32" : "lib64";
+ if (isMipsArch(Triple.getArch())) {
+ // lib32 directory has a special meaning on MIPS targets.
+ // It contains N32 ABI binaries. Use this folder if produce
+ // code for N32 ABI only.
+ if (hasMipsN32ABIArg(Args))
+ return "lib32";
+ return Triple.isArch32Bit() ? "lib" : "lib64";
+ }
- // lib32 directory has a special meaning on MIPS targets.
- // It contains N32 ABI binaries. Use this folder if produce
- // code for N32 ABI only.
- if (hasMipsN32ABIArg(Args))
+ // It happens that only x86 and PPC use the 'lib32' variant of multilib, and
+ // using that variant while targeting other architectures causes problems
+ // because the libraries are laid out in shared system roots that can't cope
+ // with a 'lib32' multilib search path being considered. So we only enable
+ // them when we know we may need it.
+ //
+ // FIXME: This is a bit of a hack. We should really unify this code for
+ // reasoning about multilib spellings with the lib dir spellings in the
+ // GCCInstallationDetector, but that is a more significant refactoring.
+ if (Triple.getArch() == llvm::Triple::x86 ||
+ Triple.getArch() == llvm::Triple::ppc)
return "lib32";
return Triple.isArch32Bit() ? "lib" : "lib64";
@@ -2241,12 +2361,18 @@ static StringRef getMultilibDir(const llvm::Triple &Triple,
Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
: Generic_ELF(D, Triple, Args) {
- GCCInstallation.init(D, Triple, Args);
+ GCCInstallation.init(Triple, Args);
llvm::Triple::ArchType Arch = Triple.getArch();
- std::string SysRoot = computeSysRoot(Args);
-
- // OpenSuse stores the linker with the compiler, add that to the search
- // path.
+ std::string SysRoot = computeSysRoot();
+
+ // Cross-compiling binutils and GCC installations (vanilla and openSUSE at
+ // least) put various tools in a triple-prefixed directory off of the parent
+ // of the GCC installation. We use the GCC triple here to ensure that we end
+ // up with tools that support the same amount of cross compiling as the
+ // detected GCC installation. For example, if we find a GCC installation
+ // targeting x86_64, but it is a bi-arch GCC installation, it can also be
+ // used to target i386.
+ // FIXME: This seems unlikely to be Linux-specific.
ToolChain::path_list &PPaths = getProgramPaths();
PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
GCCInstallation.getTriple().str() + "/bin").str());
@@ -2255,7 +2381,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
Distro Distro = DetectDistro(Arch);
- if (IsOpenSuse(Distro) || IsUbuntu(Distro)) {
+ if (IsOpenSUSE(Distro) || IsUbuntu(Distro)) {
ExtraOpts.push_back("-z");
ExtraOpts.push_back("relro");
}
@@ -2275,11 +2401,11 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
// ABI requires a mapping between the GOT and the symbol table.
// Android loader does not support .gnu.hash.
if (!IsMips && !IsAndroid) {
- if (IsRedhat(Distro) || IsOpenSuse(Distro) ||
+ if (IsRedhat(Distro) || IsOpenSUSE(Distro) ||
(IsUbuntu(Distro) && Distro >= UbuntuMaverick))
ExtraOpts.push_back("--hash-style=gnu");
- if (IsDebian(Distro) || IsOpenSuse(Distro) || Distro == UbuntuLucid ||
+ if (IsDebian(Distro) || IsOpenSUSE(Distro) || Distro == UbuntuLucid ||
Distro == UbuntuJaunty || Distro == UbuntuKarmic)
ExtraOpts.push_back("--hash-style=both");
}
@@ -2288,12 +2414,12 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
ExtraOpts.push_back("--no-add-needed");
if (Distro == DebianSqueeze || Distro == DebianWheezy ||
- Distro == DebianJessie || IsOpenSuse(Distro) ||
+ Distro == DebianJessie || IsOpenSUSE(Distro) ||
(IsRedhat(Distro) && Distro != RHEL4 && Distro != RHEL5) ||
(IsUbuntu(Distro) && Distro >= UbuntuKarmic))
ExtraOpts.push_back("--build-id");
- if (IsOpenSuse(Distro))
+ if (IsOpenSUSE(Distro))
ExtraOpts.push_back("--enable-new-dtags");
// The selection of paths to try here is designed to match the patterns which
@@ -2311,15 +2437,43 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
const std::string &LibPath = GCCInstallation.getParentLibPath();
- if (IsAndroid && isMipsR2Arch(Triple.getArch(), Args))
- addPathIfExists(GCCInstallation.getInstallPath() +
- GCCInstallation.getMultiarchSuffix() +
- "/mips-r2",
- Paths);
- else
+ // Sourcery CodeBench MIPS toolchain holds some libraries under
+ // a biarch-like suffix of the GCC installation.
+ //
+ // FIXME: It would be cleaner to model this as a variant of bi-arch. IE,
+ // instead of a '64' biarch suffix it would be 'el' or something.
+ if (IsAndroid && IsMips && isMips32r2(Args)) {
+ assert(GCCInstallation.getBiarchSuffix().empty() &&
+ "Unexpected bi-arch suffix");
+ addPathIfExists(GCCInstallation.getInstallPath() + "/mips-r2", Paths);
+ } else {
addPathIfExists((GCCInstallation.getInstallPath() +
- GCCInstallation.getMultiarchSuffix()),
+ GCCInstallation.getMIPSABIDirSuffix() +
+ GCCInstallation.getBiarchSuffix()),
Paths);
+ }
+
+ // GCC cross compiling toolchains will install target libraries which ship
+ // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as
+ // any part of the GCC installation in
+ // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat
+ // debatable, but is the reality today. We need to search this tree even
+ // when we have a sysroot somewhere else. It is the responsibility of
+ // whomever is doing the cross build targetting a sysroot using a GCC
+ // installation that is *not* within the system root to ensure two things:
+ //
+ // 1) Any DSOs that are linked in from this tree or from the install path
+ // above must be preasant on the system root and found via an
+ // appropriate rpath.
+ // 2) There must not be libraries installed into
+ // <prefix>/<triple>/<libdir> unless they should be preferred over
+ // those within the system root.
+ //
+ // Note that this matches the GCC behavior. See the below comment for where
+ // Clang diverges from GCC's behavior.
+ addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + Multilib +
+ GCCInstallation.getMIPSABIDirSuffix(),
+ Paths);
// If the GCC installation we found is inside of the sysroot, we want to
// prefer libraries installed in the parent prefix of the GCC installation.
@@ -2327,55 +2481,48 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
// outside of the system root as that can pick up unintended libraries.
// This usually happens when there is an external cross compiler on the
// host system, and a more minimal sysroot available that is the target of
- // the cross.
+ // the cross. Note that GCC does include some of these directories in some
+ // configurations but this seems somewhere between questionable and simply
+ // a bug.
if (StringRef(LibPath).startswith(SysRoot)) {
- addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + Multilib,
- Paths);
addPathIfExists(LibPath + "/" + MultiarchTriple, Paths);
addPathIfExists(LibPath + "/../" + Multilib, Paths);
}
- // On Android, libraries in the parent prefix of the GCC installation are
- // preferred to the ones under sysroot.
- if (IsAndroid) {
- addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib", Paths);
- }
- // Sourcery CodeBench MIPS toolchain holds some libraries under
- // the parent prefix of the GCC installation.
- if (IsMips) {
- std::string Suffix;
- appendMipsTargetSuffix(Suffix, Arch, Args);
- addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" +
- Multilib + Suffix,
- Paths);
- }
}
addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);
addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths);
addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
addPathIfExists(SysRoot + "/usr/lib/../" + Multilib, Paths);
- // Try walking via the GCC triple path in case of multiarch GCC
+ // Try walking via the GCC triple path in case of biarch or multiarch GCC
// installations with strange symlinks.
- if (GCCInstallation.isValid())
+ if (GCCInstallation.isValid()) {
addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
"/../../" + Multilib, Paths);
- // Add the non-multilib suffixed paths (if potentially different).
- if (GCCInstallation.isValid()) {
+ // Add the non-multilib suffixed paths (if potentially different).
const std::string &LibPath = GCCInstallation.getParentLibPath();
const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
- if (!GCCInstallation.getMultiarchSuffix().empty())
- addPathIfExists(GCCInstallation.getInstallPath(), Paths);
+ if (!GCCInstallation.getBiarchSuffix().empty())
+ addPathIfExists(GCCInstallation.getInstallPath() +
+ GCCInstallation.getMIPSABIDirSuffix(), Paths);
- if (StringRef(LibPath).startswith(SysRoot)) {
- addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib", Paths);
+ // See comments above on the multilib variant for details of why this is
+ // included even from outside the sysroot.
+ addPathIfExists(LibPath + "/../" + GCCTriple.str() +
+ "/lib" + GCCInstallation.getMIPSABIDirSuffix(), Paths);
+
+ // See comments above on the multilib variant for details of why this is
+ // only included from within the sysroot.
+ if (StringRef(LibPath).startswith(SysRoot))
addPathIfExists(LibPath, Paths);
- }
}
addPathIfExists(SysRoot + "/lib", Paths);
addPathIfExists(SysRoot + "/usr/lib", Paths);
+}
- IsPIEDefault = SanitizerArgs(*this, Args).hasZeroBaseShadow();
+bool FreeBSD::HasNativeLLVMSupport() const {
+ return true;
}
bool Linux::HasNativeLLVMSupport() const {
@@ -2393,8 +2540,8 @@ Tool *Linux::buildAssembler() const {
void Linux::addClangTargetOptions(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion();
- bool UseInitArrayDefault
- = V >= Generic_GCC::GCCVersion::Parse("4.7.0") ||
+ bool UseInitArrayDefault =
+ !V.isOlderThan(4, 7, 0) ||
getTriple().getArch() == llvm::Triple::aarch64 ||
getTriple().getEnvironment() == llvm::Triple::Android;
if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
@@ -2403,25 +2550,39 @@ void Linux::addClangTargetOptions(const ArgList &DriverArgs,
CC1Args.push_back("-fuse-init-array");
}
-std::string Linux::computeSysRoot(const ArgList &Args) const {
+std::string Linux::computeSysRoot() const {
if (!getDriver().SysRoot.empty())
return getDriver().SysRoot;
if (!GCCInstallation.isValid() || !isMipsArch(getTriple().getArch()))
return std::string();
- std::string Path =
- (GCCInstallation.getInstallPath() +
- "/../../../../" + GCCInstallation.getTriple().str() + "/libc").str();
- appendMipsTargetSuffix(Path, getTriple().getArch(), Args);
+ // Standalone MIPS toolchains use different names for sysroot folder
+ // and put it into different places. Here we try to check some known
+ // variants.
+
+ const StringRef InstallDir = GCCInstallation.getInstallPath();
+ const StringRef TripleStr = GCCInstallation.getTriple().str();
+ const StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix();
+
+ std::string Path = (InstallDir + "/../../../../" + TripleStr + "/libc" +
+ MIPSABIDirSuffix).str();
+
+ if (llvm::sys::fs::exists(Path))
+ return Path;
+
+ Path = (InstallDir + "/../../../../sysroot" + MIPSABIDirSuffix).str();
+
+ if (llvm::sys::fs::exists(Path))
+ return Path;
- return llvm::sys::fs::exists(Path) ? Path : "";
+ return std::string();
}
void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
const Driver &D = getDriver();
- std::string SysRoot = computeSysRoot(DriverArgs);
+ std::string SysRoot = computeSysRoot();
if (DriverArgs.hasArg(options::OPT_nostdinc))
return;
@@ -2430,8 +2591,8 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
- llvm::sys::Path P(D.ResourceDir);
- P.appendComponent("include");
+ SmallString<128> P(D.ResourceDir);
+ llvm::sys::path::append(P, "include");
addSystemInclude(DriverArgs, CC1Args, P.str());
}
@@ -2457,15 +2618,17 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
// Sourcery CodeBench and modern FSF Mips toolchains put extern C
// system includes under three additional directories.
if (GCCInstallation.isValid() && isMipsArch(getTriple().getArch())) {
- addExternCSystemIncludeIfExists(DriverArgs, CC1Args,
- GCCInstallation.getInstallPath() +
- "/include");
+ addExternCSystemIncludeIfExists(
+ DriverArgs, CC1Args, GCCInstallation.getInstallPath() + "/include");
- addExternCSystemIncludeIfExists(DriverArgs, CC1Args,
- GCCInstallation.getInstallPath() +
- "/../../../../" +
- GCCInstallation.getTriple().str() +
- "/libc/usr/include");
+ addExternCSystemIncludeIfExists(
+ DriverArgs, CC1Args,
+ GCCInstallation.getInstallPath() + "/../../../../" +
+ GCCInstallation.getTriple().str() + "/libc/usr/include");
+
+ addExternCSystemIncludeIfExists(
+ DriverArgs, CC1Args,
+ GCCInstallation.getInstallPath() + "/../../../../sysroot/usr/include");
}
// Implement generic Debian multiarch support.
@@ -2475,8 +2638,7 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
// FIXME: These are older forms of multiarch. It's not clear that they're
// in use in any released version of Debian, so we should consider
// removing them.
- "/usr/include/i686-linux-gnu/64",
- "/usr/include/i486-linux-gnu/64"
+ "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"
};
const StringRef X86MultiarchIncludeDirs[] = {
"/usr/include/i386-linux-gnu",
@@ -2484,8 +2646,7 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
// FIXME: These are older forms of multiarch. It's not clear that they're
// in use in any released version of Debian, so we should consider
// removing them.
- "/usr/include/x86_64-linux-gnu/32",
- "/usr/include/i686-linux-gnu",
+ "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu",
"/usr/include/i486-linux-gnu"
};
const StringRef AArch64MultiarchIncludeDirs[] = {
@@ -2566,15 +2727,17 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
/// libstdc++ installation.
/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
Twine TargetArchDir,
- Twine MultiLibSuffix,
+ Twine BiarchSuffix,
+ Twine MIPSABIDirSuffix,
const ArgList &DriverArgs,
ArgStringList &CC1Args) {
- if (!addLibStdCXXIncludePaths(Base+Suffix, TargetArchDir + MultiLibSuffix,
+ if (!addLibStdCXXIncludePaths(Base + Suffix,
+ TargetArchDir + MIPSABIDirSuffix + BiarchSuffix,
DriverArgs, CC1Args))
return false;
addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir + Suffix
- + MultiLibSuffix);
+ + MIPSABIDirSuffix + BiarchSuffix);
return true;
}
@@ -2602,37 +2765,39 @@ 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().Text;
StringRef TripleStr = GCCInstallation.getTriple().str();
+ StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix();
+ StringRef BiarchSuffix = GCCInstallation.getBiarchSuffix();
+ const GCCVersion &Version = GCCInstallation.getVersion();
- if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
- "/c++/" + Version.str(),
- TripleStr,
- GCCInstallation.getMultiarchSuffix(),
- DriverArgs, CC1Args))
+ if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
+ "/c++/" + Version.Text, TripleStr, BiarchSuffix,
+ MIPSABIDirSuffix, DriverArgs, CC1Args))
return;
const std::string IncludePathCandidates[] = {
// Gentoo is weird and places its headers inside the GCC install, so if the
- // first attempt to find the headers fails, try this pattern.
- InstallDir.str() + "/include/g++-v4",
+ // first attempt to find the headers fails, try these patterns.
+ InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +
+ Version.MinorStr,
+ InstallDir.str() + "/include/g++-v" + Version.MajorStr,
// Android standalone toolchain has C++ headers in yet another place.
- LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.str(),
+ LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
// Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
// without a subdirectory corresponding to the gcc version.
LibDir.str() + "/../include/c++",
};
for (unsigned i = 0; i < llvm::array_lengthof(IncludePathCandidates); ++i) {
- if (addLibStdCXXIncludePaths(IncludePathCandidates[i], (TripleStr +
- GCCInstallation.getMultiarchSuffix()),
- DriverArgs, CC1Args))
+ if (addLibStdCXXIncludePaths(IncludePathCandidates[i],
+ TripleStr + MIPSABIDirSuffix + BiarchSuffix,
+ DriverArgs, CC1Args))
break;
}
}
bool Linux::isPIEDefault() const {
- return IsPIEDefault;
+ return getSanitizerArgs().hasZeroBaseShadow();
}
/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
@@ -2660,3 +2825,77 @@ Tool *DragonFly::buildAssembler() const {
Tool *DragonFly::buildLinker() const {
return new tools::dragonfly::Link(*this);
}
+
+
+/// XCore tool chain
+XCore::XCore(const Driver &D, const llvm::Triple &Triple,
+ const ArgList &Args) : ToolChain(D, Triple, Args) {
+ // ProgramPaths are found via 'PATH' environment variable.
+}
+
+Tool *XCore::buildAssembler() const {
+ return new tools::XCore::Assemble(*this);
+}
+
+Tool *XCore::buildLinker() const {
+ return new tools::XCore::Link(*this);
+}
+
+bool XCore::isPICDefault() const {
+ return false;
+}
+
+bool XCore::isPIEDefault() const {
+ return false;
+}
+
+bool XCore::isPICDefaultForced() const {
+ return false;
+}
+
+bool XCore::SupportsProfiling() const {
+ return false;
+}
+
+bool XCore::hasBlocksRuntime() const {
+ return false;
+}
+
+
+void XCore::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ if (DriverArgs.hasArg(options::OPT_nostdinc) ||
+ DriverArgs.hasArg(options::OPT_nostdlibinc))
+ return;
+ if (const char *cl_include_dir = getenv("XCC_C_INCLUDE_PATH")) {
+ SmallVector<StringRef, 4> Dirs;
+ const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'};
+ StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
+ ArrayRef<StringRef> DirVec(Dirs);
+ addSystemIncludes(DriverArgs, CC1Args, DirVec);
+ }
+}
+
+void XCore::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const {
+ CC1Args.push_back("-nostdsysteminc");
+}
+
+void XCore::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ if (DriverArgs.hasArg(options::OPT_nostdinc) ||
+ DriverArgs.hasArg(options::OPT_nostdlibinc))
+ return;
+ if (const char *cl_include_dir = getenv("XCC_CPLUS_INCLUDE_PATH")) {
+ SmallVector<StringRef, 4> Dirs;
+ const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,'\0'};
+ StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
+ ArrayRef<StringRef> DirVec(Dirs);
+ addSystemIncludes(DriverArgs, CC1Args, DirVec);
+ }
+}
+
+void XCore::AddCXXStdlibLibArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ // We don't output any lib args. This is handled by xcc.
+}
OpenPOWER on IntegriCloud