Update aosp/master Clang for rebase to r222490.
Change-Id: Ic557ac55e97fbf6ee08771c7b7c3594777b0aefd
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 37fef56..b372b65 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -83,6 +83,23 @@
<< A->getAsString(Args) << "-static";
}
+// Add backslashes to escape spaces and other backslashes.
+// This is used for the space-separated argument list specified with
+// the -dwarf-debug-flags option.
+static void EscapeSpacesAndBackslashes(const char *Arg,
+ SmallVectorImpl<char> &Res) {
+ for ( ; *Arg; ++Arg) {
+ switch (*Arg) {
+ default: break;
+ case ' ':
+ case '\\':
+ Res.push_back('\\');
+ break;
+ }
+ Res.push_back(*Arg);
+ }
+}
+
// Quote target names for inclusion in GNU Make dependency files.
// Only the characters '$', '#', ' ', '\t' are quoted.
static void QuoteTarget(StringRef Target,
@@ -201,8 +218,13 @@
TC.AddCXXStdlibLibArgs(Args, CmdArgs);
else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext))
TC.AddCCKextLibArgs(Args, CmdArgs);
- else
- A.renderAsInput(Args, CmdArgs);
+ else if (A.getOption().matches(options::OPT_z)) {
+ // Pass -z prefix for gcc linker compatibility.
+ A.claim();
+ A.render(Args, CmdArgs);
+ } else {
+ A.renderAsInput(Args, CmdArgs);
+ }
}
// LIBRARY_PATH - included following the user specified library paths.
@@ -452,10 +474,10 @@
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_be:
- case llvm::Triple::arm64:
- case llvm::Triple::arm64_be:
case llvm::Triple::arm:
case llvm::Triple::armeb:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
if (Triple.isOSDarwin() || Triple.isOSWindows())
return true;
return false;
@@ -483,29 +505,6 @@
}
}
-// Handle -mfpu=.
-//
-// FIXME: Centralize feature selection, defaulting shouldn't be also in the
-// frontend target.
-static void getAArch64FPUFeatures(const Driver &D, const Arg *A,
- const ArgList &Args,
- std::vector<const char *> &Features) {
- StringRef FPU = A->getValue();
- if (FPU == "fp-armv8") {
- Features.push_back("+fp-armv8");
- } else if (FPU == "neon-fp-armv8") {
- Features.push_back("+fp-armv8");
- Features.push_back("+neon");
- } else if (FPU == "crypto-neon-fp-armv8") {
- Features.push_back("+fp-armv8");
- Features.push_back("+neon");
- Features.push_back("+crypto");
- } else if (FPU == "neon") {
- Features.push_back("+neon");
- } else
- D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
-}
-
// Handle -mhwdiv=.
static void getARMHWDivFeatures(const Driver &D, const Arg *A,
const ArgList &Args,
@@ -526,7 +525,7 @@
} else
D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
}
-
+
// Handle -mfpu=.
//
// FIXME: Centralize feature selection, defaulting shouldn't be also in the
@@ -564,6 +563,18 @@
Features.push_back("+d16");
Features.push_back("+fp-only-sp");
Features.push_back("-neon");
+ } else if (FPU == "fp5-sp-d16" || FPU == "fpv5-sp-d16") {
+ Features.push_back("+fp-armv8");
+ Features.push_back("+fp-only-sp");
+ Features.push_back("+d16");
+ Features.push_back("-neon");
+ Features.push_back("-crypto");
+ } else if (FPU == "fp5-dp-d16" || FPU == "fpv5-dp-d16" ||
+ FPU == "fp5-d16" || FPU == "fpv5-d16") {
+ Features.push_back("+fp-armv8");
+ Features.push_back("+d16");
+ Features.push_back("-neon");
+ Features.push_back("-crypto");
} else if (FPU == "fp-armv8") {
Features.push_back("+fp-armv8");
Features.push_back("-neon");
@@ -778,7 +789,11 @@
ABIName = "aapcs";
break;
default:
- ABIName = "apcs-gnu";
+ if (Triple.getOS() == llvm::Triple::NetBSD)
+ ABIName = "apcs-gnu";
+ else
+ ABIName = "aapcs";
+ break;
}
}
CmdArgs.push_back("-target-abi");
@@ -819,6 +834,21 @@
CmdArgs.push_back("-arm-use-movt=0");
}
+ // -mkernel implies -mstrict-align; don't add the redundant option.
+ if (!KernelOrKext) {
+ if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
+ options::OPT_munaligned_access)) {
+ CmdArgs.push_back("-backend-option");
+ if (A->getOption().matches(options::OPT_mno_unaligned_access))
+ CmdArgs.push_back("-arm-strict-align");
+ else {
+ if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
+ D.Diag(diag::err_target_unsupported_unaligned) << "v6m";
+ CmdArgs.push_back("-arm-no-strict-align");
+ }
+ }
+ }
+
// 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,
@@ -844,18 +874,21 @@
/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
/// targeting.
static std::string getAArch64TargetCPU(const ArgList &Args) {
- // If we have -mcpu=, use that.
- if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
- StringRef MCPU = A->getValue();
- // Handle -mcpu=native.
- if (MCPU == "native")
- return llvm::sys::getHostCPUName();
- else
- return MCPU;
+ Arg *A;
+ std::string CPU;
+ // If we have -mtune or -mcpu, use that.
+ if ((A = Args.getLastArg(options::OPT_mtune_EQ))) {
+ CPU = A->getValue();
+ } else if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
+ StringRef Mcpu = A->getValue();
+ CPU = Mcpu.split("+").first;
}
- // At some point, we may need to check -march here, but for now we only
- // one arm64 architecture.
+ // Handle CPU name is 'native'.
+ if (CPU == "native")
+ return llvm::sys::getHostCPUName();
+ else if (CPU.size())
+ return CPU;
// Make sure we pick "cyclone" if -arch is used.
// FIXME: Should this be picked by checking the target triple instead?
@@ -890,12 +923,13 @@
CmdArgs.push_back("-target-abi");
CmdArgs.push_back(ABIName);
- CmdArgs.push_back("-target-cpu");
- CmdArgs.push_back(Args.MakeArgString(getAArch64TargetCPU(Args)));
-
- if (Args.hasArg(options::OPT_mstrict_align)) {
+ if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
+ options::OPT_munaligned_access)) {
CmdArgs.push_back("-backend-option");
- CmdArgs.push_back("-aarch64-strict-align");
+ if (A->getOption().matches(options::OPT_mno_unaligned_access))
+ CmdArgs.push_back("-aarch64-strict-align");
+ else
+ CmdArgs.push_back("-aarch64-no-strict-align");
}
if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769,
@@ -922,10 +956,10 @@
// Get CPU and ABI names. They are not independent
// so we have to calculate them together.
-static void getMipsCPUAndABI(const ArgList &Args,
- const llvm::Triple &Triple,
- StringRef &CPUName,
- StringRef &ABIName) {
+void mips::getMipsCPUAndABI(const ArgList &Args,
+ const llvm::Triple &Triple,
+ StringRef &CPUName,
+ StringRef &ABIName) {
const char *DefMips32CPU = "mips32r2";
const char *DefMips64CPU = "mips64r2";
@@ -983,6 +1017,8 @@
.Cases("n32", "n64", DefMips64CPU)
.Default("");
}
+
+ // FIXME: Warn on inconsistent use of -march and -mabi.
}
// Convert ABI name to the GNU tools acceptable variant.
@@ -1036,8 +1072,28 @@
}
}
-static void getMIPSTargetFeatures(const Driver &D, const ArgList &Args,
+static void getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
+ const ArgList &Args,
std::vector<const char *> &Features) {
+ StringRef CPUName;
+ StringRef ABIName;
+ 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");
+
StringRef FloatABI = getMipsFloatABI(D, Args);
if (FloatABI == "soft") {
// FIXME: Note, this is a hack. We need to pass the selected float
@@ -1069,8 +1125,23 @@
"dspr2");
AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
"msa");
- AddTargetFeature(Args, Features, options::OPT_mfp64, options::OPT_mfp32,
- "fp64");
+
+ // Add the last -mfp32/-mfpxx/-mfp64 or if none are given and the ABI is O32
+ // pass -mfpxx
+ if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
+ options::OPT_mfp64)) {
+ if (A->getOption().matches(options::OPT_mfp32))
+ Features.push_back(Args.MakeArgString("-fp64"));
+ else if (A->getOption().matches(options::OPT_mfpxx)) {
+ Features.push_back(Args.MakeArgString("+fpxx"));
+ Features.push_back(Args.MakeArgString("+nooddspreg"));
+ } else
+ Features.push_back(Args.MakeArgString("+fp64"));
+ } else if (mips::isFPXXDefault(Triple, CPUName, ABIName)) {
+ Features.push_back(Args.MakeArgString("+fpxx"));
+ Features.push_back(Args.MakeArgString("+nooddspreg"));
+ }
+
AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
options::OPT_modd_spreg, "nooddspreg");
}
@@ -1081,7 +1152,7 @@
StringRef CPUName;
StringRef ABIName;
const llvm::Triple &Triple = getToolChain().getTriple();
- getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
+ mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
CmdArgs.push_back("-target-abi");
CmdArgs.push_back(ABIName.data());
@@ -1227,6 +1298,35 @@
options::OPT_fno_altivec, "altivec");
}
+void Clang::AddPPCTargetArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ // Select the ABI to use.
+ const char *ABIName = nullptr;
+ if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
+ ABIName = A->getValue();
+ } else if (getToolChain().getTriple().isOSLinux())
+ switch(getToolChain().getArch()) {
+ case llvm::Triple::ppc64:
+ ABIName = "elfv1";
+ break;
+ case llvm::Triple::ppc64le:
+ ABIName = "elfv2";
+ break;
+ default:
+ break;
+ }
+
+ if (ABIName) {
+ CmdArgs.push_back("-target-abi");
+ CmdArgs.push_back(ABIName);
+ }
+}
+
+bool ppc::hasPPCAbiArg(const ArgList &Args, const char *Value) {
+ Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
+ return A && (A->getValue() == StringRef(Value));
+}
+
/// Get the (LLVM) name of the R600 gpu we are targeting.
static std::string getR600TargetGPU(const ArgList &Args) {
if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
@@ -1245,7 +1345,7 @@
}
static void getSparcTargetFeatures(const ArgList &Args,
- std::vector<const char *> Features) {
+ std::vector<const char *> &Features) {
bool SoftFloatABI = true;
if (Arg *A =
Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float)) {
@@ -1260,7 +1360,7 @@
ArgStringList &CmdArgs) const {
const Driver &D = getToolChain().getDriver();
- // Select the float ABI as determined by -msoft-float, -mhard-float, and
+ // Select the float ABI as determined by -msoft-float and -mhard-float.
StringRef FloatABI;
if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
options::OPT_mhard_float)) {
@@ -1359,8 +1459,6 @@
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_be:
- case llvm::Triple::arm64:
- case llvm::Triple::arm64_be:
return getAArch64TargetCPU(Args);
case llvm::Triple::arm:
@@ -1375,7 +1473,7 @@
case llvm::Triple::mips64el: {
StringRef CPUName;
StringRef ABIName;
- getMipsCPUAndABI(Args, T, CPUName, ABIName);
+ mips::getMipsCPUAndABI(Args, T, CPUName, ABIName);
return CPUName;
}
@@ -1436,7 +1534,8 @@
CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=mcpu=") + CPU));
}
-static void getX86TargetFeatures(const llvm::Triple &Triple,
+static void getX86TargetFeatures(const Driver & D,
+ const llvm::Triple &Triple,
const ArgList &Args,
std::vector<const char *> &Features) {
if (Triple.getArchName() == "x86_64h") {
@@ -1459,6 +1558,31 @@
Features.push_back("+ssse3");
}
+ // Set features according to the -arch flag on MSVC
+ if (Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) {
+ StringRef Arch = A->getValue();
+ bool ArchUsed = false;
+ // First, look for flags that are shared in x86 and x86-64.
+ if (Triple.getArch() == llvm::Triple::x86_64 ||
+ Triple.getArch() == llvm::Triple::x86) {
+ if (Arch == "AVX" || Arch == "AVX2") {
+ ArchUsed = true;
+ Features.push_back(Args.MakeArgString("+" + Arch.lower()));
+ }
+ }
+ // Then, look for x86-specific flags.
+ if (Triple.getArch() == llvm::Triple::x86) {
+ if (Arch == "IA32") {
+ ArchUsed = true;
+ } else if (Arch == "SSE" || Arch == "SSE2") {
+ ArchUsed = true;
+ Features.push_back(Args.MakeArgString("+" + Arch.lower()));
+ }
+ }
+ if (!ArchUsed)
+ D.Diag(clang::diag::warn_drv_unused_argument) << A->getAsString(Args);
+ }
+
// Now add any that the user explicitly requested on the command line,
// which may override the defaults.
for (arg_iterator it = Args.filtered_begin(options::OPT_m_x86_Features_Group),
@@ -1560,13 +1684,132 @@
CmdArgs.push_back ("-machine-sink-split=0");
}
+// Decode AArch64 features from string like +[no]featureA+[no]featureB+...
+static bool DecodeAArch64Features(const Driver &D, StringRef text,
+ std::vector<const char *> &Features) {
+ SmallVector<StringRef, 8> Split;
+ text.split(Split, StringRef("+"), -1, false);
+
+ for (unsigned I = 0, E = Split.size(); I != E; ++I) {
+ const char *result = llvm::StringSwitch<const char *>(Split[I])
+ .Case("fp", "+fp-armv8")
+ .Case("simd", "+neon")
+ .Case("crc", "+crc")
+ .Case("crypto", "+crypto")
+ .Case("nofp", "-fp-armv8")
+ .Case("nosimd", "-neon")
+ .Case("nocrc", "-crc")
+ .Case("nocrypto", "-crypto")
+ .Default(nullptr);
+ if (result)
+ Features.push_back(result);
+ else if (Split[I] == "neon" || Split[I] == "noneon")
+ D.Diag(diag::err_drv_no_neon_modifier);
+ else
+ return false;
+ }
+ return true;
+}
+
+// Check if the CPU name and feature modifiers in -mcpu are legal. If yes,
+// decode CPU and feature.
+static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
+ std::vector<const char *> &Features) {
+ std::pair<StringRef, StringRef> Split = Mcpu.split("+");
+ CPU = Split.first;
+ if (CPU == "cyclone" || CPU == "cortex-a53" || CPU == "cortex-a57") {
+ Features.push_back("+neon");
+ Features.push_back("+crc");
+ Features.push_back("+crypto");
+ } else if (CPU == "generic") {
+ Features.push_back("+neon");
+ } else {
+ return false;
+ }
+
+ if (Split.second.size() && !DecodeAArch64Features(D, Split.second, Features))
+ return false;
+
+ return true;
+}
+
+static bool
+getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
+ const ArgList &Args,
+ std::vector<const char *> &Features) {
+ std::pair<StringRef, StringRef> Split = March.split("+");
+ if (Split.first != "armv8-a")
+ return false;
+
+ if (Split.second.size() && !DecodeAArch64Features(D, Split.second, Features))
+ return false;
+
+ return true;
+}
+
+static bool
+getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
+ const ArgList &Args,
+ std::vector<const char *> &Features) {
+ StringRef CPU;
+ if (!DecodeAArch64Mcpu(D, Mcpu, CPU, Features))
+ return false;
+
+ return true;
+}
+
+static bool
+getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune,
+ const ArgList &Args,
+ std::vector<const char *> &Features) {
+ // Handle CPU name is 'native'.
+ if (Mtune == "native")
+ Mtune = llvm::sys::getHostCPUName();
+ if (Mtune == "cyclone") {
+ Features.push_back("+zcm");
+ Features.push_back("+zcz");
+ }
+ return true;
+}
+
+static bool
+getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
+ const ArgList &Args,
+ std::vector<const char *> &Features) {
+ StringRef CPU;
+ std::vector<const char *> DecodedFeature;
+ if (!DecodeAArch64Mcpu(D, Mcpu, CPU, DecodedFeature))
+ return false;
+
+ return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features);
+}
+
static void getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
std::vector<const char *> &Features) {
- // Honor -mfpu=.
- if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ))
- getAArch64FPUFeatures(D, A, Args, Features);
- else
- Features.push_back("+neon");
+ Arg *A;
+ bool success = true;
+ // Enable NEON by default.
+ Features.push_back("+neon");
+ if ((A = Args.getLastArg(options::OPT_march_EQ)))
+ success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Features);
+ else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
+ success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
+ else if (Args.hasArg(options::OPT_arch))
+ success = getAArch64ArchFeaturesFromMcpu(D, getAArch64TargetCPU(Args), Args,
+ Features);
+
+ if (success && (A = Args.getLastArg(options::OPT_mtune_EQ)))
+ success =
+ getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, Features);
+ else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ)))
+ success =
+ getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
+ else if (Args.hasArg(options::OPT_arch))
+ success = getAArch64MicroArchFeaturesFromMcpu(D, getAArch64TargetCPU(Args),
+ Args, Features);
+
+ if (!success)
+ D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
Features.push_back("-fp-armv8");
@@ -1595,7 +1838,7 @@
case llvm::Triple::mipsel:
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
- getMIPSTargetFeatures(D, Args, Features);
+ getMIPSTargetFeatures(D, Triple, Args, Features);
break;
case llvm::Triple::arm:
@@ -1611,17 +1854,16 @@
getPPCTargetFeatures(Args, Features);
break;
case llvm::Triple::sparc:
+ case llvm::Triple::sparcv9:
getSparcTargetFeatures(Args, Features);
break;
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_be:
- case llvm::Triple::arm64:
- case llvm::Triple::arm64_be:
getAArch64TargetFeatures(D, Args, Features);
break;
case llvm::Triple::x86:
case llvm::Triple::x86_64:
- getX86TargetFeatures(Triple, Args, Features);
+ getX86TargetFeatures(D, Triple, Args, Features);
break;
}
@@ -1854,8 +2096,7 @@
} else if (Value == "-L") {
CmdArgs.push_back("-msave-temp-labels");
} else if (Value == "--fatal-warnings") {
- CmdArgs.push_back("-mllvm");
- CmdArgs.push_back("-fatal-assembler-warnings");
+ CmdArgs.push_back("-massembler-fatal-warnings");
} else if (Value == "--noexecstack") {
CmdArgs.push_back("-mnoexecstack");
} else if (Value == "-compress-debug-sections" ||
@@ -1922,31 +2163,34 @@
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) {
- if (!(Args.hasArg(options::OPT_fprofile_arcs) ||
+ if (!(Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
+ false) ||
Args.hasArg(options::OPT_fprofile_generate) ||
Args.hasArg(options::OPT_fprofile_instr_generate) ||
Args.hasArg(options::OPT_fcreate_profile) ||
Args.hasArg(options::OPT_coverage)))
return;
- // -fprofile-instr-generate requires position-independent code to build with
- // shared objects. Link against the right archive.
- const char *Lib = "libclang_rt.profile-";
- if (Args.hasArg(options::OPT_fprofile_instr_generate) &&
- Args.hasArg(options::OPT_shared))
- Lib = "libclang_rt.profile-pic-";
-
SmallString<128> LibProfile = getCompilerRTLibDir(TC);
- llvm::sys::path::append(LibProfile,
- Twine(Lib) + getArchNameForCompilerRTLib(TC) + ".a");
+ 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,
- const StringRef Sanitizer,
+ StringRef Sanitizer,
bool Shared) {
// Sanitizer runtime has name "libclang_rt.<Sanitizer>-<ArchName>.{a,so}"
// (or "libclang_rt.<Sanitizer>-<ArchName>-android.so for Android)
@@ -1960,149 +2204,114 @@
return LibSanitizer;
}
-static void addSanitizerRTLinkFlags(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs,
- const StringRef Sanitizer,
- bool BeforeLibStdCXX,
- bool ExportSymbols = true,
- bool LinkDeps = true) {
- SmallString<128> LibSanitizer =
- getSanitizerRTLibName(TC, Sanitizer, /*Shared*/ false);
-
- // Sanitizer runtime may need to come before -lstdc++ (or -lc++, libstdc++.a,
- // etc.) so that the linker picks custom versions of the global 'operator
- // new' and 'operator delete' symbols. We take the extreme (but simple)
- // strategy of inserting it at the front of the link command. It also
- // needs to be forced to end up in the executable, so wrap it in
+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.
- SmallVector<const char *, 3> LibSanitizerArgs;
- LibSanitizerArgs.push_back("-whole-archive");
- LibSanitizerArgs.push_back(Args.MakeArgString(LibSanitizer));
- LibSanitizerArgs.push_back("-no-whole-archive");
-
- CmdArgs.insert(BeforeLibStdCXX ? CmdArgs.begin() : CmdArgs.end(),
- LibSanitizerArgs.begin(), LibSanitizerArgs.end());
-
- if (LinkDeps) {
- // Link sanitizer dependencies explicitly
- CmdArgs.push_back("-lpthread");
- CmdArgs.push_back("-lrt");
- CmdArgs.push_back("-lm");
- // There's no libdl on FreeBSD.
- if (TC.getTriple().getOS() != llvm::Triple::FreeBSD)
- CmdArgs.push_back("-ldl");
- }
-
- // If possible, use a dynamic symbols file to export the symbols from the
- // runtime library. If we can't do so, use -export-dynamic instead to export
- // all symbols from the binary.
- if (ExportSymbols) {
- if (llvm::sys::fs::exists(LibSanitizer + ".syms"))
- CmdArgs.push_back(
- Args.MakeArgString("--dynamic-list=" + LibSanitizer + ".syms"));
- else
- CmdArgs.push_back("-export-dynamic");
- }
+ if (!IsShared)
+ CmdArgs.push_back("-whole-archive");
+ CmdArgs.push_back(Args.MakeArgString(LibSanitizer));
+ if (!IsShared)
+ CmdArgs.push_back("-no-whole-archive");
}
-/// If AddressSanitizer is enabled, add appropriate linker flags (Linux).
-/// This needs to be called before we add the C run-time (malloc, etc).
-static void addAsanRT(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs, bool Shared, bool IsCXX) {
- if (Shared) {
- // Link dynamic runtime if necessary.
- SmallString<128> LibSanitizer =
- getSanitizerRTLibName(TC, "asan", Shared);
- CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibSanitizer));
+// Tries to use a file with the list of dynamic symbols that need to be exported
+// from the runtime library. Returns true if the file was found.
+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"));
+ return true;
+ }
+ return false;
+}
+
+static void linkSanitizerRuntimeDeps(const ToolChain &TC,
+ ArgStringList &CmdArgs) {
+ // Force linking against the system libraries sanitizers depends on
+ // (see PR15823 why this is necessary).
+ CmdArgs.push_back("--no-as-needed");
+ CmdArgs.push_back("-lpthread");
+ CmdArgs.push_back("-lrt");
+ CmdArgs.push_back("-lm");
+ // There's no libdl on FreeBSD.
+ if (TC.getTriple().getOS() != llvm::Triple::FreeBSD)
+ CmdArgs.push_back("-ldl");
+}
+
+static void
+collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
+ SmallVectorImpl<StringRef> &SharedRuntimes,
+ SmallVectorImpl<StringRef> &StaticRuntimes,
+ SmallVectorImpl<StringRef> &HelperStaticRuntimes) {
+ const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
+ // Collect shared runtimes.
+ if (SanArgs.needsAsanRt() && SanArgs.needsSharedAsanRt()) {
+ SharedRuntimes.push_back("asan");
}
- // Do not link static runtime to DSOs or if compiling for Android.
+ // Collect static runtimes.
if (Args.hasArg(options::OPT_shared) ||
- (TC.getTriple().getEnvironment() == llvm::Triple::Android))
+ (TC.getTriple().getEnvironment() == llvm::Triple::Android)) {
+ // Don't link static runtimes into DSOs or if compiling for Android.
return;
-
- if (Shared) {
- addSanitizerRTLinkFlags(TC, Args, CmdArgs, "asan-preinit",
- /*BeforeLibStdCXX*/ true, /*ExportSymbols*/ false,
- /*LinkDeps*/ false);
- } else {
- addSanitizerRTLinkFlags(TC, Args, CmdArgs, "asan", true);
- if (IsCXX)
- addSanitizerRTLinkFlags(TC, Args, CmdArgs, "asan_cxx", true);
+ }
+ if (SanArgs.needsAsanRt()) {
+ if (SanArgs.needsSharedAsanRt()) {
+ HelperStaticRuntimes.push_back("asan-preinit");
+ } else {
+ StaticRuntimes.push_back("asan");
+ if (SanArgs.linkCXXRuntimes())
+ StaticRuntimes.push_back("asan_cxx");
+ }
+ }
+ if (SanArgs.needsDfsanRt())
+ StaticRuntimes.push_back("dfsan");
+ if (SanArgs.needsLsanRt())
+ StaticRuntimes.push_back("lsan");
+ if (SanArgs.needsMsanRt())
+ StaticRuntimes.push_back("msan");
+ if (SanArgs.needsTsanRt())
+ StaticRuntimes.push_back("tsan");
+ // WARNING: UBSan should always go last.
+ if (SanArgs.needsUbsanRt()) {
+ // If UBSan is not combined with another sanitizer, we need to pull in
+ // sanitizer_common explicitly.
+ if (StaticRuntimes.empty())
+ HelperStaticRuntimes.push_back("san");
+ StaticRuntimes.push_back("ubsan");
+ if (SanArgs.linkCXXRuntimes())
+ StaticRuntimes.push_back("ubsan_cxx");
}
}
-/// If ThreadSanitizer is enabled, add appropriate linker flags (Linux).
-/// This needs to be called before we add the C run-time (malloc, etc).
-static void addTsanRT(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs) {
- if (!Args.hasArg(options::OPT_shared))
- addSanitizerRTLinkFlags(TC, Args, CmdArgs, "tsan", true);
-}
-
-/// If MemorySanitizer is enabled, add appropriate linker flags (Linux).
-/// This needs to be called before we add the C run-time (malloc, etc).
-static void addMsanRT(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs) {
- if (!Args.hasArg(options::OPT_shared))
- addSanitizerRTLinkFlags(TC, Args, CmdArgs, "msan", true);
-}
-
-/// If LeakSanitizer is enabled, add appropriate linker flags (Linux).
-/// This needs to be called before we add the C run-time (malloc, etc).
-static void addLsanRT(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs) {
- if (!Args.hasArg(options::OPT_shared))
- addSanitizerRTLinkFlags(TC, Args, CmdArgs, "lsan", true);
-}
-
-/// If UndefinedBehaviorSanitizer is enabled, add appropriate linker flags
-/// (Linux).
-static void addUbsanRT(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs, bool IsCXX,
- bool HasOtherSanitizerRt) {
- // Do not link runtime into shared libraries.
- if (Args.hasArg(options::OPT_shared))
- return;
-
- // Need a copy of sanitizer_common. This could come from another sanitizer
- // runtime; if we're not including one, include our own copy.
- if (!HasOtherSanitizerRt)
- addSanitizerRTLinkFlags(TC, Args, CmdArgs, "san", true, false);
-
- addSanitizerRTLinkFlags(TC, Args, CmdArgs, "ubsan", false, true);
-
- // Only include the bits of the runtime which need a C++ ABI library if
- // we're linking in C++ mode.
- if (IsCXX)
- addSanitizerRTLinkFlags(TC, Args, CmdArgs, "ubsan_cxx", false, true);
-}
-
-static void addDfsanRT(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs) {
- if (!Args.hasArg(options::OPT_shared))
- addSanitizerRTLinkFlags(TC, Args, CmdArgs, "dfsan", true);
-}
-
-// Should be called before we add C++ ABI library.
-static void addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
+// Should be called before we add system libraries (C++ ABI, libstdc++/libc++,
+// C runtime, etc). Returns true if sanitizer system deps need to be linked in.
+static bool addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
- const SanitizerArgs &Sanitize = TC.getSanitizerArgs();
- const Driver &D = TC.getDriver();
- if (Sanitize.needsUbsanRt())
- addUbsanRT(TC, Args, CmdArgs, D.CCCIsCXX(),
- Sanitize.needsAsanRt() || Sanitize.needsTsanRt() ||
- Sanitize.needsMsanRt() || Sanitize.needsLsanRt());
- if (Sanitize.needsAsanRt())
- addAsanRT(TC, Args, CmdArgs, Sanitize.needsSharedAsanRt(), D.CCCIsCXX());
- if (Sanitize.needsTsanRt())
- addTsanRT(TC, Args, CmdArgs);
- if (Sanitize.needsMsanRt())
- addMsanRT(TC, Args, CmdArgs);
- if (Sanitize.needsLsanRt())
- addLsanRT(TC, Args, CmdArgs);
- if (Sanitize.needsDfsanRt())
- addDfsanRT(TC, Args, CmdArgs);
+ SmallVector<StringRef, 4> SharedRuntimes, StaticRuntimes,
+ HelperStaticRuntimes;
+ collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes,
+ HelperStaticRuntimes);
+ for (auto RT : SharedRuntimes)
+ addSanitizerRuntime(TC, Args, CmdArgs, RT, true);
+ for (auto RT : HelperStaticRuntimes)
+ addSanitizerRuntime(TC, Args, CmdArgs, RT, false);
+ bool AddExportDynamic = false;
+ for (auto RT : StaticRuntimes) {
+ addSanitizerRuntime(TC, Args, CmdArgs, RT, false);
+ AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT);
+ }
+ // If there is a static runtime with no dynamic list, force all the symbols
+ // to be dynamic to be sure we export sanitizer interface functions.
+ if (AddExportDynamic)
+ CmdArgs.push_back("-export-dynamic");
+ return !StaticRuntimes.empty();
}
static bool shouldUseFramePointerForTarget(const ArgList &Args,
@@ -2192,10 +2401,10 @@
Args.MakeArgString(TC.GetProgramPath("objcopy"));
// First extract the dwo sections.
- C.addCommand(new Command(JA, T, Exec, ExtractArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, T, Exec, ExtractArgs));
// Then remove them from the original .o file.
- C.addCommand(new Command(JA, T, Exec, StripArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, T, Exec, StripArgs));
}
/// \brief Vectorize at all optimization levels greater than 1 except for -Oz.
@@ -2245,6 +2454,26 @@
CmdArgs.push_back(types::getTypeName(Input.getType()));
}
+static std::string getMSCompatibilityVersion(const char *VersionStr) {
+ unsigned Version;
+ if (StringRef(VersionStr).getAsInteger(10, Version))
+ return "0";
+
+ if (Version < 100)
+ return llvm::utostr_32(Version) + ".0";
+
+ if (Version < 10000)
+ return llvm::utostr_32(Version / 100) + "." +
+ llvm::utostr_32(Version % 100);
+
+ unsigned Build = 0, Factor = 1;
+ for ( ; Version > 10000; Version = Version / 10, Factor = Factor * 10)
+ Build = Build + (Version % 10) * Factor;
+ return llvm::utostr_32(Version / 100) + "." +
+ llvm::utostr_32(Version % 100) + "." +
+ llvm::utostr_32(Build);
+}
+
void Clang::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -2439,7 +2668,6 @@
case llvm::Triple::thumb:
case llvm::Triple::thumbeb:
case llvm::Triple::aarch64:
- case llvm::Triple::arm64:
case llvm::Triple::mips:
case llvm::Triple::mipsel:
case llvm::Triple::mips64:
@@ -2520,7 +2748,6 @@
// 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::arm64 ||
Triple.getArch() == llvm::Triple::aarch64))
PIC = PIE = false;
if (Args.hasArg(options::OPT_static))
@@ -2561,6 +2788,12 @@
}
}
+ CmdArgs.push_back("-mthread-model");
+ if (Arg *A = Args.getLastArg(options::OPT_mthread_model))
+ CmdArgs.push_back(A->getValue());
+ else
+ CmdArgs.push_back(Args.MakeArgString(getToolChain().getThreadModel()));
+
if (!Args.hasFlag(options::OPT_fmerge_all_constants,
options::OPT_fno_merge_all_constants))
CmdArgs.push_back("-fno-merge-all-constants");
@@ -2857,8 +3090,6 @@
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_be:
- case llvm::Triple::arm64:
- case llvm::Triple::arm64_be:
AddAArch64TargetArgs(Args, CmdArgs);
break;
@@ -2869,7 +3100,14 @@
AddMIPSTargetArgs(Args, CmdArgs);
break;
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ case llvm::Triple::ppc64le:
+ AddPPCTargetArgs(Args, CmdArgs);
+ break;
+
case llvm::Triple::sparc:
+ case llvm::Triple::sparcv9:
AddSparcTargetArgs(Args, CmdArgs);
break;
@@ -2931,14 +3169,16 @@
// are preserved, all other debug options are substituted with "-g".
Args.ClaimAllArgs(options::OPT_g_Group);
if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
- if (A->getOption().matches(options::OPT_gline_tables_only)) {
+ if (A->getOption().matches(options::OPT_gline_tables_only) ||
+ A->getOption().matches(options::OPT_g1)) {
// FIXME: we should support specifying dwarf version with
// -gline-tables-only.
CmdArgs.push_back("-gline-tables-only");
- // Default is dwarf-2 for Darwin, OpenBSD and FreeBSD.
+ // Default is dwarf-2 for Darwin, OpenBSD, FreeBSD and Solaris.
const llvm::Triple &Triple = getToolChain().getTriple();
if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::OpenBSD ||
- Triple.getOS() == llvm::Triple::FreeBSD)
+ Triple.getOS() == llvm::Triple::FreeBSD ||
+ Triple.getOS() == llvm::Triple::Solaris)
CmdArgs.push_back("-gdwarf-2");
} else if (A->getOption().matches(options::OPT_gdwarf_2))
CmdArgs.push_back("-gdwarf-2");
@@ -2948,10 +3188,11 @@
CmdArgs.push_back("-gdwarf-4");
else if (!A->getOption().matches(options::OPT_g0) &&
!A->getOption().matches(options::OPT_ggdb0)) {
- // Default is dwarf-2 for Darwin, OpenBSD and FreeBSD.
+ // Default is dwarf-2 for Darwin, OpenBSD, FreeBSD and Solaris.
const llvm::Triple &Triple = getToolChain().getTriple();
if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::OpenBSD ||
- Triple.getOS() == llvm::Triple::FreeBSD)
+ Triple.getOS() == llvm::Triple::FreeBSD ||
+ Triple.getOS() == llvm::Triple::Solaris)
CmdArgs.push_back("-gdwarf-2");
else
CmdArgs.push_back("-g");
@@ -2960,7 +3201,8 @@
// We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now.
Args.ClaimAllArgs(options::OPT_g_flags_Group);
- if (Args.hasArg(options::OPT_gcolumn_info))
+ if (Args.hasFlag(options::OPT_gcolumn_info, options::OPT_gno_column_info,
+ /*Default*/ true))
CmdArgs.push_back("-dwarf-column-info");
// FIXME: Move backend command line options to the module.
@@ -3021,15 +3263,29 @@
if (Args.hasArg(options::OPT_ftest_coverage) ||
Args.hasArg(options::OPT_coverage))
CmdArgs.push_back("-femit-coverage-notes");
- if (Args.hasArg(options::OPT_fprofile_arcs) ||
+ if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
+ false) ||
Args.hasArg(options::OPT_coverage))
CmdArgs.push_back("-femit-coverage-data");
+ if (Args.hasArg(options::OPT_fcoverage_mapping) &&
+ !Args.hasArg(options::OPT_fprofile_instr_generate))
+ D.Diag(diag::err_drv_argument_only_allowed_with)
+ << "-fcoverage-mapping" << "-fprofile-instr-generate";
+
+ if (Args.hasArg(options::OPT_fcoverage_mapping))
+ CmdArgs.push_back("-fcoverage-mapping");
+
if (C.getArgs().hasArg(options::OPT_c) ||
C.getArgs().hasArg(options::OPT_S)) {
if (Output.isFilename()) {
CmdArgs.push_back("-coverage-file");
- SmallString<128> CoverageFilename(Output.getFilename());
+ SmallString<128> CoverageFilename;
+ if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o)) {
+ CoverageFilename = FinalOutput->getValue();
+ } else {
+ CoverageFilename = llvm::sys::path::filename(Output.getBaseInput());
+ }
if (llvm::sys::path::is_relative(CoverageFilename.str())) {
SmallString<128> Pwd;
if (!llvm::sys::fs::current_path(Pwd)) {
@@ -3150,10 +3406,18 @@
}
}
+ // Warn about ignored options to clang.
+ for (arg_iterator it = Args.filtered_begin(
+ options::OPT_clang_ignored_gcc_optimization_f_Group),
+ ie = Args.filtered_end(); it != ie; ++it) {
+ 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);
+ Args.AddAllArgs(CmdArgs, options::OPT_R_Group);
Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
if (Args.hasFlag(options::OPT_pedantic, options::OPT_no_pedantic, false))
CmdArgs.push_back("-pedantic");
@@ -3361,15 +3625,6 @@
const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs();
Sanitize.addArgs(Args, CmdArgs);
- if (!Args.hasFlag(options::OPT_fsanitize_recover,
- options::OPT_fno_sanitize_recover,
- true))
- CmdArgs.push_back("-fno-sanitize-recover");
-
- if (Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error,
- options::OPT_fno_sanitize_undefined_trap_on_error, false))
- CmdArgs.push_back("-fsanitize-undefined-trap-on-error");
-
// Report an error for -faltivec on anything other than PowerPC.
if (const Arg *A = Args.getLastArg(options::OPT_faltivec))
if (!(getToolChain().getArch() == llvm::Triple::ppc ||
@@ -3477,31 +3732,10 @@
StringRef alignment = Args.getLastArgValue(options::OPT_mstack_alignment);
CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment));
}
- // -mkernel implies -mstrict-align; don't add the redundant option.
- if (!KernelOrKext) {
- if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
- options::OPT_munaligned_access)) {
- if (A->getOption().matches(options::OPT_mno_unaligned_access)) {
- CmdArgs.push_back("-backend-option");
- if (getToolChain().getTriple().getArch() == llvm::Triple::aarch64 ||
- getToolChain().getTriple().getArch() == llvm::Triple::aarch64_be ||
- getToolChain().getTriple().getArch() == llvm::Triple::arm64 ||
- getToolChain().getTriple().getArch() == llvm::Triple::arm64_be)
- CmdArgs.push_back("-aarch64-strict-align");
- else
- CmdArgs.push_back("-arm-strict-align");
- } else {
- CmdArgs.push_back("-backend-option");
- if (getToolChain().getTriple().getArch() == llvm::Triple::aarch64 ||
- getToolChain().getTriple().getArch() == llvm::Triple::aarch64_be ||
- getToolChain().getTriple().getArch() == llvm::Triple::arm64 ||
- getToolChain().getTriple().getArch() == llvm::Triple::arm64_be)
- CmdArgs.push_back("-aarch64-no-strict-align");
- else
- CmdArgs.push_back("-arm-no-strict-align");
- }
- }
- }
+
+ if (getToolChain().getTriple().getArch() == llvm::Triple::aarch64 ||
+ getToolChain().getTriple().getArch() == llvm::Triple::aarch64_be)
+ CmdArgs.push_back("-fallow-half-arguments-and-returns");
if (Arg *A = Args.getLastArg(options::OPT_mrestrict_it,
options::OPT_mno_restrict_it)) {
@@ -3540,15 +3774,6 @@
A->render(Args, CmdArgs);
}
- if (Arg *A = Args.getLastArg(options::OPT_Rpass_EQ))
- A->render(Args, CmdArgs);
-
- if (Arg *A = Args.getLastArg(options::OPT_Rpass_missed_EQ))
- A->render(Args, CmdArgs);
-
- if (Arg *A = Args.getLastArg(options::OPT_Rpass_analysis_EQ))
- A->render(Args, CmdArgs);
-
if (Args.hasArg(options::OPT_mkernel)) {
if (!Args.hasArg(options::OPT_fapple_kext) && types::isCXX(InputType))
CmdArgs.push_back("-fapple-kext");
@@ -3577,14 +3802,14 @@
CmdArgs.push_back("-fblocks-runtime-optional");
}
- // -fmodules enables modules (off by default). However, for C++/Objective-C++,
- // users must also pass -fcxx-modules. The latter flag will disappear once the
- // modules implementation is solid for C++/Objective-C++ programs as well.
+ // -fmodules enables modules (off by default).
+ // Users can pass -fno-cxx-modules to turn off modules support for
+ // C++/Objective-C++ programs, which is a little less mature.
bool HaveModules = false;
if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) {
bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules,
options::OPT_fno_cxx_modules,
- false);
+ true);
if (AllowedInCXX || !types::isCXX(InputType)) {
CmdArgs.push_back("-fmodules");
HaveModules = true;
@@ -3616,15 +3841,17 @@
// -fmodule-name specifies the module that is currently being built (or
// used for header checking by -fmodule-maps).
- if (Arg *A = Args.getLastArg(options::OPT_fmodule_name))
- A->render(Args, CmdArgs);
+ Args.AddLastArg(CmdArgs, options::OPT_fmodule_name);
- // -fmodule-map-file can be used to specify a file containing module
+ // -fmodule-map-file can be used to specify files containing module
// definitions.
- if (Arg *A = Args.getLastArg(options::OPT_fmodule_map_file))
- A->render(Args, CmdArgs);
+ Args.AddAllArgs(CmdArgs, options::OPT_fmodule_map_file);
- // -fmodule-cache-path specifies where our module files should be written.
+ // -fmodule-file can be used to specify files containing precompiled modules.
+ Args.AddAllArgs(CmdArgs, options::OPT_fmodule_file);
+
+ // -fmodule-cache-path specifies where our implicitly-built module files
+ // should be written.
SmallString<128> ModuleCachePath;
if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path))
ModuleCachePath = A->getValue();
@@ -3652,14 +3879,16 @@
if (HaveModules && C.isForDiagnostics()) {
SmallString<128> VFSDir(Output.getFilename());
llvm::sys::path::replace_extension(VFSDir, ".cache");
+ // Add the cache directory as a temp so the crash diagnostics pick it up.
+ C.addTempFile(Args.MakeArgString(VFSDir));
+
llvm::sys::path::append(VFSDir, "vfs");
CmdArgs.push_back("-module-dependency-dir");
CmdArgs.push_back(Args.MakeArgString(VFSDir));
}
- if (Arg *A = Args.getLastArg(options::OPT_fmodules_user_build_path))
- if (HaveModules)
- A->render(Args, CmdArgs);
+ if (HaveModules)
+ Args.AddLastArg(CmdArgs, options::OPT_fmodules_user_build_path);
// Pass through all -fmodules-ignore-macro arguments.
Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro);
@@ -3668,8 +3897,23 @@
Args.AddLastArg(CmdArgs, options::OPT_fbuild_session_timestamp);
+ if (Arg *A = Args.getLastArg(options::OPT_fbuild_session_file)) {
+ if (Args.hasArg(options::OPT_fbuild_session_timestamp))
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << A->getAsString(Args) << "-fbuild-session-timestamp";
+
+ 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));
+ }
+
if (Args.getLastArg(options::OPT_fmodules_validate_once_per_build_session)) {
- if (!Args.getLastArg(options::OPT_fbuild_session_timestamp))
+ if (!Args.getLastArg(options::OPT_fbuild_session_timestamp,
+ options::OPT_fbuild_session_file))
D.Diag(diag::err_drv_modules_validate_once_requires_timestamp);
Args.AddLastArg(CmdArgs,
@@ -3745,16 +3989,30 @@
true))))
CmdArgs.push_back("-fms-compatibility");
- // -fmsc-version=1700 is default.
+ // -fms-compatibility-version=17.00 is default.
if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
- IsWindowsMSVC) || Args.hasArg(options::OPT_fmsc_version)) {
- StringRef msc_ver = Args.getLastArgValue(options::OPT_fmsc_version);
- if (msc_ver.empty())
- CmdArgs.push_back("-fmsc-version=1700");
- else
- CmdArgs.push_back(Args.MakeArgString("-fmsc-version=" + msc_ver));
- }
+ IsWindowsMSVC) || Args.hasArg(options::OPT_fmsc_version) ||
+ Args.hasArg(options::OPT_fms_compatibility_version)) {
+ const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version);
+ const Arg *MSCompatibilityVersion =
+ Args.getLastArg(options::OPT_fms_compatibility_version);
+ if (MSCVersion && MSCompatibilityVersion)
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << MSCVersion->getAsString(Args)
+ << MSCompatibilityVersion->getAsString(Args);
+
+ std::string Ver;
+ if (MSCompatibilityVersion)
+ Ver = Args.getLastArgValue(options::OPT_fms_compatibility_version);
+ else if (MSCVersion)
+ Ver = getMSCompatibilityVersion(MSCVersion->getValue());
+
+ if (Ver.empty())
+ CmdArgs.push_back("-fms-compatibility-version=17.00");
+ else
+ CmdArgs.push_back(Args.MakeArgString("-fms-compatibility-version=" + Ver));
+ }
// -fno-borland-extensions is default.
if (Args.hasFlag(options::OPT_fborland_extensions,
@@ -3910,6 +4168,21 @@
CmdArgs.push_back("-fpack-struct=1");
}
+ // Handle -fmax-type-align=N and -fno-type-align
+ bool SkipMaxTypeAlign = Args.hasArg(options::OPT_fno_max_type_align);
+ if (Arg *A = Args.getLastArg(options::OPT_fmax_type_align_EQ)) {
+ if (!SkipMaxTypeAlign) {
+ std::string MaxTypeAlignStr = "-fmax-type-align=";
+ MaxTypeAlignStr += A->getValue();
+ CmdArgs.push_back(Args.MakeArgString(MaxTypeAlignStr));
+ }
+ } else if (getToolChain().getTriple().isOSDarwin()) {
+ if (!SkipMaxTypeAlign) {
+ std::string MaxTypeAlignStr = "-fmax-type-align=16";
+ CmdArgs.push_back(Args.MakeArgString(MaxTypeAlignStr));
+ }
+ }
+
if (KernelOrKext || isNoCommonDefault(getToolChain().getTriple())) {
if (!Args.hasArg(options::OPT_fcommon))
CmdArgs.push_back("-fno-common");
@@ -3941,6 +4214,14 @@
D.Diag(diag::err_drv_invalid_value) << inputCharset->getAsString(Args) << value;
}
+ // -fexec_charset=UTF-8 is default. Reject others
+ if (Arg *execCharset = Args.getLastArg(
+ options::OPT_fexec_charset_EQ)) {
+ StringRef value = execCharset->getValue();
+ if (value != "UTF-8")
+ D.Diag(diag::err_drv_invalid_value) << execCharset->getAsString(Args) << value;
+ }
+
// -fcaret-diagnostics is default.
if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
options::OPT_fno_caret_diagnostics, true))
@@ -4190,8 +4471,10 @@
SmallString<256> Flags;
Flags += Exec;
for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) {
+ SmallString<128> EscapedArg;
+ EscapeSpacesAndBackslashes(OriginalArgs[i], EscapedArg);
Flags += " ";
- Flags += OriginalArgs[i];
+ Flags += EscapedArg;
}
CmdArgs.push_back("-dwarf-debug-flags");
CmdArgs.push_back(Args.MakeArgString(Flags.str()));
@@ -4213,11 +4496,12 @@
if (Args.hasArg(options::OPT__SLASH_fallback) &&
Output.getType() == types::TY_Object &&
(InputType == types::TY_C || InputType == types::TY_CXX)) {
- Command *CLCommand = getCLFallback()->GetCommand(C, JA, Output, Inputs,
- Args, LinkingOutput);
- C.addCommand(new FallbackCommand(JA, *this, Exec, CmdArgs, CLCommand));
+ auto CLCommand =
+ getCLFallback()->GetCommand(C, JA, Output, Inputs, Args, LinkingOutput);
+ C.addCommand(llvm::make_unique<FallbackCommand>(JA, *this, Exec, CmdArgs,
+ std::move(CLCommand)));
} else {
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
@@ -4457,8 +4741,11 @@
// implemented in clang.
CmdArgs.push_back("--dependent-lib=oldnames");
- if (Arg *A = Args.getLastArg(options::OPT_show_includes))
- A->render(Args, CmdArgs);
+ // Both /showIncludes and /E (and /EP) write to stdout. Allowing both
+ // would produce interleaved output, so ignore /showIncludes in such cases.
+ if (!Args.hasArg(options::OPT_E) && !Args.hasArg(options::OPT__SLASH_EP))
+ if (Arg *A = Args.getLastArg(options::OPT_show_includes))
+ A->render(Args, CmdArgs);
// This controls whether or not we emit RTTI data for polymorphic types.
if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
@@ -4617,8 +4904,10 @@
const char *Exec = getToolChain().getDriver().getClangProgramPath();
Flags += Exec;
for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) {
+ SmallString<128> EscapedArg;
+ EscapeSpacesAndBackslashes(OriginalArgs[i], EscapedArg);
Flags += " ";
- Flags += OriginalArgs[i];
+ Flags += EscapedArg;
}
CmdArgs.push_back("-dwarf-debug-flags");
CmdArgs.push_back(Args.MakeArgString(Flags.str()));
@@ -4649,7 +4938,7 @@
CmdArgs.push_back(Input.getFilename());
const char *Exec = getToolChain().getDriver().getClangProgramPath();
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
// Handle the debug info splitting at object creation time if we're
// creating an object.
@@ -4660,6 +4949,8 @@
SplitDebugName(Args, Inputs));
}
+void GnuTool::anchor() {}
+
void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -4692,19 +4983,10 @@
RenderExtraToolArgs(JA, CmdArgs);
// If using a driver driver, force the arch.
- llvm::Triple::ArchType Arch = getToolChain().getArch();
if (getToolChain().getTriple().isOSDarwin()) {
CmdArgs.push_back("-arch");
-
- // FIXME: Remove these special cases.
- if (Arch == llvm::Triple::ppc)
- CmdArgs.push_back("ppc");
- else if (Arch == llvm::Triple::ppc64)
- CmdArgs.push_back("ppc64");
- else if (Arch == llvm::Triple::ppc64le)
- CmdArgs.push_back("ppc64le");
- else
- CmdArgs.push_back(Args.MakeArgString(getToolChain().getArchName()));
+ CmdArgs.push_back(
+ Args.MakeArgString(getToolChain().getDefaultUniversalArchName()));
}
// Try to force gcc to match the tool chain we want, if we recognize
@@ -4712,6 +4994,7 @@
//
// FIXME: The triple class should directly provide the information we want
// here.
+ llvm::Triple::ArchType Arch = getToolChain().getArch();
if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc)
CmdArgs.push_back("-m32");
else if (Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::ppc64 ||
@@ -4782,7 +5065,7 @@
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void gcc::Preprocess::RenderExtraToolArgs(const JobAction &JA,
@@ -4878,7 +5161,7 @@
const char *GCCName = "hexagon-as";
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void hexagon::Link::RenderExtraToolArgs(const JobAction &JA,
@@ -4955,8 +5238,8 @@
const std::string MarchSuffix = "/" + MarchString;
const std::string G0Suffix = "/G0";
const std::string MarchG0Suffix = MarchSuffix + G0Suffix;
- const std::string RootDir = toolchains::Hexagon_TC::GetGnuDir(D.InstalledDir)
- + "/";
+ const std::string RootDir =
+ toolchains::Hexagon_TC::GetGnuDir(D.InstalledDir, Args) + "/";
const std::string StartFilesDir = RootDir
+ "hexagon/lib"
+ (buildingLib
@@ -5044,10 +5327,12 @@
}
std::string Linker = ToolChain.GetProgramPath("hexagon-ld");
- C.addCommand(new Command(JA, *this, Args.MakeArgString(Linker), CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
+ CmdArgs));
}
// Hexagon tools end.
+/// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
const char *arm::getARMCPUForMArch(const ArgList &Args,
const llvm::Triple &Triple) {
StringRef MArch;
@@ -5069,89 +5354,7 @@
}
}
- return driver::getARMCPUForMArch(MArch, Triple);
-}
-
-/// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
-//
-// FIXME: tblgen this.
-const char *driver::getARMCPUForMArch(StringRef MArch,
- const llvm::Triple &Triple) {
- switch (Triple.getOS()) {
- case llvm::Triple::NetBSD:
- if (MArch == "armv6")
- return "arm1176jzf-s";
- break;
- case llvm::Triple::Win32:
- // FIXME: this is invalid for WindowsCE
- return "cortex-a9";
- default:
- break;
- }
-
- const char *result = nullptr;
- size_t offset = StringRef::npos;
- if (MArch.startswith("arm"))
- offset = 3;
- if (MArch.startswith("thumb"))
- offset = 5;
- if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb")
- offset += 2;
- if (offset != StringRef::npos)
- result = llvm::StringSwitch<const char *>(MArch.substr(offset))
- .Cases("v2", "v2a", "arm2")
- .Case("v3", "arm6")
- .Case("v3m", "arm7m")
- .Case("v4", "strongarm")
- .Case("v4t", "arm7tdmi")
- .Cases("v5", "v5t", "arm10tdmi")
- .Cases("v5e", "v5te", "arm1022e")
- .Case("v5tej", "arm926ej-s")
- .Cases("v6", "v6k", "arm1136jf-s")
- .Case("v6j", "arm1136j-s")
- .Cases("v6z", "v6zk", "arm1176jzf-s")
- .Case("v6t2", "arm1156t2-s")
- .Cases("v6m", "v6-m", "cortex-m0")
- .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8")
- .Cases("v7s", "v7-s", "swift")
- .Cases("v7r", "v7-r", "cortex-r4")
- .Cases("v7m", "v7-m", "cortex-m3")
- .Cases("v7em", "v7e-m", "cortex-m4")
- .Cases("v8", "v8a", "v8-a", "cortex-a53")
- .Default(nullptr);
- else
- result = llvm::StringSwitch<const char *>(MArch)
- .Case("ep9312", "ep9312")
- .Case("iwmmxt", "iwmmxt")
- .Case("xscale", "xscale")
- .Default(nullptr);
-
- if (result)
- return result;
-
- // If all else failed, return the most base CPU with thumb interworking
- // supported by LLVM.
- // FIXME: Should warn once that we're falling back.
- switch (Triple.getOS()) {
- case llvm::Triple::NetBSD:
- switch (Triple.getEnvironment()) {
- case llvm::Triple::GNUEABIHF:
- case llvm::Triple::GNUEABI:
- case llvm::Triple::EABIHF:
- case llvm::Triple::EABI:
- return "arm926ej-s";
- default:
- return "strongarm";
- }
- default:
- switch (Triple.getEnvironment()) {
- case llvm::Triple::EABIHF:
- case llvm::Triple::GNUEABIHF:
- return "arm1176jzf-s";
- default:
- return "arm7tdmi";
- }
- }
+ return Triple.getARMCPUForArch(MArch);
}
/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
@@ -5190,12 +5393,12 @@
.Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "v6")
.Cases("arm1176jzf-s", "mpcorenovfp", "mpcore", "v6")
.Cases("arm1156t2-s", "arm1156t2f-s", "v6t2")
- .Cases("cortex-a5", "cortex-a7", "cortex-a8", "cortex-a9-mp", "v7")
- .Cases("cortex-a9", "cortex-a12", "cortex-a15", "krait", "v7")
+ .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")
- .Case("cortex-m4", "v7em")
+ .Cases("cortex-m4", "cortex-m7", "v7em")
.Case("swift", "v7s")
.Case("cyclone", "v8")
.Cases("cortex-a53", "cortex-a57", "v8")
@@ -5207,6 +5410,11 @@
return A && (A->getValue() == StringRef(Value));
}
+bool mips::isUCLibc(const ArgList &Args) {
+ Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
+ return A && A->getOption().matches(options::OPT_muclibc);
+}
+
bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) {
if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
return llvm::StringSwitch<bool>(NaNArg->getValue())
@@ -5222,6 +5430,22 @@
return false;
}
+bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
+ StringRef ABIName) {
+ if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
+ Triple.getVendor() != llvm::Triple::MipsTechnologies)
+ return false;
+
+ if (ABIName != "32")
+ return false;
+
+ return llvm::StringSwitch<bool>(CPUName)
+ .Cases("mips2", "mips3", "mips4", "mips5", true)
+ .Cases("mips32", "mips32r2", true)
+ .Cases("mips64", "mips64r2", true)
+ .Default(false);
+}
+
llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) {
// See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
// archs which Darwin doesn't use.
@@ -5247,7 +5471,7 @@
.Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm)
.Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm)
.Cases("armv7s", "xscale", llvm::Triple::arm)
- .Case("arm64", llvm::Triple::arm64)
+ .Case("arm64", llvm::Triple::aarch64)
.Case("r600", llvm::Triple::r600)
.Case("nvptx", llvm::Triple::nvptx)
.Case("nvptx64", llvm::Triple::nvptx64)
@@ -5365,7 +5589,7 @@
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void darwin::MachOTool::anchor() {}
@@ -5581,6 +5805,12 @@
const char *LinkingOutput) const {
assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
+ // If the number of arguments surpasses the system limits, we will encode the
+ // input files in a separate file, shortening the command line. To this end,
+ // build a list of input file names that can be passed via a file with the
+ // -filelist linker option.
+ llvm::opt::ArgStringList InputFileList;
+
// The logic here is derived from gcc's behavior; most of which
// comes from specs (starting with link_command). Consult gcc for
// more information.
@@ -5594,7 +5824,7 @@
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("touch"));
CmdArgs.push_back(Output.getFilename());
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
return;
}
@@ -5649,7 +5879,23 @@
}
AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
-
+ // Build the input file for -filelist (list of linker input files) in case we
+ // need it later
+ for (const auto &II : Inputs) {
+ if (!II.isFilename()) {
+ // This is a linker input argument.
+ // We cannot mix input arguments and file names in a -filelist input, thus
+ // we prematurely stop our list (remaining files shall be passed as
+ // arguments).
+ if (InputFileList.size() > 0)
+ break;
+
+ continue;
+ }
+
+ InputFileList.push_back(II.getFilename());
+ }
+
if (isObjCRuntimeLinked(Args) &&
!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nodefaultlibs)) {
@@ -5692,7 +5938,10 @@
const char *Exec =
Args.MakeArgString(getToolChain().GetLinkerPath());
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ std::unique_ptr<Command> Cmd =
+ llvm::make_unique<Command>(JA, *this, Exec, CmdArgs);
+ Cmd->setInputFileList(std::move(InputFileList));
+ C.addCommand(std::move(Cmd));
}
void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
@@ -5714,7 +5963,7 @@
}
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA,
@@ -5734,7 +5983,7 @@
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("dsymutil"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA,
@@ -5757,7 +6006,7 @@
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void solaris::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
@@ -5777,7 +6026,7 @@
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void solaris::Link::ConstructJob(Compilation &C, const JobAction &JA,
@@ -5882,115 +6131,7 @@
const char *Exec =
Args.MakeArgString(getToolChain().GetLinkerPath());
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
-}
-
-void auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
-
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
- options::OPT_Xassembler);
-
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
-
- for (const auto &II : Inputs)
- CmdArgs.push_back(II.getFilename());
-
- const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("gas"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
-}
-
-void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
-
- if ((!Args.hasArg(options::OPT_nostdlib)) &&
- (!Args.hasArg(options::OPT_shared))) {
- CmdArgs.push_back("-e");
- CmdArgs.push_back("_start");
- }
-
- if (Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("-Bstatic");
- CmdArgs.push_back("-dn");
- } else {
-// CmdArgs.push_back("--eh-frame-hdr");
- CmdArgs.push_back("-Bdynamic");
- if (Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back("-shared");
- } else {
- CmdArgs.push_back("--dynamic-linker");
- CmdArgs.push_back("/lib/ld.so.1"); // 64Bit Path /lib/amd64/ld.so.1
- }
- }
-
- if (Output.isFilename()) {
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- } else {
- assert(Output.isNothing() && "Invalid output.");
- }
-
- 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("crtn.o")));
- }
-
- CmdArgs.push_back(Args.MakeArgString("-L/opt/gcc4/lib/gcc/"
- + getToolChain().getTripleString()
- + "/4.2.4"));
-
- Args.AddAllArgs(CmdArgs, options::OPT_L);
- Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
- Args.AddAllArgs(CmdArgs, options::OPT_e);
-
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
-
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nodefaultlibs)) {
- // FIXME: For some reason GCC passes -lgcc before adding
- // the default system libraries. Just mimic this for now.
- CmdArgs.push_back("-lgcc");
-
- if (Args.hasArg(options::OPT_pthread))
- CmdArgs.push_back("-pthread");
- if (!Args.hasArg(options::OPT_shared))
- CmdArgs.push_back("-lc");
- CmdArgs.push_back("-lgcc");
- }
-
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- if (!Args.hasArg(options::OPT_shared))
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtend.o")));
- }
-
- addProfileRT(getToolChain(), Args, CmdArgs);
-
- const char *Exec =
- Args.MakeArgString(getToolChain().GetLinkerPath());
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
@@ -6028,7 +6169,7 @@
case llvm::Triple::mips64el: {
StringRef CPUName;
StringRef ABIName;
- getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
+ mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
CmdArgs.push_back("-mabi");
CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
@@ -6060,7 +6201,7 @@
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
@@ -6192,7 +6333,7 @@
const char *Exec =
Args.MakeArgString(getToolChain().GetLinkerPath());
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void bitrig::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
@@ -6212,7 +6353,7 @@
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void bitrig::Link::ConstructJob(Compilation &C, const JobAction &JA,
@@ -6328,7 +6469,7 @@
const char *Exec =
Args.MakeArgString(getToolChain().GetLinkerPath());
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
@@ -6350,7 +6491,7 @@
getToolChain().getArch() == llvm::Triple::mips64el) {
StringRef CPUName;
StringRef ABIName;
- getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
+ mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
CmdArgs.push_back("-march");
CmdArgs.push_back(CPUName.data());
@@ -6409,7 +6550,7 @@
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
@@ -6508,7 +6649,7 @@
}
Args.AddAllArgs(CmdArgs, options::OPT_L);
- const ToolChain::path_list Paths = ToolChain.getFilePaths();
+ const ToolChain::path_list &Paths = ToolChain.getFilePaths();
for (const auto &Path : Paths)
CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path));
Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
@@ -6521,6 +6662,7 @@
if (D.IsUsingLTO(Args))
AddGoldPlugin(ToolChain, Args, CmdArgs);
+ bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
if (!Args.hasArg(options::OPT_nostdlib) &&
@@ -6532,6 +6674,8 @@
else
CmdArgs.push_back("-lm");
}
+ if (NeedsSanitizerDeps)
+ linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
// FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
// the default system libraries. Just mimic this for now.
if (Args.hasArg(options::OPT_pg))
@@ -6586,13 +6730,11 @@
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
}
- addSanitizerRuntimes(getToolChain(), Args, CmdArgs);
-
addProfileRT(ToolChain, Args, CmdArgs);
const char *Exec =
Args.MakeArgString(getToolChain().GetLinkerPath());
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
@@ -6623,7 +6765,7 @@
case llvm::Triple::mips64el: {
StringRef CPUName;
StringRef ABIName;
- getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
+ mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
CmdArgs.push_back("-march");
CmdArgs.push_back(CPUName.data());
@@ -6666,7 +6808,7 @@
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
@@ -6702,9 +6844,7 @@
CmdArgs.push_back("elf_i386");
break;
case llvm::Triple::arm:
- case llvm::Triple::armeb:
case llvm::Triple::thumb:
- case llvm::Triple::thumbeb:
CmdArgs.push_back("-m");
switch (getToolChain().getTriple().getEnvironment()) {
case llvm::Triple::EABI:
@@ -6720,6 +6860,23 @@
break;
}
break;
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumbeb:
+ CmdArgs.push_back("-m");
+ switch (getToolChain().getTriple().getEnvironment()) {
+ case llvm::Triple::EABI:
+ case llvm::Triple::GNUEABI:
+ CmdArgs.push_back("armelfb_nbsd_eabi");
+ break;
+ case llvm::Triple::EABIHF:
+ case llvm::Triple::GNUEABIHF:
+ CmdArgs.push_back("armelfb_nbsd_eabihf");
+ break;
+ default:
+ CmdArgs.push_back("armelfb_nbsd");
+ break;
+ }
+ break;
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
if (mips::hasMipsAbiArg(Args, "32")) {
@@ -6736,6 +6893,16 @@
CmdArgs.push_back("elf64ltsmip");
}
break;
+ case llvm::Triple::ppc:
+ CmdArgs.push_back("-m");
+ CmdArgs.push_back("elf32ppc_nbsd");
+ break;
+
+ case llvm::Triple::ppc64:
+ case llvm::Triple::ppc64le:
+ CmdArgs.push_back("-m");
+ CmdArgs.push_back("elf64ppc");
+ break;
case llvm::Triple::sparc:
CmdArgs.push_back("-m");
@@ -6788,12 +6955,16 @@
unsigned Major, Minor, Micro;
getToolChain().getTriple().getOSVersion(Major, Minor, Micro);
bool useLibgcc = true;
- if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 40) || Major == 0) {
+ if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 49) || Major == 0) {
switch(getToolChain().getArch()) {
+ case llvm::Triple::aarch64:
case llvm::Triple::arm:
case llvm::Triple::armeb:
case llvm::Triple::thumb:
case llvm::Triple::thumbeb:
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ case llvm::Triple::ppc64le:
case llvm::Triple::x86:
case llvm::Triple::x86_64:
useLibgcc = false;
@@ -6845,7 +7016,7 @@
addProfileRT(getToolChain(), Args, CmdArgs);
const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
@@ -6917,13 +7088,34 @@
getToolChain().getArch() == llvm::Triple::mips64el) {
StringRef CPUName;
StringRef ABIName;
- getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
+ mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
+ ABIName = getGnuCompatibleMipsABIName(ABIName);
CmdArgs.push_back("-march");
CmdArgs.push_back(CPUName.data());
CmdArgs.push_back("-mabi");
- CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
+ CmdArgs.push_back(ABIName.data());
+
+ // -mno-shared should be emitted unless -fpic, -fpie, -fPIC, -fPIE,
+ // or -mshared (not implemented) is in effect.
+ bool IsPicOrPie = false;
+ 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)) {
+ if (A->getOption().matches(options::OPT_fPIC) ||
+ A->getOption().matches(options::OPT_fpic) ||
+ A->getOption().matches(options::OPT_fPIE) ||
+ A->getOption().matches(options::OPT_fpie))
+ IsPicOrPie = true;
+ }
+ if (!IsPicOrPie)
+ CmdArgs.push_back("-mno-shared");
+
+ // LLVM doesn't support -mplt yet and acts as if it is always given.
+ // However, -mplt has no effect with the N64 ABI.
+ CmdArgs.push_back(ABIName == "64" ? "-KPIC" : "-call_nonpic");
if (getToolChain().getArch() == llvm::Triple::mips ||
getToolChain().getArch() == llvm::Triple::mips64)
@@ -6936,8 +7128,28 @@
CmdArgs.push_back(Args.MakeArgString("-mnan=2008"));
}
- Args.AddLastArg(CmdArgs, options::OPT_mfp32, options::OPT_mfp64);
- Args.AddLastArg(CmdArgs, options::OPT_mips16, options::OPT_mno_mips16);
+ // Add the last -mfp32/-mfpxx/-mfp64 or -mfpxx if it is enabled by default.
+ if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
+ options::OPT_mfp64)) {
+ A->claim();
+ A->render(Args, CmdArgs);
+ } else if (mips::isFPXXDefault(getToolChain().getTriple(), CPUName,
+ ABIName))
+ CmdArgs.push_back("-mfpxx");
+
+ // Pass on -mmips16 or -mno-mips16. However, the assembler equivalent of
+ // -mno-mips16 is actually -no-mips16.
+ if (Arg *A = Args.getLastArg(options::OPT_mips16,
+ options::OPT_mno_mips16)) {
+ if (A->getOption().matches(options::OPT_mips16)) {
+ A->claim();
+ A->render(Args, CmdArgs);
+ } else {
+ A->claim();
+ CmdArgs.push_back("-no-mips16");
+ }
+ }
+
Args.AddLastArg(CmdArgs, options::OPT_mmicromips,
options::OPT_mno_micromips);
Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp);
@@ -6950,6 +7162,12 @@
CmdArgs.push_back(Args.MakeArgString("-mmsa"));
}
+ Args.AddLastArg(CmdArgs, options::OPT_mhard_float,
+ options::OPT_msoft_float);
+
+ Args.AddLastArg(CmdArgs, options::OPT_modd_spreg,
+ options::OPT_mno_odd_spreg);
+
NeedsKPIC = true;
} else if (getToolChain().getArch() == llvm::Triple::systemz) {
// Always pass an -march option, since our default of z10 is later
@@ -6971,7 +7189,7 @@
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
// Handle the debug info splitting at object creation time if we're
// creating an object.
@@ -7015,8 +7233,8 @@
CmdArgs.push_back("-ldl");
}
-static StringRef getLinuxDynamicLinker(const ArgList &Args,
- const toolchains::Linux &ToolChain) {
+static std::string getLinuxDynamicLinker(const ArgList &Args,
+ const toolchains::Linux &ToolChain) {
if (ToolChain.getTriple().getEnvironment() == llvm::Triple::Android) {
if (ToolChain.getTriple().isArch64Bit())
return "/system/bin/linker64";
@@ -7025,11 +7243,9 @@
} else if (ToolChain.getArch() == llvm::Triple::x86 ||
ToolChain.getArch() == llvm::Triple::sparc)
return "/lib/ld-linux.so.2";
- else if (ToolChain.getArch() == llvm::Triple::aarch64 ||
- ToolChain.getArch() == llvm::Triple::arm64)
+ else if (ToolChain.getArch() == llvm::Triple::aarch64)
return "/lib/ld-linux-aarch64.so.1";
- else if (ToolChain.getArch() == llvm::Triple::aarch64_be ||
- ToolChain.getArch() == llvm::Triple::arm64_be)
+ else if (ToolChain.getArch() == llvm::Triple::aarch64_be)
return "/lib/ld-linux-aarch64_be.so.1";
else if (ToolChain.getArch() == llvm::Triple::arm ||
ToolChain.getArch() == llvm::Triple::thumb) {
@@ -7044,24 +7260,38 @@
else
return "/lib/ld-linux.so.3"; /* TODO: check which dynamic linker name. */
} else if (ToolChain.getArch() == llvm::Triple::mips ||
- ToolChain.getArch() == llvm::Triple::mipsel) {
- if (mips::isNaN2008(Args, ToolChain.getTriple()))
- return "/lib/ld-linux-mipsn8.so.1";
- return "/lib/ld.so.1";
- } else if (ToolChain.getArch() == llvm::Triple::mips64 ||
+ ToolChain.getArch() == llvm::Triple::mipsel ||
+ ToolChain.getArch() == llvm::Triple::mips64 ||
ToolChain.getArch() == llvm::Triple::mips64el) {
- if (mips::hasMipsAbiArg(Args, "n32"))
- return mips::isNaN2008(Args, ToolChain.getTriple())
- ? "/lib32/ld-linux-mipsn8.so.1" : "/lib32/ld.so.1";
- return mips::isNaN2008(Args, ToolChain.getTriple())
- ? "/lib64/ld-linux-mipsn8.so.1" : "/lib64/ld.so.1";
+ StringRef CPUName;
+ StringRef ABIName;
+ mips::getMipsCPUAndABI(Args, ToolChain.getTriple(), CPUName, ABIName);
+ bool IsNaN2008 = mips::isNaN2008(Args, ToolChain.getTriple());
+
+ StringRef LibDir = llvm::StringSwitch<llvm::StringRef>(ABIName)
+ .Case("o32", "/lib")
+ .Case("n32", "/lib32")
+ .Case("n64", "/lib64")
+ .Default("/lib");
+ StringRef LibName;
+ if (mips::isUCLibc(Args))
+ LibName = IsNaN2008 ? "ld-uClibc-mipsn8.so.0" : "ld-uClibc.so.0";
+ else
+ LibName = IsNaN2008 ? "ld-linux-mipsn8.so.1" : "ld.so.1";
+
+ return (LibDir + "/" + LibName).str();
} else if (ToolChain.getArch() == llvm::Triple::ppc)
return "/lib/ld.so.1";
- else if (ToolChain.getArch() == llvm::Triple::ppc64 ||
- ToolChain.getArch() == llvm::Triple::systemz)
+ else if (ToolChain.getArch() == llvm::Triple::ppc64) {
+ if (ppc::hasPPCAbiArg(Args, "elfv2"))
+ return "/lib64/ld64.so.2";
return "/lib64/ld64.so.1";
- else if (ToolChain.getArch() == llvm::Triple::ppc64le)
+ } else if (ToolChain.getArch() == llvm::Triple::ppc64le) {
+ if (ppc::hasPPCAbiArg(Args, "elfv1"))
+ return "/lib64/ld64.so.1";
return "/lib64/ld64.so.2";
+ } else if (ToolChain.getArch() == llvm::Triple::systemz)
+ return "/lib64/ld64.so.1";
else if (ToolChain.getArch() == llvm::Triple::sparcv9)
return "/lib64/ld-linux.so.2";
else if (ToolChain.getArch() == llvm::Triple::x86_64 &&
@@ -7078,7 +7308,15 @@
switch(RLT) {
case ToolChain::RLT_CompilerRT:
- addClangRTLinux(TC, Args, CmdArgs);
+ 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);
+ break;
+ }
break;
case ToolChain::RLT_Libgcc:
AddLibgcc(TC.getTriple(), D, CmdArgs, Args);
@@ -7086,6 +7324,53 @@
}
}
+static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
+ switch (T.getArch()) {
+ case llvm::Triple::x86:
+ return "elf_i386";
+ case llvm::Triple::aarch64:
+ return "aarch64linux";
+ case llvm::Triple::aarch64_be:
+ return "aarch64_be_linux";
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ return "armelf_linux_eabi";
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumbeb:
+ return "armebelf_linux_eabi"; /* TODO: check which NAME. */
+ case llvm::Triple::ppc:
+ return "elf32ppclinux";
+ case llvm::Triple::ppc64:
+ return "elf64ppc";
+ case llvm::Triple::ppc64le:
+ return "elf64lppc";
+ case llvm::Triple::sparc:
+ return "elf32_sparc";
+ case llvm::Triple::sparcv9:
+ return "elf64_sparc";
+ case llvm::Triple::mips:
+ return "elf32btsmip";
+ case llvm::Triple::mipsel:
+ return "elf32ltsmip";
+ case llvm::Triple::mips64:
+ if (mips::hasMipsAbiArg(Args, "n32"))
+ return "elf32btsmipn32";
+ return "elf64btsmip";
+ case llvm::Triple::mips64el:
+ if (mips::hasMipsAbiArg(Args, "n32"))
+ return "elf32ltsmipn32";
+ return "elf64ltsmip";
+ case llvm::Triple::systemz:
+ return "elf64_s390";
+ case llvm::Triple::x86_64:
+ if (T.getEnvironment() == llvm::Triple::GNUX32)
+ return "elf32_x86_64";
+ return "elf_x86_64";
+ default:
+ llvm_unreachable("Unexpected arch");
+ }
+}
+
void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -7135,53 +7420,7 @@
}
CmdArgs.push_back("-m");
- if (ToolChain.getArch() == llvm::Triple::x86)
- CmdArgs.push_back("elf_i386");
- else if (ToolChain.getArch() == llvm::Triple::aarch64 ||
- ToolChain.getArch() == llvm::Triple::arm64)
- CmdArgs.push_back("aarch64linux");
- else if (ToolChain.getArch() == llvm::Triple::aarch64_be ||
- ToolChain.getArch() == llvm::Triple::arm64_be)
- CmdArgs.push_back("aarch64_be_linux");
- else if (ToolChain.getArch() == llvm::Triple::arm
- || ToolChain.getArch() == llvm::Triple::thumb)
- CmdArgs.push_back("armelf_linux_eabi");
- else if (ToolChain.getArch() == llvm::Triple::armeb
- || ToolChain.getArch() == llvm::Triple::thumbeb)
- CmdArgs.push_back("armebelf_linux_eabi"); /* TODO: check which NAME. */
- else if (ToolChain.getArch() == llvm::Triple::ppc)
- CmdArgs.push_back("elf32ppclinux");
- else if (ToolChain.getArch() == llvm::Triple::ppc64)
- CmdArgs.push_back("elf64ppc");
- else if (ToolChain.getArch() == llvm::Triple::ppc64le)
- CmdArgs.push_back("elf64lppc");
- else if (ToolChain.getArch() == llvm::Triple::sparc)
- CmdArgs.push_back("elf32_sparc");
- else if (ToolChain.getArch() == llvm::Triple::sparcv9)
- CmdArgs.push_back("elf64_sparc");
- else if (ToolChain.getArch() == llvm::Triple::mips)
- CmdArgs.push_back("elf32btsmip");
- else if (ToolChain.getArch() == llvm::Triple::mipsel)
- CmdArgs.push_back("elf32ltsmip");
- else if (ToolChain.getArch() == llvm::Triple::mips64) {
- if (mips::hasMipsAbiArg(Args, "n32"))
- CmdArgs.push_back("elf32btsmipn32");
- else
- CmdArgs.push_back("elf64btsmip");
- }
- else if (ToolChain.getArch() == llvm::Triple::mips64el) {
- if (mips::hasMipsAbiArg(Args, "n32"))
- CmdArgs.push_back("elf32ltsmipn32");
- else
- CmdArgs.push_back("elf64ltsmip");
- }
- else if (ToolChain.getArch() == llvm::Triple::systemz)
- CmdArgs.push_back("elf64_s390");
- else if (ToolChain.getArch() == llvm::Triple::x86_64 &&
- ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUX32)
- CmdArgs.push_back("elf32_x86_64");
- else
- CmdArgs.push_back("elf_x86_64");
+ CmdArgs.push_back(getLDMOption(ToolChain.getTriple(), Args));
if (Args.hasArg(options::OPT_static)) {
if (ToolChain.getArch() == llvm::Triple::arm ||
@@ -7245,7 +7484,7 @@
Args.AddAllArgs(CmdArgs, options::OPT_L);
Args.AddAllArgs(CmdArgs, options::OPT_u);
- const ToolChain::path_list Paths = ToolChain.getFilePaths();
+ const ToolChain::path_list &Paths = ToolChain.getFilePaths();
for (const auto &Path : Paths)
CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path));
@@ -7256,9 +7495,8 @@
if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
CmdArgs.push_back("--no-demangle");
+ bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
-
- addSanitizerRuntimes(getToolChain(), Args, CmdArgs);
// The profile runtime also needs access to system libraries.
addProfileRT(getToolChain(), Args, CmdArgs);
@@ -7280,6 +7518,9 @@
if (Args.hasArg(options::OPT_static))
CmdArgs.push_back("--start-group");
+ if (NeedsSanitizerDeps)
+ linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
+
LibOpenMP UsedOpenMPLib = LibUnknown;
if (Args.hasArg(options::OPT_fopenmp)) {
UsedOpenMPLib = LibGOMP;
@@ -7336,7 +7577,8 @@
}
}
- C.addCommand(new Command(JA, *this, ToolChain.Linker.c_str(), CmdArgs));
+ C.addCommand(
+ llvm::make_unique<Command>(JA, *this, ToolChain.Linker.c_str(), CmdArgs));
}
void minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
@@ -7355,7 +7597,7 @@
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void minix::Link::ConstructJob(Compilation &C, const JobAction &JA,
@@ -7409,7 +7651,7 @@
}
const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
/// DragonFly Tools
@@ -7437,7 +7679,7 @@
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
@@ -7445,12 +7687,9 @@
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;
+ bool UseGCC47 = llvm::sys::fs::exists("/usr/lib/gcc47");
if (!D.SysRoot.empty())
CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
@@ -7587,18 +7826,38 @@
addProfileRT(getToolChain(), Args, CmdArgs);
const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
static void addSanitizerRTWindows(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs,
- const StringRef RTName) {
+ 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
+// from clang itself to prevent clang from falling back to itself.
+static std::string FindVisualStudioExecutable(const ToolChain &TC,
+ const char *Exe,
+ const char *ClangProgramPath) {
+ const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
+ std::string visualStudioBinDir;
+ if (MSVC.getVisualStudioBinariesFolder(ClangProgramPath,
+ visualStudioBinDir)) {
+ SmallString<128> FilePath(visualStudioBinDir);
+ llvm::sys::path::append(FilePath, Exe);
+ if (llvm::sys::fs::can_execute(FilePath.c_str()))
+ return FilePath.str();
+ }
+
+ return Exe;
+}
+
void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -7619,6 +7878,39 @@
CmdArgs.push_back("-defaultlib:libcmt");
}
+ if (!llvm::sys::Process::GetEnv("LIB")) {
+ // If the VC environment hasn't been configured (perhaps because the user
+ // did not run vcvarsall), try to build a consistent link environment. If
+ // 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());
+ if (MSVC.getVisualStudioInstallDir(VisualStudioDir)) {
+ SmallString<128> LibDir(VisualStudioDir);
+ llvm::sys::path::append(LibDir, "VC", "lib");
+ switch (MSVC.getArch()) {
+ case llvm::Triple::x86:
+ // x86 just puts the libraries directly in lib
+ break;
+ case llvm::Triple::x86_64:
+ llvm::sys::path::append(LibDir, "amd64");
+ break;
+ case llvm::Triple::arm:
+ llvm::sys::path::append(LibDir, "arm");
+ break;
+ default:
+ break;
+ }
+ CmdArgs.push_back(
+ Args.MakeArgString(std::string("-libpath:") + LibDir.c_str()));
+ }
+
+ std::string WindowsSdkLibPath;
+ if (MSVC.getWindowsSDKLibraryPath(WindowsSdkLibPath))
+ CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
+ WindowsSdkLibPath.c_str()));
+ }
+
CmdArgs.push_back("-nologo");
if (Args.hasArg(options::OPT_g_Group)) {
@@ -7640,7 +7932,14 @@
CmdArgs.push_back(Args.MakeArgString("-debug"));
CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
// FIXME: Handle 64-bit.
- if (DLL) {
+ 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");
+ // 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");
} else {
@@ -7649,19 +7948,40 @@
}
}
- Args.AddAllArgValues(CmdArgs, options::OPT_l);
Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
- // Add filenames immediately.
- for (const auto &Input : Inputs)
- if (Input.isFilename())
+ // Add filenames, libraries, and other linker inputs.
+ for (const auto &Input : Inputs) {
+ if (Input.isFilename()) {
CmdArgs.push_back(Input.getFilename());
- else
- Input.getInputArg().renderAsInput(Args, CmdArgs);
+ continue;
+ }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("link.exe"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ const Arg &A = Input.getInputArg();
+
+ // Render -l options differently for the MSVC linker.
+ if (A.getOption().matches(options::OPT_l)) {
+ StringRef Lib = A.getValue();
+ const char *LinkLibArg;
+ if (Lib.endswith(".lib"))
+ LinkLibArg = Args.MakeArgString(Lib);
+ else
+ LinkLibArg = Args.MakeArgString(Lib + ".lib");
+ CmdArgs.push_back(LinkLibArg);
+ continue;
+ }
+
+ // Otherwise, this is some other kind of linker input option like -Wl, -z,
+ // or -L. Render it, even if MSVC doesn't understand it.
+ 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()));
+ const char *Exec = Args.MakeArgString(linkPath);
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void visualstudio::Compile::ConstructJob(Compilation &C, const JobAction &JA,
@@ -7672,40 +7992,10 @@
C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput));
}
-// Try to find FallbackName on PATH that is not identical to ClangProgramPath.
-// If one cannot be found, return FallbackName.
-// We do this special search to prevent clang-cl from falling back onto itself
-// if it's available as cl.exe on the path.
-static std::string FindFallback(const char *FallbackName,
- const char *ClangProgramPath) {
- llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH");
- if (!OptPath.hasValue())
- return FallbackName;
-
- const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
- SmallVector<StringRef, 8> PathSegments;
- llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr);
-
- for (size_t i = 0, e = PathSegments.size(); i != e; ++i) {
- const StringRef &PathSegment = PathSegments[i];
- if (PathSegment.empty())
- continue;
-
- SmallString<128> FilePath(PathSegment);
- llvm::sys::path::append(FilePath, FallbackName);
- if (llvm::sys::fs::can_execute(Twine(FilePath)) &&
- !llvm::sys::fs::equivalent(Twine(FilePath), ClangProgramPath))
- return FilePath.str();
- }
-
- return FallbackName;
-}
-
-Command *visualstudio::Compile::GetCommand(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
+std::unique_ptr<Command> visualstudio::Compile::GetCommand(
+ Compilation &C, const JobAction &JA, const InputInfo &Output,
+ const InputInfoList &Inputs, const ArgList &Args,
+ const char *LinkingOutput) const {
ArgStringList CmdArgs;
CmdArgs.push_back("/nologo");
CmdArgs.push_back("/c"); // Compile only.
@@ -7783,8 +8073,10 @@
CmdArgs.push_back(Fo);
const Driver &D = getToolChain().getDriver();
- std::string Exec = FindFallback("cl.exe", D.getClangProgramPath());
- return new Command(JA, *this, Args.MakeArgString(Exec), CmdArgs);
+ std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe",
+ D.getClangProgramPath());
+ return llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
+ CmdArgs);
}
@@ -7821,7 +8113,7 @@
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
void XCore::Link::ConstructJob(Compilation &C, const JobAction &JA,
@@ -7848,5 +8140,183 @@
AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
+
+void CrossWindows::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
+ const auto &TC =
+ static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain());
+ ArgStringList CmdArgs;
+ const char *Exec;
+
+ switch (TC.getArch()) {
+ default: llvm_unreachable("unsupported architecture");
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ break;
+ case llvm::Triple::x86:
+ CmdArgs.push_back("--32");
+ break;
+ case llvm::Triple::x86_64:
+ CmdArgs.push_back("--64");
+ break;
+ }
+
+ Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back(Output.getFilename());
+
+ for (const auto &Input : Inputs)
+ CmdArgs.push_back(Input.getFilename());
+
+ const std::string Assembler = TC.GetProgramPath("as");
+ Exec = Args.MakeArgString(Assembler);
+
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
+}
+
+void CrossWindows::Link::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
+ const auto &TC =
+ static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain());
+ const llvm::Triple &T = TC.getTriple();
+ const Driver &D = TC.getDriver();
+ SmallString<128> EntryPoint;
+ ArgStringList CmdArgs;
+ const char *Exec;
+
+ // Silence warning for "clang -g foo.o -o foo"
+ Args.ClaimAllArgs(options::OPT_g_Group);
+ // and "clang -emit-llvm foo.o -o foo"
+ Args.ClaimAllArgs(options::OPT_emit_llvm);
+ // and for "clang -w foo.o -o foo"
+ Args.ClaimAllArgs(options::OPT_w);
+ // Other warning options are already handled somewhere else.
+
+ if (!D.SysRoot.empty())
+ CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+ if (Args.hasArg(options::OPT_pie))
+ CmdArgs.push_back("-pie");
+ if (Args.hasArg(options::OPT_rdynamic))
+ CmdArgs.push_back("-export-dynamic");
+ if (Args.hasArg(options::OPT_s))
+ CmdArgs.push_back("--strip-all");
+
+ CmdArgs.push_back("-m");
+ switch (TC.getArch()) {
+ default: llvm_unreachable("unsupported architecture");
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ // FIXME: this is incorrect for WinCE
+ CmdArgs.push_back("thumb2pe");
+ break;
+ case llvm::Triple::x86:
+ CmdArgs.push_back("i386pe");
+ EntryPoint.append("_");
+ break;
+ case llvm::Triple::x86_64:
+ CmdArgs.push_back("i386pep");
+ break;
+ }
+
+ if (Args.hasArg(options::OPT_shared)) {
+ switch (T.getArch()) {
+ default: llvm_unreachable("unsupported architecture");
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ case llvm::Triple::x86_64:
+ EntryPoint.append("_DllMainCRTStartup");
+ break;
+ case llvm::Triple::x86:
+ EntryPoint.append("_DllMainCRTStartup@12");
+ break;
+ }
+
+ CmdArgs.push_back("-shared");
+ CmdArgs.push_back("-Bdynamic");
+
+ CmdArgs.push_back("--enable-auto-image-base");
+
+ CmdArgs.push_back("--entry");
+ CmdArgs.push_back(Args.MakeArgString(EntryPoint));
+ } else {
+ EntryPoint.append("mainCRTStartup");
+
+ CmdArgs.push_back(Args.hasArg(options::OPT_static) ? "-Bstatic"
+ : "-Bdynamic");
+
+ if (!Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nostartfiles)) {
+ CmdArgs.push_back("--entry");
+ CmdArgs.push_back(Args.MakeArgString(EntryPoint));
+ }
+
+ // FIXME: handle subsystem
+ }
+
+ // NOTE: deal with multiple definitions on Windows (e.g. COMDAT)
+ CmdArgs.push_back("--allow-multiple-definition");
+
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back(Output.getFilename());
+
+ if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_rdynamic)) {
+ SmallString<261> ImpLib(Output.getFilename());
+ llvm::sys::path::replace_extension(ImpLib, ".lib");
+
+ CmdArgs.push_back("--out-implib");
+ CmdArgs.push_back(Args.MakeArgString(ImpLib));
+ }
+
+ if (!Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nostartfiles)) {
+ const std::string CRTPath(D.SysRoot + "/usr/lib/");
+ const char *CRTBegin;
+
+ CRTBegin =
+ Args.hasArg(options::OPT_shared) ? "crtbeginS.obj" : "crtbegin.obj";
+ CmdArgs.push_back(Args.MakeArgString(CRTPath + CRTBegin));
+ }
+
+ Args.AddAllArgs(CmdArgs, options::OPT_L);
+
+ const auto &Paths = TC.getFilePaths();
+ for (const auto &Path : Paths)
+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path));
+
+ AddLinkerInputs(TC, Inputs, Args, CmdArgs);
+
+ if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nodefaultlibs)) {
+ bool StaticCXX = Args.hasArg(options::OPT_static_libstdcxx) &&
+ !Args.hasArg(options::OPT_static);
+ if (StaticCXX)
+ CmdArgs.push_back("-Bstatic");
+ TC.AddCXXStdlibLibArgs(Args, CmdArgs);
+ if (StaticCXX)
+ CmdArgs.push_back("-Bdynamic");
+ }
+
+ if (!Args.hasArg(options::OPT_nostdlib)) {
+ if (!Args.hasArg(options::OPT_nodefaultlibs)) {
+ // TODO handle /MT[d] /MD[d]
+ CmdArgs.push_back("-lmsvcrt");
+ AddRunTimeLibs(TC, D, CmdArgs, Args);
+ }
+ }
+
+ const std::string Linker = TC.GetProgramPath("ld");
+ Exec = Args.MakeArgString(Linker);
+
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
+}
+