diff options
author | dim <dim@FreeBSD.org> | 2013-06-10 20:45:12 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-06-10 20:45:12 +0000 |
commit | ea266cad53e3d49771fa38103913d3ec7a166694 (patch) | |
tree | 8f7776b7310bebaf415ac5b69e46e9f928c37144 /lib/Driver | |
parent | c72c57c9e9b69944e3e009cd5e209634839581d3 (diff) | |
download | FreeBSD-src-ea266cad53e3d49771fa38103913d3ec7a166694.zip FreeBSD-src-ea266cad53e3d49771fa38103913d3ec7a166694.tar.gz |
Vendor import of clang tags/RELEASE_33/final r183502 (effectively, 3.3
release):
http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_33/final@183502
Diffstat (limited to 'lib/Driver')
-rw-r--r-- | lib/Driver/ArgList.cpp | 15 | ||||
-rw-r--r-- | lib/Driver/Driver.cpp | 56 | ||||
-rw-r--r-- | lib/Driver/SanitizerArgs.h | 8 | ||||
-rw-r--r-- | lib/Driver/ToolChain.cpp | 8 | ||||
-rw-r--r-- | lib/Driver/ToolChains.cpp | 249 | ||||
-rw-r--r-- | lib/Driver/ToolChains.h | 13 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 440 | ||||
-rw-r--r-- | lib/Driver/WindowsToolChain.cpp | 4 |
8 files changed, 589 insertions, 204 deletions
diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp index 6c57b62..4b8d151 100644 --- a/lib/Driver/ArgList.cpp +++ b/lib/Driver/ArgList.cpp @@ -206,6 +206,13 @@ bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const { return Default; } +bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg, + bool Default) const { + if (Arg *A = getLastArg(Pos, PosAlias, Neg)) + return A->getOption().matches(Pos) || A->getOption().matches(PosAlias); + return Default; +} + StringRef ArgList::getLastArgValue(OptSpecifier Id, StringRef Default) const { if (Arg *A = getLastArg(Id)) @@ -241,6 +248,14 @@ void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const { } } +void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id0, + OptSpecifier Id1) const { + if (Arg *A = getLastArg(Id0, Id1)) { + A->claim(); + A->render(*this, Output); + } +} + void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const { for (arg_iterator it = filtered_begin(Id0, Id1, Id2), diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index ad1921b..1dbbc9a 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -491,9 +491,8 @@ void Driver::generateCompilationDiagnostics(Compilation &C, << "\n\n********************"; } else { // Failure, remove preprocessed files. - if (!C.getArgs().hasArg(options::OPT_save_temps)) { + if (!C.getArgs().hasArg(options::OPT_save_temps)) C.CleanupFileList(C.getTempFiles(), true); - } Diag(clang::diag::note_drv_command_failed_diag_msg) << "Error generating preprocessed source(s)."; @@ -825,17 +824,6 @@ void Driver::BuildUniversalActions(const ToolChain &TC, if (!Archs.size()) Archs.push_back(Args.MakeArgString(TC.getDefaultUniversalArchName())); - // FIXME: We killed off some others but these aren't yet detected in a - // functional manner. If we added information to jobs about which "auxiliary" - // files they wrote then we could detect the conflict these cause downstream. - if (Archs.size() > 1) { - // No recovery needed, the point of this is just to prevent - // overwriting the same files. - if (const Arg *A = Args.getLastArg(options::OPT_save_temps)) - Diag(clang::diag::err_drv_invalid_opt_with_multiple_archs) - << A->getAsString(Args); - } - ActionList SingleActions; BuildActions(TC, Args, BAInputs, SingleActions); @@ -1221,6 +1209,17 @@ void Driver::BuildJobs(Compilation &C) const { } } + // Collect the list of architectures. + llvm::StringSet<> ArchNames; + if (C.getDefaultToolChain().getTriple().isOSDarwin()) { + for (ArgList::const_iterator it = C.getArgs().begin(), ie = C.getArgs().end(); + it != ie; ++it) { + Arg *A = *it; + if (A->getOption().matches(options::OPT_arch)) + ArchNames.insert(A->getValue()); + } + } + for (ActionList::const_iterator it = C.getActions().begin(), ie = C.getActions().end(); it != ie; ++it) { Action *A = *it; @@ -1243,6 +1242,7 @@ void Driver::BuildJobs(Compilation &C) const { BuildJobsForAction(C, A, &C.getDefaultToolChain(), /*BoundArch*/0, /*AtTopLevel*/ true, + /*MultipleArchs*/ ArchNames.size() > 1, /*LinkingOutput*/ LinkingOutput, II); } @@ -1337,6 +1337,7 @@ void Driver::BuildJobsForAction(Compilation &C, const ToolChain *TC, const char *BoundArch, bool AtTopLevel, + bool MultipleArchs, const char *LinkingOutput, InputInfo &Result) const { llvm::PrettyStackTraceString CrashInfo("Building compilation jobs"); @@ -1364,7 +1365,7 @@ void Driver::BuildJobsForAction(Compilation &C, TC = &C.getDefaultToolChain(); BuildJobsForAction(C, *BAA->begin(), TC, BAA->getArchName(), - AtTopLevel, LinkingOutput, Result); + AtTopLevel, MultipleArchs, LinkingOutput, Result); return; } @@ -1387,8 +1388,8 @@ void Driver::BuildJobsForAction(Compilation &C, SubJobAtTopLevel = true; InputInfo II; - BuildJobsForAction(C, *it, TC, BoundArch, - SubJobAtTopLevel, LinkingOutput, II); + BuildJobsForAction(C, *it, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, + LinkingOutput, II); InputInfos.push_back(II); } @@ -1404,7 +1405,8 @@ void Driver::BuildJobsForAction(Compilation &C, if (JA->getType() == types::TY_Nothing) Result = InputInfo(A->getType(), BaseInput); else - Result = InputInfo(GetNamedOutputPath(C, *JA, BaseInput, AtTopLevel), + Result = InputInfo(GetNamedOutputPath(C, *JA, BaseInput, BoundArch, + AtTopLevel, MultipleArchs), A->getType(), BaseInput); if (CCCPrintBindings && !CCGenDiagnostics) { @@ -1425,7 +1427,9 @@ void Driver::BuildJobsForAction(Compilation &C, const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, - bool AtTopLevel) const { + const char *BoundArch, + bool AtTopLevel, + bool MultipleArchs) const { llvm::PrettyStackTraceString CrashInfo("Computing output path"); // Output to a user requested destination? if (AtTopLevel && !isa<DsymutilJobAction>(JA) && @@ -1460,8 +1464,14 @@ const char *Driver::GetNamedOutputPath(Compilation &C, // Determine what the derived output name should be. const char *NamedOutput; - if (JA.getType() == types::TY_Image) { - NamedOutput = DefaultImageName.c_str(); + if (JA.getType() == types::TY_Image) { + if (MultipleArchs && BoundArch) { + SmallString<128> Output(DefaultImageName.c_str()); + Output += "-"; + Output.append(BoundArch); + NamedOutput = C.getArgs().MakeArgString(Output.c_str()); + } else + NamedOutput = DefaultImageName.c_str(); } else { const char *Suffix = types::getTypeTempSuffix(JA.getType()); assert(Suffix && "All types used for output should have a suffix."); @@ -1469,7 +1479,11 @@ const char *Driver::GetNamedOutputPath(Compilation &C, std::string::size_type End = std::string::npos; if (!types::appendSuffixForType(JA.getType())) End = BaseName.rfind('.'); - std::string Suffixed(BaseName.substr(0, End)); + SmallString<128> Suffixed(BaseName.substr(0, End)); + if (MultipleArchs && BoundArch) { + Suffixed += "-"; + Suffixed.append(BoundArch); + } Suffixed += '.'; Suffixed += Suffix; NamedOutput = C.getArgs().MakeArgString(Suffixed.c_str()); diff --git a/lib/Driver/SanitizerArgs.h b/lib/Driver/SanitizerArgs.h index e61f15a..326d80d 100644 --- a/lib/Driver/SanitizerArgs.h +++ b/lib/Driver/SanitizerArgs.h @@ -38,7 +38,8 @@ class SanitizerArgs { NeedsTsanRt = Thread, NeedsMsanRt = Memory, NeedsUbsanRt = Undefined | Integer, - NotAllowedWithTrap = Vptr + NotAllowedWithTrap = Vptr, + HasZeroBaseShadow = Thread | Memory }; unsigned Kind; std::string BlacklistFile; @@ -50,7 +51,7 @@ class SanitizerArgs { SanitizerArgs() : Kind(0), BlacklistFile(""), MsanTrackOrigins(false), AsanZeroBaseShadow(false), UbsanTrapOnError(false) {} /// Parses the sanitizer arguments from an argument list. - SanitizerArgs(const Driver &D, const ArgList &Args); + SanitizerArgs(const ToolChain &TC, const ArgList &Args); bool needsAsanRt() const { return Kind & NeedsAsanRt; } bool needsTsanRt() const { return Kind & NeedsTsanRt; } @@ -63,6 +64,9 @@ class SanitizerArgs { bool sanitizesVptr() const { return Kind & Vptr; } bool notAllowedWithTrap() const { return Kind & NotAllowedWithTrap; } + bool hasZeroBaseShadow() const { + return (Kind & HasZeroBaseShadow) || AsanZeroBaseShadow; + } void addArgs(const ArgList &Args, ArgStringList &CmdArgs) const { if (!Kind) diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index 19270b2..71f5393 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -19,6 +19,7 @@ #include "clang/Driver/Options.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileSystem.h" using namespace clang::driver; using namespace clang; @@ -333,6 +334,13 @@ ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{ CC1Args.push_back(DriverArgs.MakeArgString(Path)); } +void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs, + ArgStringList &CC1Args, + const Twine &Path) { + if (llvm::sys::fs::exists(Path)) + addExternCSystemInclude(DriverArgs, CC1Args, Path); +} + /// \brief Utility function to add a list of system include directories to CC1. /*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs, ArgStringList &CC1Args, diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index bcfe51e..fffba0e 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -294,7 +294,7 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, } } - SanitizerArgs Sanitize(getDriver(), Args); + SanitizerArgs Sanitize(*this, Args); // Add Ubsan runtime library, if required. if (Sanitize.needsUbsanRt()) { @@ -878,6 +878,10 @@ bool Darwin::isPICDefault() const { return true; } +bool Darwin::isPIEDefault() const { + return false; +} + bool Darwin::isPICDefaultForced() const { return getArch() == llvm::Triple::x86_64; } @@ -1082,6 +1086,7 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector( }; static const char *const ARMHFTriples[] = { "arm-linux-gnueabihf", + "armv7hl-redhat-linux-gnueabi" }; static const char *const X86_64LibDirs[] = { "/lib64", "/lib" }; @@ -1116,7 +1121,8 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector( static const char *const MIPSELLibDirs[] = { "/lib" }; static const char *const MIPSELTriples[] = { "mipsel-linux-gnu", - "mipsel-linux-android" + "mipsel-linux-android", + "mips-linux-gnu" }; static const char *const MIPS64LibDirs[] = { "/lib64", "/lib" }; @@ -1140,6 +1146,15 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector( "ppc64-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" + }; + switch (TargetTriple.getArch()) { case llvm::Triple::aarch64: LibDirs.append(AArch64LibDirs, AArch64LibDirs @@ -1240,6 +1255,12 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector( MultiarchTripleAliases.append( PPCTriples, PPCTriples + llvm::array_lengthof(PPCTriples)); break; + case llvm::Triple::systemz: + LibDirs.append( + SystemZLibDirs, SystemZLibDirs + llvm::array_lengthof(SystemZLibDirs)); + TripleAliases.append( + SystemZTriples, SystemZTriples + llvm::array_lengthof(SystemZTriples)); + break; default: // By default, just rely on the standard lib directories and the original @@ -1256,29 +1277,102 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector( MultiarchTripleAliases.push_back(MultiarchTriple.str()); } +static bool isSoftFloatABI(const ArgList &Args) { + Arg *A = Args.getLastArg(options::OPT_msoft_float, + options::OPT_mhard_float, + options::OPT_mfloat_abi_EQ); + if (!A) return false; + + return A->getOption().matches(options::OPT_msoft_float) || + (A->getOption().matches(options::OPT_mfloat_abi_EQ) && + A->getValue() == StringRef("soft")); +} + +static bool isMipsArch(llvm::Triple::ArchType Arch) { + return Arch == llvm::Triple::mips || + Arch == llvm::Triple::mipsel || + Arch == llvm::Triple::mips64 || + Arch == llvm::Triple::mips64el; +} + +static bool isMips16(const ArgList &Args) { + Arg *A = Args.getLastArg(options::OPT_mips16, + options::OPT_mno_mips16); + return A && A->getOption().matches(options::OPT_mips16); +} + +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); +} + // 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 StringRef getTargetMultiarchSuffix(llvm::Triple::ArchType TargetArch, - const ArgList &Args) { - if (TargetArch == llvm::Triple::x86_64 || - TargetArch == llvm::Triple::ppc64) - return "/64"; +static void appendMipsTargetSuffix(std::string &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"; + if (TargetArch == llvm::Triple::mipsel || + TargetArch == llvm::Triple::mips64el) + Path += "/el"; +} + +static StringRef getMipsTargetABISuffix(llvm::Triple::ArchType TargetArch, + const ArgList &Args) { if (TargetArch == llvm::Triple::mips64 || - TargetArch == llvm::Triple::mips64el) { - if (hasMipsN32ABIArg(Args)) - return "/n32"; - else - return "/64"; - } + TargetArch == llvm::Triple::mips64el) + return hasMipsN32ABIArg(Args) ? "/n32" : "/64"; return "/32"; } +static bool findTargetMultiarchSuffix(std::string &Suffix, + StringRef Path, + llvm::Triple::ArchType TargetArch, + const ArgList &Args) { + if (isMipsArch(TargetArch)) { + StringRef ABISuffix = getMipsTargetABISuffix(TargetArch, Args); + + // 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 (TargetArch == llvm::Triple::mips64 || + TargetArch == llvm::Triple::mips64el) + Suffix += ABISuffix; + + if (llvm::sys::fs::exists(Path + Suffix + "/crtbegin.o")) + return true; + + // 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 (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"); +} + void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( llvm::Triple::ArchType TargetArch, const ArgList &Args, const std::string &LibDir, @@ -1328,9 +1422,11 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( // *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 // crtbegin.o without the subdirectory. - StringRef MultiarchSuffix = getTargetMultiarchSuffix(TargetArch, Args); - if (llvm::sys::fs::exists(LI->path() + MultiarchSuffix + "/crtbegin.o")) { - GCCMultiarchSuffix = MultiarchSuffix.str(); + + std::string MultiarchSuffix; + if (findTargetMultiarchSuffix(MultiarchSuffix, + LI->path(), TargetArch, Args)) { + GCCMultiarchSuffix = MultiarchSuffix; } else { if (NeedsMultiarchSuffix || !llvm::sys::fs::exists(LI->path() + "/crtbegin.o")) @@ -1396,6 +1492,10 @@ bool Generic_GCC::isPICDefault() const { return false; } +bool Generic_GCC::isPIEDefault() const { + return false; +} + bool Generic_GCC::isPICDefaultForced() const { return false; } @@ -1630,6 +1730,10 @@ bool TCEToolChain::isPICDefault() const { return false; } +bool TCEToolChain::isPIEDefault() const { + return false; +} + bool TCEToolChain::isPICDefaultForced() const { return false; } @@ -1773,6 +1877,42 @@ Tool *NetBSD::buildLinker() const { return new tools::netbsd::Link(*this); } +ToolChain::CXXStdlibType +NetBSD::GetCXXStdlibType(const ArgList &Args) const { + if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { + StringRef Value = A->getValue(); + 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 ToolChain::CST_Libstdcxx; +} + +void NetBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + if (DriverArgs.hasArg(options::OPT_nostdlibinc) || + DriverArgs.hasArg(options::OPT_nostdincxx)) + return; + + switch (GetCXXStdlibType(DriverArgs)) { + case ToolChain::CST_Libcxx: + addSystemInclude(DriverArgs, CC1Args, + getDriver().SysRoot + "/usr/include/c++/"); + break; + case ToolChain::CST_Libstdcxx: + addSystemInclude(DriverArgs, CC1Args, + getDriver().SysRoot + "/usr/include/g++"); + addSystemInclude(DriverArgs, CC1Args, + getDriver().SysRoot + "/usr/include/g++/backward"); + break; + } +} + /// Minix - Minix tool chain which can call as(1) and ld(1) directly. Minix::Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) @@ -2036,13 +2176,6 @@ static void addPathIfExists(Twine Path, ToolChain::path_list &Paths) { if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str()); } -static bool isMipsArch(llvm::Triple::ArchType Arch) { - return Arch == llvm::Triple::mips || - Arch == llvm::Triple::mipsel || - Arch == llvm::Triple::mips64 || - Arch == llvm::Triple::mips64el; -} - static bool isMipsR2Arch(llvm::Triple::ArchType Arch, const ArgList &Args) { if (Arch != llvm::Triple::mips && @@ -2079,7 +2212,7 @@ static StringRef getMultilibDir(const llvm::Triple &Triple, Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args) { llvm::Triple::ArchType Arch = Triple.getArch(); - const std::string &SysRoot = getDriver().SysRoot; + std::string SysRoot = computeSysRoot(Args); // OpenSuse stores the linker with the compiler, add that to the search // path. @@ -2100,13 +2233,17 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) ExtraOpts.push_back("-X"); const bool IsAndroid = Triple.getEnvironment() == llvm::Triple::Android; + const bool IsMips = isMipsArch(Arch); + + if (IsMips && !SysRoot.empty()) + ExtraOpts.push_back("--sysroot=" + SysRoot); // Do not use 'gnu' hash style for Mips targets because .gnu.hash // and the MIPS ABI require .dynsym to be sorted in different ways. // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS // ABI requires a mapping between the GOT and the symbol table. // Android loader does not support .gnu.hash. - if (!isMipsArch(Arch) && !IsAndroid) { + if (!IsMips && !IsAndroid) { if (IsRedhat(Distro) || IsOpenSuse(Distro) || (IsUbuntu(Distro) && Distro >= UbuntuMaverick)) ExtraOpts.push_back("--hash-style=gnu"); @@ -2171,6 +2308,15 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 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); @@ -2197,6 +2343,8 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) } addPathIfExists(SysRoot + "/lib", Paths); addPathIfExists(SysRoot + "/usr/lib", Paths); + + IsPIEDefault = SanitizerArgs(*this, Args).hasZeroBaseShadow(); } bool Linux::HasNativeLLVMSupport() const { @@ -2224,15 +2372,31 @@ void Linux::addClangTargetOptions(const ArgList &DriverArgs, CC1Args.push_back("-fuse-init-array"); } +std::string Linux::computeSysRoot(const ArgList &Args) 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); + + return llvm::sys::fs::exists(Path) ? Path : ""; +} + void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { const Driver &D = getDriver(); + std::string SysRoot = computeSysRoot(DriverArgs); if (DriverArgs.hasArg(options::OPT_nostdinc)) return; if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) - addSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/local/include"); + addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include"); if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { llvm::sys::Path P(D.ResourceDir); @@ -2250,7 +2414,7 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, CIncludeDirs.split(dirs, ":"); for (SmallVectorImpl<StringRef>::iterator I = dirs.begin(), E = dirs.end(); I != E; ++I) { - StringRef Prefix = llvm::sys::path::is_absolute(*I) ? D.SysRoot : ""; + StringRef Prefix = llvm::sys::path::is_absolute(*I) ? SysRoot : ""; addExternCSystemInclude(DriverArgs, CC1Args, Prefix + *I); } return; @@ -2259,6 +2423,20 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, // Lacking those, try to detect the correct set of system includes for the // target triple. + // 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() + + "/../../../../" + + GCCInstallation.getTriple().str() + + "/libc/usr/include"); + } + // Implement generic Debian multiarch support. const StringRef X86_64MultiarchIncludeDirs[] = { "/usr/include/x86_64-linux-gnu", @@ -2324,8 +2502,8 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, for (ArrayRef<StringRef>::iterator I = MultiarchIncludeDirs.begin(), E = MultiarchIncludeDirs.end(); I != E; ++I) { - if (llvm::sys::fs::exists(D.SysRoot + *I)) { - addExternCSystemInclude(DriverArgs, CC1Args, D.SysRoot + *I); + if (llvm::sys::fs::exists(SysRoot + *I)) { + addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + *I); break; } } @@ -2336,9 +2514,9 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, // Add an include of '/include' directly. This isn't provided by default by // system GCCs, but is often used with cross-compiling GCCs, and harmless to // add even when Clang is acting as-if it were a system compiler. - addExternCSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/include"); + addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); - addExternCSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/include"); + addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); } /// \brief Helper to add the three variant paths for a libstdc++ installation. @@ -2422,6 +2600,10 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, } } +bool Linux::isPIEDefault() const { + return IsPIEDefault; +} + /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. DragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) @@ -2434,7 +2616,10 @@ DragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList getFilePaths().push_back(getDriver().Dir + "/../lib"); getFilePaths().push_back("/usr/lib"); - getFilePaths().push_back("/usr/lib/gcc41"); + if (llvm::sys::fs::exists("/usr/lib/gcc47")) + getFilePaths().push_back("/usr/lib/gcc47"); + else + getFilePaths().push_back("/usr/lib/gcc44"); } Tool *DragonFly::buildAssembler() const { diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 3421c53..3afd8dd 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -123,6 +123,7 @@ public: virtual bool IsUnwindTablesDefault() const; virtual bool isPICDefault() const; + virtual bool isPIEDefault() const; virtual bool isPICDefaultForced() const; protected: @@ -332,6 +333,7 @@ public: return ToolChain::RLT_CompilerRT; } virtual bool isPICDefault() const; + virtual bool isPIEDefault() const; virtual bool isPICDefaultForced() const; virtual bool SupportsProfiling() const; @@ -472,6 +474,11 @@ public: virtual bool IsMathErrnoDefault() const { return false; } virtual bool IsObjCNonFragileABIDefault() const { return true; } + virtual CXXStdlibType GetCXXStdlibType(const ArgList &Args) const; + + virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const; + protected: virtual Tool *buildAssembler() const; virtual Tool *buildLinker() const; @@ -509,9 +516,11 @@ public: ArgStringList &CC1Args) const; virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const; + virtual bool isPIEDefault() const; std::string Linker; std::vector<std::string> ExtraOpts; + bool IsPIEDefault; protected: virtual Tool *buildAssembler() const; @@ -526,6 +535,8 @@ private: static bool addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir, const ArgList &DriverArgs, ArgStringList &CC1Args); + + std::string computeSysRoot(const ArgList &Args) const; }; class LLVM_LIBRARY_VISIBILITY Hexagon_TC : public Linux { @@ -562,6 +573,7 @@ public: bool IsMathErrnoDefault() const; bool isPICDefault() const; + bool isPIEDefault() const; bool isPICDefaultForced() const; }; @@ -572,6 +584,7 @@ public: virtual bool IsIntegratedAssemblerDefault() const; virtual bool IsUnwindTablesDefault() const; virtual bool isPICDefault() const; + virtual bool isPIEDefault() const; virtual bool isPICDefaultForced() const; virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs, diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 77a72ba..aba1fe4 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include <sys/stat.h> #include "Tools.h" #include "InputInfo.h" #include "SanitizerArgs.h" @@ -544,6 +545,9 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) { if (Triple.isOSDarwin()) return true; return false; + + case llvm::Triple::systemz: + return false; } } @@ -815,7 +819,9 @@ void Clang::AddARMTargetArgs(const ArgList &Args, CmdArgs.push_back("-mno-global-merge"); } - if (Args.hasArg(options::OPT_mno_implicit_float)) + if (!Args.hasFlag(options::OPT_mimplicit_float, + options::OPT_mno_implicit_float, + true)) CmdArgs.push_back("-no-implicit-float"); } @@ -851,8 +857,15 @@ static void getMipsCPUAndABI(const ArgList &Args, CPUName = A->getValue(); } - if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) + if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { ABIName = A->getValue(); + // Convert a GNU style Mips ABI name to the name + // accepted by LLVM Mips backend. + ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName) + .Case("32", "o32") + .Case("64", "n64") + .Default(ABIName); + } // Setup default CPU and ABI names. if (CPUName.empty() && ABIName.empty()) { @@ -899,8 +912,6 @@ static StringRef getGnuCompatibleMipsABIName(StringRef ABI) { // Select the MIPS float ABI as determined by -msoft-float, -mhard-float, // and -mfloat-abi=. static StringRef getMipsFloatABI(const Driver &D, const ArgList &Args) { - // Select the float ABI as determined by -msoft-float, -mhard-float, - // and -mfloat-abi=. StringRef FloatABI; if (Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, @@ -911,7 +922,7 @@ static StringRef getMipsFloatABI(const Driver &D, const ArgList &Args) { FloatABI = "hard"; else { FloatABI = A->getValue(); - if (FloatABI != "soft" && FloatABI != "single" && FloatABI != "hard") { + if (FloatABI != "soft" && FloatABI != "hard") { D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args); FloatABI = "hard"; } @@ -944,7 +955,7 @@ static void AddTargetFeature(const ArgList &Args, } void Clang::AddMIPSTargetArgs(const ArgList &Args, - ArgStringList &CmdArgs) const { + ArgStringList &CmdArgs) const { const Driver &D = getToolChain().getDriver(); StringRef CPUName; StringRef ABIName; @@ -977,12 +988,6 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args, CmdArgs.push_back("-mips16-hard-float"); } } - else if (FloatABI == "single") { - // Restrict the use of hardware floating-point - // instructions to 32-bit operations. - CmdArgs.push_back("-target-feature"); - CmdArgs.push_back("+single-float"); - } else { // Floating point operations and argument passing are hard. assert(FloatABI == "hard" && "Invalid float abi!"); @@ -991,9 +996,15 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args, } AddTargetFeature(Args, CmdArgs, + options::OPT_msingle_float, options::OPT_mdouble_float, + "single-float"); + AddTargetFeature(Args, CmdArgs, options::OPT_mips16, options::OPT_mno_mips16, "mips16"); AddTargetFeature(Args, CmdArgs, + options::OPT_mmicromips, options::OPT_mno_micromips, + "micromips"); + AddTargetFeature(Args, CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp, "dsp"); AddTargetFeature(Args, CmdArgs, @@ -1127,11 +1138,11 @@ static std::string getR600TargetGPU(const ArgList &Args) { if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { std::string GPUName = A->getValue(); return llvm::StringSwitch<const char *>(GPUName) - .Cases("rv610", "rv620", "rv630", "r600") - .Cases("rv635", "rs780", "rs880", "r600") + .Cases("rv630", "rv635", "r600") + .Cases("rv610", "rv620", "rs780", "rs880") .Case("rv740", "rv770") .Case("palm", "cedar") - .Cases("sumo", "sumo2", "redwood") + .Cases("sumo", "sumo2", "sumo") .Case("hemlock", "cypress") .Case("aruba", "cayman") .Default(GPUName.c_str()); @@ -1255,6 +1266,7 @@ void Clang::AddX86TargetArgs(const ArgList &Args, Args.hasArg(options::OPT_fapple_kext)); if (Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mno_soft_float, + options::OPT_mimplicit_float, options::OPT_mno_implicit_float)) { const Option &O = A->getOption(); NoImplicitFloat = (O.matches(options::OPT_mno_implicit_float) || @@ -1452,6 +1464,18 @@ static void addExceptionArgs(const ArgList &Args, types::ID InputType, CmdArgs.push_back("-fexceptions"); } +static bool ShouldDisableAutolink(const ArgList &Args, + const ToolChain &TC) { + bool Default = true; + if (TC.getTriple().isOSDarwin()) { + // The native darwin assembler doesn't support the linker_option directives, + // so we disable them if we think the .s file will be passed to it. + Default = TC.useIntegratedAs(); + } + return !Args.hasFlag(options::OPT_fautolink, options::OPT_fno_autolink, + Default); +} + static bool ShouldDisableCFI(const ArgList &Args, const ToolChain &TC) { bool Default = true; @@ -1508,11 +1532,12 @@ static bool UseRelaxAll(Compilation &C, const ArgList &Args) { RelaxDefault); } -SanitizerArgs::SanitizerArgs(const Driver &D, const ArgList &Args) +SanitizerArgs::SanitizerArgs(const ToolChain &TC, const ArgList &Args) : Kind(0), BlacklistFile(""), MsanTrackOrigins(false), AsanZeroBaseShadow(false) { unsigned AllKinds = 0; // All kinds of sanitizers that were turned on // at least once (possibly, disabled further). + const Driver &D = TC.getDriver(); for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) { unsigned Add, Remove; if (!parse(D, Args, *I, Add, Remove, true)) @@ -1604,11 +1629,20 @@ SanitizerArgs::SanitizerArgs(const Driver &D, const ArgList &Args) /* Default */false); // Parse -f(no-)sanitize-address-zero-base-shadow options. - if (NeedsAsan) + if (NeedsAsan) { + bool IsAndroid = (TC.getTriple().getEnvironment() == llvm::Triple::Android); + bool ZeroBaseShadowDefault = IsAndroid; AsanZeroBaseShadow = - Args.hasFlag(options::OPT_fsanitize_address_zero_base_shadow, - options::OPT_fno_sanitize_address_zero_base_shadow, - /* Default */false); + Args.hasFlag(options::OPT_fsanitize_address_zero_base_shadow, + options::OPT_fno_sanitize_address_zero_base_shadow, + ZeroBaseShadowDefault); + // Zero-base shadow is a requirement on Android. + if (IsAndroid && !AsanZeroBaseShadow) { + D.Diag(diag::err_drv_argument_not_allowed_with) + << "-fno-sanitize-address-zero-base-shadow" + << lastArgumentForKind(D, Args, Address); + } + } } static void addSanitizerRTLinkFlagsLinux( @@ -1637,6 +1671,7 @@ static void addSanitizerRTLinkFlagsLinux( LibSanitizerArgs.begin(), LibSanitizerArgs.end()); CmdArgs.push_back("-lpthread"); + CmdArgs.push_back("-lrt"); CmdArgs.push_back("-ldl"); // If possible, use a dynamic symbols file to export the symbols from the @@ -1656,11 +1691,6 @@ static void addSanitizerRTLinkFlagsLinux( static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { if(TC.getTriple().getEnvironment() == llvm::Triple::Android) { - if (!Args.hasArg(options::OPT_shared)) { - if (!Args.hasArg(options::OPT_pie)) - TC.getDriver().Diag(diag::err_drv_asan_android_requires_pie); - } - SmallString<128> LibAsan(TC.getDriver().ResourceDir); llvm::sys::path::append(LibAsan, "lib", "linux", (Twine("libclang_rt.asan-") + @@ -1668,13 +1698,6 @@ static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args, CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibAsan)); } else { if (!Args.hasArg(options::OPT_shared)) { - bool ZeroBaseShadow = Args.hasFlag( - options::OPT_fsanitize_address_zero_base_shadow, - options::OPT_fno_sanitize_address_zero_base_shadow, false); - if (ZeroBaseShadow && !Args.hasArg(options::OPT_pie)) { - TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) << - "-fsanitize-address-zero-base-shadow" << "-pie"; - } addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "asan", true); } } @@ -1685,9 +1708,6 @@ static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args, static void addTsanRTLinux(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { if (!Args.hasArg(options::OPT_shared)) { - if (!Args.hasArg(options::OPT_pie)) - TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) << - "-fsanitize=thread" << "-pie"; addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "tsan", true); } } @@ -1697,9 +1717,6 @@ static void addTsanRTLinux(const ToolChain &TC, const ArgList &Args, static void addMsanRTLinux(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { if (!Args.hasArg(options::OPT_shared)) { - if (!Args.hasArg(options::OPT_pie)) - TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) << - "-fsanitize=memory" << "-pie"; addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "msan", true); } } @@ -1764,14 +1781,27 @@ static bool shouldUseLeafFramePointer(const ArgList &Args, /// If the PWD environment variable is set, add a CC1 option to specify the /// debug compilation directory. static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs) { - if (const char *pwd = ::getenv("PWD")) { - // GCC also verifies that stat(pwd) and stat(".") have the same inode - // number. Not doing those because stats are slow, but we could. - if (llvm::sys::path::is_absolute(pwd)) { - std::string CompDir = pwd; - CmdArgs.push_back("-fdebug-compilation-dir"); - CmdArgs.push_back(Args.MakeArgString(CompDir)); - } + struct stat StatPWDBuf, StatDotBuf; + + const char *pwd = ::getenv("PWD"); + if (!pwd) + return; + + if (llvm::sys::path::is_absolute(pwd) && + stat(pwd, &StatPWDBuf) == 0 && + stat(".", &StatDotBuf) == 0 && + StatPWDBuf.st_ino == StatDotBuf.st_ino && + StatPWDBuf.st_dev == StatDotBuf.st_dev) { + CmdArgs.push_back("-fdebug-compilation-dir"); + CmdArgs.push_back(Args.MakeArgString(pwd)); + return; + } + + // Fall back to using getcwd. + SmallString<128> cwd; + if (!llvm::sys::fs::current_path(cwd)) { + CmdArgs.push_back("-fdebug-compilation-dir"); + CmdArgs.push_back(Args.MakeArgString(cwd)); } } @@ -1817,6 +1847,13 @@ static void SplitDebugInfo(const ToolChain &TC, Compilation &C, C.addCommand(new Command(JA, T, Exec, StripArgs)); } +static bool isOptimizationLevelFast(const ArgList &Args) { + if (Arg *A = Args.getLastArg(options::OPT_O_Group)) + if (A->getOption().matches(options::OPT_Ofast)) + return true; + return false; +} + void Clang::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -1969,6 +2006,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-analyzer-checker=deadcode"); + if (types::isCXX(Inputs[0].getType())) + CmdArgs.push_back("-analyzer-checker=cplusplus"); + // Enable the following experimental checkers for testing. CmdArgs.push_back("-analyzer-checker=security.insecureAPI.UncheckedReturn"); CmdArgs.push_back("-analyzer-checker=security.insecureAPI.getpw"); @@ -1997,37 +2037,38 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CheckCodeGenerationOptions(D, Args); - // For the PIC and PIE flag options, this logic is different from the legacy - // logic in very old versions of GCC, as that logic was just a bug no one had - // ever fixed. This logic is both more rational and consistent with GCC's new - // logic now that the bugs are fixed. The last argument relating to either - // PIC or PIE wins, and no other argument is used. If the last argument is - // any flavor of the '-fno-...' arguments, both PIC and PIE are disabled. Any - // PIE option implicitly enables PIC at the same level. - bool PIE = false; - bool PIC = getToolChain().isPICDefault(); + bool PIE = getToolChain().isPIEDefault(); + bool PIC = PIE || getToolChain().isPICDefault(); bool IsPICLevelTwo = PIC; - if (Arg *A = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, - options::OPT_fpic, options::OPT_fno_pic, - options::OPT_fPIE, options::OPT_fno_PIE, - options::OPT_fpie, options::OPT_fno_pie)) { - Option O = A->getOption(); - if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) || - O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) { - PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie); - PIC = PIE || O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic); - IsPICLevelTwo = O.matches(options::OPT_fPIE) || - O.matches(options::OPT_fPIC); - } else { - PIE = PIC = false; - } - } + + // For the PIC and PIE flag options, this logic is different from the + // legacy logic in very old versions of GCC, as that logic was just + // a bug no one had ever fixed. This logic is both more rational and + // consistent with GCC's new logic now that the bugs are fixed. The last + // argument relating to either PIC or PIE wins, and no other argument is + // used. If the last argument is any flavor of the '-fno-...' arguments, + // both PIC and PIE are disabled. Any PIE option implicitly enables PIC + // at the same level. + Arg *LastPICArg =Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, + options::OPT_fpic, options::OPT_fno_pic, + options::OPT_fPIE, options::OPT_fno_PIE, + options::OPT_fpie, options::OPT_fno_pie); // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness // is forced, then neither PIC nor PIE flags will have no effect. - if (getToolChain().isPICDefaultForced()) { - PIE = false; - PIC = getToolChain().isPICDefault(); - IsPICLevelTwo = PIC; + if (!getToolChain().isPICDefaultForced()) { + if (LastPICArg) { + Option O = LastPICArg->getOption(); + if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) || + O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) { + PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie); + PIC = PIE || O.matches(options::OPT_fPIC) || + O.matches(options::OPT_fpic); + IsPICLevelTwo = O.matches(options::OPT_fPIE) || + O.matches(options::OPT_fPIC); + } else { + PIE = PIC = false; + } + } } // Inroduce a Darwin-specific hack. If the default is PIC but the flags @@ -2101,7 +2142,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss, options::OPT_fno_zero_initialized_in_bss)) CmdArgs.push_back("-mno-zero-initialized-in-bss"); - if (!Args.hasFlag(options::OPT_fstrict_aliasing, + + bool OFastEnabled = isOptimizationLevelFast(Args); + // If -Ofast is the optimization level, then -fstrict-aliasing should be + // enabled. This alias option is being used to simplify the hasFlag logic. + OptSpecifier StrictAliasingAliasOption = OFastEnabled ? options::OPT_Ofast : + options::OPT_fstrict_aliasing; + if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption, options::OPT_fno_strict_aliasing, getToolChain().IsStrictAliasingDefault())) CmdArgs.push_back("-relaxed-aliasing"); @@ -2117,13 +2164,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Handle segmented stacks. if (Args.hasArg(options::OPT_fsplit_stack)) CmdArgs.push_back("-split-stacks"); + + // If -Ofast is the optimization level, then -ffast-math should be enabled. + // This alias option is being used to simplify the getLastArg logic. + OptSpecifier FastMathAliasOption = OFastEnabled ? options::OPT_Ofast : + options::OPT_ffast_math; // Handle various floating point optimization flags, mapping them to the // appropriate LLVM code generation flags. The pattern for all of these is to // default off the codegen optimizations, and if any flag enables them and no // flag disables them after the flag enabling them, enable the codegen // optimization. This is complicated by several "umbrella" flags. - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_ffinite_math_only, options::OPT_fno_finite_math_only, @@ -2133,7 +2185,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, A->getOption().getID() != options::OPT_fno_finite_math_only && A->getOption().getID() != options::OPT_fhonor_infinities) CmdArgs.push_back("-menable-no-infs"); - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_ffinite_math_only, options::OPT_fno_finite_math_only, @@ -2146,7 +2198,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes. bool MathErrno = getToolChain().IsMathErrnoDefault(); - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_fmath_errno, options::OPT_fno_math_errno)) @@ -2159,7 +2211,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // entire set of LLVM optimizations, so collect them through all the flag // madness. bool AssociativeMath = false; - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations, options::OPT_fno_unsafe_math_optimizations, @@ -2170,7 +2222,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, A->getOption().getID() != options::OPT_fno_associative_math) AssociativeMath = true; bool ReciprocalMath = false; - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations, options::OPT_fno_unsafe_math_optimizations, @@ -2181,7 +2233,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, A->getOption().getID() != options::OPT_fno_reciprocal_math) ReciprocalMath = true; bool SignedZeros = true; - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations, options::OPT_fno_unsafe_math_optimizations, @@ -2192,7 +2244,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, A->getOption().getID() != options::OPT_fsigned_zeros) SignedZeros = false; bool TrappingMath = true; - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations, options::OPT_fno_unsafe_math_optimizations, @@ -2208,7 +2260,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Validate and pass through -fp-contract option. - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_ffp_contract)) { if (A->getOption().getID() == options::OPT_ffp_contract) { @@ -2219,7 +2271,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, D.Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName() << Val; } - } else if (A->getOption().getID() == options::OPT_ffast_math) { + } else if (A->getOption().matches(options::OPT_ffast_math) || + (OFastEnabled && A->getOption().matches(options::OPT_Ofast))) { // If fast-math is set then set the fp-contract mode to fast. CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast")); } @@ -2230,9 +2283,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // preprocessor macros. This is distinct from enabling any optimizations as // these options induce language changes which must survive serialization // and deserialization, etc. - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math)) - if (A->getOption().matches(options::OPT_ffast_math)) - CmdArgs.push_back("-ffast-math"); + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, + options::OPT_fno_fast_math)) + if (!A->getOption().matches(options::OPT_fno_fast_math)) + CmdArgs.push_back("-ffast-math"); if (Arg *A = Args.getLastArg(options::OPT_ffinite_math_only, options::OPT_fno_fast_math)) if (A->getOption().matches(options::OPT_ffinite_math_only)) CmdArgs.push_back("-ffinite-math-only"); @@ -2597,6 +2651,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (ShouldDisableDwarfDirectory(Args, getToolChain())) CmdArgs.push_back("-fno-dwarf-directory-asm"); + if (ShouldDisableAutolink(Args, getToolChain())) + CmdArgs.push_back("-fno-autolink"); + // Add in -fdebug-compilation-dir if necessary. addDebugCompDirArg(Args, CmdArgs); @@ -2705,7 +2762,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree); Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type); - SanitizerArgs Sanitize(D, Args); + SanitizerArgs Sanitize(getToolChain(), Args); Sanitize.addArgs(Args, CmdArgs); if (!Args.hasFlag(options::OPT_fsanitize_recover, @@ -2892,16 +2949,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval); Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after); - // -fmodules-autolink (on by default when modules is enabled) automatically - // links against libraries for imported modules. This requires the - // integrated assembler. - if (HaveModules && getToolChain().useIntegratedAs() && - Args.hasFlag(options::OPT_fmodules_autolink, - options::OPT_fno_modules_autolink, - true)) { - CmdArgs.push_back("-fmodules-autolink"); - } - // -faccess-control is default. if (Args.hasFlag(options::OPT_fno_access_control, options::OPT_faccess_control, @@ -3198,9 +3245,42 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Color diagnostics are the default, unless the terminal doesn't support // them. - if (Args.hasFlag(options::OPT_fcolor_diagnostics, - options::OPT_fno_color_diagnostics, - llvm::sys::Process::StandardErrHasColors())) + // Support both clang's -f[no-]color-diagnostics and gcc's + // -f[no-]diagnostics-colors[=never|always|auto]. + enum { Colors_On, Colors_Off, Colors_Auto } ShowColors = Colors_Auto; + for (ArgList::const_iterator it = Args.begin(), ie = Args.end(); + it != ie; ++it) { + const Option &O = (*it)->getOption(); + if (!O.matches(options::OPT_fcolor_diagnostics) && + !O.matches(options::OPT_fdiagnostics_color) && + !O.matches(options::OPT_fno_color_diagnostics) && + !O.matches(options::OPT_fno_diagnostics_color) && + !O.matches(options::OPT_fdiagnostics_color_EQ)) + continue; + + (*it)->claim(); + if (O.matches(options::OPT_fcolor_diagnostics) || + O.matches(options::OPT_fdiagnostics_color)) { + ShowColors = Colors_On; + } else if (O.matches(options::OPT_fno_color_diagnostics) || + O.matches(options::OPT_fno_diagnostics_color)) { + ShowColors = Colors_Off; + } else { + assert(O.matches(options::OPT_fdiagnostics_color_EQ)); + StringRef value((*it)->getValue()); + if (value == "always") + ShowColors = Colors_On; + else if (value == "never") + ShowColors = Colors_Off; + else if (value == "auto") + ShowColors = Colors_Auto; + else + getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) + << ("-fdiagnostics-color=" + value).str(); + } + } + if (ShowColors == Colors_On || + (ShowColors == Colors_Auto && llvm::sys::Process::StandardErrHasColors())) CmdArgs.push_back("-fcolor-diagnostics"); if (!Args.hasFlag(options::OPT_fshow_source_location, @@ -3222,8 +3302,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, false)) CmdArgs.push_back("-fasm-blocks"); + // If -Ofast is the optimization level, then -fvectorize should be enabled. + // This alias option is being used to simplify the hasFlag logic. + OptSpecifier VectorizeAliasOption = OFastEnabled ? options::OPT_Ofast : + options::OPT_fvectorize; + // -fvectorize is default. - if (Args.hasFlag(options::OPT_fvectorize, + if (Args.hasFlag(options::OPT_fvectorize, VectorizeAliasOption, options::OPT_fno_vectorize, true)) { CmdArgs.push_back("-backend-option"); CmdArgs.push_back("-vectorize-loops"); @@ -3233,7 +3318,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasFlag(options::OPT_fslp_vectorize, options::OPT_fno_slp_vectorize, false)) { CmdArgs.push_back("-backend-option"); - CmdArgs.push_back("-vectorize"); + CmdArgs.push_back("-vectorize-slp"); + } + + // -fno-slp-vectorize-aggressive is default. + if (Args.hasFlag(options::OPT_fslp_vectorize_aggressive, + options::OPT_fno_slp_vectorize_aggressive, false)) { + CmdArgs.push_back("-backend-option"); + CmdArgs.push_back("-vectorize-slp-aggressive"); } if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ)) @@ -3298,6 +3390,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Forward -fcomment-block-commands to -cc1. Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands); + // Forward -fparse-all-comments to -cc1. + Args.AddAllArgs(CmdArgs, options::OPT_fparse_all_comments); // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option // parser. @@ -3673,6 +3767,14 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = getToolChain().getDriver().getClangProgramPath(); C.addCommand(new Command(JA, *this, Exec, CmdArgs)); + + // Handle the debug info splitting at object creation time if we're + // creating an object. + // TODO: Currently only works on linux with newer objcopy. + if (Args.hasArg(options::OPT_gsplit_dwarf) && + (getToolChain().getTriple().getOS() == llvm::Triple::Linux)) + SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, + SplitDebugName(Args, Inputs)); } void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, @@ -3867,7 +3969,6 @@ void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back( Args.MakeArgString(std::string("-G") + SmallDataThreshold)); - Args.AddAllArgs(CmdArgs, options::OPT_g_Group); Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); @@ -4579,7 +4680,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_L); - SanitizerArgs Sanitize(getToolChain().getDriver(), Args); + SanitizerArgs Sanitize(getToolChain(), Args); // If we're building a dynamic lib with -fsanitize=address, // unresolved symbols may appear. Mark all // of them as dynamic_lookup. Linking executables is handled in @@ -5706,6 +5807,12 @@ void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, else CmdArgs.push_back("-EL"); + Args.AddLastArg(CmdArgs, options::OPT_mips16, options::OPT_mno_mips16); + Args.AddLastArg(CmdArgs, options::OPT_mmicromips, + options::OPT_mno_micromips); + Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp); + Args.AddLastArg(CmdArgs, options::OPT_mdspr2, options::OPT_mno_dspr2); + Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, options::OPT_fpic, options::OPT_fno_pic, options::OPT_fPIE, options::OPT_fno_PIE, @@ -5717,6 +5824,9 @@ void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, LastPICArg->getOption().matches(options::OPT_fpie))) { CmdArgs.push_back("-KPIC"); } + } else if (getToolChain().getArch() == llvm::Triple::systemz) { + // At the moment we always produce z10 code. + CmdArgs.push_back("-march=z10"); } Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, @@ -5784,6 +5894,10 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, const Driver &D = ToolChain.getDriver(); const bool isAndroid = ToolChain.getTriple().getEnvironment() == llvm::Triple::Android; + SanitizerArgs Sanitize(getToolChain(), Args); + const bool IsPIE = + !Args.hasArg(options::OPT_shared) && + (Args.hasArg(options::OPT_pie) || Sanitize.hasZeroBaseShadow()); ArgStringList CmdArgs; @@ -5798,7 +5912,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, if (!D.SysRoot.empty()) CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); - if (Args.hasArg(options::OPT_pie) && !Args.hasArg(options::OPT_shared)) + if (IsPIE) CmdArgs.push_back("-pie"); if (Args.hasArg(options::OPT_rdynamic)) @@ -5844,6 +5958,8 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, else CmdArgs.push_back("elf64ltsmip"); } + else if (ToolChain.getArch() == llvm::Triple::systemz) + CmdArgs.push_back("elf64_s390"); else CmdArgs.push_back("elf_x86_64"); @@ -5890,7 +6006,8 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, } else if (ToolChain.getArch() == llvm::Triple::ppc) CmdArgs.push_back("/lib/ld.so.1"); - else if (ToolChain.getArch() == llvm::Triple::ppc64) + else if (ToolChain.getArch() == llvm::Triple::ppc64 || + ToolChain.getArch() == llvm::Triple::systemz) CmdArgs.push_back("/lib64/ld64.so.1"); else CmdArgs.push_back("/lib64/ld-linux-x86-64.so.2"); @@ -5904,7 +6021,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, if (!isAndroid) { const char *crt1 = NULL; if (!Args.hasArg(options::OPT_shared)){ - if (Args.hasArg(options::OPT_pie)) + if (IsPIE) crt1 = "Scrt1.o"; else crt1 = "crt1.o"; @@ -5920,7 +6037,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o"; else if (Args.hasArg(options::OPT_shared)) crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o"; - else if (Args.hasArg(options::OPT_pie)) + else if (IsPIE) crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o"; else crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o"; @@ -5971,8 +6088,6 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs); - SanitizerArgs Sanitize(D, Args); - // Call these before we add the C++ ABI library. if (Sanitize.needsUbsanRt()) addUbsanRTLinux(getToolChain(), Args, CmdArgs, D.CCCIsCXX, @@ -6030,7 +6145,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, const char *crtend; if (Args.hasArg(options::OPT_shared)) crtend = isAndroid ? "crtend_so.o" : "crtendS.o"; - else if (Args.hasArg(options::OPT_pie)) + else if (IsPIE) crtend = isAndroid ? "crtend_android.o" : "crtendS.o"; else crtend = isAndroid ? "crtend_android.o" : "crtend.o"; @@ -6162,21 +6277,29 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { + bool UseGCC47 = false; const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; + if (llvm::sys::fs::exists("/usr/lib/gcc47", UseGCC47)) + UseGCC47 = false; + if (!D.SysRoot.empty()) CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); + CmdArgs.push_back("--eh-frame-hdr"); if (Args.hasArg(options::OPT_static)) { CmdArgs.push_back("-Bstatic"); } else { + if (Args.hasArg(options::OPT_rdynamic)) + CmdArgs.push_back("-export-dynamic"); if (Args.hasArg(options::OPT_shared)) CmdArgs.push_back("-Bshareable"); else { CmdArgs.push_back("-dynamic-linker"); CmdArgs.push_back("/usr/libexec/ld-elf.so.2"); } + CmdArgs.push_back("--hash-style=both"); } // When building 32-bit code on DragonFly/pc64, we have to explicitly @@ -6196,18 +6319,26 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nostartfiles)) { if (!Args.hasArg(options::OPT_shared)) { - CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crt1.o"))); - CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crti.o"))); - CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); - } else { - CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crti.o"))); - CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o"))); + if (Args.hasArg(options::OPT_pg)) + CmdArgs.push_back(Args.MakeArgString( + getToolChain().GetFilePath("gcrt1.o"))); + else { + if (Args.hasArg(options::OPT_pie)) + CmdArgs.push_back(Args.MakeArgString( + getToolChain().GetFilePath("Scrt1.o"))); + else + CmdArgs.push_back(Args.MakeArgString( + getToolChain().GetFilePath("crt1.o"))); + } } + CmdArgs.push_back(Args.MakeArgString( + getToolChain().GetFilePath("crti.o"))); + if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) + CmdArgs.push_back(Args.MakeArgString( + getToolChain().GetFilePath("crtbeginS.o"))); + else + CmdArgs.push_back(Args.MakeArgString( + getToolChain().GetFilePath("crtbegin.o"))); } Args.AddAllArgs(CmdArgs, options::OPT_L); @@ -6220,20 +6351,19 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, !Args.hasArg(options::OPT_nodefaultlibs)) { // FIXME: GCC passes on -lgcc, -lgcc_pic and a whole lot of // rpaths - CmdArgs.push_back("-L/usr/lib/gcc41"); + if (UseGCC47) + CmdArgs.push_back("-L/usr/lib/gcc47"); + else + CmdArgs.push_back("-L/usr/lib/gcc44"); if (!Args.hasArg(options::OPT_static)) { - CmdArgs.push_back("-rpath"); - CmdArgs.push_back("/usr/lib/gcc41"); - - CmdArgs.push_back("-rpath-link"); - CmdArgs.push_back("/usr/lib/gcc41"); - - CmdArgs.push_back("-rpath"); - CmdArgs.push_back("/usr/lib"); - - CmdArgs.push_back("-rpath-link"); - CmdArgs.push_back("/usr/lib"); + if (UseGCC47) { + CmdArgs.push_back("-rpath"); + CmdArgs.push_back("/usr/lib/gcc47"); + } else { + CmdArgs.push_back("-rpath"); + CmdArgs.push_back("/usr/lib/gcc44"); + } } if (D.CCCIsCXX) { @@ -6241,13 +6371,6 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-lm"); } - if (Args.hasArg(options::OPT_shared)) { - CmdArgs.push_back("-lgcc_pic"); - } else { - CmdArgs.push_back("-lgcc"); - } - - if (Args.hasArg(options::OPT_pthread)) CmdArgs.push_back("-lpthread"); @@ -6255,23 +6378,42 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-lc"); } - if (Args.hasArg(options::OPT_shared)) { - CmdArgs.push_back("-lgcc_pic"); + if (UseGCC47) { + if (Args.hasArg(options::OPT_static) || + Args.hasArg(options::OPT_static_libgcc)) { + CmdArgs.push_back("-lgcc"); + CmdArgs.push_back("-lgcc_eh"); + } else { + if (Args.hasArg(options::OPT_shared_libgcc)) { + CmdArgs.push_back("-lgcc_pic"); + if (!Args.hasArg(options::OPT_shared)) + CmdArgs.push_back("-lgcc"); + } else { + CmdArgs.push_back("-lgcc"); + CmdArgs.push_back("--as-needed"); + CmdArgs.push_back("-lgcc_pic"); + CmdArgs.push_back("--no-as-needed"); + } + } } else { - CmdArgs.push_back("-lgcc"); + if (Args.hasArg(options::OPT_shared)) { + CmdArgs.push_back("-lgcc_pic"); + } else { + CmdArgs.push_back("-lgcc"); + } } } if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nostartfiles)) { - if (!Args.hasArg(options::OPT_shared)) + if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtend.o"))); + getToolChain().GetFilePath("crtendS.o"))); else CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtendS.o"))); + getToolChain().GetFilePath("crtend.o"))); CmdArgs.push_back(Args.MakeArgString( - getToolChain().GetFilePath("crtn.o"))); + getToolChain().GetFilePath("crtn.o"))); } addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); diff --git a/lib/Driver/WindowsToolChain.cpp b/lib/Driver/WindowsToolChain.cpp index dac7e77..622c492 100644 --- a/lib/Driver/WindowsToolChain.cpp +++ b/lib/Driver/WindowsToolChain.cpp @@ -60,6 +60,10 @@ bool Windows::isPICDefault() const { return getArch() == llvm::Triple::x86_64; } +bool Windows::isPIEDefault() const { + return false; +} + bool Windows::isPICDefaultForced() const { return getArch() == llvm::Triple::x86_64; } |