summaryrefslogtreecommitdiffstats
path: root/lib/Driver/ToolChains
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Driver/ToolChains')
-rw-r--r--lib/Driver/ToolChains/Arch/AArch64.cpp30
-rw-r--r--lib/Driver/ToolChains/Arch/AArch64.h5
-rw-r--r--lib/Driver/ToolChains/Arch/Mips.cpp4
-rw-r--r--lib/Driver/ToolChains/Arch/X86.cpp6
-rw-r--r--lib/Driver/ToolChains/Clang.cpp100
-rw-r--r--lib/Driver/ToolChains/CommonArgs.cpp54
-rw-r--r--lib/Driver/ToolChains/Darwin.cpp151
-rw-r--r--lib/Driver/ToolChains/Darwin.h6
-rw-r--r--lib/Driver/ToolChains/Gnu.cpp44
-rw-r--r--lib/Driver/ToolChains/HIP.cpp8
-rw-r--r--lib/Driver/ToolChains/MSP430.cpp233
-rw-r--r--lib/Driver/ToolChains/MSP430.h71
-rw-r--r--lib/Driver/ToolChains/MSVC.cpp2
-rw-r--r--lib/Driver/ToolChains/MinGW.cpp6
-rw-r--r--lib/Driver/ToolChains/NetBSD.cpp12
-rw-r--r--lib/Driver/ToolChains/NetBSD.h4
-rw-r--r--lib/Driver/ToolChains/PS4CPU.cpp6
-rw-r--r--lib/Driver/ToolChains/Solaris.h2
-rw-r--r--lib/Driver/ToolChains/WebAssembly.cpp38
19 files changed, 661 insertions, 121 deletions
diff --git a/lib/Driver/ToolChains/Arch/AArch64.cpp b/lib/Driver/ToolChains/Arch/AArch64.cpp
index 1dc516b963..71e55fe79e 100644
--- a/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -19,10 +19,17 @@ using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
+/// \returns true if the given triple can determine the default CPU type even
+/// if -arch is not specified.
+static bool isCPUDeterminedByTriple(const llvm::Triple &Triple) {
+ return Triple.isOSDarwin();
+}
+
/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
/// targeting. Set \p A to the Arg corresponding to the -mcpu argument if it is
/// provided, or to nullptr otherwise.
-std::string aarch64::getAArch64TargetCPU(const ArgList &Args, Arg *&A) {
+std::string aarch64::getAArch64TargetCPU(const ArgList &Args,
+ const llvm::Triple &Triple, Arg *&A) {
std::string CPU;
// If we have -mcpu, use that.
if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
@@ -36,9 +43,9 @@ std::string aarch64::getAArch64TargetCPU(const ArgList &Args, Arg *&A) {
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?
- if (Args.getLastArg(options::OPT_arch))
+ // Make sure we pick "cyclone" if -arch is used or when targetting a Darwin
+ // OS.
+ if (Args.getLastArg(options::OPT_arch) || Triple.isOSDarwin())
return "cyclone";
return "generic";
@@ -152,7 +159,9 @@ getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features);
}
-void aarch64::getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
+void aarch64::getAArch64TargetFeatures(const Driver &D,
+ const llvm::Triple &Triple,
+ const ArgList &Args,
std::vector<StringRef> &Features) {
Arg *A;
bool success = true;
@@ -162,9 +171,9 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
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, A),
- Args, Features);
+ else if (Args.hasArg(options::OPT_arch) || isCPUDeterminedByTriple(Triple))
+ success = getAArch64ArchFeaturesFromMcpu(
+ D, getAArch64TargetCPU(Args, Triple, A), Args, Features);
if (success && (A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)))
success =
@@ -172,9 +181,10 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ)))
success =
getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
- else if (success && Args.hasArg(options::OPT_arch))
+ else if (success &&
+ (Args.hasArg(options::OPT_arch) || isCPUDeterminedByTriple(Triple)))
success = getAArch64MicroArchFeaturesFromMcpu(
- D, getAArch64TargetCPU(Args, A), Args, Features);
+ D, getAArch64TargetCPU(Args, Triple, A), Args, Features);
if (!success)
D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
diff --git a/lib/Driver/ToolChains/Arch/AArch64.h b/lib/Driver/ToolChains/Arch/AArch64.h
index 62e419cc19..5f6148ebd6 100644
--- a/lib/Driver/ToolChains/Arch/AArch64.h
+++ b/lib/Driver/ToolChains/Arch/AArch64.h
@@ -21,11 +21,12 @@ namespace driver {
namespace tools {
namespace aarch64 {
-void getAArch64TargetFeatures(const Driver &D, const llvm::opt::ArgList &Args,
+void getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args,
std::vector<llvm::StringRef> &Features);
std::string getAArch64TargetCPU(const llvm::opt::ArgList &Args,
- llvm::opt::Arg *&A);
+ const llvm::Triple &Triple, llvm::opt::Arg *&A);
} // end namespace aarch64
} // end namespace target
diff --git a/lib/Driver/ToolChains/Arch/Mips.cpp b/lib/Driver/ToolChains/Arch/Mips.cpp
index a1591039db..e10a5e1c77 100644
--- a/lib/Driver/ToolChains/Arch/Mips.cpp
+++ b/lib/Driver/ToolChains/Arch/Mips.cpp
@@ -47,12 +47,12 @@ void mips::getMipsCPUAndABI(const ArgList &Args, const llvm::Triple &Triple,
}
// MIPS3 is the default for mips64*-unknown-openbsd.
- if (Triple.getOS() == llvm::Triple::OpenBSD)
+ if (Triple.isOSOpenBSD())
DefMips64CPU = "mips3";
// MIPS2 is the default for mips(el)?-unknown-freebsd.
// MIPS3 is the default for mips64(el)?-unknown-freebsd.
- if (Triple.getOS() == llvm::Triple::FreeBSD) {
+ if (Triple.isOSFreeBSD()) {
DefMips32CPU = "mips2";
DefMips64CPU = "mips3";
}
diff --git a/lib/Driver/ToolChains/Arch/X86.cpp b/lib/Driver/ToolChains/Arch/X86.cpp
index bc707857d8..45648945d5 100644
--- a/lib/Driver/ToolChains/Arch/X86.cpp
+++ b/lib/Driver/ToolChains/Arch/X86.cpp
@@ -23,12 +23,8 @@ using namespace llvm::opt;
const char *x86::getX86TargetCPU(const ArgList &Args,
const llvm::Triple &Triple) {
if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
- if (StringRef(A->getValue()) != "native") {
- if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h")
- return "core-avx2";
-
+ if (StringRef(A->getValue()) != "native")
return A->getValue();
- }
// FIXME: Reject attempts to use -march=native unless the target matches
// the host.
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index e3dfb09c73..75f16898df 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -19,12 +19,14 @@
#include "AMDGPU.h"
#include "CommonArgs.h"
#include "Hexagon.h"
+#include "MSP430.h"
#include "InputInfo.h"
#include "PS4CPU.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Version.h"
+#include "clang/Driver/Distro.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/SanitizerArgs.h"
@@ -341,7 +343,7 @@ static void getTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
break;
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_be:
- aarch64::getAArch64TargetFeatures(D, Args, Features);
+ aarch64::getAArch64TargetFeatures(D, Triple, Args, Features);
break;
case llvm::Triple::x86:
case llvm::Triple::x86_64:
@@ -363,6 +365,8 @@ static void getTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
case llvm::Triple::amdgcn:
amdgpu::getAMDGPUTargetFeatures(D, Args, Features);
break;
+ case llvm::Triple::msp430:
+ msp430::getMSP430TargetFeatures(D, Args, Features);
}
// Find the last of each feature.
@@ -526,7 +530,7 @@ static bool useFramePointerForTargetByDefault(const ArgList &Args,
break;
}
- if (Triple.getOS() == llvm::Triple::NetBSD) {
+ if (Triple.isOSNetBSD()) {
return !areOptimizationsEnabled(Args);
}
@@ -2360,9 +2364,6 @@ static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs,
// Treat blocks as analysis entry points.
CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
- // Enable compatilibily mode to avoid analyzer-config related errors.
- CmdArgs.push_back("-analyzer-config-compatibility-mode=true");
-
// Add default argument set.
if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
CmdArgs.push_back("-analyzer-checker=core");
@@ -2472,6 +2473,50 @@ static void RenderSSPOptions(const ToolChain &TC, const ArgList &Args,
}
}
+static void RenderTrivialAutoVarInitOptions(const Driver &D,
+ const ToolChain &TC,
+ const ArgList &Args,
+ ArgStringList &CmdArgs) {
+ auto DefaultTrivialAutoVarInit = TC.GetDefaultTrivialAutoVarInit();
+ StringRef TrivialAutoVarInit = "";
+
+ for (const Arg *A : Args) {
+ switch (A->getOption().getID()) {
+ default:
+ continue;
+ case options::OPT_ftrivial_auto_var_init: {
+ A->claim();
+ StringRef Val = A->getValue();
+ if (Val == "uninitialized" || Val == "zero" || Val == "pattern")
+ TrivialAutoVarInit = Val;
+ else
+ D.Diag(diag::err_drv_unsupported_option_argument)
+ << A->getOption().getName() << Val;
+ break;
+ }
+ }
+ }
+
+ if (TrivialAutoVarInit.empty())
+ switch (DefaultTrivialAutoVarInit) {
+ case LangOptions::TrivialAutoVarInitKind::Uninitialized:
+ break;
+ case LangOptions::TrivialAutoVarInitKind::Pattern:
+ TrivialAutoVarInit = "pattern";
+ break;
+ case LangOptions::TrivialAutoVarInitKind::Zero:
+ TrivialAutoVarInit = "zero";
+ break;
+ }
+
+ if (!TrivialAutoVarInit.empty()) {
+ if (TrivialAutoVarInit == "zero" && !Args.hasArg(options::OPT_enable_trivial_var_init_zero))
+ D.Diag(diag::err_drv_trivial_auto_var_init_zero_disabled);
+ CmdArgs.push_back(
+ Args.MakeArgString("-ftrivial-auto-var-init=" + TrivialAutoVarInit));
+ }
+}
+
static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs) {
const unsigned ForwardedArguments[] = {
options::OPT_cl_opt_disable,
@@ -2804,8 +2849,8 @@ static void RenderCharacterOptions(const ArgList &Args, const llvm::Triple &T,
} else {
bool IsARM = T.isARM() || T.isThumb() || T.isAArch64();
CmdArgs.push_back("-fwchar-type=int");
- if (IsARM && !(T.isOSWindows() || T.getOS() == llvm::Triple::NetBSD ||
- T.getOS() == llvm::Triple::OpenBSD))
+ if (IsARM && !(T.isOSWindows() || T.isOSNetBSD() ||
+ T.isOSOpenBSD()))
CmdArgs.push_back("-fno-signed-wchar");
else
CmdArgs.push_back("-fsigned-wchar");
@@ -3694,6 +3739,24 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (isa<AnalyzeJobAction>(JA))
RenderAnalyzerOptions(Args, CmdArgs, Triple, Input);
+ // Enable compatilibily mode to avoid analyzer-config related errors.
+ // Since we can't access frontend flags through hasArg, let's manually iterate
+ // through them.
+ bool FoundAnalyzerConfig = false;
+ for (auto Arg : Args.filtered(options::OPT_Xclang))
+ if (StringRef(Arg->getValue()) == "-analyzer-config") {
+ FoundAnalyzerConfig = true;
+ break;
+ }
+ if (!FoundAnalyzerConfig)
+ for (auto Arg : Args.filtered(options::OPT_Xanalyzer))
+ if (StringRef(Arg->getValue()) == "-analyzer-config") {
+ FoundAnalyzerConfig = true;
+ break;
+ }
+ if (FoundAnalyzerConfig)
+ CmdArgs.push_back("-analyzer-config-compatibility-mode=true");
+
CheckCodeGenerationOptions(D, Args);
unsigned FunctionAlignment = ParseFunctionAlignment(TC, Args);
@@ -4053,7 +4116,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
ABICompatArg->render(Args, CmdArgs);
// Add runtime flag for PS4 when PGO, coverage, or sanitizers are enabled.
- if (RawTriple.isPS4CPU()) {
+ if (RawTriple.isPS4CPU() &&
+ !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
PS4cpu::addProfileRTArgs(TC, Args, CmdArgs);
PS4cpu::addSanitizerArgs(TC, CmdArgs);
}
@@ -4373,6 +4437,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ);
Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_cuda_number_of_sm_EQ);
Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_cuda_blocks_per_sm_EQ);
+ if (Args.hasFlag(options::OPT_fopenmp_optimistic_collapse,
+ options::OPT_fno_openmp_optimistic_collapse,
+ /*Default=*/false))
+ CmdArgs.push_back("-fopenmp-optimistic-collapse");
// When in OpenMP offloading mode with NVPTX target, forward
// cuda-mode flag
@@ -4463,6 +4531,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString("-mspeculative-load-hardening"));
RenderSSPOptions(TC, Args, CmdArgs, KernelOrKext);
+ RenderTrivialAutoVarInitOptions(D, TC, Args, CmdArgs);
// Translate -mstackrealign
if (Args.hasFlag(options::OPT_mstackrealign, options::OPT_mno_stackrealign,
@@ -5160,6 +5229,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fwhole-program-vtables");
}
+ bool RequiresSplitLTOUnit = WholeProgramVTables || Sanitize.needsLTO();
+ bool SplitLTOUnit =
+ Args.hasFlag(options::OPT_fsplit_lto_unit,
+ options::OPT_fno_split_lto_unit, RequiresSplitLTOUnit);
+ if (RequiresSplitLTOUnit && !SplitLTOUnit)
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << "-fno-split-lto-unit"
+ << (WholeProgramVTables ? "-fwhole-program-vtables" : "-fsanitize=cfi");
+ if (SplitLTOUnit)
+ CmdArgs.push_back("-fsplit-lto-unit");
+
if (Arg *A = Args.getLastArg(options::OPT_fexperimental_isel,
options::OPT_fno_experimental_isel)) {
CmdArgs.push_back("-mllvm");
@@ -5227,6 +5307,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasFlag(options::OPT_faddrsig, options::OPT_fno_addrsig,
(TC.getTriple().isOSBinFormatELF() ||
TC.getTriple().isOSBinFormatCOFF()) &&
+ !TC.getTriple().isPS4() &&
+ !TC.getTriple().isOSNetBSD() &&
+ !Distro(D.getVFS()).IsGentoo() &&
+ !TC.getTriple().isAndroid() &&
TC.useIntegratedAs()))
CmdArgs.push_back("-faddrsig");
diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp
index 2bdff39f0d..d7e316befa 100644
--- a/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/lib/Driver/ToolChains/CommonArgs.cpp
@@ -220,21 +220,6 @@ static std::string getR600TargetGPU(const ArgList &Args) {
return "";
}
-static std::string getNios2TargetCPU(const ArgList &Args) {
- Arg *A = Args.getLastArg(options::OPT_mcpu_EQ);
- if (!A)
- A = Args.getLastArg(options::OPT_march_EQ);
-
- if (!A)
- return "";
-
- const char *name = A->getValue();
- return llvm::StringSwitch<const char *>(name)
- .Case("r1", "nios2r1")
- .Case("r2", "nios2r2")
- .Default(name);
-}
-
static std::string getLanaiTargetCPU(const ArgList &Args) {
if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
return A->getValue();
@@ -271,7 +256,7 @@ std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T,
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_be:
- return aarch64::getAArch64TargetCPU(Args, A);
+ return aarch64::getAArch64TargetCPU(Args, T, A);
case llvm::Triple::arm:
case llvm::Triple::armeb:
@@ -287,10 +272,6 @@ std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T,
return A->getValue();
return "";
- case llvm::Triple::nios2: {
- return getNios2TargetCPU(Args);
- }
-
case llvm::Triple::mips:
case llvm::Triple::mipsel:
case llvm::Triple::mips64:
@@ -603,19 +584,19 @@ void tools::linkSanitizerRuntimeDeps(const ToolChain &TC,
if (TC.getTriple().getOS() != llvm::Triple::RTEMS &&
!TC.getTriple().isAndroid()) {
CmdArgs.push_back("-lpthread");
- if (TC.getTriple().getOS() != llvm::Triple::OpenBSD)
+ if (!TC.getTriple().isOSOpenBSD())
CmdArgs.push_back("-lrt");
}
CmdArgs.push_back("-lm");
// There's no libdl on all OSes.
- if (TC.getTriple().getOS() != llvm::Triple::FreeBSD &&
- TC.getTriple().getOS() != llvm::Triple::NetBSD &&
- TC.getTriple().getOS() != llvm::Triple::OpenBSD &&
- TC.getTriple().getOS() != llvm::Triple::RTEMS)
+ if (!TC.getTriple().isOSFreeBSD() &&
+ !TC.getTriple().isOSNetBSD() &&
+ !TC.getTriple().isOSOpenBSD() &&
+ TC.getTriple().getOS() != llvm::Triple::RTEMS)
CmdArgs.push_back("-ldl");
// Required for backtrace on some OSes
- if (TC.getTriple().getOS() == llvm::Triple::NetBSD ||
- TC.getTriple().getOS() == llvm::Triple::FreeBSD)
+ if (TC.getTriple().isOSFreeBSD() ||
+ TC.getTriple().isOSNetBSD())
CmdArgs.push_back("-lexecinfo");
}
@@ -790,13 +771,13 @@ bool tools::addXRayRuntime(const ToolChain&TC, const ArgList &Args, ArgStringLis
void tools::linkXRayRuntimeDeps(const ToolChain &TC, ArgStringList &CmdArgs) {
CmdArgs.push_back("--no-as-needed");
CmdArgs.push_back("-lpthread");
- if (TC.getTriple().getOS() != llvm::Triple::OpenBSD)
+ if (!TC.getTriple().isOSOpenBSD())
CmdArgs.push_back("-lrt");
CmdArgs.push_back("-lm");
- if (TC.getTriple().getOS() != llvm::Triple::FreeBSD &&
- TC.getTriple().getOS() != llvm::Triple::NetBSD &&
- TC.getTriple().getOS() != llvm::Triple::OpenBSD)
+ if (!TC.getTriple().isOSFreeBSD() &&
+ !TC.getTriple().isOSNetBSD() &&
+ !TC.getTriple().isOSOpenBSD())
CmdArgs.push_back("-ldl");
}
@@ -933,7 +914,7 @@ tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) {
}
// OpenBSD-specific defaults for PIE
- if (Triple.getOS() == llvm::Triple::OpenBSD) {
+ if (Triple.isOSOpenBSD()) {
switch (ToolChain.getArch()) {
case llvm::Triple::arm:
case llvm::Triple::aarch64:
@@ -1159,11 +1140,8 @@ static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
Args.hasArg(options::OPT_static);
- // The driver ignores -shared-libgcc and therefore treats such cases as
- // unspecified. Breaking out the two variables as below makes the current
- // behavior explicit.
- bool UnspecifiedLibgcc = !StaticLibgcc;
- bool SharedLibgcc = !StaticLibgcc;
+ bool SharedLibgcc = Args.hasArg(options::OPT_shared_libgcc);
+ bool UnspecifiedLibgcc = !StaticLibgcc && !SharedLibgcc;
// Gcc adds libgcc arguments in various ways:
//
@@ -1180,7 +1158,7 @@ static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
if (LibGccFirst)
CmdArgs.push_back("-lgcc");
- bool AsNeeded = D.CCCIsCC() && !StaticLibgcc && !isAndroid && !isCygMing;
+ bool AsNeeded = D.CCCIsCC() && UnspecifiedLibgcc && !isAndroid && !isCygMing;
if (AsNeeded)
CmdArgs.push_back("--as-needed");
diff --git a/lib/Driver/ToolChains/Darwin.cpp b/lib/Driver/ToolChains/Darwin.cpp
index e5dafa2b09..c395c9a443 100644
--- a/lib/Driver/ToolChains/Darwin.cpp
+++ b/lib/Driver/ToolChains/Darwin.cpp
@@ -224,13 +224,20 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
options::OPT_fno_application_extension, false))
CmdArgs.push_back("-application_extension");
- if (D.isUsingLTO()) {
- // If we are using LTO, then automatically create a temporary file path for
- // the linker to use, so that it's lifetime will extend past a possible
- // dsymutil step.
- if (Version[0] >= 116 && NeedsTempPath(Inputs)) {
- const char *TmpPath = C.getArgs().MakeArgString(
- D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object)));
+ if (D.isUsingLTO() && Version[0] >= 116 && NeedsTempPath(Inputs)) {
+ std::string TmpPathName;
+ if (D.getLTOMode() == LTOK_Full) {
+ // If we are using full LTO, then automatically create a temporary file
+ // path for the linker to use, so that it's lifetime will extend past a
+ // possible dsymutil step.
+ TmpPathName =
+ D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object));
+ } else if (D.getLTOMode() == LTOK_Thin)
+ // If we are using thin LTO, then create a directory instead.
+ TmpPathName = D.GetTemporaryDirectory("thinlto");
+
+ if (!TmpPathName.empty()) {
+ auto *TmpPath = C.getArgs().MakeArgString(TmpPathName);
C.addTempFile(TmpPath);
CmdArgs.push_back("-object_path_lto");
CmdArgs.push_back(TmpPath);
@@ -1287,6 +1294,18 @@ struct DarwinPlatform {
return DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Value);
}
+ /// Constructs an inferred SDKInfo value based on the version inferred from
+ /// the SDK path itself. Only works for values that were created by inferring
+ /// the platform from the SDKPath.
+ DarwinSDKInfo inferSDKInfo() {
+ assert(Kind == InferredFromSDK && "can infer SDK info only");
+ llvm::VersionTuple Version;
+ bool IsValid = !Version.tryParse(OSVersion);
+ (void)IsValid;
+ assert(IsValid && "invalid SDK version");
+ return DarwinSDKInfo(Version);
+ }
+
private:
DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument)
: Kind(Kind), Platform(Platform), Argument(Argument) {}
@@ -1420,8 +1439,11 @@ getDeploymentTargetFromEnvironmentVariables(const Driver &TheDriver,
}
/// Tries to infer the deployment target from the SDK specified by -isysroot
-/// (or SDKROOT).
-Optional<DarwinPlatform> inferDeploymentTargetFromSDK(DerivedArgList &Args) {
+/// (or SDKROOT). Uses the version specified in the SDKSettings.json file if
+/// it's available.
+Optional<DarwinPlatform>
+inferDeploymentTargetFromSDK(DerivedArgList &Args,
+ const Optional<DarwinSDKInfo> &SDKInfo) {
const Arg *A = Args.getLastArg(options::OPT_isysroot);
if (!A)
return None;
@@ -1429,28 +1451,37 @@ Optional<DarwinPlatform> inferDeploymentTargetFromSDK(DerivedArgList &Args) {
StringRef SDK = Darwin::getSDKName(isysroot);
if (!SDK.size())
return None;
- // Slice the version number out.
- // Version number is between the first and the last number.
- size_t StartVer = SDK.find_first_of("0123456789");
- size_t EndVer = SDK.find_last_of("0123456789");
- if (StartVer != StringRef::npos && EndVer > StartVer) {
- StringRef Version = SDK.slice(StartVer, EndVer + 1);
- if (SDK.startswith("iPhoneOS") || SDK.startswith("iPhoneSimulator"))
- return DarwinPlatform::createFromSDK(
- Darwin::IPhoneOS, Version,
- /*IsSimulator=*/SDK.startswith("iPhoneSimulator"));
- else if (SDK.startswith("MacOSX"))
- return DarwinPlatform::createFromSDK(Darwin::MacOS,
- getSystemOrSDKMacOSVersion(Version));
- else if (SDK.startswith("WatchOS") || SDK.startswith("WatchSimulator"))
- return DarwinPlatform::createFromSDK(
- Darwin::WatchOS, Version,
- /*IsSimulator=*/SDK.startswith("WatchSimulator"));
- else if (SDK.startswith("AppleTVOS") || SDK.startswith("AppleTVSimulator"))
- return DarwinPlatform::createFromSDK(
- Darwin::TvOS, Version,
- /*IsSimulator=*/SDK.startswith("AppleTVSimulator"));
- }
+
+ std::string Version;
+ if (SDKInfo) {
+ // Get the version from the SDKSettings.json if it's available.
+ Version = SDKInfo->getVersion().getAsString();
+ } else {
+ // Slice the version number out.
+ // Version number is between the first and the last number.
+ size_t StartVer = SDK.find_first_of("0123456789");
+ size_t EndVer = SDK.find_last_of("0123456789");
+ if (StartVer != StringRef::npos && EndVer > StartVer)
+ Version = SDK.slice(StartVer, EndVer + 1);
+ }
+ if (Version.empty())
+ return None;
+
+ if (SDK.startswith("iPhoneOS") || SDK.startswith("iPhoneSimulator"))
+ return DarwinPlatform::createFromSDK(
+ Darwin::IPhoneOS, Version,
+ /*IsSimulator=*/SDK.startswith("iPhoneSimulator"));
+ else if (SDK.startswith("MacOSX"))
+ return DarwinPlatform::createFromSDK(Darwin::MacOS,
+ getSystemOrSDKMacOSVersion(Version));
+ else if (SDK.startswith("WatchOS") || SDK.startswith("WatchSimulator"))
+ return DarwinPlatform::createFromSDK(
+ Darwin::WatchOS, Version,
+ /*IsSimulator=*/SDK.startswith("WatchSimulator"));
+ else if (SDK.startswith("AppleTVOS") || SDK.startswith("AppleTVSimulator"))
+ return DarwinPlatform::createFromSDK(
+ Darwin::TvOS, Version,
+ /*IsSimulator=*/SDK.startswith("AppleTVSimulator"));
return None;
}
@@ -1525,6 +1556,22 @@ Optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
Args.getLastArg(options::OPT_target));
}
+Optional<DarwinSDKInfo> parseSDKSettings(llvm::vfs::FileSystem &VFS,
+ const ArgList &Args,
+ const Driver &TheDriver) {
+ const Arg *A = Args.getLastArg(options::OPT_isysroot);
+ if (!A)
+ return None;
+ StringRef isysroot = A->getValue();
+ auto SDKInfoOrErr = driver::parseDarwinSDKInfo(VFS, isysroot);
+ if (!SDKInfoOrErr) {
+ llvm::consumeError(SDKInfoOrErr.takeError());
+ TheDriver.Diag(diag::warn_drv_darwin_sdk_invalid_settings);
+ return None;
+ }
+ return *SDKInfoOrErr;
+}
+
} // namespace
void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
@@ -1549,6 +1596,10 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
}
}
+ // Read the SDKSettings.json file for more information, like the SDK version
+ // that we can pass down to the compiler.
+ SDKInfo = parseSDKSettings(getVFS(), Args, getDriver());
+
// The OS and the version can be specified using the -target argument.
Optional<DarwinPlatform> OSTarget =
getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver());
@@ -1594,16 +1645,22 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple());
if (OSTarget) {
// Don't infer simulator from the arch when the SDK is also specified.
- Optional<DarwinPlatform> SDKTarget = inferDeploymentTargetFromSDK(Args);
+ Optional<DarwinPlatform> SDKTarget =
+ inferDeploymentTargetFromSDK(Args, SDKInfo);
if (SDKTarget)
OSTarget->setEnvironment(SDKTarget->getEnvironment());
}
}
// If there is no command-line argument to specify the Target version and
// no environment variable defined, see if we can set the default based
- // on -isysroot.
- if (!OSTarget)
- OSTarget = inferDeploymentTargetFromSDK(Args);
+ // on -isysroot using SDKSettings.json if it exists.
+ if (!OSTarget) {
+ OSTarget = inferDeploymentTargetFromSDK(Args, SDKInfo);
+ /// If the target was successfully constructed from the SDK path, try to
+ /// infer the SDK info if the SDK doesn't have it.
+ if (OSTarget && !SDKInfo)
+ SDKInfo = OSTarget->inferSDKInfo();
+ }
// If no OS targets have been specified, try to guess platform from -target
// or arch name and compute the version from the triple.
if (!OSTarget)
@@ -1702,10 +1759,11 @@ void DarwinClang::AddClangCXXStdlibIncludeArgs(
break;
// On Darwin, libc++ may be installed alongside the compiler in
// include/c++/v1.
- // Get from 'foo/bin' to 'foo'.
- SmallString<128> P = llvm::sys::path::parent_path(InstallDir);
- // Get to 'foo/include/c++/v1'.
- llvm::sys::path::append(P, "include", "c++", "v1");
+ // Get from 'foo/bin' to 'foo/include/c++/v1'.
+ SmallString<128> P = InstallDir;
+ // Note that InstallDir can be relative, so we have to '..' and not
+ // parent_path.
+ llvm::sys::path::append(P, "..", "include", "c++", "v1");
addSystemInclude(DriverArgs, CC1Args, P);
break;
}
@@ -1967,12 +2025,8 @@ DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args,
else if (Name == "pentIIm3")
DAL->AddJoinedArg(nullptr, MArch, "pentium2");
- else if (Name == "x86_64")
- DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
- else if (Name == "x86_64h") {
+ else if (Name == "x86_64" || Name == "x86_64h")
DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
- DAL->AddJoinedArg(nullptr, MArch, "x86_64h");
- }
else if (Name == "arm")
DAL->AddJoinedArg(nullptr, MArch, "armv4t");
@@ -2046,6 +2100,15 @@ void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
options::OPT_fno_aligned_allocation) &&
isAlignedAllocationUnavailable())
CC1Args.push_back("-faligned-alloc-unavailable");
+
+ if (SDKInfo) {
+ /// Pass the SDK version to the compiler when the SDK information is
+ /// available.
+ std::string Arg;
+ llvm::raw_string_ostream OS(Arg);
+ OS << "-target-sdk-version=" << SDKInfo->getVersion();
+ CC1Args.push_back(DriverArgs.MakeArgString(OS.str()));
+ }
}
DerivedArgList *
diff --git a/lib/Driver/ToolChains/Darwin.h b/lib/Driver/ToolChains/Darwin.h
index e6a88dce3c..d753f8967a 100644
--- a/lib/Driver/ToolChains/Darwin.h
+++ b/lib/Driver/ToolChains/Darwin.h
@@ -11,9 +11,10 @@
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H
#include "Cuda.h"
-#include "clang/Driver/XRayArgs.h"
+#include "clang/Driver/DarwinSDKInfo.h"
#include "clang/Driver/Tool.h"
#include "clang/Driver/ToolChain.h"
+#include "clang/Driver/XRayArgs.h"
namespace clang {
namespace driver {
@@ -288,6 +289,9 @@ public:
/// The OS version we are targeting.
mutable VersionTuple TargetVersion;
+ /// The information about the darwin SDK that was used.
+ mutable Optional<DarwinSDKInfo> SDKInfo;
+
CudaInstallationDetector CudaInstallation;
private:
diff --git a/lib/Driver/ToolChains/Gnu.cpp b/lib/Driver/ToolChains/Gnu.cpp
index 3850e1c02e..2ad45097dc 100644
--- a/lib/Driver/ToolChains/Gnu.cpp
+++ b/lib/Driver/ToolChains/Gnu.cpp
@@ -878,6 +878,10 @@ static bool isRISCV(llvm::Triple::ArchType Arch) {
return Arch == llvm::Triple::riscv32 || Arch == llvm::Triple::riscv64;
}
+static bool isMSP430(llvm::Triple::ArchType Arch) {
+ return Arch == llvm::Triple::msp430;
+}
+
static Multilib makeMultilib(StringRef commonSuffix) {
return Multilib(commonSuffix, commonSuffix, commonSuffix);
}
@@ -1423,6 +1427,26 @@ static void findAndroidArmMultilibs(const Driver &D,
Result.Multilibs = AndroidArmMultilibs;
}
+static bool findMSP430Multilibs(const Driver &D,
+ const llvm::Triple &TargetTriple,
+ StringRef Path, const ArgList &Args,
+ DetectedMultilibs &Result) {
+ FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
+ Multilib MSP430Multilib = makeMultilib("/430");
+ // FIXME: when clang starts to support msp430x ISA additional logic
+ // to select between multilib must be implemented
+ // Multilib MSP430xMultilib = makeMultilib("/large");
+
+ Result.Multilibs.push_back(MSP430Multilib);
+ Result.Multilibs.FilterOut(NonExistent);
+
+ Multilib::flags_list Flags;
+ if (Result.Multilibs.select(Flags, Result.SelectedMultilib))
+ return true;
+
+ return false;
+}
+
static void findRISCVMultilibs(const Driver &D,
const llvm::Triple &TargetTriple, StringRef Path,
const ArgList &Args, DetectedMultilibs &Result) {
@@ -1911,6 +1935,9 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
static const char *const MIPSN32ELTriples[] = {
"mips64el-linux-gnuabin32", "mipsisa64r6el-linux-gnuabin32"};
+ static const char *const MSP430LibDirs[] = {"/lib"};
+ static const char *const MSP430Triples[] = {"msp430-elf"};
+
static const char *const PPCLibDirs[] = {"/lib32", "/lib"};
static const char *const PPCTriples[] = {
"powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe",
@@ -2135,6 +2162,10 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
BiarchTripleAliases.append(begin(MIPSN32ELTriples), end(MIPSN32ELTriples));
BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
break;
+ case llvm::Triple::msp430:
+ LibDirs.append(begin(MSP430LibDirs), end(MSP430LibDirs));
+ TripleAliases.append(begin(MSP430Triples), end(MSP430Triples));
+ break;
case llvm::Triple::ppc:
LibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));
TripleAliases.append(begin(PPCTriples), end(PPCTriples));
@@ -2206,6 +2237,8 @@ bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs(
return false;
} else if (isRISCV(TargetArch)) {
findRISCVMultilibs(D, TargetTriple, Path, Args, Detected);
+ } else if (isMSP430(TargetArch)) {
+ findMSP430Multilibs(D, TargetTriple, Path, Args, Detected);
} else if (!findBiarchMultilibs(D, TargetTriple, Path, Args,
NeedsBiarchSuffix, Detected)) {
return false;
@@ -2435,7 +2468,7 @@ bool Generic_GCC::isPICDefault() const {
case llvm::Triple::x86_64:
return getTriple().isOSWindows();
case llvm::Triple::ppc64:
- case llvm::Triple::ppc64le:
+ // Big endian PPC is PIC by default
return !getTriple().isOSBinFormatMachO() && !getTriple().isMacOSX();
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
@@ -2474,7 +2507,14 @@ bool Generic_GCC::IsIntegratedAssemblerDefault() const {
case llvm::Triple::mipsel:
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
+ case llvm::Triple::msp430:
return true;
+ case llvm::Triple::sparc:
+ case llvm::Triple::sparcel:
+ case llvm::Triple::sparcv9:
+ if (getTriple().isOSSolaris() || getTriple().isOSOpenBSD())
+ return true;
+ return false;
default:
return false;
}
@@ -2597,7 +2637,7 @@ void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs,
bool UseInitArrayDefault =
getTriple().getArch() == llvm::Triple::aarch64 ||
getTriple().getArch() == llvm::Triple::aarch64_be ||
- (getTriple().getOS() == llvm::Triple::FreeBSD &&
+ (getTriple().isOSFreeBSD() &&
getTriple().getOSMajorVersion() >= 12) ||
(getTriple().getOS() == llvm::Triple::Linux &&
((!GCCInstallation.isValid() || !V.isOlderThan(4, 7, 0)) ||
diff --git a/lib/Driver/ToolChains/HIP.cpp b/lib/Driver/ToolChains/HIP.cpp
index b44aadda79..868765cf88 100644
--- a/lib/Driver/ToolChains/HIP.cpp
+++ b/lib/Driver/ToolChains/HIP.cpp
@@ -24,6 +24,12 @@ using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
+#if _WIN32 || _WIN64
+#define NULL_FILE "nul"
+#else
+#define NULL_FILE "/dev/null"
+#endif
+
namespace {
static void addBCLib(Compilation &C, const ArgList &Args,
@@ -197,7 +203,7 @@ void AMDGCN::constructHIPFatbinCommand(Compilation &C, const JobAction &JA,
// ToDo: Remove the dummy host binary entry which is required by
// clang-offload-bundler.
std::string BundlerTargetArg = "-targets=host-x86_64-unknown-linux";
- std::string BundlerInputArg = "-inputs=/dev/null";
+ std::string BundlerInputArg = "-inputs=" NULL_FILE;
for (const auto &II : Inputs) {
const auto* A = II.getAction();
diff --git a/lib/Driver/ToolChains/MSP430.cpp b/lib/Driver/ToolChains/MSP430.cpp
new file mode 100644
index 0000000000..b2ff88dbd0
--- /dev/null
+++ b/lib/Driver/ToolChains/MSP430.cpp
@@ -0,0 +1,233 @@
+//===--- MSP430.cpp - MSP430 Helpers for Tools ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MSP430.h"
+#include "CommonArgs.h"
+#include "Gnu.h"
+#include "InputInfo.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Multilib.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+static bool isSupportedMCU(const StringRef MCU) {
+ return llvm::StringSwitch<bool>(MCU)
+#define MSP430_MCU(NAME) .Case(NAME, true)
+#include "clang/Basic/MSP430Target.def"
+ .Default(false);
+}
+
+static StringRef getSupportedHWMult(const Arg *MCU) {
+ if (!MCU)
+ return "none";
+
+ return llvm::StringSwitch<StringRef>(MCU->getValue())
+#define MSP430_MCU_FEAT(NAME, HWMULT) .Case(NAME, HWMULT)
+#include "clang/Basic/MSP430Target.def"
+ .Default("none");
+}
+
+static StringRef getHWMultLib(const ArgList &Args) {
+ StringRef HWMult = Args.getLastArgValue(options::OPT_mhwmult_EQ, "auto");
+ if (HWMult == "auto") {
+ HWMult = getSupportedHWMult(Args.getLastArg(options::OPT_mmcu_EQ));
+ }
+
+ return llvm::StringSwitch<StringRef>(HWMult)
+ .Case("16bit", "-lmul_16")
+ .Case("32bit", "-lmul_32")
+ .Case("f5series", "-lmul_f5")
+ .Default("-lmul_none");
+}
+
+void msp430::getMSP430TargetFeatures(const Driver &D, const ArgList &Args,
+ std::vector<StringRef> &Features) {
+ const Arg *MCU = Args.getLastArg(options::OPT_mmcu_EQ);
+ if (MCU && !isSupportedMCU(MCU->getValue())) {
+ D.Diag(diag::err_drv_clang_unsupported) << MCU->getValue();
+ return;
+ }
+
+ const Arg *HWMultArg = Args.getLastArg(options::OPT_mhwmult_EQ);
+ if (!MCU && !HWMultArg)
+ return;
+
+ StringRef HWMult = HWMultArg ? HWMultArg->getValue() : "auto";
+ StringRef SupportedHWMult = getSupportedHWMult(MCU);
+
+ if (HWMult == "auto") {
+ // 'auto' - deduce hw multiplier support based on mcu name provided.
+ // If no mcu name is provided, assume no hw multiplier is supported.
+ if (!MCU)
+ D.Diag(clang::diag::warn_drv_msp430_hwmult_no_device);
+ HWMult = SupportedHWMult;
+ }
+
+ if (HWMult == "none") {
+ // 'none' - disable hw multiplier.
+ Features.push_back("-hwmult16");
+ Features.push_back("-hwmult32");
+ Features.push_back("-hwmultf5");
+ return;
+ }
+
+ if (MCU && SupportedHWMult == "none")
+ D.Diag(clang::diag::warn_drv_msp430_hwmult_unsupported) << HWMult;
+ if (MCU && HWMult != SupportedHWMult)
+ D.Diag(clang::diag::warn_drv_msp430_hwmult_mismatch)
+ << SupportedHWMult << HWMult;
+
+ if (HWMult == "16bit") {
+ // '16bit' - for 16-bit only hw multiplier.
+ Features.push_back("+hwmult16");
+ } else if (HWMult == "32bit") {
+ // '32bit' - for 16/32-bit hw multiplier.
+ Features.push_back("+hwmult32");
+ } else if (HWMult == "f5series") {
+ // 'f5series' - for 16/32-bit hw multiplier supported by F5 series mcus.
+ Features.push_back("+hwmultf5");
+ } else {
+ D.Diag(clang::diag::err_drv_unsupported_option_argument)
+ << HWMultArg->getAsString(Args) << HWMult;
+ }
+}
+
+/// MSP430 Toolchain
+MSP430ToolChain::MSP430ToolChain(const Driver &D, const llvm::Triple &Triple,
+ const ArgList &Args)
+ : Generic_ELF(D, Triple, Args) {
+
+ StringRef MultilibSuf = "";
+
+ GCCInstallation.init(Triple, Args);
+ if (GCCInstallation.isValid()) {
+ MultilibSuf = GCCInstallation.getMultilib().gccSuffix();
+
+ SmallString<128> GCCBinPath;
+ llvm::sys::path::append(GCCBinPath,
+ GCCInstallation.getParentLibPath(), "..", "bin");
+ addPathIfExists(D, GCCBinPath, getProgramPaths());
+
+ SmallString<128> GCCRtPath;
+ llvm::sys::path::append(GCCRtPath,
+ GCCInstallation.getInstallPath(), MultilibSuf);
+ addPathIfExists(D, GCCRtPath, getFilePaths());
+ }
+
+ SmallString<128> SysRootDir(computeSysRoot());
+ llvm::sys::path::append(SysRootDir, "lib", MultilibSuf);
+ addPathIfExists(D, SysRootDir, getFilePaths());
+}
+
+std::string MSP430ToolChain::computeSysRoot() const {
+ if (!getDriver().SysRoot.empty())
+ return getDriver().SysRoot;
+
+ SmallString<128> Dir;
+ if (GCCInstallation.isValid())
+ llvm::sys::path::append(Dir, GCCInstallation.getParentLibPath(), "..",
+ GCCInstallation.getTriple().str());
+ else
+ llvm::sys::path::append(Dir, getDriver().Dir, "..", getTriple().str());
+
+ return Dir.str();
+}
+
+void MSP430ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ if (DriverArgs.hasArg(options::OPT_nostdinc) ||
+ DriverArgs.hasArg(options::OPT_nostdlibinc))
+ return;
+
+ SmallString<128> Dir(computeSysRoot());
+ llvm::sys::path::append(Dir, "include");
+ addSystemInclude(DriverArgs, CC1Args, Dir.str());
+}
+
+void MSP430ToolChain::addClangTargetOptions(const ArgList &DriverArgs,
+ ArgStringList &CC1Args,
+ Action::OffloadKind) const {
+ CC1Args.push_back("-nostdsysteminc");
+
+ const auto *MCUArg = DriverArgs.getLastArg(options::OPT_mmcu_EQ);
+ if (!MCUArg)
+ return;
+
+ const StringRef MCU = MCUArg->getValue();
+ if (MCU.startswith("msp430i")) {
+ // 'i' should be in lower case as it's defined in TI MSP430-GCC headers
+ CC1Args.push_back(DriverArgs.MakeArgString(
+ "-D__MSP430i" + MCU.drop_front(7).upper() + "__"));
+ } else {
+ CC1Args.push_back(DriverArgs.MakeArgString("-D__" + MCU.upper() + "__"));
+ }
+}
+
+Tool *MSP430ToolChain::buildLinker() const {
+ return new tools::msp430::Linker(*this);
+}
+
+void msp430::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
+ const ToolChain &ToolChain = getToolChain();
+ const Driver &D = ToolChain.getDriver();
+ std::string Linker = ToolChain.GetProgramPath(getShortName());
+ ArgStringList CmdArgs;
+
+ if (!D.SysRoot.empty())
+ CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+ Args.AddAllArgs(CmdArgs, options::OPT_L);
+ ToolChain.AddFilePathLibArgs(Args, CmdArgs);
+
+ if (!Args.hasArg(options::OPT_T)) {
+ if (const Arg *MCUArg = Args.getLastArg(options::OPT_mmcu_EQ))
+ CmdArgs.push_back(
+ Args.MakeArgString("-T" + StringRef(MCUArg->getValue()) + ".ld"));
+ } else {
+ Args.AddAllArgs(CmdArgs, options::OPT_T);
+ }
+
+ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
+ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o")));
+ }
+
+ AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
+
+ CmdArgs.push_back("--start-group");
+ CmdArgs.push_back(Args.MakeArgString(getHWMultLib(Args)));
+ CmdArgs.push_back("-lgcc");
+ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+ CmdArgs.push_back("-lc");
+ CmdArgs.push_back("-lcrt");
+ CmdArgs.push_back("-lnosys");
+ }
+ CmdArgs.push_back("--end-group");
+
+ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
+ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
+ }
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back(Output.getFilename());
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
+ CmdArgs, Inputs));
+}
diff --git a/lib/Driver/ToolChains/MSP430.h b/lib/Driver/ToolChains/MSP430.h
new file mode 100644
index 0000000000..0fdceb75b9
--- /dev/null
+++ b/lib/Driver/ToolChains/MSP430.h
@@ -0,0 +1,71 @@
+//===--- MSP430.h - MSP430-specific Tool Helpers ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSP430_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSP430_H
+
+#include "Gnu.h"
+#include "InputInfo.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/Option.h"
+
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace driver {
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY MSP430ToolChain : public Generic_ELF {
+public:
+ MSP430ToolChain(const Driver &D, const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args);
+ void
+ AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
+ void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args,
+ Action::OffloadKind) const override;
+
+protected:
+ Tool *buildLinker() const override;
+
+private:
+ std::string computeSysRoot() const;
+};
+
+} // end namespace toolchains
+
+namespace tools {
+namespace msp430 {
+
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+ Linker(const ToolChain &TC)
+ : GnuTool("MSP430::Linker", "msp430-elf-ld", TC) {}
+ bool hasIntegratedCPP() const override { return false; }
+ bool isLinkJob() const override { return true; }
+ void ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output, const InputInfoList &Inputs,
+ const llvm::opt::ArgList &TCArgs,
+ const char *LinkingOutput) const override;
+};
+
+void getMSP430TargetFeatures(const Driver &D, const llvm::opt::ArgList &Args,
+ std::vector<llvm::StringRef> &Features);
+} // end namespace msp430
+} // end namespace tools
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSP430_H
diff --git a/lib/Driver/ToolChains/MSVC.cpp b/lib/Driver/ToolChains/MSVC.cpp
index 839f313623..7e34b0df5c 100644
--- a/lib/Driver/ToolChains/MSVC.cpp
+++ b/lib/Driver/ToolChains/MSVC.cpp
@@ -1286,7 +1286,7 @@ VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
if (MSVT.empty() &&
Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
IsWindowsMSVC)) {
- // -fms-compatibility-version=19.11 is default, aka 2017
+ // -fms-compatibility-version=19.11 is default, aka 2017, 15.3
MSVT = VersionTuple(19, 11);
}
return MSVT;
diff --git a/lib/Driver/ToolChains/MinGW.cpp b/lib/Driver/ToolChains/MinGW.cpp
index 836d7c1551..2d5217d03d 100644
--- a/lib/Driver/ToolChains/MinGW.cpp
+++ b/lib/Driver/ToolChains/MinGW.cpp
@@ -429,6 +429,12 @@ bool toolchains::MinGW::HasNativeLLVMSupport() const {
}
bool toolchains::MinGW::IsUnwindTablesDefault(const ArgList &Args) const {
+ Arg *ExceptionArg = Args.getLastArg(options::OPT_fsjlj_exceptions,
+ options::OPT_fseh_exceptions,
+ options::OPT_fdwarf_exceptions);
+ if (ExceptionArg &&
+ ExceptionArg->getOption().matches(options::OPT_fseh_exceptions))
+ return true;
return getArch() == llvm::Triple::x86_64;
}
diff --git a/lib/Driver/ToolChains/NetBSD.cpp b/lib/Driver/ToolChains/NetBSD.cpp
index 73e230b3ea..b1321cacaf 100644
--- a/lib/Driver/ToolChains/NetBSD.cpp
+++ b/lib/Driver/ToolChains/NetBSD.cpp
@@ -448,12 +448,24 @@ SanitizerMask NetBSD::getSupportedSanitizers() const {
Res |= SanitizerKind::Vptr;
}
if (IsX86_64) {
+ Res |= SanitizerKind::DataFlow;
Res |= SanitizerKind::Efficiency;
Res |= SanitizerKind::Fuzzer;
Res |= SanitizerKind::FuzzerNoLink;
+ Res |= SanitizerKind::HWAddress;
Res |= SanitizerKind::KernelAddress;
+ Res |= SanitizerKind::KernelHWAddress;
+ Res |= SanitizerKind::KernelMemory;
Res |= SanitizerKind::Memory;
Res |= SanitizerKind::Thread;
}
return Res;
}
+
+void NetBSD::addClangTargetOptions(const ArgList &,
+ ArgStringList &CC1Args,
+ Action::OffloadKind) const {
+ const SanitizerArgs &SanArgs = getSanitizerArgs();
+ if (SanArgs.hasAnySanitizer())
+ CC1Args.push_back("-D_REENTRANT");
+}
diff --git a/lib/Driver/ToolChains/NetBSD.h b/lib/Driver/ToolChains/NetBSD.h
index 49e3a58d02..ae0865fd65 100644
--- a/lib/Driver/ToolChains/NetBSD.h
+++ b/lib/Driver/ToolChains/NetBSD.h
@@ -76,6 +76,10 @@ public:
SanitizerMask getSupportedSanitizers() const override;
+ void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args,
+ Action::OffloadKind DeviceOffloadKind) const override;
+
protected:
Tool *buildAssembler() const override;
Tool *buildLinker() const override;
diff --git a/lib/Driver/ToolChains/PS4CPU.cpp b/lib/Driver/ToolChains/PS4CPU.cpp
index a4b74d4923..0708d25fe4 100644
--- a/lib/Driver/ToolChains/PS4CPU.cpp
+++ b/lib/Driver/ToolChains/PS4CPU.cpp
@@ -121,7 +121,8 @@ static void ConstructPS4LinkJob(const Tool &T, Compilation &C,
assert(Output.isNothing() && "Invalid output.");
}
- AddPS4SanitizerArgs(ToolChain, CmdArgs);
+ if(!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
+ AddPS4SanitizerArgs(ToolChain, CmdArgs);
Args.AddAllArgs(CmdArgs, options::OPT_L);
Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
@@ -190,7 +191,8 @@ static void ConstructGoldLinkJob(const Tool &T, Compilation &C,
assert(Output.isNothing() && "Invalid output.");
}
- AddPS4SanitizerArgs(ToolChain, CmdArgs);
+ if(!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
+ AddPS4SanitizerArgs(ToolChain, CmdArgs);
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
const char *crt1 = nullptr;
diff --git a/lib/Driver/ToolChains/Solaris.h b/lib/Driver/ToolChains/Solaris.h
index 9e14269b39..4d9c828b5c 100644
--- a/lib/Driver/ToolChains/Solaris.h
+++ b/lib/Driver/ToolChains/Solaris.h
@@ -55,8 +55,6 @@ public:
Solaris(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args);
- bool IsIntegratedAssemblerDefault() const override { return true; }
-
void
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
diff --git a/lib/Driver/ToolChains/WebAssembly.cpp b/lib/Driver/ToolChains/WebAssembly.cpp
index 6776a41dad..6310d5faba 100644
--- a/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/lib/Driver/ToolChains/WebAssembly.cpp
@@ -24,6 +24,15 @@ using namespace llvm::opt;
wasm::Linker::Linker(const ToolChain &TC)
: GnuTool("wasm::Linker", "lld", TC) {}
+/// Following the conventions in https://wiki.debian.org/Multiarch/Tuples,
+/// we remove the vendor field to form the multiarch triple.
+static std::string getMultiarchTriple(const Driver &D,
+ const llvm::Triple &TargetTriple,
+ StringRef SysRoot) {
+ return (TargetTriple.getArchName() + "-" +
+ TargetTriple.getOSAndEnvironmentName()).str();
+}
+
bool wasm::Linker::isLinkJob() const { return true; }
bool wasm::Linker::hasIntegratedCPP() const { return false; }
@@ -75,7 +84,17 @@ WebAssembly::WebAssembly(const Driver &D, const llvm::Triple &Triple,
getProgramPaths().push_back(getDriver().getInstalledDir());
- getFilePaths().push_back(getDriver().SysRoot + "/lib");
+ if (getTriple().getOS() == llvm::Triple::UnknownOS) {
+ // Theoretically an "unknown" OS should mean no standard libraries, however
+ // it could also mean that a custom set of libraries is in use, so just add
+ // /lib to the search path. Disable multiarch in this case, to discourage
+ // paths containing "unknown" from acquiring meanings.
+ getFilePaths().push_back(getDriver().SysRoot + "/lib");
+ } else {
+ const std::string MultiarchTriple =
+ getMultiarchTriple(getDriver(), Triple, getDriver().SysRoot);
+ getFilePaths().push_back(getDriver().SysRoot + "/lib/" + MultiarchTriple);
+ }
}
bool WebAssembly::IsMathErrnoDefault() const { return false; }
@@ -124,16 +143,29 @@ WebAssembly::GetCXXStdlibType(const ArgList &Args) const {
void WebAssembly::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
- if (!DriverArgs.hasArg(options::OPT_nostdinc))
+ if (!DriverArgs.hasArg(options::OPT_nostdinc)) {
+ if (getTriple().getOS() != llvm::Triple::UnknownOS) {
+ const std::string MultiarchTriple =
+ getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot);
+ addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include/" + MultiarchTriple);
+ }
addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include");
+ }
}
void WebAssembly::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
if (!DriverArgs.hasArg(options::OPT_nostdlibinc) &&
- !DriverArgs.hasArg(options::OPT_nostdincxx))
+ !DriverArgs.hasArg(options::OPT_nostdincxx)) {
+ if (getTriple().getOS() != llvm::Triple::UnknownOS) {
+ const std::string MultiarchTriple =
+ getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot);
+ addSystemInclude(DriverArgs, CC1Args,
+ getDriver().SysRoot + "/include/" + MultiarchTriple + "/c++/v1");
+ }
addSystemInclude(DriverArgs, CC1Args,
getDriver().SysRoot + "/include/c++/v1");
+ }
}
void WebAssembly::AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,