Update aosp/master clang for rebase to r230699.
Change-Id: I6a546ab3d4ae37119eebb735e102cca4f80ab520
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 28b9068..b0e581b 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -10,9 +10,11 @@
#include "Tools.h"
#include "InputInfo.h"
#include "ToolChains.h"
+#include "clang/Basic/CharInfo.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Version.h"
+#include "clang/Config/config.h"
#include "clang/Driver/Action.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
@@ -32,13 +34,16 @@
#include "llvm/Support/Compression.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Format.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h"
+#ifdef LLVM_ON_UNIX
+#include <unistd.h> // For getuid().
+#endif
+
using namespace clang::driver;
using namespace clang::driver::tools;
using namespace clang;
@@ -589,6 +594,12 @@
Features.push_back("+crypto");
} else if (FPU == "neon") {
Features.push_back("+neon");
+ } else if (FPU == "neon-vfpv3") {
+ Features.push_back("+vfp3");
+ Features.push_back("+neon");
+ } else if (FPU == "neon-vfpv4") {
+ Features.push_back("+neon");
+ Features.push_back("+vfp4");
} else if (FPU == "none") {
Features.push_back("-vfp2");
Features.push_back("-vfp3");
@@ -759,6 +770,7 @@
// Select the ABI to use.
//
// FIXME: Support -meabi.
+ // FIXME: Parts of this are duplicated in the backend, unify this somehow.
const char *ABIName = nullptr;
if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
ABIName = A->getValue();
@@ -766,8 +778,7 @@
// The backend is hardwired to assume AAPCS for M-class processors, ensure
// the frontend matches that.
if (Triple.getEnvironment() == llvm::Triple::EABI ||
- (Triple.getOS() == llvm::Triple::UnknownOS &&
- Triple.getObjectFormat() == llvm::Triple::MachO) ||
+ Triple.getOS() == llvm::Triple::UnknownOS ||
StringRef(CPUName).startswith("cortex-m")) {
ABIName = "aapcs";
} else {
@@ -932,6 +943,19 @@
CmdArgs.push_back("-aarch64-no-strict-align");
}
+ if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769,
+ options::OPT_mno_fix_cortex_a53_835769)) {
+ CmdArgs.push_back("-backend-option");
+ if (A->getOption().matches(options::OPT_mfix_cortex_a53_835769))
+ CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1");
+ else
+ CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=0");
+ } else if (Triple.getEnvironment() == llvm::Triple::Android) {
+ // Enabled A53 errata (835769) workaround by default on android
+ CmdArgs.push_back("-backend-option");
+ CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1");
+ }
+
// Setting -mno-global-merge disables the codegen global merge pass. Setting
// -mglobal-merge has no effect as the pass is enabled by default.
if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
@@ -939,6 +963,11 @@
if (A->getOption().matches(options::OPT_mno_global_merge))
CmdArgs.push_back("-mno-global-merge");
}
+
+ if (Args.hasArg(options::OPT_ffixed_x18)) {
+ CmdArgs.push_back("-backend-option");
+ CmdArgs.push_back("-aarch64-reserve-x18");
+ }
}
// Get CPU and ABI names. They are not independent
@@ -958,6 +987,10 @@
DefMips64CPU = "mips64r6";
}
+ // MIPS3 is the default for mips64*-unknown-openbsd.
+ if (Triple.getOS() == llvm::Triple::OpenBSD)
+ DefMips64CPU = "mips3";
+
if (Arg *A = Args.getLastArg(options::OPT_march_EQ,
options::OPT_mcpu_EQ))
CPUName = A->getValue();
@@ -1067,17 +1100,6 @@
mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
ABIName = getGnuCompatibleMipsABIName(ABIName);
- // Always override the backend's default ABI.
- std::string ABIFeature = llvm::StringSwitch<StringRef>(ABIName)
- .Case("32", "+o32")
- .Case("n32", "+n32")
- .Case("64", "+n64")
- .Case("eabi", "+eabi")
- .Default(("+" + ABIName).str());
- Features.push_back("-o32");
- Features.push_back("-n64");
- Features.push_back(Args.MakeArgString(ABIFeature));
-
AddTargetFeature(Args, Features, options::OPT_mno_abicalls,
options::OPT_mabicalls, "noabicalls");
@@ -1416,6 +1438,10 @@
return Is64Bit ? "core2" : "yonah";
}
+ // Set up default CPU name for PS4 compilers.
+ if (Triple.isPS4CPU())
+ return "btver2";
+
// On Android use targets compatible with gcc
if (Triple.getEnvironment() == llvm::Triple::Android)
return Is64Bit ? "x86-64" : "i686";
@@ -1499,6 +1525,7 @@
return getSystemZTargetCPU(Args);
case llvm::Triple::r600:
+ case llvm::Triple::amdgcn:
return getR600TargetGPU(Args);
}
}
@@ -1509,7 +1536,7 @@
// as gold requires -plugin to come before any -plugin-opt that -Wl might
// forward.
CmdArgs.push_back("-plugin");
- std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so";
+ std::string Plugin = ToolChain.getDriver().Dir + "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold.so";
CmdArgs.push_back(Args.MakeArgString(Plugin));
// Try to pass driver level flags relevant to LTO code generation down to
@@ -1704,7 +1731,7 @@
std::vector<const char *> &Features) {
std::pair<StringRef, StringRef> Split = Mcpu.split("+");
CPU = Split.first;
- if (CPU == "cyclone" || CPU == "cortex-a53" || CPU == "cortex-a57") {
+ if (CPU == "cyclone" || CPU == "cortex-a53" || CPU == "cortex-a57" || CPU == "cortex-a72") {
Features.push_back("+neon");
Features.push_back("+crc");
Features.push_back("+crypto");
@@ -1893,55 +1920,28 @@
Triple.getArch() == llvm::Triple::arm));
}
-namespace {
- struct ExceptionSettings {
- bool ExceptionsEnabled;
- bool ShouldUseExceptionTables;
- ExceptionSettings() : ExceptionsEnabled(false),
- ShouldUseExceptionTables(false) {}
- };
-} // end anonymous namespace.
-
// exceptionSettings() exists to share the logic between -cc1 and linker
// invocations.
-static ExceptionSettings exceptionSettings(const ArgList &Args,
- const llvm::Triple &Triple) {
- ExceptionSettings ES;
-
- // Are exceptions enabled by default?
- ES.ExceptionsEnabled = (Triple.getArch() != llvm::Triple::xcore);
-
- // This keeps track of whether exceptions were explicitly turned on or off.
- bool DidHaveExplicitExceptionFlag = false;
-
+static bool exceptionSettings(const ArgList &Args, const llvm::Triple &Triple) {
if (Arg *A = Args.getLastArg(options::OPT_fexceptions,
- options::OPT_fno_exceptions)) {
+ options::OPT_fno_exceptions))
if (A->getOption().matches(options::OPT_fexceptions))
- ES.ExceptionsEnabled = true;
- else
- ES.ExceptionsEnabled = false;
+ return true;
- DidHaveExplicitExceptionFlag = true;
- }
-
- // Exception tables and cleanups can be enabled with -fexceptions even if the
- // language itself doesn't support exceptions.
- if (ES.ExceptionsEnabled && DidHaveExplicitExceptionFlag)
- ES.ShouldUseExceptionTables = true;
-
- return ES;
+ return false;
}
-/// addExceptionArgs - Adds exception related arguments to the driver command
-/// arguments. There's a master flag, -fexceptions and also language specific
-/// flags to enable/disable C++ and Objective-C exceptions.
-/// This makes it possible to for example disable C++ exceptions but enable
-/// Objective-C exceptions.
+/// Adds exception related arguments to the driver command arguments. There's a
+/// master flag, -fexceptions and also language specific flags to enable/disable
+/// C++ and Objective-C exceptions. This makes it possible to for example
+/// disable C++ exceptions but enable Objective-C exceptions.
static void addExceptionArgs(const ArgList &Args, types::ID InputType,
- const llvm::Triple &Triple,
- bool KernelOrKext,
+ const ToolChain &TC, bool KernelOrKext,
const ObjCRuntime &objcRuntime,
ArgStringList &CmdArgs) {
+ const Driver &D = TC.getDriver();
+ const llvm::Triple &Triple = TC.getTriple();
+
if (KernelOrKext) {
// -mkernel and -fapple-kext imply no exceptions, so claim exception related
// arguments now to avoid warnings about unused arguments.
@@ -1954,8 +1954,8 @@
return;
}
- // Gather the exception settings from the command line arguments.
- ExceptionSettings ES = exceptionSettings(Args, Triple);
+ // Gather the exception settings from the command line arguments.
+ bool EH = exceptionSettings(Args, Triple);
// Obj-C exceptions are enabled by default, regardless of -fexceptions. This
// is not necessarily sensible, but follows GCC.
@@ -1965,31 +1965,43 @@
true)) {
CmdArgs.push_back("-fobjc-exceptions");
- ES.ShouldUseExceptionTables |=
- shouldUseExceptionTablesForObjCExceptions(objcRuntime, Triple);
+ EH |= shouldUseExceptionTablesForObjCExceptions(objcRuntime, Triple);
}
if (types::isCXX(InputType)) {
- bool CXXExceptionsEnabled = ES.ExceptionsEnabled;
-
- if (Arg *A = Args.getLastArg(options::OPT_fcxx_exceptions,
- options::OPT_fno_cxx_exceptions,
- options::OPT_fexceptions,
- options::OPT_fno_exceptions)) {
- if (A->getOption().matches(options::OPT_fcxx_exceptions))
- CXXExceptionsEnabled = true;
- else if (A->getOption().matches(options::OPT_fno_cxx_exceptions))
- CXXExceptionsEnabled = false;
- }
+ bool CXXExceptionsEnabled =
+ Triple.getArch() != llvm::Triple::xcore && !Triple.isPS4CPU();
+ Arg *ExceptionArg = Args.getLastArg(
+ options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions,
+ options::OPT_fexceptions, options::OPT_fno_exceptions);
+ if (ExceptionArg)
+ CXXExceptionsEnabled =
+ ExceptionArg->getOption().matches(options::OPT_fcxx_exceptions) ||
+ ExceptionArg->getOption().matches(options::OPT_fexceptions);
if (CXXExceptionsEnabled) {
+ if (Triple.isPS4CPU()) {
+ ToolChain::RTTIMode RTTIMode = TC.getRTTIMode();
+ assert(ExceptionArg &&
+ "On the PS4 exceptions should only be enabled if passing "
+ "an argument");
+ if (RTTIMode == ToolChain::RM_DisabledExplicitly) {
+ const Arg *RTTIArg = TC.getRTTIArg();
+ assert(RTTIArg && "RTTI disabled explicitly but no RTTIArg!");
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << RTTIArg->getAsString(Args) << ExceptionArg->getAsString(Args);
+ } else if (RTTIMode == ToolChain::RM_EnabledImplicitly)
+ D.Diag(diag::warn_drv_enabling_rtti_with_exceptions);
+ } else
+ assert(TC.getRTTIMode() != ToolChain::RM_DisabledImplicitly);
+
CmdArgs.push_back("-fcxx-exceptions");
- ES.ShouldUseExceptionTables = true;
+ EH = true;
}
}
- if (ES.ShouldUseExceptionTables)
+ if (EH)
CmdArgs.push_back("-fexceptions");
}
@@ -2015,7 +2027,7 @@
/// \brief Check whether the given input tree contains any compilation actions.
static bool ContainsCompileAction(const Action *A) {
- if (isa<CompileJobAction>(A))
+ if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A))
return true;
for (const auto &Act : *A)
@@ -2116,11 +2128,13 @@
// Until ARM libraries are build separately, we have them all in one library
static StringRef getArchNameForCompilerRTLib(const ToolChain &TC) {
- if (TC.getArch() == llvm::Triple::arm ||
- TC.getArch() == llvm::Triple::armeb)
+ // FIXME: handle 64-bit
+ if (TC.getTriple().isOSWindows() &&
+ !TC.getTriple().isWindowsItaniumEnvironment())
+ return "i386";
+ if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb)
return "arm";
- else
- return TC.getArchName();
+ return TC.getArchName();
}
static SmallString<128> getCompilerRTLibDir(const ToolChain &TC) {
@@ -2128,38 +2142,48 @@
SmallString<128> Res(TC.getDriver().ResourceDir);
const llvm::Triple &Triple = TC.getTriple();
// TC.getOS() yield "freebsd10.0" whereas "freebsd" is expected.
- StringRef OSLibName = (Triple.getOS() == llvm::Triple::FreeBSD) ?
- "freebsd" : TC.getOS();
+ StringRef OSLibName =
+ (Triple.getOS() == llvm::Triple::FreeBSD) ? "freebsd" : TC.getOS();
llvm::sys::path::append(Res, "lib", OSLibName);
return Res;
}
+static SmallString<128> getCompilerRT(const ToolChain &TC, StringRef Component,
+ bool Shared = false) {
+ const char *Env = TC.getTriple().getEnvironment() == llvm::Triple::Android
+ ? "-android"
+ : "";
+
+ bool IsOSWindows = TC.getTriple().isOSWindows();
+ StringRef Arch = getArchNameForCompilerRTLib(TC);
+ const char *Prefix = IsOSWindows ? "" : "lib";
+ const char *Suffix =
+ Shared ? (IsOSWindows ? ".dll" : ".so") : (IsOSWindows ? ".lib" : ".a");
+
+ SmallString<128> Path = getCompilerRTLibDir(TC);
+ llvm::sys::path::append(Path, Prefix + Twine("clang_rt.") + Component + "-" +
+ Arch + Env + Suffix);
+
+ return Path;
+}
+
// This adds the static libclang_rt.builtins-arch.a directly to the command line
// FIXME: Make sure we can also emit shared objects if they're requested
// and available, check for possible errors, etc.
-static void addClangRTLinux(
- const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) {
- SmallString<128> LibClangRT = getCompilerRTLibDir(TC);
- llvm::sys::path::append(LibClangRT, Twine("libclang_rt.builtins-") +
- getArchNameForCompilerRTLib(TC) +
- ".a");
+static void addClangRT(const ToolChain &TC, const ArgList &Args,
+ ArgStringList &CmdArgs) {
+ CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, "builtins")));
- CmdArgs.push_back(Args.MakeArgString(LibClangRT));
- CmdArgs.push_back("-lgcc_s");
- if (TC.getDriver().CCCIsCXX())
- CmdArgs.push_back("-lgcc_eh");
+ if (!TC.getTriple().isOSWindows()) {
+ // FIXME: why do we link against gcc when we are using compiler-rt?
+ CmdArgs.push_back("-lgcc_s");
+ if (TC.getDriver().CCCIsCXX())
+ CmdArgs.push_back("-lgcc_eh");
+ }
}
-static void addClangRTWindows(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs) {
- SmallString<128> LibClangRT = getCompilerRTLibDir(TC);
- llvm::sys::path::append(LibClangRT, Twine("libclang_rt.builtins-") +
- getArchNameForCompilerRTLib(TC) + ".lib");
- CmdArgs.push_back(Args.MakeArgString(LibClangRT));
-}
-
-static void addProfileRT(
- const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) {
+static void addProfileRT(const ToolChain &TC, const ArgList &Args,
+ ArgStringList &CmdArgs) {
if (!(Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
false) ||
Args.hasArg(options::OPT_fprofile_generate) ||
@@ -2168,38 +2192,17 @@
Args.hasArg(options::OPT_coverage)))
return;
- SmallString<128> LibProfile = getCompilerRTLibDir(TC);
- llvm::sys::path::append(LibProfile, Twine("libclang_rt.profile-") +
- getArchNameForCompilerRTLib(TC) +
- ".a");
-
- CmdArgs.push_back(Args.MakeArgString(LibProfile));
-}
-
-static SmallString<128> getSanitizerRTLibName(const ToolChain &TC,
- StringRef Sanitizer,
- bool Shared) {
- // Sanitizer runtime has name "libclang_rt.<Sanitizer>-<ArchName>.{a,so}"
- // (or "libclang_rt.<Sanitizer>-<ArchName>-android.so for Android)
- const char *EnvSuffix =
- TC.getTriple().getEnvironment() == llvm::Triple::Android ? "-android" : "";
- SmallString<128> LibSanitizer = getCompilerRTLibDir(TC);
- llvm::sys::path::append(LibSanitizer,
- Twine("libclang_rt.") + Sanitizer + "-" +
- getArchNameForCompilerRTLib(TC) + EnvSuffix +
- (Shared ? ".so" : ".a"));
- return LibSanitizer;
+ CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, "profile")));
}
static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs, StringRef Sanitizer,
bool IsShared) {
- SmallString<128> LibSanitizer = getSanitizerRTLibName(TC, Sanitizer, IsShared);
// Static runtimes must be forced into executable, so we wrap them in
// whole-archive.
if (!IsShared)
CmdArgs.push_back("-whole-archive");
- CmdArgs.push_back(Args.MakeArgString(LibSanitizer));
+ CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Sanitizer, IsShared)));
if (!IsShared)
CmdArgs.push_back("-no-whole-archive");
}
@@ -2209,10 +2212,9 @@
static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs,
StringRef Sanitizer) {
- SmallString<128> LibSanitizer = getSanitizerRTLibName(TC, Sanitizer, false);
- if (llvm::sys::fs::exists(LibSanitizer + ".syms")) {
- CmdArgs.push_back(
- Args.MakeArgString("--dynamic-list=" + LibSanitizer + ".syms"));
+ SmallString<128> SanRT = getCompilerRT(TC, Sanitizer);
+ if (llvm::sys::fs::exists(SanRT + ".syms")) {
+ CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + SanRT + ".syms"));
return true;
}
return false;
@@ -2301,27 +2303,49 @@
return !StaticRuntimes.empty();
}
+static bool areOptimizationsEnabled(const ArgList &Args) {
+ // Find the last -O arg and see if it is non-zero.
+ if (Arg *A = Args.getLastArg(options::OPT_O_Group))
+ return !A->getOption().matches(options::OPT_O0);
+ // Defaults to -O0.
+ return false;
+}
+
static bool shouldUseFramePointerForTarget(const ArgList &Args,
const llvm::Triple &Triple) {
- switch (Triple.getArch()) {
- // Don't use a frame pointer on linux if optimizing for certain targets.
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- case llvm::Triple::systemz:
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- if (Triple.isOSLinux())
- if (Arg *A = Args.getLastArg(options::OPT_O_Group))
- if (!A->getOption().matches(options::OPT_O0))
- return false;
- return true;
- case llvm::Triple::xcore:
+ // XCore never wants frame pointers, regardless of OS.
+ if (Triple.getArch() == llvm::Triple::xcore) {
return false;
- default:
- return true;
}
+
+ if (Triple.isOSLinux()) {
+ switch (Triple.getArch()) {
+ // Don't use a frame pointer on linux if optimizing for certain targets.
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ case llvm::Triple::systemz:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ return !areOptimizationsEnabled(Args);
+ default:
+ return true;
+ }
+ }
+
+ if (Triple.isOSWindows()) {
+ switch (Triple.getArch()) {
+ case llvm::Triple::x86:
+ return !areOptimizationsEnabled(Args);
+ default:
+ // All other supported Windows ISAs use xdata unwind information, so frame
+ // pointers are not generally useful.
+ return false;
+ }
+ }
+
+ return true;
}
static bool shouldUseFramePointer(const ArgList &Args,
@@ -2339,6 +2363,9 @@
options::OPT_momit_leaf_frame_pointer))
return A->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer);
+ if (Triple.isPS4CPU())
+ return false;
+
return shouldUseFramePointerForTarget(Args, Triple);
}
@@ -2461,6 +2488,48 @@
llvm::utostr_32(Build);
}
+// Claim options we don't want to warn if they are unused. We do this for
+// options that build systems might add but are unused when assembling or only
+// running the preprocessor for example.
+static void claimNoWarnArgs(const ArgList &Args) {
+ // Don't warn about unused -f(no-)?lto. This can happen when we're
+ // preprocessing, precompiling or assembling.
+ Args.ClaimAllArgs(options::OPT_flto);
+ Args.ClaimAllArgs(options::OPT_fno_lto);
+}
+
+static void appendUserToPath(SmallVectorImpl<char> &Result) {
+#ifdef LLVM_ON_UNIX
+ const char *Username = getenv("LOGNAME");
+#else
+ const char *Username = getenv("USERNAME");
+#endif
+ if (Username) {
+ // Validate that LoginName can be used in a path, and get its length.
+ size_t Len = 0;
+ for (const char *P = Username; *P; ++P, ++Len) {
+ if (!isAlphanumeric(*P) && *P != '_') {
+ Username = nullptr;
+ break;
+ }
+ }
+
+ if (Username && Len > 0) {
+ Result.append(Username, Username + Len);
+ return;
+ }
+ }
+
+ // Fallback to user id.
+#ifdef LLVM_ON_UNIX
+ std::string UID = llvm::utostr(getuid());
+#else
+ // FIXME: Windows seems to have an 'SID' that might work.
+ std::string UID = "9999";
+#endif
+ Result.append(UID.begin(), UID.end());
+}
+
void Clang::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -2541,7 +2610,8 @@
} else if (isa<VerifyPCHJobAction>(JA)) {
CmdArgs.push_back("-verify-pch");
} else {
- assert(isa<CompileJobAction>(JA) && "Invalid action for clang tool.");
+ assert((isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) &&
+ "Invalid action for clang tool.");
if (JA.getType() == types::TY_Nothing) {
CmdArgs.push_back("-fsyntax-only");
@@ -2734,8 +2804,7 @@
// Note that these flags are trump-cards. Regardless of the order w.r.t. the
// PIC or PIE options above, if these show up, PIC is disabled.
llvm::Triple Triple(TripleStr);
- if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6) ||
- Triple.getArch() == llvm::Triple::aarch64))
+ if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6)))
PIC = PIE = false;
if (Args.hasArg(options::OPT_static))
PIC = PIE = false;
@@ -2787,6 +2856,19 @@
// LLVM Code Generator Options.
+ if (Args.hasArg(options::OPT_frewrite_map_file) ||
+ Args.hasArg(options::OPT_frewrite_map_file_EQ)) {
+ for (arg_iterator
+ MFI = Args.filtered_begin(options::OPT_frewrite_map_file,
+ options::OPT_frewrite_map_file_EQ),
+ MFE = Args.filtered_end();
+ MFI != MFE; ++MFI) {
+ CmdArgs.push_back("-frewrite-map-file");
+ CmdArgs.push_back((*MFI)->getValue());
+ (*MFI)->claim();
+ }
+ }
+
if (Arg *A = Args.getLastArg(options::OPT_Wframe_larger_than_EQ)) {
StringRef v = A->getValue();
CmdArgs.push_back("-mllvm");
@@ -2948,6 +3030,8 @@
!TrappingMath)
CmdArgs.push_back("-menable-unsafe-fp-math");
+ if (!SignedZeros)
+ CmdArgs.push_back("-fno-signed-zeros");
// Validate and pass through -fp-contract option.
if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
@@ -3232,6 +3316,10 @@
CmdArgs.push_back("-fdata-sections");
}
+ if (!Args.hasFlag(options::OPT_funique_section_names,
+ options::OPT_fno_unique_section_names, true))
+ CmdArgs.push_back("-fno-unique-section-names");
+
Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
if (Args.hasArg(options::OPT_fprofile_instr_generate) &&
@@ -3400,9 +3488,7 @@
D.Diag(diag::warn_ignored_gcc_optimization) << (*it)->getAsString(Args);
}
- // Don't warn about unused -flto. This can happen when we're preprocessing or
- // precompiling.
- Args.ClaimAllArgs(options::OPT_flto);
+ claimNoWarnArgs(Args);
Args.AddAllArgs(CmdArgs, options::OPT_R_Group);
Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
@@ -3425,8 +3511,10 @@
else
Std->render(Args, CmdArgs);
+ // If -f(no-)trigraphs appears after the language standard flag, honor it.
if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi,
- options::OPT_trigraphs))
+ options::OPT_ftrigraphs,
+ options::OPT_fno_trigraphs))
if (A != Std)
A->render(Args, CmdArgs);
} else {
@@ -3442,7 +3530,8 @@
else if (IsWindowsMSVC)
CmdArgs.push_back("-std=c++11");
- Args.AddLastArg(CmdArgs, options::OPT_trigraphs);
+ Args.AddLastArg(CmdArgs, options::OPT_ftrigraphs,
+ options::OPT_fno_trigraphs);
}
// GCC's behavior for -Wwrite-strings is a bit strange:
@@ -3561,6 +3650,11 @@
CmdArgs.push_back(A->getValue());
}
+ if (Arg *A = Args.getLastArg(options::OPT_fspell_checking_limit_EQ)) {
+ CmdArgs.push_back("-fspell-checking-limit");
+ CmdArgs.push_back(A->getValue());
+ }
+
// Pass -fmessage-length=.
CmdArgs.push_back("-fmessage-length");
if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
@@ -3720,6 +3814,15 @@
CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment));
}
+ if (Args.hasArg(options::OPT_mstack_probe_size)) {
+ StringRef Size = Args.getLastArgValue(options::OPT_mstack_probe_size);
+
+ if (!Size.empty())
+ CmdArgs.push_back(Args.MakeArgString("-mstack-probe-size=" + Size));
+ else
+ CmdArgs.push_back("-mstack-probe-size=0");
+ }
+
if (getToolChain().getTriple().getArch() == llvm::Triple::aarch64 ||
getToolChain().getTriple().getArch() == llvm::Triple::aarch64_be)
CmdArgs.push_back("-fallow-half-arguments-and-returns");
@@ -3826,6 +3929,12 @@
CmdArgs.push_back("-fmodules-strict-decluse");
}
+ // -fno-implicit-modules turns off implicitly compiling modules on demand.
+ if (!Args.hasFlag(options::OPT_fimplicit_modules,
+ options::OPT_fno_implicit_modules)) {
+ CmdArgs.push_back("-fno-implicit-modules");
+ }
+
// -fmodule-name specifies the module that is currently being built (or
// used for header checking by -fmodule-maps).
Args.AddLastArg(CmdArgs, options::OPT_fmodule_name);
@@ -3853,7 +3962,8 @@
// No module path was provided: use the default.
llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false,
ModuleCachePath);
- llvm::sys::path::append(ModuleCachePath, "org.llvm.clang");
+ llvm::sys::path::append(ModuleCachePath, "org.llvm.clang.");
+ appendUserToPath(ModuleCachePath);
llvm::sys::path::append(ModuleCachePath, "ModuleCache");
}
const char Arg[] = "-fmodules-cache-path=";
@@ -3892,10 +4002,9 @@
llvm::sys::fs::file_status Status;
if (llvm::sys::fs::status(A->getValue(), Status))
D.Diag(diag::err_drv_no_such_file) << A->getValue();
- char TimeStamp[48];
- snprintf(TimeStamp, sizeof(TimeStamp), "-fbuild-session-timestamp=%" PRIu64,
- (uint64_t)Status.getLastModificationTime().toEpochTime());
- CmdArgs.push_back(Args.MakeArgString(TimeStamp));
+ CmdArgs.push_back(Args.MakeArgString(
+ "-fbuild-session-timestamp=" +
+ Twine((uint64_t)Status.getLastModificationTime().toEpochTime())));
}
if (Args.getLastArg(options::OPT_fmodules_validate_once_per_build_session)) {
@@ -3921,21 +4030,11 @@
false))
CmdArgs.push_back("-fno-elide-constructors");
- // -frtti is default.
- if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti) ||
- KernelOrKext) {
- CmdArgs.push_back("-fno-rtti");
+ ToolChain::RTTIMode RTTIMode = getToolChain().getRTTIMode();
- // -fno-rtti cannot usefully be combined with -fsanitize=vptr.
- if (Sanitize.sanitizesVptr()) {
- std::string NoRttiArg =
- Args.getLastArg(options::OPT_mkernel,
- options::OPT_fapple_kext,
- options::OPT_fno_rtti)->getAsString(Args);
- D.Diag(diag::err_drv_argument_not_allowed_with)
- << "-fsanitize=vptr" << NoRttiArg;
- }
- }
+ if (RTTIMode == ToolChain::RM_DisabledExplicitly ||
+ RTTIMode == ToolChain::RM_DisabledImplicitly)
+ CmdArgs.push_back("-fno-rtti");
// -fshort-enums=0 is default for all architectures except Hexagon.
if (Args.hasFlag(options::OPT_fshort_enums,
@@ -3968,6 +4067,11 @@
IsWindowsMSVC))
CmdArgs.push_back("-fms-extensions");
+ // -fno-use-line-directives is default.
+ if (Args.hasFlag(options::OPT_fuse_line_directives,
+ options::OPT_fno_use_line_directives, false))
+ CmdArgs.push_back("-fuse-line-directives");
+
// -fms-compatibility=0 is default.
if (Args.hasFlag(options::OPT_fms_compatibility,
options::OPT_fno_ms_compatibility,
@@ -3996,7 +4100,7 @@
Ver = getMSCompatibilityVersion(MSCVersion->getValue());
if (Ver.empty())
- CmdArgs.push_back("-fms-compatibility-version=17.00");
+ CmdArgs.push_back("-fms-compatibility-version=18.00");
else
CmdArgs.push_back(Args.MakeArgString("-fms-compatibility-version=" + Ver));
}
@@ -4113,7 +4217,7 @@
// Handle GCC-style exception args.
if (!C.getDriver().IsCLMode())
- addExceptionArgs(Args, InputType, getToolChain().getTriple(), KernelOrKext,
+ addExceptionArgs(Args, InputType, getToolChain(), KernelOrKext,
objcRuntime, CmdArgs);
if (getToolChain().UseSjLjExceptions())
@@ -4307,6 +4411,11 @@
false))
CmdArgs.push_back("-fasm-blocks");
+ // -fgnu-inline-asm is default.
+ if (!Args.hasFlag(options::OPT_fgnu_inline_asm,
+ options::OPT_fno_gnu_inline_asm, true))
+ CmdArgs.push_back("-fno-gnu-inline-asm");
+
// Enable vectorization per default according to the optimization level
// selected. For optimization levels that want vectorization we use the alias
// option to simplify the hasFlag logic.
@@ -4414,18 +4523,27 @@
// Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
// parser.
Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
+ bool OptDisabled = false;
for (arg_iterator it = Args.filtered_begin(options::OPT_mllvm),
ie = Args.filtered_end(); it != ie; ++it) {
(*it)->claim();
// We translate this by hand to the -cc1 argument, since nightly test uses
// it and developers have been trained to spell it with -mllvm.
- if (StringRef((*it)->getValue(0)) == "-disable-llvm-optzns")
+ if (StringRef((*it)->getValue(0)) == "-disable-llvm-optzns") {
CmdArgs.push_back("-disable-llvm-optzns");
- else
+ OptDisabled = true;
+ } else
(*it)->render(Args, CmdArgs);
}
+ // With -save-temps, we want to save the unoptimized bitcode output from the
+ // CompileJobAction, so disable optimizations if they are not already
+ // disabled.
+ if (C.getDriver().isSaveTempsEnabled() && !OptDisabled &&
+ isa<CompileJobAction>(JA))
+ CmdArgs.push_back("-disable-llvm-optzns");
+
if (Output.getType() == types::TY_Dependencies) {
// Handled with other dependency code.
} else if (Output.isFilename()) {
@@ -4471,7 +4589,8 @@
// can propagate it to the backend.
bool SplitDwarf = Args.hasArg(options::OPT_gsplit_dwarf) &&
getToolChain().getTriple().isOSLinux() &&
- (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA));
+ (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA) ||
+ isa<BackendJobAction>(JA));
const char *SplitDwarfOut;
if (SplitDwarf) {
CmdArgs.push_back("-split-dwarf-file");
@@ -4495,7 +4614,7 @@
// 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 (SplitDwarf && !isa<CompileJobAction>(JA))
+ if (SplitDwarf && !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, SplitDwarfOut);
if (Arg *A = Args.getLastArg(options::OPT_pg))
@@ -4743,8 +4862,8 @@
EHFlags EH = parseClangCLEHFlags(D, Args);
// FIXME: Do something with NoExceptC.
if (EH.Synch || EH.Asynch) {
- CmdArgs.push_back("-fexceptions");
CmdArgs.push_back("-fcxx-exceptions");
+ CmdArgs.push_back("-fexceptions");
}
// /EP should expand to -E -P.
@@ -4753,6 +4872,19 @@
CmdArgs.push_back("-P");
}
+ unsigned VolatileOptionID;
+ if (getToolChain().getTriple().getArch() == llvm::Triple::x86_64 ||
+ getToolChain().getTriple().getArch() == llvm::Triple::x86)
+ VolatileOptionID = options::OPT__SLASH_volatile_ms;
+ else
+ VolatileOptionID = options::OPT__SLASH_volatile_iso;
+
+ if (Arg *A = Args.getLastArg(options::OPT__SLASH_volatile_Group))
+ VolatileOptionID = A->getOption().getID();
+
+ if (VolatileOptionID == options::OPT__SLASH_volatile_ms)
+ CmdArgs.push_back("-fms-volatile");
+
Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg);
Arg *BestCaseArg = Args.getLastArg(options::OPT__SLASH_vmb);
if (MostGeneralArg && BestCaseArg)
@@ -4797,6 +4929,17 @@
return CLFallback.get();
}
+void ClangAs::AddMIPSTargetArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ StringRef CPUName;
+ StringRef ABIName;
+ const llvm::Triple &Triple = getToolChain().getTriple();
+ mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
+
+ CmdArgs.push_back("-target-abi");
+ CmdArgs.push_back(ABIName.data());
+}
+
void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -4812,6 +4955,8 @@
// and "clang -emit-llvm -c foo.s"
Args.ClaimAllArgs(options::OPT_emit_llvm);
+ claimNoWarnArgs(Args);
+
// Invoke ourselves in -cc1as mode.
//
// FIXME: Implement custom jobs for internal actions.
@@ -4902,6 +5047,19 @@
// FIXME: Add -static support, once we have it.
+ // Add target specific flags.
+ switch(getToolChain().getArch()) {
+ default:
+ break;
+
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ AddMIPSTargetArgs(Args, CmdArgs);
+ break;
+ }
+
// Consume all the warning flags. Usually this would be handled more
// gracefully by -cc1 (warning about unknown warning flags, etc) but -cc1as
// doesn't handle that so rather than warning about unused flags that are
@@ -5064,16 +5222,22 @@
ArgStringList &CmdArgs) const {
const Driver &D = getToolChain().getDriver();
+ switch (JA.getType()) {
// If -flto, etc. are present then make sure not to force assembly output.
- if (JA.getType() == types::TY_LLVM_IR || JA.getType() == types::TY_LTO_IR ||
- JA.getType() == types::TY_LLVM_BC || JA.getType() == types::TY_LTO_BC)
+ case types::TY_LLVM_IR:
+ case types::TY_LTO_IR:
+ case types::TY_LLVM_BC:
+ case types::TY_LTO_BC:
CmdArgs.push_back("-c");
- else {
- if (JA.getType() != types::TY_PP_Asm)
- D.Diag(diag::err_drv_invalid_gcc_output_type)
- << getTypeName(JA.getType());
-
+ break;
+ case types::TY_PP_Asm:
CmdArgs.push_back("-S");
+ break;
+ case types::TY_Nothing:
+ CmdArgs.push_back("-fsyntax-only");
+ break;
+ default:
+ D.Diag(diag::err_drv_invalid_gcc_output_type) << getTypeName(JA.getType());
}
}
@@ -5092,6 +5256,7 @@
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
+ claimNoWarnArgs(Args);
const Driver &D = getToolChain().getDriver();
ArgStringList CmdArgs;
@@ -5382,16 +5547,30 @@
.Cases("arm1156t2-s", "arm1156t2f-s", "v6t2")
.Cases("cortex-a5", "cortex-a7", "cortex-a8", "v7")
.Cases("cortex-a9", "cortex-a12", "cortex-a15", "cortex-a17", "krait", "v7")
- .Cases("cortex-r4", "cortex-r5", "v7r")
- .Case("cortex-m0", "v6m")
- .Case("cortex-m3", "v7m")
+ .Cases("cortex-r4", "cortex-r5", "cortex-r7", "v7r")
+ .Cases("sc000", "cortex-m0", "cortex-m0plus", "cortex-m1", "v6m")
+ .Cases("sc300", "cortex-m3", "v7m")
.Cases("cortex-m4", "cortex-m7", "v7em")
.Case("swift", "v7s")
.Case("cyclone", "v8")
- .Cases("cortex-a53", "cortex-a57", "v8")
+ .Cases("cortex-a53", "cortex-a57", "cortex-a72", "v8")
.Default("");
}
+void arm::appendEBLinkFlags(const ArgList &Args, ArgStringList &CmdArgs, const llvm::Triple &Triple) {
+ if (Args.hasArg(options::OPT_r))
+ return;
+
+ StringRef Suffix = getLLVMArchSuffixForARM(getARMCPUForMArch(Args, Triple));
+ const char *LinkFlag = llvm::StringSwitch<const char *>(Suffix)
+ .Cases("v4", "v4t", "v5", "v5e", nullptr)
+ .Cases("v6", "v6t2", nullptr)
+ .Default("--be8");
+
+ if (LinkFlag)
+ CmdArgs.push_back(LinkFlag);
+}
+
bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
return A && (A->getValue() == StringRef(Value));
@@ -5428,8 +5607,8 @@
return llvm::StringSwitch<bool>(CPUName)
.Cases("mips2", "mips3", "mips4", "mips5", true)
- .Cases("mips32", "mips32r2", true)
- .Cases("mips64", "mips64r2", true)
+ .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
+ .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
.Default(false);
}
@@ -5460,6 +5639,7 @@
.Cases("armv7s", "xscale", llvm::Triple::arm)
.Case("arm64", llvm::Triple::aarch64)
.Case("r600", llvm::Triple::r600)
+ .Case("amdgcn", llvm::Triple::amdgcn)
.Case("nvptx", llvm::Triple::nvptx)
.Case("nvptx64", llvm::Triple::nvptx64)
.Case("amdil", llvm::Triple::amdil)
@@ -5633,7 +5813,8 @@
// If we are using LTO, then automatically create a temporary file path for
// the linker to use, so that it's lifetime will extend past a possible
// dsymutil step.
- if (Version[0] >= 116 && D.IsUsingLTO(Args) && NeedsTempPath(Inputs)) {
+ if (Version[0] >= 116 && D.IsUsingLTO(getToolChain(), Args) &&
+ NeedsTempPath(Inputs)) {
const char *TmpPath = C.getArgs().MakeArgString(
D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object)));
C.addTempFile(TmpPath);
@@ -5923,6 +6104,12 @@
Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
Args.AddAllArgs(CmdArgs, options::OPT_F);
+ // -iframework should be forwarded as -F.
+ for (auto it = Args.filtered_begin(options::OPT_iframework),
+ ie = Args.filtered_end(); it != ie; ++it)
+ CmdArgs.push_back(Args.MakeArgString(std::string("-F") +
+ (*it)->getValue()));
+
const char *Exec =
Args.MakeArgString(getToolChain().GetLinkerPath());
std::unique_ptr<Command> Cmd =
@@ -6001,6 +6188,7 @@
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
+ claimNoWarnArgs(Args);
ArgStringList CmdArgs;
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
@@ -6126,6 +6314,7 @@
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
+ claimNoWarnArgs(Args);
ArgStringList CmdArgs;
bool NeedsKPIC = false;
@@ -6328,6 +6517,7 @@
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
+ claimNoWarnArgs(Args);
ArgStringList CmdArgs;
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
@@ -6464,6 +6654,7 @@
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
+ claimNoWarnArgs(Args);
ArgStringList CmdArgs;
// When building 32-bit code on FreeBSD/amd64, we have to explicitly
@@ -6646,7 +6837,7 @@
Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
Args.AddAllArgs(CmdArgs, options::OPT_r);
- if (D.IsUsingLTO(Args))
+ if (D.IsUsingLTO(getToolChain(), Args))
AddGoldPlugin(ToolChain, Args, CmdArgs);
bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
@@ -6729,6 +6920,7 @@
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
+ claimNoWarnArgs(Args);
ArgStringList CmdArgs;
// GNU as needs different flags for creating the correct output format
@@ -6849,6 +7041,7 @@
break;
case llvm::Triple::armeb:
case llvm::Triple::thumbeb:
+ arm::appendEBLinkFlags(Args, CmdArgs, getToolChain().getTriple());
CmdArgs.push_back("-m");
switch (getToolChain().getTriple().getEnvironment()) {
case llvm::Triple::EABI:
@@ -7011,6 +7204,8 @@
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
+ claimNoWarnArgs(Args);
+
ArgStringList CmdArgs;
bool NeedsKPIC = false;
@@ -7289,19 +7484,17 @@
}
static void AddRunTimeLibs(const ToolChain &TC, const Driver &D,
- ArgStringList &CmdArgs, const ArgList &Args) {
+ ArgStringList &CmdArgs, const ArgList &Args) {
// Make use of compiler-rt if --rtlib option is used
ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(Args);
- switch(RLT) {
+ switch (RLT) {
case ToolChain::RLT_CompilerRT:
switch (TC.getTriple().getOS()) {
default: llvm_unreachable("unsupported OS");
case llvm::Triple::Win32:
- addClangRTWindows(TC, Args, CmdArgs);
- break;
case llvm::Triple::Linux:
- addClangRTLinux(TC, Args, CmdArgs);
+ addClangRT(TC, Args, CmdArgs);
break;
}
break;
@@ -7399,6 +7592,10 @@
if (Args.hasArg(options::OPT_s))
CmdArgs.push_back("-s");
+ if (ToolChain.getArch() == llvm::Triple::armeb ||
+ ToolChain.getArch() == llvm::Triple::thumbeb)
+ arm::appendEBLinkFlags(Args, CmdArgs, getToolChain().getTriple());
+
for (const auto &Opt : ToolChain.ExtraOpts)
CmdArgs.push_back(Opt.c_str());
@@ -7476,7 +7673,7 @@
for (const auto &Path : Paths)
CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path));
- if (D.IsUsingLTO(Args))
+ if (D.IsUsingLTO(getToolChain(), Args))
AddGoldPlugin(ToolChain, Args, CmdArgs);
if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
@@ -7573,6 +7770,7 @@
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
+ claimNoWarnArgs(Args);
ArgStringList CmdArgs;
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
@@ -7650,6 +7848,7 @@
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
+ claimNoWarnArgs(Args);
ArgStringList CmdArgs;
// When building 32-bit code on DragonFly/pc64, we have to explicitly
@@ -7816,15 +8015,6 @@
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
-static void addSanitizerRTWindows(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs,
- StringRef RTName) {
- SmallString<128> LibSanitizer(getCompilerRTLibDir(TC));
- llvm::sys::path::append(LibSanitizer,
- Twine("clang_rt.") + RTName + ".lib");
- CmdArgs.push_back(Args.MakeArgString(LibSanitizer));
-}
-
// Try to find Exe from a Visual Studio distribution. This first tries to find
// an installed copy of Visual Studio and, failing that, looks in the PATH,
// making sure that whatever executable that's found is not a same-named exe
@@ -7851,19 +8041,16 @@
const ArgList &Args,
const char *LinkingOutput) const {
ArgStringList CmdArgs;
+ const ToolChain &TC = getToolChain();
- if (Output.isFilename()) {
+ assert((Output.isFilename() || Output.isNothing()) && "invalid output");
+ if (Output.isFilename())
CmdArgs.push_back(Args.MakeArgString(std::string("-out:") +
Output.getFilename()));
- } else {
- assert(Output.isNothing() && "Invalid output.");
- }
if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles) &&
- !C.getDriver().IsCLMode()) {
+ !Args.hasArg(options::OPT_nostartfiles) && !C.getDriver().IsCLMode())
CmdArgs.push_back("-defaultlib:libcmt");
- }
if (!llvm::sys::Process::GetEnv("LIB")) {
// If the VC environment hasn't been configured (perhaps because the user
@@ -7871,7 +8058,7 @@
// the environment variable is set however, assume the user knows what he's
// doing.
std::string VisualStudioDir;
- const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(getToolChain());
+ const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
if (MSVC.getVisualStudioInstallDir(VisualStudioDir)) {
SmallString<128> LibDir(VisualStudioDir);
llvm::sys::path::append(LibDir, "VC", "lib");
@@ -7900,12 +8087,10 @@
CmdArgs.push_back("-nologo");
- if (Args.hasArg(options::OPT_g_Group)) {
+ if (Args.hasArg(options::OPT_g_Group))
CmdArgs.push_back("-debug");
- }
bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd);
-
if (DLL) {
CmdArgs.push_back(Args.MakeArgString("-dll"));
@@ -7915,23 +8100,28 @@
ImplibName.str()));
}
- if (getToolChain().getSanitizerArgs().needsAsanRt()) {
+ if (TC.getSanitizerArgs().needsAsanRt()) {
CmdArgs.push_back(Args.MakeArgString("-debug"));
CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
- // FIXME: Handle 64-bit.
if (Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
- addSanitizerRTWindows(getToolChain(), Args, CmdArgs, "asan_dynamic-i386");
- addSanitizerRTWindows(getToolChain(), Args, CmdArgs,
- "asan_dynamic_runtime_thunk-i386");
+ static const char *CompilerRTComponents[] = {
+ "asan_dynamic",
+ "asan_dynamic_runtime_thunk",
+ };
+ for (const auto &Component : CompilerRTComponents)
+ CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Component)));
// Make sure the dynamic runtime thunk is not optimized out at link time
// to ensure proper SEH handling.
CmdArgs.push_back(Args.MakeArgString("-include:___asan_seh_interceptor"));
} else if (DLL) {
- addSanitizerRTWindows(getToolChain(), Args, CmdArgs,
- "asan_dll_thunk-i386");
+ CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, "asan_dll_thunk")));
} else {
- addSanitizerRTWindows(getToolChain(), Args, CmdArgs, "asan-i386");
- addSanitizerRTWindows(getToolChain(), Args, CmdArgs, "asan_cxx-i386");
+ static const char *CompilerRTComponents[] = {
+ "asan",
+ "asan_cxx",
+ };
+ for (const auto &Component : CompilerRTComponents)
+ CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Component)));
}
}
@@ -7963,10 +8153,26 @@
A.renderAsInput(Args, CmdArgs);
}
- // It's not sufficient to just use link from the program PATH, because other
- // environments like GnuWin32 install their own link.exe which may come first.
- llvm::SmallString<128> linkPath(FindVisualStudioExecutable(
- getToolChain(), "link.exe", C.getDriver().getClangProgramPath()));
+ // We need to special case some linker paths. In the case of lld, we need to
+ // translate 'lld' into 'lld-link', and in the case of the regular msvc
+ // linker, we need to use a special search algorithm.
+ llvm::SmallString<128> linkPath;
+ StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "link");
+ if (Linker.equals_lower("lld"))
+ Linker = "lld-link";
+
+ if (Linker.equals_lower("link")) {
+ // If we're using the MSVC linker, it's not sufficient to just use link
+ // from the program PATH, because other environments like GnuWin32 install
+ // their own link.exe which may come first.
+ linkPath = FindVisualStudioExecutable(TC, "link.exe",
+ C.getDriver().getClangProgramPath());
+ } else {
+ linkPath = Linker;
+ llvm::sys::path::replace_extension(linkPath, "exe");
+ linkPath = TC.GetProgramPath(linkPath.c_str());
+ }
+
const char *Exec = Args.MakeArgString(linkPath);
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
@@ -8075,6 +8281,7 @@
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
+ claimNoWarnArgs(Args);
ArgStringList CmdArgs;
CmdArgs.push_back("-o");
@@ -8120,8 +8327,7 @@
if (Args.hasArg(options::OPT_v))
CmdArgs.push_back("-v");
- ExceptionSettings EH = exceptionSettings(Args, getToolChain().getTriple());
- if (EH.ShouldUseExceptionTables)
+ if (exceptionSettings(Args, getToolChain().getTriple()))
CmdArgs.push_back("-fexceptions");
AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
@@ -8135,6 +8341,7 @@
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
+ claimNoWarnArgs(Args);
const auto &TC =
static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain());
ArgStringList CmdArgs;
@@ -8306,4 +8513,3 @@
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
-