diff options
Diffstat (limited to 'clang/lib/Driver/ToolChains/Clang.cpp')
-rw-r--r-- | clang/lib/Driver/ToolChains/Clang.cpp | 234 |
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); |