aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Driver/ToolChains/Clang.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Driver/ToolChains/Clang.cpp')
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp234
1 files changed, 131 insertions, 103 deletions
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index c9bbdb2ac72e..97435f1a73de 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -27,6 +27,7 @@
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/MakeSupport.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Version.h"
#include "clang/Config/config.h"
@@ -51,6 +52,7 @@
#include "llvm/Support/Process.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/Support/YAMLParser.h"
+#include <cctype>
using namespace clang::driver;
using namespace clang::driver::tools;
@@ -97,34 +99,6 @@ static void EscapeSpacesAndBackslashes(const char *Arg,
}
}
-// Quote target names for inclusion in GNU Make dependency files.
-// Only the characters '$', '#', ' ', '\t' are quoted.
-static void QuoteTarget(StringRef Target, SmallVectorImpl<char> &Res) {
- for (unsigned i = 0, e = Target.size(); i != e; ++i) {
- switch (Target[i]) {
- case ' ':
- case '\t':
- // Escape the preceding backslashes
- for (int j = i - 1; j >= 0 && Target[j] == '\\'; --j)
- Res.push_back('\\');
-
- // Escape the space/tab
- Res.push_back('\\');
- break;
- case '$':
- Res.push_back('$');
- break;
- case '#':
- Res.push_back('\\');
- break;
- default:
- break;
- }
-
- Res.push_back(Target[i]);
- }
-}
-
/// Apply \a Work on the current tool chain \a RegularToolChain and any other
/// offloading tool chain that is associated with the current action \a JA.
static void
@@ -567,7 +541,7 @@ static bool useFramePointerForTargetByDefault(const ArgList &Args,
break;
}
- if (Triple.isOSNetBSD()) {
+ if (Triple.isOSFuchsia() || Triple.isOSNetBSD()) {
return !areOptimizationsEnabled(Args);
}
@@ -1144,7 +1118,7 @@ static void RenderDebugInfoCompressionArgs(const ArgList &Args,
if (Value == "none") {
CmdArgs.push_back("--compress-debug-sections=none");
} else if (Value == "zlib") {
- if (llvm::zlib::isAvailable()) {
+ if (llvm::compression::zlib::isAvailable()) {
CmdArgs.push_back(
Args.MakeArgString("--compress-debug-sections=" + Twine(Value)));
} else {
@@ -1249,7 +1223,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
} else {
CmdArgs.push_back("-MT");
SmallString<128> Quoted;
- QuoteTarget(A->getValue(), Quoted);
+ quoteMakeTarget(A->getValue(), Quoted);
CmdArgs.push_back(Args.MakeArgString(Quoted));
}
}
@@ -1274,7 +1248,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-MT");
SmallString<128> Quoted;
- QuoteTarget(DepTarget, Quoted);
+ quoteMakeTarget(DepTarget, Quoted);
CmdArgs.push_back(Args.MakeArgString(Quoted));
}
@@ -2228,8 +2202,23 @@ void Clang::AddSparcTargetArgs(const ArgList &Args,
void Clang::AddSystemZTargetArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
- bool HasBackchain = Args.hasFlag(options::OPT_mbackchain,
- options::OPT_mno_backchain, false);
+ if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)) {
+ StringRef Name = A->getValue();
+
+ std::string TuneCPU;
+ if (Name == "native")
+ TuneCPU = std::string(llvm::sys::getHostCPUName());
+ else
+ TuneCPU = std::string(Name);
+
+ if (!TuneCPU.empty()) {
+ CmdArgs.push_back("-tune-cpu");
+ CmdArgs.push_back(Args.MakeArgString(TuneCPU));
+ }
+ }
+
+ bool HasBackchain =
+ Args.hasFlag(options::OPT_mbackchain, options::OPT_mno_backchain, false);
bool HasPackedStack = Args.hasFlag(options::OPT_mpacked_stack,
options::OPT_mno_packed_stack, false);
systemz::FloatABI FloatABI =
@@ -2341,7 +2330,7 @@ void Clang::AddHexagonTargetArgs(const ArgList &Args,
if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
CmdArgs.push_back("-mllvm");
CmdArgs.push_back(Args.MakeArgString("-hexagon-small-data-threshold=" +
- Twine(G.getValue())));
+ Twine(G.value())));
}
if (!Args.hasArg(options::OPT_fno_short_enums))
@@ -3231,6 +3220,16 @@ static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs,
Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
}
+static bool isValidSymbolName(StringRef S) {
+ if (S.empty())
+ return false;
+
+ if (std::isdigit(S[0]))
+ return false;
+
+ return llvm::all_of(S, [](char C) { return std::isalnum(C) || C == '_'; });
+}
+
static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
const ArgList &Args, ArgStringList &CmdArgs,
bool KernelOrKext) {
@@ -3362,6 +3361,16 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
}
A->render(Args, CmdArgs);
}
+
+ if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_symbol_EQ)) {
+ StringRef Value = A->getValue();
+ if (!isValidSymbolName(Value)) {
+ D.Diag(diag::err_drv_argument_only_allowed_with)
+ << A->getOption().getName() << "legal symbol name";
+ return;
+ }
+ A->render(Args, CmdArgs);
+ }
}
static void RenderSCPOptions(const ToolChain &TC, const ArgList &Args,
@@ -3750,38 +3759,49 @@ static void RenderModulesOptions(Compilation &C, const Driver &D,
Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval);
Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after);
- Args.AddLastArg(CmdArgs, options::OPT_fbuild_session_timestamp);
+ if (HaveClangModules) {
+ 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";
+ 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();
- CmdArgs.push_back(Args.MakeArgString(
- "-fbuild-session-timestamp=" +
- Twine((uint64_t)std::chrono::duration_cast<std::chrono::seconds>(
- Status.getLastModificationTime().time_since_epoch())
- .count())));
- }
+ llvm::sys::fs::file_status Status;
+ if (llvm::sys::fs::status(A->getValue(), Status))
+ D.Diag(diag::err_drv_no_such_file) << A->getValue();
+ CmdArgs.push_back(Args.MakeArgString(
+ "-fbuild-session-timestamp=" +
+ Twine((uint64_t)std::chrono::duration_cast<std::chrono::seconds>(
+ Status.getLastModificationTime().time_since_epoch())
+ .count())));
+ }
- if (Args.getLastArg(options::OPT_fmodules_validate_once_per_build_session)) {
- if (!Args.getLastArg(options::OPT_fbuild_session_timestamp,
- options::OPT_fbuild_session_file))
- D.Diag(diag::err_drv_modules_validate_once_requires_timestamp);
+ if (Args.getLastArg(
+ options::OPT_fmodules_validate_once_per_build_session)) {
+ 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,
- options::OPT_fmodules_validate_once_per_build_session);
- }
+ Args.AddLastArg(CmdArgs,
+ options::OPT_fmodules_validate_once_per_build_session);
+ }
- if (Args.hasFlag(options::OPT_fmodules_validate_system_headers,
- options::OPT_fno_modules_validate_system_headers,
- ImplicitModules))
- CmdArgs.push_back("-fmodules-validate-system-headers");
+ if (Args.hasFlag(options::OPT_fmodules_validate_system_headers,
+ options::OPT_fno_modules_validate_system_headers,
+ ImplicitModules))
+ CmdArgs.push_back("-fmodules-validate-system-headers");
- Args.AddLastArg(CmdArgs, options::OPT_fmodules_disable_diagnostic_validation);
+ Args.AddLastArg(CmdArgs,
+ options::OPT_fmodules_disable_diagnostic_validation);
+ } else {
+ Args.ClaimAllArgs(options::OPT_fbuild_session_timestamp);
+ Args.ClaimAllArgs(options::OPT_fbuild_session_file);
+ Args.ClaimAllArgs(options::OPT_fmodules_validate_once_per_build_session);
+ Args.ClaimAllArgs(options::OPT_fmodules_validate_system_headers);
+ Args.ClaimAllArgs(options::OPT_fno_modules_validate_system_headers);
+ Args.ClaimAllArgs(options::OPT_fmodules_disable_diagnostic_validation);
+ }
}
static void RenderCharacterOptions(const ArgList &Args, const llvm::Triple &T,
@@ -4422,12 +4442,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.hasFlag(options::OPT_offload_new_driver,
options::OPT_no_offload_new_driver, false));
+ bool IsRDCMode =
+ Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false);
bool IsUsingLTO = D.isUsingLTO(IsDeviceOffloadAction);
auto LTOMode = D.getLTOMode(IsDeviceOffloadAction);
// A header module compilation doesn't have a main input file, so invent a
// fake one as a placeholder.
- const char *ModuleName = [&]{
+ const char *ModuleName = [&] {
auto *ModuleNameArg = Args.getLastArg(options::OPT_fmodule_name_EQ);
return ModuleNameArg ? ModuleNameArg->getValue() : "";
}();
@@ -6285,10 +6307,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
if (IsCuda || IsHIP) {
- if (!Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false) &&
- Args.hasArg(options::OPT_offload_new_driver))
- D.Diag(diag::err_drv_no_rdc_new_driver);
- if (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false))
+ if (IsRDCMode)
CmdArgs.push_back("-fgpu-rdc");
if (Args.hasFlag(options::OPT_fgpu_defer_diag,
options::OPT_fno_gpu_defer_diag, false))
@@ -6313,6 +6332,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (IsUsingLTO)
Args.AddLastArg(CmdArgs, options::OPT_mibt_seal);
+ if (Arg *A = Args.getLastArg(options::OPT_mfunction_return_EQ))
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("-mfunction-return=") + A->getValue()));
+
// Forward -f options with positive and negative forms; we translate these by
// hand. Do not propagate PGO options to the GPU-side compilations as the
// profile info is for the host-side compilation only.
@@ -6956,13 +6979,22 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
}
- // Host-side cuda compilation receives all device-side outputs in a single
- // fatbin as Inputs[1]. Include the binary with -fcuda-include-gpubinary.
+ // Host-side offloading compilation receives all device-side outputs. Include
+ // them in the host compilation depending on the target. If the host inputs
+ // are not empty we use the new-driver scheme, otherwise use the old scheme.
if ((IsCuda || IsHIP) && CudaDeviceInput) {
+ CmdArgs.push_back("-fcuda-include-gpubinary");
+ CmdArgs.push_back(CudaDeviceInput->getFilename());
+ } else if (!HostOffloadingInputs.empty()) {
+ if (IsCuda && !IsRDCMode) {
+ assert(HostOffloadingInputs.size() == 1 && "Only one input expected");
CmdArgs.push_back("-fcuda-include-gpubinary");
- CmdArgs.push_back(CudaDeviceInput->getFilename());
- if (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false))
- CmdArgs.push_back("-fgpu-rdc");
+ CmdArgs.push_back(HostOffloadingInputs.front().getFilename());
+ } else {
+ for (const InputInfo Input : HostOffloadingInputs)
+ CmdArgs.push_back(Args.MakeArgString("-fembed-offload-object=" +
+ TC.getInputFilename(Input)));
+ }
}
if (IsCuda) {
@@ -7011,12 +7043,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
}
- // Host-side offloading recieves the device object files and embeds it in a
- // named section including the associated target triple and architecture.
- for (const InputInfo Input : HostOffloadingInputs)
- CmdArgs.push_back(Args.MakeArgString("-fembed-offload-object=" +
- TC.getInputFilename(Input)));
-
if (Triple.isAMDGPU()) {
handleAMDGPUCodeObjectVersionOptions(D, Args, CmdArgs);
@@ -8314,7 +8340,8 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA,
ArgStringList Features;
SmallVector<StringRef> FeatureArgs;
- getTargetFeatures(TC->getDriver(), TC->getTriple(), Args, Features, false);
+ getTargetFeatures(TC->getDriver(), TC->getTriple(), TCArgs, Features,
+ false);
llvm::copy_if(Features, std::back_inserter(FeatureArgs),
[](StringRef Arg) { return !Arg.startswith("-target"); });
@@ -8382,7 +8409,7 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
for (StringRef LibName : BCLibs)
CmdArgs.push_back(Args.MakeArgString(
- "-target-library=" + Action::GetOffloadKindName(Action::OFK_OpenMP) +
+ "--bitcode-library=" + Action::GetOffloadKindName(Action::OFK_OpenMP) +
"-" + TC->getTripleString() + "-" + Arch + "=" + LibName));
}
@@ -8402,63 +8429,64 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
} else if (A->getOption().matches(options::OPT_O0))
OOpt = "0";
if (!OOpt.empty())
- CmdArgs.push_back(Args.MakeArgString(Twine("-opt-level=O") + OOpt));
+ CmdArgs.push_back(Args.MakeArgString(Twine("--opt-level=O") + OOpt));
}
}
- CmdArgs.push_back("-host-triple");
- CmdArgs.push_back(Args.MakeArgString(TheTriple.getTriple()));
+ CmdArgs.push_back(
+ Args.MakeArgString("--host-triple=" + TheTriple.getTriple()));
if (Args.hasArg(options::OPT_v))
- CmdArgs.push_back("-v");
+ CmdArgs.push_back("--verbose");
- // Add debug information if present.
if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) {
- const Option &Opt = A->getOption();
- if (Opt.matches(options::OPT_gN_Group)) {
- if (Opt.matches(options::OPT_gline_directives_only) ||
- Opt.matches(options::OPT_gline_tables_only))
- CmdArgs.push_back("-gline-directives-only");
- } else
- CmdArgs.push_back("-g");
+ if (!A->getOption().matches(options::OPT_g0))
+ CmdArgs.push_back("--device-debug");
}
for (const auto &A : Args.getAllArgValues(options::OPT_Xcuda_ptxas))
- CmdArgs.push_back(Args.MakeArgString("-ptxas-args=" + A));
+ CmdArgs.push_back(Args.MakeArgString("--ptxas-args=" + A));
// Forward remarks passes to the LLVM backend in the wrapper.
if (const Arg *A = Args.getLastArg(options::OPT_Rpass_EQ))
CmdArgs.push_back(
- Args.MakeArgString(Twine("-pass-remarks=") + A->getValue()));
+ Args.MakeArgString(Twine("--pass-remarks=") + A->getValue()));
if (const Arg *A = Args.getLastArg(options::OPT_Rpass_missed_EQ))
CmdArgs.push_back(
- Args.MakeArgString(Twine("-pass-remarks-missed=") + A->getValue()));
+ Args.MakeArgString(Twine("--pass-remarks-missed=") + A->getValue()));
if (const Arg *A = Args.getLastArg(options::OPT_Rpass_analysis_EQ))
CmdArgs.push_back(
- Args.MakeArgString(Twine("-pass-remarks-analysis=") + A->getValue()));
+ Args.MakeArgString(Twine("--pass-remarks-analysis=") + A->getValue()));
if (Args.getLastArg(options::OPT_save_temps_EQ))
- CmdArgs.push_back("-save-temps");
+ CmdArgs.push_back("--save-temps");
// Construct the link job so we can wrap around it.
Linker->ConstructJob(C, JA, Output, Inputs, Args, LinkingOutput);
const auto &LinkCommand = C.getJobs().getJobs().back();
// Forward -Xoffload-linker<-triple> arguments to the device link job.
- for (auto *Arg : Args.filtered(options::OPT_Xoffload_linker)) {
- StringRef Val = Arg->getValue(0);
+ for (Arg *A : Args.filtered(options::OPT_Xoffload_linker)) {
+ StringRef Val = A->getValue(0);
if (Val.empty())
CmdArgs.push_back(
- Args.MakeArgString(Twine("-device-linker=") + Arg->getValue(1)));
+ Args.MakeArgString(Twine("--device-linker=") + A->getValue(1)));
else
CmdArgs.push_back(Args.MakeArgString(
- "-device-linker=" +
+ "--device-linker=" +
ToolChain::getOpenMPTriple(Val.drop_front()).getTriple() + "=" +
- Arg->getValue(1)));
+ A->getValue(1)));
}
Args.ClaimAllArgs(options::OPT_Xoffload_linker);
+ // Forward `-mllvm` arguments to the LLVM invocations if present.
+ for (Arg *A : Args.filtered(options::OPT_mllvm)) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back(A->getValue());
+ A->claim();
+ }
+
// Add the linker arguments to be forwarded by the wrapper.
- CmdArgs.push_back("-linker-path");
- CmdArgs.push_back(LinkCommand->getExecutable());
+ CmdArgs.push_back(Args.MakeArgString(Twine("--linker-path=") +
+ LinkCommand->getExecutable()));
CmdArgs.push_back("--");
for (const char *LinkArg : LinkCommand->getArguments())
CmdArgs.push_back(LinkArg);