17330f729Sjoerg //===-- Clang.cpp - Clang+LLVM ToolChain Implementations --------*- C++ -*-===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg
97330f729Sjoerg #include "Clang.h"
10*e038c9c4Sjoerg #include "AMDGPU.h"
117330f729Sjoerg #include "Arch/AArch64.h"
127330f729Sjoerg #include "Arch/ARM.h"
13*e038c9c4Sjoerg #include "Arch/M68k.h"
147330f729Sjoerg #include "Arch/Mips.h"
157330f729Sjoerg #include "Arch/PPC.h"
167330f729Sjoerg #include "Arch/RISCV.h"
177330f729Sjoerg #include "Arch/Sparc.h"
187330f729Sjoerg #include "Arch/SystemZ.h"
19*e038c9c4Sjoerg #include "Arch/VE.h"
207330f729Sjoerg #include "Arch/X86.h"
217330f729Sjoerg #include "CommonArgs.h"
227330f729Sjoerg #include "Hexagon.h"
237330f729Sjoerg #include "InputInfo.h"
24*e038c9c4Sjoerg #include "MSP430.h"
257330f729Sjoerg #include "PS4CPU.h"
267330f729Sjoerg #include "clang/Basic/CharInfo.h"
277330f729Sjoerg #include "clang/Basic/CodeGenOptions.h"
287330f729Sjoerg #include "clang/Basic/LangOptions.h"
297330f729Sjoerg #include "clang/Basic/ObjCRuntime.h"
307330f729Sjoerg #include "clang/Basic/Version.h"
317330f729Sjoerg #include "clang/Driver/Distro.h"
327330f729Sjoerg #include "clang/Driver/DriverDiagnostic.h"
337330f729Sjoerg #include "clang/Driver/Options.h"
347330f729Sjoerg #include "clang/Driver/SanitizerArgs.h"
357330f729Sjoerg #include "clang/Driver/XRayArgs.h"
367330f729Sjoerg #include "llvm/ADT/StringExtras.h"
377330f729Sjoerg #include "llvm/Config/llvm-config.h"
387330f729Sjoerg #include "llvm/Option/ArgList.h"
397330f729Sjoerg #include "llvm/Support/CodeGen.h"
40*e038c9c4Sjoerg #include "llvm/Support/Compiler.h"
417330f729Sjoerg #include "llvm/Support/Compression.h"
427330f729Sjoerg #include "llvm/Support/FileSystem.h"
43*e038c9c4Sjoerg #include "llvm/Support/Host.h"
447330f729Sjoerg #include "llvm/Support/Path.h"
457330f729Sjoerg #include "llvm/Support/Process.h"
467330f729Sjoerg #include "llvm/Support/TargetParser.h"
477330f729Sjoerg #include "llvm/Support/YAMLParser.h"
487330f729Sjoerg
497330f729Sjoerg using namespace clang::driver;
507330f729Sjoerg using namespace clang::driver::tools;
517330f729Sjoerg using namespace clang;
527330f729Sjoerg using namespace llvm::opt;
537330f729Sjoerg
CheckPreprocessingOptions(const Driver & D,const ArgList & Args)547330f729Sjoerg static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
557330f729Sjoerg if (Arg *A =
567330f729Sjoerg Args.getLastArg(clang::driver::options::OPT_C, options::OPT_CC)) {
577330f729Sjoerg if (!Args.hasArg(options::OPT_E) && !Args.hasArg(options::OPT__SLASH_P) &&
587330f729Sjoerg !Args.hasArg(options::OPT__SLASH_EP) && !D.CCCIsCPP()) {
597330f729Sjoerg D.Diag(clang::diag::err_drv_argument_only_allowed_with)
607330f729Sjoerg << A->getBaseArg().getAsString(Args)
617330f729Sjoerg << (D.IsCLMode() ? "/E, /P or /EP" : "-E");
627330f729Sjoerg }
637330f729Sjoerg }
647330f729Sjoerg }
657330f729Sjoerg
CheckCodeGenerationOptions(const Driver & D,const ArgList & Args)667330f729Sjoerg static void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) {
677330f729Sjoerg // In gcc, only ARM checks this, but it seems reasonable to check universally.
687330f729Sjoerg if (Args.hasArg(options::OPT_static))
697330f729Sjoerg if (const Arg *A =
707330f729Sjoerg Args.getLastArg(options::OPT_dynamic, options::OPT_mdynamic_no_pic))
717330f729Sjoerg D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
727330f729Sjoerg << "-static";
737330f729Sjoerg }
747330f729Sjoerg
757330f729Sjoerg // Add backslashes to escape spaces and other backslashes.
767330f729Sjoerg // This is used for the space-separated argument list specified with
777330f729Sjoerg // the -dwarf-debug-flags option.
EscapeSpacesAndBackslashes(const char * Arg,SmallVectorImpl<char> & Res)787330f729Sjoerg static void EscapeSpacesAndBackslashes(const char *Arg,
797330f729Sjoerg SmallVectorImpl<char> &Res) {
807330f729Sjoerg for (; *Arg; ++Arg) {
817330f729Sjoerg switch (*Arg) {
827330f729Sjoerg default:
837330f729Sjoerg break;
847330f729Sjoerg case ' ':
857330f729Sjoerg case '\\':
867330f729Sjoerg Res.push_back('\\');
877330f729Sjoerg break;
887330f729Sjoerg }
897330f729Sjoerg Res.push_back(*Arg);
907330f729Sjoerg }
917330f729Sjoerg }
927330f729Sjoerg
937330f729Sjoerg // Quote target names for inclusion in GNU Make dependency files.
947330f729Sjoerg // Only the characters '$', '#', ' ', '\t' are quoted.
QuoteTarget(StringRef Target,SmallVectorImpl<char> & Res)957330f729Sjoerg static void QuoteTarget(StringRef Target, SmallVectorImpl<char> &Res) {
967330f729Sjoerg for (unsigned i = 0, e = Target.size(); i != e; ++i) {
977330f729Sjoerg switch (Target[i]) {
987330f729Sjoerg case ' ':
997330f729Sjoerg case '\t':
1007330f729Sjoerg // Escape the preceding backslashes
1017330f729Sjoerg for (int j = i - 1; j >= 0 && Target[j] == '\\'; --j)
1027330f729Sjoerg Res.push_back('\\');
1037330f729Sjoerg
1047330f729Sjoerg // Escape the space/tab
1057330f729Sjoerg Res.push_back('\\');
1067330f729Sjoerg break;
1077330f729Sjoerg case '$':
1087330f729Sjoerg Res.push_back('$');
1097330f729Sjoerg break;
1107330f729Sjoerg case '#':
1117330f729Sjoerg Res.push_back('\\');
1127330f729Sjoerg break;
1137330f729Sjoerg default:
1147330f729Sjoerg break;
1157330f729Sjoerg }
1167330f729Sjoerg
1177330f729Sjoerg Res.push_back(Target[i]);
1187330f729Sjoerg }
1197330f729Sjoerg }
1207330f729Sjoerg
1217330f729Sjoerg /// Apply \a Work on the current tool chain \a RegularToolChain and any other
1227330f729Sjoerg /// offloading tool chain that is associated with the current action \a JA.
1237330f729Sjoerg static void
forAllAssociatedToolChains(Compilation & C,const JobAction & JA,const ToolChain & RegularToolChain,llvm::function_ref<void (const ToolChain &)> Work)1247330f729Sjoerg forAllAssociatedToolChains(Compilation &C, const JobAction &JA,
1257330f729Sjoerg const ToolChain &RegularToolChain,
1267330f729Sjoerg llvm::function_ref<void(const ToolChain &)> Work) {
1277330f729Sjoerg // Apply Work on the current/regular tool chain.
1287330f729Sjoerg Work(RegularToolChain);
1297330f729Sjoerg
1307330f729Sjoerg // Apply Work on all the offloading tool chains associated with the current
1317330f729Sjoerg // action.
1327330f729Sjoerg if (JA.isHostOffloading(Action::OFK_Cuda))
1337330f729Sjoerg Work(*C.getSingleOffloadToolChain<Action::OFK_Cuda>());
1347330f729Sjoerg else if (JA.isDeviceOffloading(Action::OFK_Cuda))
1357330f729Sjoerg Work(*C.getSingleOffloadToolChain<Action::OFK_Host>());
1367330f729Sjoerg else if (JA.isHostOffloading(Action::OFK_HIP))
1377330f729Sjoerg Work(*C.getSingleOffloadToolChain<Action::OFK_HIP>());
1387330f729Sjoerg else if (JA.isDeviceOffloading(Action::OFK_HIP))
1397330f729Sjoerg Work(*C.getSingleOffloadToolChain<Action::OFK_Host>());
1407330f729Sjoerg
1417330f729Sjoerg if (JA.isHostOffloading(Action::OFK_OpenMP)) {
1427330f729Sjoerg auto TCs = C.getOffloadToolChains<Action::OFK_OpenMP>();
1437330f729Sjoerg for (auto II = TCs.first, IE = TCs.second; II != IE; ++II)
1447330f729Sjoerg Work(*II->second);
1457330f729Sjoerg } else if (JA.isDeviceOffloading(Action::OFK_OpenMP))
1467330f729Sjoerg Work(*C.getSingleOffloadToolChain<Action::OFK_Host>());
1477330f729Sjoerg
1487330f729Sjoerg //
1497330f729Sjoerg // TODO: Add support for other offloading programming models here.
1507330f729Sjoerg //
1517330f729Sjoerg }
1527330f729Sjoerg
1537330f729Sjoerg /// This is a helper function for validating the optional refinement step
1547330f729Sjoerg /// parameter in reciprocal argument strings. Return false if there is an error
1557330f729Sjoerg /// parsing the refinement step. Otherwise, return true and set the Position
1567330f729Sjoerg /// of the refinement step in the input string.
getRefinementStep(StringRef In,const Driver & D,const Arg & A,size_t & Position)1577330f729Sjoerg static bool getRefinementStep(StringRef In, const Driver &D,
1587330f729Sjoerg const Arg &A, size_t &Position) {
1597330f729Sjoerg const char RefinementStepToken = ':';
1607330f729Sjoerg Position = In.find(RefinementStepToken);
1617330f729Sjoerg if (Position != StringRef::npos) {
1627330f729Sjoerg StringRef Option = A.getOption().getName();
1637330f729Sjoerg StringRef RefStep = In.substr(Position + 1);
1647330f729Sjoerg // Allow exactly one numeric character for the additional refinement
1657330f729Sjoerg // step parameter. This is reasonable for all currently-supported
1667330f729Sjoerg // operations and architectures because we would expect that a larger value
1677330f729Sjoerg // of refinement steps would cause the estimate "optimization" to
1687330f729Sjoerg // under-perform the native operation. Also, if the estimate does not
1697330f729Sjoerg // converge quickly, it probably will not ever converge, so further
1707330f729Sjoerg // refinement steps will not produce a better answer.
1717330f729Sjoerg if (RefStep.size() != 1) {
1727330f729Sjoerg D.Diag(diag::err_drv_invalid_value) << Option << RefStep;
1737330f729Sjoerg return false;
1747330f729Sjoerg }
1757330f729Sjoerg char RefStepChar = RefStep[0];
1767330f729Sjoerg if (RefStepChar < '0' || RefStepChar > '9') {
1777330f729Sjoerg D.Diag(diag::err_drv_invalid_value) << Option << RefStep;
1787330f729Sjoerg return false;
1797330f729Sjoerg }
1807330f729Sjoerg }
1817330f729Sjoerg return true;
1827330f729Sjoerg }
1837330f729Sjoerg
1847330f729Sjoerg /// The -mrecip flag requires processing of many optional parameters.
ParseMRecip(const Driver & D,const ArgList & Args,ArgStringList & OutStrings)1857330f729Sjoerg static void ParseMRecip(const Driver &D, const ArgList &Args,
1867330f729Sjoerg ArgStringList &OutStrings) {
1877330f729Sjoerg StringRef DisabledPrefixIn = "!";
1887330f729Sjoerg StringRef DisabledPrefixOut = "!";
1897330f729Sjoerg StringRef EnabledPrefixOut = "";
1907330f729Sjoerg StringRef Out = "-mrecip=";
1917330f729Sjoerg
1927330f729Sjoerg Arg *A = Args.getLastArg(options::OPT_mrecip, options::OPT_mrecip_EQ);
1937330f729Sjoerg if (!A)
1947330f729Sjoerg return;
1957330f729Sjoerg
1967330f729Sjoerg unsigned NumOptions = A->getNumValues();
1977330f729Sjoerg if (NumOptions == 0) {
1987330f729Sjoerg // No option is the same as "all".
1997330f729Sjoerg OutStrings.push_back(Args.MakeArgString(Out + "all"));
2007330f729Sjoerg return;
2017330f729Sjoerg }
2027330f729Sjoerg
2037330f729Sjoerg // Pass through "all", "none", or "default" with an optional refinement step.
2047330f729Sjoerg if (NumOptions == 1) {
2057330f729Sjoerg StringRef Val = A->getValue(0);
2067330f729Sjoerg size_t RefStepLoc;
2077330f729Sjoerg if (!getRefinementStep(Val, D, *A, RefStepLoc))
2087330f729Sjoerg return;
2097330f729Sjoerg StringRef ValBase = Val.slice(0, RefStepLoc);
2107330f729Sjoerg if (ValBase == "all" || ValBase == "none" || ValBase == "default") {
2117330f729Sjoerg OutStrings.push_back(Args.MakeArgString(Out + Val));
2127330f729Sjoerg return;
2137330f729Sjoerg }
2147330f729Sjoerg }
2157330f729Sjoerg
2167330f729Sjoerg // Each reciprocal type may be enabled or disabled individually.
2177330f729Sjoerg // Check each input value for validity, concatenate them all back together,
2187330f729Sjoerg // and pass through.
2197330f729Sjoerg
2207330f729Sjoerg llvm::StringMap<bool> OptionStrings;
2217330f729Sjoerg OptionStrings.insert(std::make_pair("divd", false));
2227330f729Sjoerg OptionStrings.insert(std::make_pair("divf", false));
2237330f729Sjoerg OptionStrings.insert(std::make_pair("vec-divd", false));
2247330f729Sjoerg OptionStrings.insert(std::make_pair("vec-divf", false));
2257330f729Sjoerg OptionStrings.insert(std::make_pair("sqrtd", false));
2267330f729Sjoerg OptionStrings.insert(std::make_pair("sqrtf", false));
2277330f729Sjoerg OptionStrings.insert(std::make_pair("vec-sqrtd", false));
2287330f729Sjoerg OptionStrings.insert(std::make_pair("vec-sqrtf", false));
2297330f729Sjoerg
2307330f729Sjoerg for (unsigned i = 0; i != NumOptions; ++i) {
2317330f729Sjoerg StringRef Val = A->getValue(i);
2327330f729Sjoerg
2337330f729Sjoerg bool IsDisabled = Val.startswith(DisabledPrefixIn);
2347330f729Sjoerg // Ignore the disablement token for string matching.
2357330f729Sjoerg if (IsDisabled)
2367330f729Sjoerg Val = Val.substr(1);
2377330f729Sjoerg
2387330f729Sjoerg size_t RefStep;
2397330f729Sjoerg if (!getRefinementStep(Val, D, *A, RefStep))
2407330f729Sjoerg return;
2417330f729Sjoerg
2427330f729Sjoerg StringRef ValBase = Val.slice(0, RefStep);
2437330f729Sjoerg llvm::StringMap<bool>::iterator OptionIter = OptionStrings.find(ValBase);
2447330f729Sjoerg if (OptionIter == OptionStrings.end()) {
2457330f729Sjoerg // Try again specifying float suffix.
2467330f729Sjoerg OptionIter = OptionStrings.find(ValBase.str() + 'f');
2477330f729Sjoerg if (OptionIter == OptionStrings.end()) {
2487330f729Sjoerg // The input name did not match any known option string.
2497330f729Sjoerg D.Diag(diag::err_drv_unknown_argument) << Val;
2507330f729Sjoerg return;
2517330f729Sjoerg }
2527330f729Sjoerg // The option was specified without a float or double suffix.
2537330f729Sjoerg // Make sure that the double entry was not already specified.
2547330f729Sjoerg // The float entry will be checked below.
2557330f729Sjoerg if (OptionStrings[ValBase.str() + 'd']) {
2567330f729Sjoerg D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Val;
2577330f729Sjoerg return;
2587330f729Sjoerg }
2597330f729Sjoerg }
2607330f729Sjoerg
2617330f729Sjoerg if (OptionIter->second == true) {
2627330f729Sjoerg // Duplicate option specified.
2637330f729Sjoerg D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Val;
2647330f729Sjoerg return;
2657330f729Sjoerg }
2667330f729Sjoerg
2677330f729Sjoerg // Mark the matched option as found. Do not allow duplicate specifiers.
2687330f729Sjoerg OptionIter->second = true;
2697330f729Sjoerg
2707330f729Sjoerg // If the precision was not specified, also mark the double entry as found.
2717330f729Sjoerg if (ValBase.back() != 'f' && ValBase.back() != 'd')
2727330f729Sjoerg OptionStrings[ValBase.str() + 'd'] = true;
2737330f729Sjoerg
2747330f729Sjoerg // Build the output string.
2757330f729Sjoerg StringRef Prefix = IsDisabled ? DisabledPrefixOut : EnabledPrefixOut;
2767330f729Sjoerg Out = Args.MakeArgString(Out + Prefix + Val);
2777330f729Sjoerg if (i != NumOptions - 1)
2787330f729Sjoerg Out = Args.MakeArgString(Out + ",");
2797330f729Sjoerg }
2807330f729Sjoerg
2817330f729Sjoerg OutStrings.push_back(Args.MakeArgString(Out));
2827330f729Sjoerg }
2837330f729Sjoerg
2847330f729Sjoerg /// The -mprefer-vector-width option accepts either a positive integer
2857330f729Sjoerg /// or the string "none".
ParseMPreferVectorWidth(const Driver & D,const ArgList & Args,ArgStringList & CmdArgs)2867330f729Sjoerg static void ParseMPreferVectorWidth(const Driver &D, const ArgList &Args,
2877330f729Sjoerg ArgStringList &CmdArgs) {
2887330f729Sjoerg Arg *A = Args.getLastArg(options::OPT_mprefer_vector_width_EQ);
2897330f729Sjoerg if (!A)
2907330f729Sjoerg return;
2917330f729Sjoerg
2927330f729Sjoerg StringRef Value = A->getValue();
2937330f729Sjoerg if (Value == "none") {
2947330f729Sjoerg CmdArgs.push_back("-mprefer-vector-width=none");
2957330f729Sjoerg } else {
2967330f729Sjoerg unsigned Width;
2977330f729Sjoerg if (Value.getAsInteger(10, Width)) {
2987330f729Sjoerg D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
2997330f729Sjoerg return;
3007330f729Sjoerg }
3017330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-mprefer-vector-width=" + Value));
3027330f729Sjoerg }
3037330f729Sjoerg }
3047330f729Sjoerg
getWebAssemblyTargetFeatures(const ArgList & Args,std::vector<StringRef> & Features)305*e038c9c4Sjoerg static void getWebAssemblyTargetFeatures(const ArgList &Args,
306*e038c9c4Sjoerg std::vector<StringRef> &Features) {
307*e038c9c4Sjoerg handleTargetFeaturesGroup(Args, Features, options::OPT_m_wasm_Features_Group);
308*e038c9c4Sjoerg }
309*e038c9c4Sjoerg
getTargetFeatures(const Driver & D,const llvm::Triple & Triple,const ArgList & Args,ArgStringList & CmdArgs,bool ForAS,bool IsAux=false)310*e038c9c4Sjoerg static void getTargetFeatures(const Driver &D, const llvm::Triple &Triple,
311*e038c9c4Sjoerg const ArgList &Args, ArgStringList &CmdArgs,
312*e038c9c4Sjoerg bool ForAS, bool IsAux = false) {
313*e038c9c4Sjoerg std::vector<StringRef> Features;
314*e038c9c4Sjoerg switch (Triple.getArch()) {
315*e038c9c4Sjoerg default:
316*e038c9c4Sjoerg break;
317*e038c9c4Sjoerg case llvm::Triple::mips:
318*e038c9c4Sjoerg case llvm::Triple::mipsel:
319*e038c9c4Sjoerg case llvm::Triple::mips64:
320*e038c9c4Sjoerg case llvm::Triple::mips64el:
321*e038c9c4Sjoerg mips::getMIPSTargetFeatures(D, Triple, Args, Features);
322*e038c9c4Sjoerg break;
323*e038c9c4Sjoerg
324*e038c9c4Sjoerg case llvm::Triple::arm:
325*e038c9c4Sjoerg case llvm::Triple::armeb:
326*e038c9c4Sjoerg case llvm::Triple::thumb:
327*e038c9c4Sjoerg case llvm::Triple::thumbeb:
328*e038c9c4Sjoerg arm::getARMTargetFeatures(D, Triple, Args, CmdArgs, Features, ForAS);
329*e038c9c4Sjoerg break;
330*e038c9c4Sjoerg
331*e038c9c4Sjoerg case llvm::Triple::ppc:
332*e038c9c4Sjoerg case llvm::Triple::ppcle:
333*e038c9c4Sjoerg case llvm::Triple::ppc64:
334*e038c9c4Sjoerg case llvm::Triple::ppc64le:
335*e038c9c4Sjoerg ppc::getPPCTargetFeatures(D, Triple, Args, Features);
336*e038c9c4Sjoerg break;
337*e038c9c4Sjoerg case llvm::Triple::riscv32:
338*e038c9c4Sjoerg case llvm::Triple::riscv64:
339*e038c9c4Sjoerg riscv::getRISCVTargetFeatures(D, Triple, Args, Features);
340*e038c9c4Sjoerg break;
341*e038c9c4Sjoerg case llvm::Triple::systemz:
342*e038c9c4Sjoerg systemz::getSystemZTargetFeatures(D, Args, Features);
343*e038c9c4Sjoerg break;
344*e038c9c4Sjoerg case llvm::Triple::aarch64:
345*e038c9c4Sjoerg case llvm::Triple::aarch64_32:
346*e038c9c4Sjoerg case llvm::Triple::aarch64_be:
347*e038c9c4Sjoerg aarch64::getAArch64TargetFeatures(D, Triple, Args, Features);
348*e038c9c4Sjoerg break;
349*e038c9c4Sjoerg case llvm::Triple::x86:
350*e038c9c4Sjoerg case llvm::Triple::x86_64:
351*e038c9c4Sjoerg x86::getX86TargetFeatures(D, Triple, Args, Features);
352*e038c9c4Sjoerg break;
353*e038c9c4Sjoerg case llvm::Triple::hexagon:
354*e038c9c4Sjoerg hexagon::getHexagonTargetFeatures(D, Args, Features);
355*e038c9c4Sjoerg break;
356*e038c9c4Sjoerg case llvm::Triple::wasm32:
357*e038c9c4Sjoerg case llvm::Triple::wasm64:
358*e038c9c4Sjoerg getWebAssemblyTargetFeatures(Args, Features);
359*e038c9c4Sjoerg break;
360*e038c9c4Sjoerg case llvm::Triple::sparc:
361*e038c9c4Sjoerg case llvm::Triple::sparcel:
362*e038c9c4Sjoerg case llvm::Triple::sparcv9:
363*e038c9c4Sjoerg sparc::getSparcTargetFeatures(D, Args, Features);
364*e038c9c4Sjoerg break;
365*e038c9c4Sjoerg case llvm::Triple::r600:
366*e038c9c4Sjoerg case llvm::Triple::amdgcn:
367*e038c9c4Sjoerg amdgpu::getAMDGPUTargetFeatures(D, Triple, Args, Features);
368*e038c9c4Sjoerg break;
369*e038c9c4Sjoerg case llvm::Triple::m68k:
370*e038c9c4Sjoerg m68k::getM68kTargetFeatures(D, Triple, Args, Features);
371*e038c9c4Sjoerg break;
372*e038c9c4Sjoerg case llvm::Triple::msp430:
373*e038c9c4Sjoerg msp430::getMSP430TargetFeatures(D, Args, Features);
374*e038c9c4Sjoerg break;
375*e038c9c4Sjoerg case llvm::Triple::ve:
376*e038c9c4Sjoerg ve::getVETargetFeatures(D, Args, Features);
377*e038c9c4Sjoerg break;
378*e038c9c4Sjoerg }
379*e038c9c4Sjoerg
380*e038c9c4Sjoerg for (auto Feature : unifyTargetFeatures(Features)) {
381*e038c9c4Sjoerg CmdArgs.push_back(IsAux ? "-aux-target-feature" : "-target-feature");
382*e038c9c4Sjoerg CmdArgs.push_back(Feature.data());
383*e038c9c4Sjoerg }
384*e038c9c4Sjoerg }
385*e038c9c4Sjoerg
3867330f729Sjoerg static bool
shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime & runtime,const llvm::Triple & Triple)3877330f729Sjoerg shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime,
3887330f729Sjoerg const llvm::Triple &Triple) {
3897330f729Sjoerg // We use the zero-cost exception tables for Objective-C if the non-fragile
3907330f729Sjoerg // ABI is enabled or when compiling for x86_64 and ARM on Snow Leopard and
3917330f729Sjoerg // later.
3927330f729Sjoerg if (runtime.isNonFragile())
3937330f729Sjoerg return true;
3947330f729Sjoerg
3957330f729Sjoerg if (!Triple.isMacOSX())
3967330f729Sjoerg return false;
3977330f729Sjoerg
3987330f729Sjoerg return (!Triple.isMacOSXVersionLT(10, 5) &&
3997330f729Sjoerg (Triple.getArch() == llvm::Triple::x86_64 ||
4007330f729Sjoerg Triple.getArch() == llvm::Triple::arm));
4017330f729Sjoerg }
4027330f729Sjoerg
4037330f729Sjoerg /// Adds exception related arguments to the driver command arguments. There's a
4047330f729Sjoerg /// master flag, -fexceptions and also language specific flags to enable/disable
4057330f729Sjoerg /// C++ and Objective-C exceptions. This makes it possible to for example
4067330f729Sjoerg /// disable C++ exceptions but enable Objective-C exceptions.
addExceptionArgs(const ArgList & Args,types::ID InputType,const ToolChain & TC,bool KernelOrKext,const ObjCRuntime & objcRuntime,ArgStringList & CmdArgs)407*e038c9c4Sjoerg static bool addExceptionArgs(const ArgList &Args, types::ID InputType,
4087330f729Sjoerg const ToolChain &TC, bool KernelOrKext,
4097330f729Sjoerg const ObjCRuntime &objcRuntime,
4107330f729Sjoerg ArgStringList &CmdArgs) {
4117330f729Sjoerg const llvm::Triple &Triple = TC.getTriple();
4127330f729Sjoerg
4137330f729Sjoerg if (KernelOrKext) {
4147330f729Sjoerg // -mkernel and -fapple-kext imply no exceptions, so claim exception related
4157330f729Sjoerg // arguments now to avoid warnings about unused arguments.
4167330f729Sjoerg Args.ClaimAllArgs(options::OPT_fexceptions);
4177330f729Sjoerg Args.ClaimAllArgs(options::OPT_fno_exceptions);
4187330f729Sjoerg Args.ClaimAllArgs(options::OPT_fobjc_exceptions);
4197330f729Sjoerg Args.ClaimAllArgs(options::OPT_fno_objc_exceptions);
4207330f729Sjoerg Args.ClaimAllArgs(options::OPT_fcxx_exceptions);
4217330f729Sjoerg Args.ClaimAllArgs(options::OPT_fno_cxx_exceptions);
422*e038c9c4Sjoerg Args.ClaimAllArgs(options::OPT_fasync_exceptions);
423*e038c9c4Sjoerg Args.ClaimAllArgs(options::OPT_fno_async_exceptions);
424*e038c9c4Sjoerg return false;
4257330f729Sjoerg }
4267330f729Sjoerg
4277330f729Sjoerg // See if the user explicitly enabled exceptions.
4287330f729Sjoerg bool EH = Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
4297330f729Sjoerg false);
4307330f729Sjoerg
431*e038c9c4Sjoerg bool EHa = Args.hasFlag(options::OPT_fasync_exceptions,
432*e038c9c4Sjoerg options::OPT_fno_async_exceptions, false);
433*e038c9c4Sjoerg if (EHa) {
434*e038c9c4Sjoerg CmdArgs.push_back("-fasync-exceptions");
435*e038c9c4Sjoerg EH = true;
436*e038c9c4Sjoerg }
437*e038c9c4Sjoerg
4387330f729Sjoerg // Obj-C exceptions are enabled by default, regardless of -fexceptions. This
4397330f729Sjoerg // is not necessarily sensible, but follows GCC.
4407330f729Sjoerg if (types::isObjC(InputType) &&
4417330f729Sjoerg Args.hasFlag(options::OPT_fobjc_exceptions,
4427330f729Sjoerg options::OPT_fno_objc_exceptions, true)) {
4437330f729Sjoerg CmdArgs.push_back("-fobjc-exceptions");
4447330f729Sjoerg
4457330f729Sjoerg EH |= shouldUseExceptionTablesForObjCExceptions(objcRuntime, Triple);
4467330f729Sjoerg }
4477330f729Sjoerg
4487330f729Sjoerg if (types::isCXX(InputType)) {
4497330f729Sjoerg // Disable C++ EH by default on XCore and PS4.
4507330f729Sjoerg bool CXXExceptionsEnabled =
4517330f729Sjoerg Triple.getArch() != llvm::Triple::xcore && !Triple.isPS4CPU();
4527330f729Sjoerg Arg *ExceptionArg = Args.getLastArg(
4537330f729Sjoerg options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions,
4547330f729Sjoerg options::OPT_fexceptions, options::OPT_fno_exceptions);
4557330f729Sjoerg if (ExceptionArg)
4567330f729Sjoerg CXXExceptionsEnabled =
4577330f729Sjoerg ExceptionArg->getOption().matches(options::OPT_fcxx_exceptions) ||
4587330f729Sjoerg ExceptionArg->getOption().matches(options::OPT_fexceptions);
4597330f729Sjoerg
4607330f729Sjoerg if (CXXExceptionsEnabled) {
4617330f729Sjoerg CmdArgs.push_back("-fcxx-exceptions");
4627330f729Sjoerg
4637330f729Sjoerg EH = true;
4647330f729Sjoerg }
4657330f729Sjoerg }
4667330f729Sjoerg
467*e038c9c4Sjoerg // OPT_fignore_exceptions means exception could still be thrown,
468*e038c9c4Sjoerg // but no clean up or catch would happen in current module.
469*e038c9c4Sjoerg // So we do not set EH to false.
470*e038c9c4Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fignore_exceptions);
471*e038c9c4Sjoerg
4727330f729Sjoerg if (EH)
4737330f729Sjoerg CmdArgs.push_back("-fexceptions");
474*e038c9c4Sjoerg return EH;
4757330f729Sjoerg }
4767330f729Sjoerg
ShouldEnableAutolink(const ArgList & Args,const ToolChain & TC,const JobAction & JA)477*e038c9c4Sjoerg static bool ShouldEnableAutolink(const ArgList &Args, const ToolChain &TC,
478*e038c9c4Sjoerg const JobAction &JA) {
4797330f729Sjoerg bool Default = true;
4807330f729Sjoerg if (TC.getTriple().isOSDarwin()) {
4817330f729Sjoerg // The native darwin assembler doesn't support the linker_option directives,
4827330f729Sjoerg // so we disable them if we think the .s file will be passed to it.
4837330f729Sjoerg Default = TC.useIntegratedAs();
4847330f729Sjoerg }
485*e038c9c4Sjoerg // The linker_option directives are intended for host compilation.
486*e038c9c4Sjoerg if (JA.isDeviceOffloading(Action::OFK_Cuda) ||
487*e038c9c4Sjoerg JA.isDeviceOffloading(Action::OFK_HIP))
488*e038c9c4Sjoerg Default = false;
489*e038c9c4Sjoerg return Args.hasFlag(options::OPT_fautolink, options::OPT_fno_autolink,
4907330f729Sjoerg Default);
4917330f729Sjoerg }
4927330f729Sjoerg
ShouldDisableDwarfDirectory(const ArgList & Args,const ToolChain & TC)4937330f729Sjoerg static bool ShouldDisableDwarfDirectory(const ArgList &Args,
4947330f729Sjoerg const ToolChain &TC) {
4957330f729Sjoerg bool UseDwarfDirectory =
4967330f729Sjoerg Args.hasFlag(options::OPT_fdwarf_directory_asm,
4977330f729Sjoerg options::OPT_fno_dwarf_directory_asm, TC.useIntegratedAs());
4987330f729Sjoerg return !UseDwarfDirectory;
4997330f729Sjoerg }
5007330f729Sjoerg
5017330f729Sjoerg // Convert an arg of the form "-gN" or "-ggdbN" or one of their aliases
5027330f729Sjoerg // to the corresponding DebugInfoKind.
DebugLevelToInfoKind(const Arg & A)5037330f729Sjoerg static codegenoptions::DebugInfoKind DebugLevelToInfoKind(const Arg &A) {
5047330f729Sjoerg assert(A.getOption().matches(options::OPT_gN_Group) &&
5057330f729Sjoerg "Not a -g option that specifies a debug-info level");
5067330f729Sjoerg if (A.getOption().matches(options::OPT_g0) ||
5077330f729Sjoerg A.getOption().matches(options::OPT_ggdb0))
5087330f729Sjoerg return codegenoptions::NoDebugInfo;
5097330f729Sjoerg if (A.getOption().matches(options::OPT_gline_tables_only) ||
5107330f729Sjoerg A.getOption().matches(options::OPT_ggdb1))
5117330f729Sjoerg return codegenoptions::DebugLineTablesOnly;
5127330f729Sjoerg if (A.getOption().matches(options::OPT_gline_directives_only))
5137330f729Sjoerg return codegenoptions::DebugDirectivesOnly;
5147330f729Sjoerg return codegenoptions::LimitedDebugInfo;
5157330f729Sjoerg }
5167330f729Sjoerg
mustUseNonLeafFramePointerForTarget(const llvm::Triple & Triple)5177330f729Sjoerg static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) {
5187330f729Sjoerg switch (Triple.getArch()){
5197330f729Sjoerg default:
5207330f729Sjoerg return false;
5217330f729Sjoerg case llvm::Triple::arm:
5227330f729Sjoerg case llvm::Triple::thumb:
5237330f729Sjoerg // ARM Darwin targets require a frame pointer to be always present to aid
5247330f729Sjoerg // offline debugging via backtraces.
5257330f729Sjoerg return Triple.isOSDarwin();
5267330f729Sjoerg }
5277330f729Sjoerg }
5287330f729Sjoerg
useFramePointerForTargetByDefault(const ArgList & Args,const llvm::Triple & Triple)5297330f729Sjoerg static bool useFramePointerForTargetByDefault(const ArgList &Args,
5307330f729Sjoerg const llvm::Triple &Triple) {
531*e038c9c4Sjoerg if (Args.hasArg(options::OPT_pg) && !Args.hasArg(options::OPT_mfentry))
5327330f729Sjoerg return true;
5337330f729Sjoerg
5347330f729Sjoerg switch (Triple.getArch()) {
5357330f729Sjoerg case llvm::Triple::xcore:
5367330f729Sjoerg case llvm::Triple::wasm32:
5377330f729Sjoerg case llvm::Triple::wasm64:
5387330f729Sjoerg case llvm::Triple::msp430:
5397330f729Sjoerg // XCore never wants frame pointers, regardless of OS.
5407330f729Sjoerg // WebAssembly never wants frame pointers.
5417330f729Sjoerg return false;
5427330f729Sjoerg case llvm::Triple::ppc:
543*e038c9c4Sjoerg case llvm::Triple::ppcle:
5447330f729Sjoerg case llvm::Triple::ppc64:
5457330f729Sjoerg case llvm::Triple::ppc64le:
5467330f729Sjoerg case llvm::Triple::riscv32:
5477330f729Sjoerg case llvm::Triple::riscv64:
548*e038c9c4Sjoerg case llvm::Triple::amdgcn:
549*e038c9c4Sjoerg case llvm::Triple::r600:
5507330f729Sjoerg return !areOptimizationsEnabled(Args);
5517330f729Sjoerg default:
5527330f729Sjoerg break;
5537330f729Sjoerg }
5547330f729Sjoerg
5557330f729Sjoerg if (Triple.isOSNetBSD()) {
5567330f729Sjoerg return !areOptimizationsEnabled(Args);
5577330f729Sjoerg }
5587330f729Sjoerg
5597330f729Sjoerg if (Triple.isOSLinux() || Triple.getOS() == llvm::Triple::CloudABI ||
5607330f729Sjoerg Triple.isOSHurd()) {
5617330f729Sjoerg switch (Triple.getArch()) {
5627330f729Sjoerg // Don't use a frame pointer on linux if optimizing for certain targets.
563*e038c9c4Sjoerg case llvm::Triple::arm:
564*e038c9c4Sjoerg case llvm::Triple::armeb:
565*e038c9c4Sjoerg case llvm::Triple::thumb:
566*e038c9c4Sjoerg case llvm::Triple::thumbeb:
567*e038c9c4Sjoerg if (Triple.isAndroid())
568*e038c9c4Sjoerg return true;
569*e038c9c4Sjoerg LLVM_FALLTHROUGH;
5707330f729Sjoerg case llvm::Triple::mips64:
5717330f729Sjoerg case llvm::Triple::mips64el:
5727330f729Sjoerg case llvm::Triple::mips:
5737330f729Sjoerg case llvm::Triple::mipsel:
5747330f729Sjoerg case llvm::Triple::systemz:
5757330f729Sjoerg case llvm::Triple::x86:
5767330f729Sjoerg case llvm::Triple::x86_64:
5777330f729Sjoerg return !areOptimizationsEnabled(Args);
5787330f729Sjoerg default:
5797330f729Sjoerg return true;
5807330f729Sjoerg }
5817330f729Sjoerg }
5827330f729Sjoerg
5837330f729Sjoerg if (Triple.isOSWindows()) {
5847330f729Sjoerg switch (Triple.getArch()) {
5857330f729Sjoerg case llvm::Triple::x86:
5867330f729Sjoerg return !areOptimizationsEnabled(Args);
5877330f729Sjoerg case llvm::Triple::x86_64:
5887330f729Sjoerg return Triple.isOSBinFormatMachO();
5897330f729Sjoerg case llvm::Triple::arm:
5907330f729Sjoerg case llvm::Triple::thumb:
5917330f729Sjoerg // Windows on ARM builds with FPO disabled to aid fast stack walking
5927330f729Sjoerg return true;
5937330f729Sjoerg default:
5947330f729Sjoerg // All other supported Windows ISAs use xdata unwind information, so frame
5957330f729Sjoerg // pointers are not generally useful.
5967330f729Sjoerg return false;
5977330f729Sjoerg }
5987330f729Sjoerg }
5997330f729Sjoerg
6007330f729Sjoerg return true;
6017330f729Sjoerg }
6027330f729Sjoerg
6037330f729Sjoerg static CodeGenOptions::FramePointerKind
getFramePointerKind(const ArgList & Args,const llvm::Triple & Triple)6047330f729Sjoerg getFramePointerKind(const ArgList &Args, const llvm::Triple &Triple) {
6057330f729Sjoerg // We have 4 states:
6067330f729Sjoerg //
6077330f729Sjoerg // 00) leaf retained, non-leaf retained
6087330f729Sjoerg // 01) leaf retained, non-leaf omitted (this is invalid)
6097330f729Sjoerg // 10) leaf omitted, non-leaf retained
6107330f729Sjoerg // (what -momit-leaf-frame-pointer was designed for)
6117330f729Sjoerg // 11) leaf omitted, non-leaf omitted
6127330f729Sjoerg //
6137330f729Sjoerg // "omit" options taking precedence over "no-omit" options is the only way
6147330f729Sjoerg // to make 3 valid states representable
6157330f729Sjoerg Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
6167330f729Sjoerg options::OPT_fno_omit_frame_pointer);
6177330f729Sjoerg bool OmitFP = A && A->getOption().matches(options::OPT_fomit_frame_pointer);
6187330f729Sjoerg bool NoOmitFP =
6197330f729Sjoerg A && A->getOption().matches(options::OPT_fno_omit_frame_pointer);
620*e038c9c4Sjoerg bool OmitLeafFP = Args.hasFlag(options::OPT_momit_leaf_frame_pointer,
621*e038c9c4Sjoerg options::OPT_mno_omit_leaf_frame_pointer,
622*e038c9c4Sjoerg Triple.isAArch64() || Triple.isPS4CPU());
6237330f729Sjoerg if (NoOmitFP || mustUseNonLeafFramePointerForTarget(Triple) ||
6247330f729Sjoerg (!OmitFP && useFramePointerForTargetByDefault(Args, Triple))) {
625*e038c9c4Sjoerg if (OmitLeafFP)
6267330f729Sjoerg return CodeGenOptions::FramePointerKind::NonLeaf;
6277330f729Sjoerg return CodeGenOptions::FramePointerKind::All;
6287330f729Sjoerg }
6297330f729Sjoerg return CodeGenOptions::FramePointerKind::None;
6307330f729Sjoerg }
6317330f729Sjoerg
6327330f729Sjoerg /// Add a CC1 option to specify the debug compilation directory.
addDebugCompDirArg(const ArgList & Args,ArgStringList & CmdArgs,const llvm::vfs::FileSystem & VFS)6337330f729Sjoerg static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs,
6347330f729Sjoerg const llvm::vfs::FileSystem &VFS) {
635*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_ffile_compilation_dir_EQ,
636*e038c9c4Sjoerg options::OPT_fdebug_compilation_dir_EQ)) {
637*e038c9c4Sjoerg if (A->getOption().matches(options::OPT_ffile_compilation_dir_EQ))
638*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(Twine("-fdebug-compilation-dir=") +
639*e038c9c4Sjoerg A->getValue()));
640*e038c9c4Sjoerg else
641*e038c9c4Sjoerg A->render(Args, CmdArgs);
6427330f729Sjoerg } else if (llvm::ErrorOr<std::string> CWD =
6437330f729Sjoerg VFS.getCurrentWorkingDirectory()) {
644*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString("-fdebug-compilation-dir=" + *CWD));
6457330f729Sjoerg }
6467330f729Sjoerg }
6477330f729Sjoerg
6487330f729Sjoerg /// Add a CC1 and CC1AS option to specify the debug file path prefix map.
addDebugPrefixMapArg(const Driver & D,const ArgList & Args,ArgStringList & CmdArgs)6497330f729Sjoerg static void addDebugPrefixMapArg(const Driver &D, const ArgList &Args, ArgStringList &CmdArgs) {
650*e038c9c4Sjoerg for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ,
651*e038c9c4Sjoerg options::OPT_fdebug_prefix_map_EQ)) {
6527330f729Sjoerg StringRef Map = A->getValue();
6537330f729Sjoerg if (Map.find('=') == StringRef::npos)
654*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_argument_to_option)
655*e038c9c4Sjoerg << Map << A->getOption().getName();
6567330f729Sjoerg else
6577330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-fdebug-prefix-map=" + Map));
6587330f729Sjoerg A->claim();
6597330f729Sjoerg }
6607330f729Sjoerg }
6617330f729Sjoerg
662*e038c9c4Sjoerg /// Add a CC1 and CC1AS option to specify the macro file path prefix map.
addMacroPrefixMapArg(const Driver & D,const ArgList & Args,ArgStringList & CmdArgs)663*e038c9c4Sjoerg static void addMacroPrefixMapArg(const Driver &D, const ArgList &Args,
664*e038c9c4Sjoerg ArgStringList &CmdArgs) {
665*e038c9c4Sjoerg for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ,
666*e038c9c4Sjoerg options::OPT_fmacro_prefix_map_EQ)) {
667*e038c9c4Sjoerg StringRef Map = A->getValue();
668*e038c9c4Sjoerg if (Map.find('=') == StringRef::npos)
669*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_argument_to_option)
670*e038c9c4Sjoerg << Map << A->getOption().getName();
671*e038c9c4Sjoerg else
672*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString("-fmacro-prefix-map=" + Map));
673*e038c9c4Sjoerg A->claim();
674*e038c9c4Sjoerg }
675*e038c9c4Sjoerg }
676*e038c9c4Sjoerg
677*e038c9c4Sjoerg /// Add a CC1 and CC1AS option to specify the coverage file path prefix map.
addCoveragePrefixMapArg(const Driver & D,const ArgList & Args,ArgStringList & CmdArgs)678*e038c9c4Sjoerg static void addCoveragePrefixMapArg(const Driver &D, const ArgList &Args,
679*e038c9c4Sjoerg ArgStringList &CmdArgs) {
680*e038c9c4Sjoerg for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ,
681*e038c9c4Sjoerg options::OPT_fcoverage_prefix_map_EQ)) {
682*e038c9c4Sjoerg StringRef Map = A->getValue();
683*e038c9c4Sjoerg if (Map.find('=') == StringRef::npos)
684*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_argument_to_option)
685*e038c9c4Sjoerg << Map << A->getOption().getName();
686*e038c9c4Sjoerg else
687*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString("-fcoverage-prefix-map=" + Map));
688*e038c9c4Sjoerg A->claim();
689*e038c9c4Sjoerg }
690*e038c9c4Sjoerg }
691*e038c9c4Sjoerg
6927330f729Sjoerg /// Vectorize at all optimization levels greater than 1 except for -Oz.
6937330f729Sjoerg /// For -Oz the loop vectorizer is disabled, while the slp vectorizer is
6947330f729Sjoerg /// enabled.
shouldEnableVectorizerAtOLevel(const ArgList & Args,bool isSlpVec)6957330f729Sjoerg static bool shouldEnableVectorizerAtOLevel(const ArgList &Args, bool isSlpVec) {
6967330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
6977330f729Sjoerg if (A->getOption().matches(options::OPT_O4) ||
6987330f729Sjoerg A->getOption().matches(options::OPT_Ofast))
6997330f729Sjoerg return true;
7007330f729Sjoerg
7017330f729Sjoerg if (A->getOption().matches(options::OPT_O0))
7027330f729Sjoerg return false;
7037330f729Sjoerg
7047330f729Sjoerg assert(A->getOption().matches(options::OPT_O) && "Must have a -O flag");
7057330f729Sjoerg
7067330f729Sjoerg // Vectorize -Os.
7077330f729Sjoerg StringRef S(A->getValue());
7087330f729Sjoerg if (S == "s")
7097330f729Sjoerg return true;
7107330f729Sjoerg
7117330f729Sjoerg // Don't vectorize -Oz, unless it's the slp vectorizer.
7127330f729Sjoerg if (S == "z")
7137330f729Sjoerg return isSlpVec;
7147330f729Sjoerg
7157330f729Sjoerg unsigned OptLevel = 0;
7167330f729Sjoerg if (S.getAsInteger(10, OptLevel))
7177330f729Sjoerg return false;
7187330f729Sjoerg
7197330f729Sjoerg return OptLevel > 1;
7207330f729Sjoerg }
7217330f729Sjoerg
7227330f729Sjoerg return false;
7237330f729Sjoerg }
7247330f729Sjoerg
7257330f729Sjoerg /// Add -x lang to \p CmdArgs for \p Input.
addDashXForInput(const ArgList & Args,const InputInfo & Input,ArgStringList & CmdArgs)7267330f729Sjoerg static void addDashXForInput(const ArgList &Args, const InputInfo &Input,
7277330f729Sjoerg ArgStringList &CmdArgs) {
7287330f729Sjoerg // When using -verify-pch, we don't want to provide the type
7297330f729Sjoerg // 'precompiled-header' if it was inferred from the file extension
7307330f729Sjoerg if (Args.hasArg(options::OPT_verify_pch) && Input.getType() == types::TY_PCH)
7317330f729Sjoerg return;
7327330f729Sjoerg
7337330f729Sjoerg CmdArgs.push_back("-x");
7347330f729Sjoerg if (Args.hasArg(options::OPT_rewrite_objc))
7357330f729Sjoerg CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX));
7367330f729Sjoerg else {
7377330f729Sjoerg // Map the driver type to the frontend type. This is mostly an identity
7387330f729Sjoerg // mapping, except that the distinction between module interface units
7397330f729Sjoerg // and other source files does not exist at the frontend layer.
7407330f729Sjoerg const char *ClangType;
7417330f729Sjoerg switch (Input.getType()) {
7427330f729Sjoerg case types::TY_CXXModule:
7437330f729Sjoerg ClangType = "c++";
7447330f729Sjoerg break;
7457330f729Sjoerg case types::TY_PP_CXXModule:
7467330f729Sjoerg ClangType = "c++-cpp-output";
7477330f729Sjoerg break;
7487330f729Sjoerg default:
7497330f729Sjoerg ClangType = types::getTypeName(Input.getType());
7507330f729Sjoerg break;
7517330f729Sjoerg }
7527330f729Sjoerg CmdArgs.push_back(ClangType);
7537330f729Sjoerg }
7547330f729Sjoerg }
7557330f729Sjoerg
addPGOAndCoverageFlags(const ToolChain & TC,Compilation & C,const Driver & D,const InputInfo & Output,const ArgList & Args,ArgStringList & CmdArgs)7567330f729Sjoerg static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C,
7577330f729Sjoerg const Driver &D, const InputInfo &Output,
7587330f729Sjoerg const ArgList &Args,
7597330f729Sjoerg ArgStringList &CmdArgs) {
7607330f729Sjoerg
7617330f729Sjoerg auto *PGOGenerateArg = Args.getLastArg(options::OPT_fprofile_generate,
7627330f729Sjoerg options::OPT_fprofile_generate_EQ,
7637330f729Sjoerg options::OPT_fno_profile_generate);
7647330f729Sjoerg if (PGOGenerateArg &&
7657330f729Sjoerg PGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate))
7667330f729Sjoerg PGOGenerateArg = nullptr;
7677330f729Sjoerg
7687330f729Sjoerg auto *CSPGOGenerateArg = Args.getLastArg(options::OPT_fcs_profile_generate,
7697330f729Sjoerg options::OPT_fcs_profile_generate_EQ,
7707330f729Sjoerg options::OPT_fno_profile_generate);
7717330f729Sjoerg if (CSPGOGenerateArg &&
7727330f729Sjoerg CSPGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate))
7737330f729Sjoerg CSPGOGenerateArg = nullptr;
7747330f729Sjoerg
7757330f729Sjoerg auto *ProfileGenerateArg = Args.getLastArg(
7767330f729Sjoerg options::OPT_fprofile_instr_generate,
7777330f729Sjoerg options::OPT_fprofile_instr_generate_EQ,
7787330f729Sjoerg options::OPT_fno_profile_instr_generate);
7797330f729Sjoerg if (ProfileGenerateArg &&
7807330f729Sjoerg ProfileGenerateArg->getOption().matches(
7817330f729Sjoerg options::OPT_fno_profile_instr_generate))
7827330f729Sjoerg ProfileGenerateArg = nullptr;
7837330f729Sjoerg
7847330f729Sjoerg if (PGOGenerateArg && ProfileGenerateArg)
7857330f729Sjoerg D.Diag(diag::err_drv_argument_not_allowed_with)
7867330f729Sjoerg << PGOGenerateArg->getSpelling() << ProfileGenerateArg->getSpelling();
7877330f729Sjoerg
7887330f729Sjoerg auto *ProfileUseArg = getLastProfileUseArg(Args);
7897330f729Sjoerg
7907330f729Sjoerg if (PGOGenerateArg && ProfileUseArg)
7917330f729Sjoerg D.Diag(diag::err_drv_argument_not_allowed_with)
7927330f729Sjoerg << ProfileUseArg->getSpelling() << PGOGenerateArg->getSpelling();
7937330f729Sjoerg
7947330f729Sjoerg if (ProfileGenerateArg && ProfileUseArg)
7957330f729Sjoerg D.Diag(diag::err_drv_argument_not_allowed_with)
7967330f729Sjoerg << ProfileGenerateArg->getSpelling() << ProfileUseArg->getSpelling();
7977330f729Sjoerg
798*e038c9c4Sjoerg if (CSPGOGenerateArg && PGOGenerateArg) {
7997330f729Sjoerg D.Diag(diag::err_drv_argument_not_allowed_with)
8007330f729Sjoerg << CSPGOGenerateArg->getSpelling() << PGOGenerateArg->getSpelling();
801*e038c9c4Sjoerg PGOGenerateArg = nullptr;
802*e038c9c4Sjoerg }
8037330f729Sjoerg
8047330f729Sjoerg if (ProfileGenerateArg) {
8057330f729Sjoerg if (ProfileGenerateArg->getOption().matches(
8067330f729Sjoerg options::OPT_fprofile_instr_generate_EQ))
8077330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(Twine("-fprofile-instrument-path=") +
8087330f729Sjoerg ProfileGenerateArg->getValue()));
8097330f729Sjoerg // The default is to use Clang Instrumentation.
8107330f729Sjoerg CmdArgs.push_back("-fprofile-instrument=clang");
8117330f729Sjoerg if (TC.getTriple().isWindowsMSVCEnvironment()) {
8127330f729Sjoerg // Add dependent lib for clang_rt.profile
813*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(
814*e038c9c4Sjoerg "--dependent-lib=" + TC.getCompilerRTBasename(Args, "profile")));
8157330f729Sjoerg }
8167330f729Sjoerg }
8177330f729Sjoerg
8187330f729Sjoerg Arg *PGOGenArg = nullptr;
8197330f729Sjoerg if (PGOGenerateArg) {
8207330f729Sjoerg assert(!CSPGOGenerateArg);
8217330f729Sjoerg PGOGenArg = PGOGenerateArg;
8227330f729Sjoerg CmdArgs.push_back("-fprofile-instrument=llvm");
8237330f729Sjoerg }
8247330f729Sjoerg if (CSPGOGenerateArg) {
8257330f729Sjoerg assert(!PGOGenerateArg);
8267330f729Sjoerg PGOGenArg = CSPGOGenerateArg;
8277330f729Sjoerg CmdArgs.push_back("-fprofile-instrument=csllvm");
8287330f729Sjoerg }
8297330f729Sjoerg if (PGOGenArg) {
8307330f729Sjoerg if (TC.getTriple().isWindowsMSVCEnvironment()) {
831*e038c9c4Sjoerg // Add dependent lib for clang_rt.profile
832*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(
833*e038c9c4Sjoerg "--dependent-lib=" + TC.getCompilerRTBasename(Args, "profile")));
8347330f729Sjoerg }
8357330f729Sjoerg if (PGOGenArg->getOption().matches(
8367330f729Sjoerg PGOGenerateArg ? options::OPT_fprofile_generate_EQ
8377330f729Sjoerg : options::OPT_fcs_profile_generate_EQ)) {
8387330f729Sjoerg SmallString<128> Path(PGOGenArg->getValue());
8397330f729Sjoerg llvm::sys::path::append(Path, "default_%m.profraw");
8407330f729Sjoerg CmdArgs.push_back(
8417330f729Sjoerg Args.MakeArgString(Twine("-fprofile-instrument-path=") + Path));
8427330f729Sjoerg }
8437330f729Sjoerg }
8447330f729Sjoerg
8457330f729Sjoerg if (ProfileUseArg) {
8467330f729Sjoerg if (ProfileUseArg->getOption().matches(options::OPT_fprofile_instr_use_EQ))
8477330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(
8487330f729Sjoerg Twine("-fprofile-instrument-use-path=") + ProfileUseArg->getValue()));
8497330f729Sjoerg else if ((ProfileUseArg->getOption().matches(
8507330f729Sjoerg options::OPT_fprofile_use_EQ) ||
8517330f729Sjoerg ProfileUseArg->getOption().matches(
8527330f729Sjoerg options::OPT_fprofile_instr_use))) {
8537330f729Sjoerg SmallString<128> Path(
8547330f729Sjoerg ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue());
8557330f729Sjoerg if (Path.empty() || llvm::sys::fs::is_directory(Path))
8567330f729Sjoerg llvm::sys::path::append(Path, "default.profdata");
8577330f729Sjoerg CmdArgs.push_back(
8587330f729Sjoerg Args.MakeArgString(Twine("-fprofile-instrument-use-path=") + Path));
8597330f729Sjoerg }
8607330f729Sjoerg }
8617330f729Sjoerg
862*e038c9c4Sjoerg bool EmitCovNotes = Args.hasFlag(options::OPT_ftest_coverage,
863*e038c9c4Sjoerg options::OPT_fno_test_coverage, false) ||
8647330f729Sjoerg Args.hasArg(options::OPT_coverage);
865*e038c9c4Sjoerg bool EmitCovData = TC.needsGCovInstrumentation(Args);
8667330f729Sjoerg if (EmitCovNotes)
867*e038c9c4Sjoerg CmdArgs.push_back("-ftest-coverage");
8687330f729Sjoerg if (EmitCovData)
869*e038c9c4Sjoerg CmdArgs.push_back("-fprofile-arcs");
8707330f729Sjoerg
8717330f729Sjoerg if (Args.hasFlag(options::OPT_fcoverage_mapping,
8727330f729Sjoerg options::OPT_fno_coverage_mapping, false)) {
8737330f729Sjoerg if (!ProfileGenerateArg)
8747330f729Sjoerg D.Diag(clang::diag::err_drv_argument_only_allowed_with)
8757330f729Sjoerg << "-fcoverage-mapping"
8767330f729Sjoerg << "-fprofile-instr-generate";
8777330f729Sjoerg
8787330f729Sjoerg CmdArgs.push_back("-fcoverage-mapping");
8797330f729Sjoerg }
8807330f729Sjoerg
881*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_ffile_compilation_dir_EQ,
882*e038c9c4Sjoerg options::OPT_fcoverage_compilation_dir_EQ)) {
883*e038c9c4Sjoerg if (A->getOption().matches(options::OPT_ffile_compilation_dir_EQ))
884*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(
885*e038c9c4Sjoerg Twine("-fcoverage-compilation-dir=") + A->getValue()));
886*e038c9c4Sjoerg else
887*e038c9c4Sjoerg A->render(Args, CmdArgs);
888*e038c9c4Sjoerg } else if (llvm::ErrorOr<std::string> CWD =
889*e038c9c4Sjoerg D.getVFS().getCurrentWorkingDirectory()) {
890*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString("-fcoverage-compilation-dir=" + *CWD));
891*e038c9c4Sjoerg }
892*e038c9c4Sjoerg
8937330f729Sjoerg if (Args.hasArg(options::OPT_fprofile_exclude_files_EQ)) {
8947330f729Sjoerg auto *Arg = Args.getLastArg(options::OPT_fprofile_exclude_files_EQ);
8957330f729Sjoerg if (!Args.hasArg(options::OPT_coverage))
8967330f729Sjoerg D.Diag(clang::diag::err_drv_argument_only_allowed_with)
8977330f729Sjoerg << "-fprofile-exclude-files="
8987330f729Sjoerg << "--coverage";
8997330f729Sjoerg
9007330f729Sjoerg StringRef v = Arg->getValue();
9017330f729Sjoerg CmdArgs.push_back(
9027330f729Sjoerg Args.MakeArgString(Twine("-fprofile-exclude-files=" + v)));
9037330f729Sjoerg }
9047330f729Sjoerg
9057330f729Sjoerg if (Args.hasArg(options::OPT_fprofile_filter_files_EQ)) {
9067330f729Sjoerg auto *Arg = Args.getLastArg(options::OPT_fprofile_filter_files_EQ);
9077330f729Sjoerg if (!Args.hasArg(options::OPT_coverage))
9087330f729Sjoerg D.Diag(clang::diag::err_drv_argument_only_allowed_with)
9097330f729Sjoerg << "-fprofile-filter-files="
9107330f729Sjoerg << "--coverage";
9117330f729Sjoerg
9127330f729Sjoerg StringRef v = Arg->getValue();
9137330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(Twine("-fprofile-filter-files=" + v)));
9147330f729Sjoerg }
9157330f729Sjoerg
916*e038c9c4Sjoerg if (const auto *A = Args.getLastArg(options::OPT_fprofile_update_EQ)) {
917*e038c9c4Sjoerg StringRef Val = A->getValue();
918*e038c9c4Sjoerg if (Val == "atomic" || Val == "prefer-atomic")
919*e038c9c4Sjoerg CmdArgs.push_back("-fprofile-update=atomic");
920*e038c9c4Sjoerg else if (Val != "single")
921*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_option_argument)
922*e038c9c4Sjoerg << A->getOption().getName() << Val;
923*e038c9c4Sjoerg } else if (TC.getSanitizerArgs().needsTsanRt()) {
924*e038c9c4Sjoerg CmdArgs.push_back("-fprofile-update=atomic");
925*e038c9c4Sjoerg }
926*e038c9c4Sjoerg
9277330f729Sjoerg // Leave -fprofile-dir= an unused argument unless .gcda emission is
9287330f729Sjoerg // enabled. To be polite, with '-fprofile-arcs -fno-profile-arcs' consider
9297330f729Sjoerg // the flag used. There is no -fno-profile-dir, so the user has no
9307330f729Sjoerg // targeted way to suppress the warning.
9317330f729Sjoerg Arg *FProfileDir = nullptr;
9327330f729Sjoerg if (Args.hasArg(options::OPT_fprofile_arcs) ||
9337330f729Sjoerg Args.hasArg(options::OPT_coverage))
9347330f729Sjoerg FProfileDir = Args.getLastArg(options::OPT_fprofile_dir);
9357330f729Sjoerg
9367330f729Sjoerg // Put the .gcno and .gcda files (if needed) next to the object file or
9377330f729Sjoerg // bitcode file in the case of LTO.
9387330f729Sjoerg // FIXME: There should be a simpler way to find the object file for this
9397330f729Sjoerg // input, and this code probably does the wrong thing for commands that
9407330f729Sjoerg // compile and link all at once.
9417330f729Sjoerg if ((Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S)) &&
9427330f729Sjoerg (EmitCovNotes || EmitCovData) && Output.isFilename()) {
9437330f729Sjoerg SmallString<128> OutputFilename;
944*e038c9c4Sjoerg if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT__SLASH_Fo))
945*e038c9c4Sjoerg OutputFilename = FinalOutput->getValue();
946*e038c9c4Sjoerg else if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
9477330f729Sjoerg OutputFilename = FinalOutput->getValue();
9487330f729Sjoerg else
9497330f729Sjoerg OutputFilename = llvm::sys::path::filename(Output.getBaseInput());
9507330f729Sjoerg SmallString<128> CoverageFilename = OutputFilename;
9517330f729Sjoerg if (llvm::sys::path::is_relative(CoverageFilename))
9527330f729Sjoerg (void)D.getVFS().makeAbsolute(CoverageFilename);
9537330f729Sjoerg llvm::sys::path::replace_extension(CoverageFilename, "gcno");
9547330f729Sjoerg
9557330f729Sjoerg CmdArgs.push_back("-coverage-notes-file");
9567330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(CoverageFilename));
9577330f729Sjoerg
9587330f729Sjoerg if (EmitCovData) {
9597330f729Sjoerg if (FProfileDir) {
9607330f729Sjoerg CoverageFilename = FProfileDir->getValue();
9617330f729Sjoerg llvm::sys::path::append(CoverageFilename, OutputFilename);
9627330f729Sjoerg }
9637330f729Sjoerg llvm::sys::path::replace_extension(CoverageFilename, "gcda");
9647330f729Sjoerg CmdArgs.push_back("-coverage-data-file");
9657330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(CoverageFilename));
9667330f729Sjoerg }
9677330f729Sjoerg }
9687330f729Sjoerg }
9697330f729Sjoerg
9707330f729Sjoerg /// Check whether the given input tree contains any compilation actions.
ContainsCompileAction(const Action * A)9717330f729Sjoerg static bool ContainsCompileAction(const Action *A) {
9727330f729Sjoerg if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A))
9737330f729Sjoerg return true;
9747330f729Sjoerg
9757330f729Sjoerg for (const auto &AI : A->inputs())
9767330f729Sjoerg if (ContainsCompileAction(AI))
9777330f729Sjoerg return true;
9787330f729Sjoerg
9797330f729Sjoerg return false;
9807330f729Sjoerg }
9817330f729Sjoerg
9827330f729Sjoerg /// Check if -relax-all should be passed to the internal assembler.
9837330f729Sjoerg /// This is done by default when compiling non-assembler source with -O0.
UseRelaxAll(Compilation & C,const ArgList & Args)9847330f729Sjoerg static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
9857330f729Sjoerg bool RelaxDefault = true;
9867330f729Sjoerg
9877330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_O_Group))
9887330f729Sjoerg RelaxDefault = A->getOption().matches(options::OPT_O0);
9897330f729Sjoerg
9907330f729Sjoerg if (RelaxDefault) {
9917330f729Sjoerg RelaxDefault = false;
9927330f729Sjoerg for (const auto &Act : C.getActions()) {
9937330f729Sjoerg if (ContainsCompileAction(Act)) {
9947330f729Sjoerg RelaxDefault = true;
9957330f729Sjoerg break;
9967330f729Sjoerg }
9977330f729Sjoerg }
9987330f729Sjoerg }
9997330f729Sjoerg
10007330f729Sjoerg return Args.hasFlag(options::OPT_mrelax_all, options::OPT_mno_relax_all,
10017330f729Sjoerg RelaxDefault);
10027330f729Sjoerg }
10037330f729Sjoerg
10047330f729Sjoerg // Extract the integer N from a string spelled "-dwarf-N", returning 0
10057330f729Sjoerg // on mismatch. The StringRef input (rather than an Arg) allows
10067330f729Sjoerg // for use by the "-Xassembler" option parser.
DwarfVersionNum(StringRef ArgValue)10077330f729Sjoerg static unsigned DwarfVersionNum(StringRef ArgValue) {
10087330f729Sjoerg return llvm::StringSwitch<unsigned>(ArgValue)
10097330f729Sjoerg .Case("-gdwarf-2", 2)
10107330f729Sjoerg .Case("-gdwarf-3", 3)
10117330f729Sjoerg .Case("-gdwarf-4", 4)
10127330f729Sjoerg .Case("-gdwarf-5", 5)
10137330f729Sjoerg .Default(0);
10147330f729Sjoerg }
10157330f729Sjoerg
1016*e038c9c4Sjoerg // Find a DWARF format version option.
1017*e038c9c4Sjoerg // This function is a complementary for DwarfVersionNum().
getDwarfNArg(const ArgList & Args)1018*e038c9c4Sjoerg static const Arg *getDwarfNArg(const ArgList &Args) {
1019*e038c9c4Sjoerg return Args.getLastArg(options::OPT_gdwarf_2, options::OPT_gdwarf_3,
1020*e038c9c4Sjoerg options::OPT_gdwarf_4, options::OPT_gdwarf_5,
1021*e038c9c4Sjoerg options::OPT_gdwarf);
1022*e038c9c4Sjoerg }
1023*e038c9c4Sjoerg
RenderDebugEnablingArgs(const ArgList & Args,ArgStringList & CmdArgs,codegenoptions::DebugInfoKind DebugInfoKind,unsigned DwarfVersion,llvm::DebuggerKind DebuggerTuning)10247330f729Sjoerg static void RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs,
10257330f729Sjoerg codegenoptions::DebugInfoKind DebugInfoKind,
10267330f729Sjoerg unsigned DwarfVersion,
10277330f729Sjoerg llvm::DebuggerKind DebuggerTuning) {
10287330f729Sjoerg switch (DebugInfoKind) {
10297330f729Sjoerg case codegenoptions::DebugDirectivesOnly:
10307330f729Sjoerg CmdArgs.push_back("-debug-info-kind=line-directives-only");
10317330f729Sjoerg break;
10327330f729Sjoerg case codegenoptions::DebugLineTablesOnly:
10337330f729Sjoerg CmdArgs.push_back("-debug-info-kind=line-tables-only");
10347330f729Sjoerg break;
1035*e038c9c4Sjoerg case codegenoptions::DebugInfoConstructor:
1036*e038c9c4Sjoerg CmdArgs.push_back("-debug-info-kind=constructor");
1037*e038c9c4Sjoerg break;
10387330f729Sjoerg case codegenoptions::LimitedDebugInfo:
10397330f729Sjoerg CmdArgs.push_back("-debug-info-kind=limited");
10407330f729Sjoerg break;
10417330f729Sjoerg case codegenoptions::FullDebugInfo:
10427330f729Sjoerg CmdArgs.push_back("-debug-info-kind=standalone");
10437330f729Sjoerg break;
1044*e038c9c4Sjoerg case codegenoptions::UnusedTypeInfo:
1045*e038c9c4Sjoerg CmdArgs.push_back("-debug-info-kind=unused-types");
1046*e038c9c4Sjoerg break;
10477330f729Sjoerg default:
10487330f729Sjoerg break;
10497330f729Sjoerg }
10507330f729Sjoerg if (DwarfVersion > 0)
10517330f729Sjoerg CmdArgs.push_back(
10527330f729Sjoerg Args.MakeArgString("-dwarf-version=" + Twine(DwarfVersion)));
10537330f729Sjoerg switch (DebuggerTuning) {
10547330f729Sjoerg case llvm::DebuggerKind::GDB:
10557330f729Sjoerg CmdArgs.push_back("-debugger-tuning=gdb");
10567330f729Sjoerg break;
10577330f729Sjoerg case llvm::DebuggerKind::LLDB:
10587330f729Sjoerg CmdArgs.push_back("-debugger-tuning=lldb");
10597330f729Sjoerg break;
10607330f729Sjoerg case llvm::DebuggerKind::SCE:
10617330f729Sjoerg CmdArgs.push_back("-debugger-tuning=sce");
10627330f729Sjoerg break;
1063*e038c9c4Sjoerg case llvm::DebuggerKind::DBX:
1064*e038c9c4Sjoerg CmdArgs.push_back("-debugger-tuning=dbx");
1065*e038c9c4Sjoerg break;
10667330f729Sjoerg default:
10677330f729Sjoerg break;
10687330f729Sjoerg }
10697330f729Sjoerg }
10707330f729Sjoerg
checkDebugInfoOption(const Arg * A,const ArgList & Args,const Driver & D,const ToolChain & TC)10717330f729Sjoerg static bool checkDebugInfoOption(const Arg *A, const ArgList &Args,
10727330f729Sjoerg const Driver &D, const ToolChain &TC) {
10737330f729Sjoerg assert(A && "Expected non-nullptr argument.");
10747330f729Sjoerg if (TC.supportsDebugInfoOption(A))
10757330f729Sjoerg return true;
10767330f729Sjoerg D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target)
10777330f729Sjoerg << A->getAsString(Args) << TC.getTripleString();
10787330f729Sjoerg return false;
10797330f729Sjoerg }
10807330f729Sjoerg
RenderDebugInfoCompressionArgs(const ArgList & Args,ArgStringList & CmdArgs,const Driver & D,const ToolChain & TC)10817330f729Sjoerg static void RenderDebugInfoCompressionArgs(const ArgList &Args,
10827330f729Sjoerg ArgStringList &CmdArgs,
10837330f729Sjoerg const Driver &D,
10847330f729Sjoerg const ToolChain &TC) {
1085*e038c9c4Sjoerg const Arg *A = Args.getLastArg(options::OPT_gz_EQ);
10867330f729Sjoerg if (!A)
10877330f729Sjoerg return;
10887330f729Sjoerg if (checkDebugInfoOption(A, Args, D, TC)) {
10897330f729Sjoerg StringRef Value = A->getValue();
10907330f729Sjoerg if (Value == "none") {
10917330f729Sjoerg CmdArgs.push_back("--compress-debug-sections=none");
10927330f729Sjoerg } else if (Value == "zlib" || Value == "zlib-gnu") {
10937330f729Sjoerg if (llvm::zlib::isAvailable()) {
10947330f729Sjoerg CmdArgs.push_back(
10957330f729Sjoerg Args.MakeArgString("--compress-debug-sections=" + Twine(Value)));
10967330f729Sjoerg } else {
10977330f729Sjoerg D.Diag(diag::warn_debug_compression_unavailable);
10987330f729Sjoerg }
10997330f729Sjoerg } else {
11007330f729Sjoerg D.Diag(diag::err_drv_unsupported_option_argument)
11017330f729Sjoerg << A->getOption().getName() << Value;
11027330f729Sjoerg }
11037330f729Sjoerg }
11047330f729Sjoerg }
11057330f729Sjoerg
RelocationModelName(llvm::Reloc::Model Model)11067330f729Sjoerg static const char *RelocationModelName(llvm::Reloc::Model Model) {
11077330f729Sjoerg switch (Model) {
11087330f729Sjoerg case llvm::Reloc::Static:
11097330f729Sjoerg return "static";
11107330f729Sjoerg case llvm::Reloc::PIC_:
11117330f729Sjoerg return "pic";
11127330f729Sjoerg case llvm::Reloc::DynamicNoPIC:
11137330f729Sjoerg return "dynamic-no-pic";
11147330f729Sjoerg case llvm::Reloc::ROPI:
11157330f729Sjoerg return "ropi";
11167330f729Sjoerg case llvm::Reloc::RWPI:
11177330f729Sjoerg return "rwpi";
11187330f729Sjoerg case llvm::Reloc::ROPI_RWPI:
11197330f729Sjoerg return "ropi-rwpi";
11207330f729Sjoerg }
11217330f729Sjoerg llvm_unreachable("Unknown Reloc::Model kind");
11227330f729Sjoerg }
handleAMDGPUCodeObjectVersionOptions(const Driver & D,const ArgList & Args,ArgStringList & CmdArgs)1123*e038c9c4Sjoerg static void handleAMDGPUCodeObjectVersionOptions(const Driver &D,
1124*e038c9c4Sjoerg const ArgList &Args,
1125*e038c9c4Sjoerg ArgStringList &CmdArgs) {
1126*e038c9c4Sjoerg // If no version was requested by the user, use the default value from the
1127*e038c9c4Sjoerg // back end. This is consistent with the value returned from
1128*e038c9c4Sjoerg // getAMDGPUCodeObjectVersion. This lets clang emit IR for amdgpu without
1129*e038c9c4Sjoerg // requiring the corresponding llvm to have the AMDGPU target enabled,
1130*e038c9c4Sjoerg // provided the user (e.g. front end tests) can use the default.
1131*e038c9c4Sjoerg if (haveAMDGPUCodeObjectVersionArgument(D, Args)) {
1132*e038c9c4Sjoerg unsigned CodeObjVer = getAMDGPUCodeObjectVersion(D, Args);
1133*e038c9c4Sjoerg CmdArgs.insert(CmdArgs.begin() + 1,
1134*e038c9c4Sjoerg Args.MakeArgString(Twine("--amdhsa-code-object-version=") +
1135*e038c9c4Sjoerg Twine(CodeObjVer)));
1136*e038c9c4Sjoerg CmdArgs.insert(CmdArgs.begin() + 1, "-mllvm");
1137*e038c9c4Sjoerg }
1138*e038c9c4Sjoerg }
11397330f729Sjoerg
AddPreprocessingOptions(Compilation & C,const JobAction & JA,const Driver & D,const ArgList & Args,ArgStringList & CmdArgs,const InputInfo & Output,const InputInfoList & Inputs) const11407330f729Sjoerg void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
11417330f729Sjoerg const Driver &D, const ArgList &Args,
11427330f729Sjoerg ArgStringList &CmdArgs,
11437330f729Sjoerg const InputInfo &Output,
11447330f729Sjoerg const InputInfoList &Inputs) const {
11457330f729Sjoerg const bool IsIAMCU = getToolChain().getTriple().isOSIAMCU();
11467330f729Sjoerg
11477330f729Sjoerg CheckPreprocessingOptions(D, Args);
11487330f729Sjoerg
11497330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_C);
11507330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_CC);
11517330f729Sjoerg
11527330f729Sjoerg // Handle dependency file generation.
11537330f729Sjoerg Arg *ArgM = Args.getLastArg(options::OPT_MM);
11547330f729Sjoerg if (!ArgM)
11557330f729Sjoerg ArgM = Args.getLastArg(options::OPT_M);
11567330f729Sjoerg Arg *ArgMD = Args.getLastArg(options::OPT_MMD);
11577330f729Sjoerg if (!ArgMD)
11587330f729Sjoerg ArgMD = Args.getLastArg(options::OPT_MD);
11597330f729Sjoerg
11607330f729Sjoerg // -M and -MM imply -w.
11617330f729Sjoerg if (ArgM)
11627330f729Sjoerg CmdArgs.push_back("-w");
11637330f729Sjoerg else
11647330f729Sjoerg ArgM = ArgMD;
11657330f729Sjoerg
11667330f729Sjoerg if (ArgM) {
11677330f729Sjoerg // Determine the output location.
11687330f729Sjoerg const char *DepFile;
11697330f729Sjoerg if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
11707330f729Sjoerg DepFile = MF->getValue();
11717330f729Sjoerg C.addFailureResultFile(DepFile, &JA);
11727330f729Sjoerg } else if (Output.getType() == types::TY_Dependencies) {
11737330f729Sjoerg DepFile = Output.getFilename();
11747330f729Sjoerg } else if (!ArgMD) {
11757330f729Sjoerg DepFile = "-";
11767330f729Sjoerg } else {
11777330f729Sjoerg DepFile = getDependencyFileName(Args, Inputs);
11787330f729Sjoerg C.addFailureResultFile(DepFile, &JA);
11797330f729Sjoerg }
11807330f729Sjoerg CmdArgs.push_back("-dependency-file");
11817330f729Sjoerg CmdArgs.push_back(DepFile);
11827330f729Sjoerg
11837330f729Sjoerg bool HasTarget = false;
11847330f729Sjoerg for (const Arg *A : Args.filtered(options::OPT_MT, options::OPT_MQ)) {
11857330f729Sjoerg HasTarget = true;
11867330f729Sjoerg A->claim();
11877330f729Sjoerg if (A->getOption().matches(options::OPT_MT)) {
11887330f729Sjoerg A->render(Args, CmdArgs);
11897330f729Sjoerg } else {
11907330f729Sjoerg CmdArgs.push_back("-MT");
11917330f729Sjoerg SmallString<128> Quoted;
11927330f729Sjoerg QuoteTarget(A->getValue(), Quoted);
11937330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(Quoted));
11947330f729Sjoerg }
11957330f729Sjoerg }
11967330f729Sjoerg
11977330f729Sjoerg // Add a default target if one wasn't specified.
11987330f729Sjoerg if (!HasTarget) {
11997330f729Sjoerg const char *DepTarget;
12007330f729Sjoerg
12017330f729Sjoerg // If user provided -o, that is the dependency target, except
12027330f729Sjoerg // when we are only generating a dependency file.
12037330f729Sjoerg Arg *OutputOpt = Args.getLastArg(options::OPT_o);
12047330f729Sjoerg if (OutputOpt && Output.getType() != types::TY_Dependencies) {
12057330f729Sjoerg DepTarget = OutputOpt->getValue();
12067330f729Sjoerg } else {
12077330f729Sjoerg // Otherwise derive from the base input.
12087330f729Sjoerg //
12097330f729Sjoerg // FIXME: This should use the computed output file location.
12107330f729Sjoerg SmallString<128> P(Inputs[0].getBaseInput());
12117330f729Sjoerg llvm::sys::path::replace_extension(P, "o");
12127330f729Sjoerg DepTarget = Args.MakeArgString(llvm::sys::path::filename(P));
12137330f729Sjoerg }
12147330f729Sjoerg
12157330f729Sjoerg CmdArgs.push_back("-MT");
12167330f729Sjoerg SmallString<128> Quoted;
12177330f729Sjoerg QuoteTarget(DepTarget, Quoted);
12187330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(Quoted));
12197330f729Sjoerg }
12207330f729Sjoerg
12217330f729Sjoerg if (ArgM->getOption().matches(options::OPT_M) ||
12227330f729Sjoerg ArgM->getOption().matches(options::OPT_MD))
12237330f729Sjoerg CmdArgs.push_back("-sys-header-deps");
12247330f729Sjoerg if ((isa<PrecompileJobAction>(JA) &&
12257330f729Sjoerg !Args.hasArg(options::OPT_fno_module_file_deps)) ||
12267330f729Sjoerg Args.hasArg(options::OPT_fmodule_file_deps))
12277330f729Sjoerg CmdArgs.push_back("-module-file-deps");
12287330f729Sjoerg }
12297330f729Sjoerg
12307330f729Sjoerg if (Args.hasArg(options::OPT_MG)) {
12317330f729Sjoerg if (!ArgM || ArgM->getOption().matches(options::OPT_MD) ||
12327330f729Sjoerg ArgM->getOption().matches(options::OPT_MMD))
12337330f729Sjoerg D.Diag(diag::err_drv_mg_requires_m_or_mm);
12347330f729Sjoerg CmdArgs.push_back("-MG");
12357330f729Sjoerg }
12367330f729Sjoerg
12377330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_MP);
12387330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_MV);
12397330f729Sjoerg
1240*e038c9c4Sjoerg // Add offload include arguments specific for CUDA/HIP. This must happen
1241*e038c9c4Sjoerg // before we -I or -include anything else, because we must pick up the
1242*e038c9c4Sjoerg // CUDA/HIP headers from the particular CUDA/ROCm installation, rather than
1243*e038c9c4Sjoerg // from e.g. /usr/local/include.
12447330f729Sjoerg if (JA.isOffloading(Action::OFK_Cuda))
12457330f729Sjoerg getToolChain().AddCudaIncludeArgs(Args, CmdArgs);
1246*e038c9c4Sjoerg if (JA.isOffloading(Action::OFK_HIP))
1247*e038c9c4Sjoerg getToolChain().AddHIPIncludeArgs(Args, CmdArgs);
12487330f729Sjoerg
12497330f729Sjoerg // If we are offloading to a target via OpenMP we need to include the
12507330f729Sjoerg // openmp_wrappers folder which contains alternative system headers.
12517330f729Sjoerg if (JA.isDeviceOffloading(Action::OFK_OpenMP) &&
12527330f729Sjoerg getToolChain().getTriple().isNVPTX()){
12537330f729Sjoerg if (!Args.hasArg(options::OPT_nobuiltininc)) {
12547330f729Sjoerg // Add openmp_wrappers/* to our system include path. This lets us wrap
12557330f729Sjoerg // standard library headers.
12567330f729Sjoerg SmallString<128> P(D.ResourceDir);
12577330f729Sjoerg llvm::sys::path::append(P, "include");
12587330f729Sjoerg llvm::sys::path::append(P, "openmp_wrappers");
12597330f729Sjoerg CmdArgs.push_back("-internal-isystem");
12607330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(P));
12617330f729Sjoerg }
12627330f729Sjoerg
12637330f729Sjoerg CmdArgs.push_back("-include");
1264*e038c9c4Sjoerg CmdArgs.push_back("__clang_openmp_device_functions.h");
12657330f729Sjoerg }
12667330f729Sjoerg
12677330f729Sjoerg // Add -i* options, and automatically translate to
12687330f729Sjoerg // -include-pch/-include-pth for transparent PCH support. It's
12697330f729Sjoerg // wonky, but we include looking for .gch so we can support seamless
12707330f729Sjoerg // replacement into a build system already set up to be generating
12717330f729Sjoerg // .gch files.
12727330f729Sjoerg
12737330f729Sjoerg if (getToolChain().getDriver().IsCLMode()) {
12747330f729Sjoerg const Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
12757330f729Sjoerg const Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
12767330f729Sjoerg if (YcArg && JA.getKind() >= Action::PrecompileJobClass &&
12777330f729Sjoerg JA.getKind() <= Action::AssembleJobClass) {
12787330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-building-pch-with-obj"));
1279*e038c9c4Sjoerg // -fpch-instantiate-templates is the default when creating
1280*e038c9c4Sjoerg // precomp using /Yc
1281*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fpch_instantiate_templates,
1282*e038c9c4Sjoerg options::OPT_fno_pch_instantiate_templates, true))
1283*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString("-fpch-instantiate-templates"));
12847330f729Sjoerg }
12857330f729Sjoerg if (YcArg || YuArg) {
12867330f729Sjoerg StringRef ThroughHeader = YcArg ? YcArg->getValue() : YuArg->getValue();
12877330f729Sjoerg if (!isa<PrecompileJobAction>(JA)) {
12887330f729Sjoerg CmdArgs.push_back("-include-pch");
12897330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(D.GetClPchPath(
12907330f729Sjoerg C, !ThroughHeader.empty()
12917330f729Sjoerg ? ThroughHeader
12927330f729Sjoerg : llvm::sys::path::filename(Inputs[0].getBaseInput()))));
12937330f729Sjoerg }
12947330f729Sjoerg
12957330f729Sjoerg if (ThroughHeader.empty()) {
12967330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(
12977330f729Sjoerg Twine("-pch-through-hdrstop-") + (YcArg ? "create" : "use")));
12987330f729Sjoerg } else {
12997330f729Sjoerg CmdArgs.push_back(
13007330f729Sjoerg Args.MakeArgString(Twine("-pch-through-header=") + ThroughHeader));
13017330f729Sjoerg }
13027330f729Sjoerg }
13037330f729Sjoerg }
13047330f729Sjoerg
13057330f729Sjoerg bool RenderedImplicitInclude = false;
13067330f729Sjoerg for (const Arg *A : Args.filtered(options::OPT_clang_i_Group)) {
13077330f729Sjoerg if (A->getOption().matches(options::OPT_include)) {
13087330f729Sjoerg // Handling of gcc-style gch precompiled headers.
13097330f729Sjoerg bool IsFirstImplicitInclude = !RenderedImplicitInclude;
13107330f729Sjoerg RenderedImplicitInclude = true;
13117330f729Sjoerg
13127330f729Sjoerg bool FoundPCH = false;
13137330f729Sjoerg SmallString<128> P(A->getValue());
13147330f729Sjoerg // We want the files to have a name like foo.h.pch. Add a dummy extension
13157330f729Sjoerg // so that replace_extension does the right thing.
13167330f729Sjoerg P += ".dummy";
13177330f729Sjoerg llvm::sys::path::replace_extension(P, "pch");
13187330f729Sjoerg if (llvm::sys::fs::exists(P))
13197330f729Sjoerg FoundPCH = true;
13207330f729Sjoerg
13217330f729Sjoerg if (!FoundPCH) {
13227330f729Sjoerg llvm::sys::path::replace_extension(P, "gch");
13237330f729Sjoerg if (llvm::sys::fs::exists(P)) {
13247330f729Sjoerg FoundPCH = true;
13257330f729Sjoerg }
13267330f729Sjoerg }
13277330f729Sjoerg
13287330f729Sjoerg if (FoundPCH) {
13297330f729Sjoerg if (IsFirstImplicitInclude) {
13307330f729Sjoerg A->claim();
13317330f729Sjoerg CmdArgs.push_back("-include-pch");
13327330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(P));
13337330f729Sjoerg continue;
13347330f729Sjoerg } else {
13357330f729Sjoerg // Ignore the PCH if not first on command line and emit warning.
13367330f729Sjoerg D.Diag(diag::warn_drv_pch_not_first_include) << P
13377330f729Sjoerg << A->getAsString(Args);
13387330f729Sjoerg }
13397330f729Sjoerg }
13407330f729Sjoerg } else if (A->getOption().matches(options::OPT_isystem_after)) {
13417330f729Sjoerg // Handling of paths which must come late. These entries are handled by
13427330f729Sjoerg // the toolchain itself after the resource dir is inserted in the right
13437330f729Sjoerg // search order.
13447330f729Sjoerg // Do not claim the argument so that the use of the argument does not
13457330f729Sjoerg // silently go unnoticed on toolchains which do not honour the option.
13467330f729Sjoerg continue;
13477330f729Sjoerg } else if (A->getOption().matches(options::OPT_stdlibxx_isystem)) {
13487330f729Sjoerg // Translated to -internal-isystem by the driver, no need to pass to cc1.
13497330f729Sjoerg continue;
13507330f729Sjoerg }
13517330f729Sjoerg
13527330f729Sjoerg // Not translated, render as usual.
13537330f729Sjoerg A->claim();
13547330f729Sjoerg A->render(Args, CmdArgs);
13557330f729Sjoerg }
13567330f729Sjoerg
13577330f729Sjoerg Args.AddAllArgs(CmdArgs,
13587330f729Sjoerg {options::OPT_D, options::OPT_U, options::OPT_I_Group,
13597330f729Sjoerg options::OPT_F, options::OPT_index_header_map});
13607330f729Sjoerg
13617330f729Sjoerg // Add -Wp, and -Xpreprocessor if using the preprocessor.
13627330f729Sjoerg
13637330f729Sjoerg // FIXME: There is a very unfortunate problem here, some troubled
13647330f729Sjoerg // souls abuse -Wp, to pass preprocessor options in gcc syntax. To
13657330f729Sjoerg // really support that we would have to parse and then translate
13667330f729Sjoerg // those options. :(
13677330f729Sjoerg Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
13687330f729Sjoerg options::OPT_Xpreprocessor);
13697330f729Sjoerg
13707330f729Sjoerg // -I- is a deprecated GCC feature, reject it.
13717330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_I_))
13727330f729Sjoerg D.Diag(diag::err_drv_I_dash_not_supported) << A->getAsString(Args);
13737330f729Sjoerg
13747330f729Sjoerg // If we have a --sysroot, and don't have an explicit -isysroot flag, add an
13757330f729Sjoerg // -isysroot to the CC1 invocation.
13767330f729Sjoerg StringRef sysroot = C.getSysRoot();
13777330f729Sjoerg if (sysroot != "") {
13787330f729Sjoerg if (!Args.hasArg(options::OPT_isysroot)) {
13797330f729Sjoerg CmdArgs.push_back("-isysroot");
13807330f729Sjoerg CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
13817330f729Sjoerg }
13827330f729Sjoerg }
13837330f729Sjoerg
13847330f729Sjoerg // Parse additional include paths from environment variables.
13857330f729Sjoerg // FIXME: We should probably sink the logic for handling these from the
13867330f729Sjoerg // frontend into the driver. It will allow deleting 4 otherwise unused flags.
13877330f729Sjoerg // CPATH - included following the user specified includes (but prior to
13887330f729Sjoerg // builtin and standard includes).
13897330f729Sjoerg addDirectoryList(Args, CmdArgs, "-I", "CPATH");
13907330f729Sjoerg // C_INCLUDE_PATH - system includes enabled when compiling C.
13917330f729Sjoerg addDirectoryList(Args, CmdArgs, "-c-isystem", "C_INCLUDE_PATH");
13927330f729Sjoerg // CPLUS_INCLUDE_PATH - system includes enabled when compiling C++.
13937330f729Sjoerg addDirectoryList(Args, CmdArgs, "-cxx-isystem", "CPLUS_INCLUDE_PATH");
13947330f729Sjoerg // OBJC_INCLUDE_PATH - system includes enabled when compiling ObjC.
13957330f729Sjoerg addDirectoryList(Args, CmdArgs, "-objc-isystem", "OBJC_INCLUDE_PATH");
13967330f729Sjoerg // OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++.
13977330f729Sjoerg addDirectoryList(Args, CmdArgs, "-objcxx-isystem", "OBJCPLUS_INCLUDE_PATH");
13987330f729Sjoerg
13997330f729Sjoerg // While adding the include arguments, we also attempt to retrieve the
14007330f729Sjoerg // arguments of related offloading toolchains or arguments that are specific
14017330f729Sjoerg // of an offloading programming model.
14027330f729Sjoerg
14037330f729Sjoerg // Add C++ include arguments, if needed.
14047330f729Sjoerg if (types::isCXX(Inputs[0].getType())) {
14057330f729Sjoerg bool HasStdlibxxIsystem = Args.hasArg(options::OPT_stdlibxx_isystem);
14067330f729Sjoerg forAllAssociatedToolChains(
14077330f729Sjoerg C, JA, getToolChain(),
14087330f729Sjoerg [&Args, &CmdArgs, HasStdlibxxIsystem](const ToolChain &TC) {
14097330f729Sjoerg HasStdlibxxIsystem ? TC.AddClangCXXStdlibIsystemArgs(Args, CmdArgs)
14107330f729Sjoerg : TC.AddClangCXXStdlibIncludeArgs(Args, CmdArgs);
14117330f729Sjoerg });
14127330f729Sjoerg }
14137330f729Sjoerg
14147330f729Sjoerg // Add system include arguments for all targets but IAMCU.
14157330f729Sjoerg if (!IsIAMCU)
14167330f729Sjoerg forAllAssociatedToolChains(C, JA, getToolChain(),
14177330f729Sjoerg [&Args, &CmdArgs](const ToolChain &TC) {
14187330f729Sjoerg TC.AddClangSystemIncludeArgs(Args, CmdArgs);
14197330f729Sjoerg });
14207330f729Sjoerg else {
14217330f729Sjoerg // For IAMCU add special include arguments.
14227330f729Sjoerg getToolChain().AddIAMCUIncludeArgs(Args, CmdArgs);
14237330f729Sjoerg }
1424*e038c9c4Sjoerg
1425*e038c9c4Sjoerg addMacroPrefixMapArg(D, Args, CmdArgs);
1426*e038c9c4Sjoerg addCoveragePrefixMapArg(D, Args, CmdArgs);
14277330f729Sjoerg }
14287330f729Sjoerg
14297330f729Sjoerg // FIXME: Move to target hook.
isSignedCharDefault(const llvm::Triple & Triple)14307330f729Sjoerg static bool isSignedCharDefault(const llvm::Triple &Triple) {
14317330f729Sjoerg switch (Triple.getArch()) {
14327330f729Sjoerg default:
14337330f729Sjoerg return true;
14347330f729Sjoerg
14357330f729Sjoerg case llvm::Triple::aarch64:
1436*e038c9c4Sjoerg case llvm::Triple::aarch64_32:
14377330f729Sjoerg case llvm::Triple::aarch64_be:
14387330f729Sjoerg case llvm::Triple::arm:
14397330f729Sjoerg case llvm::Triple::armeb:
14407330f729Sjoerg case llvm::Triple::thumb:
14417330f729Sjoerg case llvm::Triple::thumbeb:
14427330f729Sjoerg if (Triple.isOSDarwin() || Triple.isOSWindows())
14437330f729Sjoerg return true;
14447330f729Sjoerg return false;
14457330f729Sjoerg
14467330f729Sjoerg case llvm::Triple::ppc:
14477330f729Sjoerg case llvm::Triple::ppc64:
14487330f729Sjoerg if (Triple.isOSDarwin())
14497330f729Sjoerg return true;
14507330f729Sjoerg return false;
14517330f729Sjoerg
14527330f729Sjoerg case llvm::Triple::hexagon:
1453*e038c9c4Sjoerg case llvm::Triple::ppcle:
14547330f729Sjoerg case llvm::Triple::ppc64le:
14557330f729Sjoerg case llvm::Triple::riscv32:
14567330f729Sjoerg case llvm::Triple::riscv64:
14577330f729Sjoerg case llvm::Triple::systemz:
14587330f729Sjoerg case llvm::Triple::xcore:
14597330f729Sjoerg return false;
14607330f729Sjoerg }
14617330f729Sjoerg }
14627330f729Sjoerg
hasMultipleInvocations(const llvm::Triple & Triple,const ArgList & Args)1463*e038c9c4Sjoerg static bool hasMultipleInvocations(const llvm::Triple &Triple,
1464*e038c9c4Sjoerg const ArgList &Args) {
1465*e038c9c4Sjoerg // Supported only on Darwin where we invoke the compiler multiple times
1466*e038c9c4Sjoerg // followed by an invocation to lipo.
1467*e038c9c4Sjoerg if (!Triple.isOSDarwin())
14687330f729Sjoerg return false;
1469*e038c9c4Sjoerg // If more than one "-arch <arch>" is specified, we're targeting multiple
1470*e038c9c4Sjoerg // architectures resulting in a fat binary.
1471*e038c9c4Sjoerg return Args.getAllArgValues(options::OPT_arch).size() > 1;
1472*e038c9c4Sjoerg }
14737330f729Sjoerg
checkRemarksOptions(const Driver & D,const ArgList & Args,const llvm::Triple & Triple)1474*e038c9c4Sjoerg static bool checkRemarksOptions(const Driver &D, const ArgList &Args,
1475*e038c9c4Sjoerg const llvm::Triple &Triple) {
1476*e038c9c4Sjoerg // When enabling remarks, we need to error if:
1477*e038c9c4Sjoerg // * The remark file is specified but we're targeting multiple architectures,
1478*e038c9c4Sjoerg // which means more than one remark file is being generated.
1479*e038c9c4Sjoerg bool hasMultipleInvocations = ::hasMultipleInvocations(Triple, Args);
1480*e038c9c4Sjoerg bool hasExplicitOutputFile =
1481*e038c9c4Sjoerg Args.getLastArg(options::OPT_foptimization_record_file_EQ);
1482*e038c9c4Sjoerg if (hasMultipleInvocations && hasExplicitOutputFile) {
1483*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_output_with_multiple_archs)
1484*e038c9c4Sjoerg << "-foptimization-record-file";
1485*e038c9c4Sjoerg return false;
1486*e038c9c4Sjoerg }
14877330f729Sjoerg return true;
14887330f729Sjoerg }
1489*e038c9c4Sjoerg
renderRemarksOptions(const ArgList & Args,ArgStringList & CmdArgs,const llvm::Triple & Triple,const InputInfo & Input,const InputInfo & Output,const JobAction & JA)1490*e038c9c4Sjoerg static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs,
1491*e038c9c4Sjoerg const llvm::Triple &Triple,
1492*e038c9c4Sjoerg const InputInfo &Input,
1493*e038c9c4Sjoerg const InputInfo &Output, const JobAction &JA) {
1494*e038c9c4Sjoerg StringRef Format = "yaml";
1495*e038c9c4Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ))
1496*e038c9c4Sjoerg Format = A->getValue();
1497*e038c9c4Sjoerg
1498*e038c9c4Sjoerg CmdArgs.push_back("-opt-record-file");
1499*e038c9c4Sjoerg
1500*e038c9c4Sjoerg const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ);
1501*e038c9c4Sjoerg if (A) {
1502*e038c9c4Sjoerg CmdArgs.push_back(A->getValue());
1503*e038c9c4Sjoerg } else {
1504*e038c9c4Sjoerg bool hasMultipleArchs =
1505*e038c9c4Sjoerg Triple.isOSDarwin() && // Only supported on Darwin platforms.
1506*e038c9c4Sjoerg Args.getAllArgValues(options::OPT_arch).size() > 1;
1507*e038c9c4Sjoerg
1508*e038c9c4Sjoerg SmallString<128> F;
1509*e038c9c4Sjoerg
1510*e038c9c4Sjoerg if (Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S)) {
1511*e038c9c4Sjoerg if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
1512*e038c9c4Sjoerg F = FinalOutput->getValue();
1513*e038c9c4Sjoerg } else {
1514*e038c9c4Sjoerg if (Format != "yaml" && // For YAML, keep the original behavior.
1515*e038c9c4Sjoerg Triple.isOSDarwin() && // Enable this only on darwin, since it's the only platform supporting .dSYM bundles.
1516*e038c9c4Sjoerg Output.isFilename())
1517*e038c9c4Sjoerg F = Output.getFilename();
1518*e038c9c4Sjoerg }
1519*e038c9c4Sjoerg
1520*e038c9c4Sjoerg if (F.empty()) {
1521*e038c9c4Sjoerg // Use the input filename.
1522*e038c9c4Sjoerg F = llvm::sys::path::stem(Input.getBaseInput());
1523*e038c9c4Sjoerg
1524*e038c9c4Sjoerg // If we're compiling for an offload architecture (i.e. a CUDA device),
1525*e038c9c4Sjoerg // we need to make the file name for the device compilation different
1526*e038c9c4Sjoerg // from the host compilation.
1527*e038c9c4Sjoerg if (!JA.isDeviceOffloading(Action::OFK_None) &&
1528*e038c9c4Sjoerg !JA.isDeviceOffloading(Action::OFK_Host)) {
1529*e038c9c4Sjoerg llvm::sys::path::replace_extension(F, "");
1530*e038c9c4Sjoerg F += Action::GetOffloadingFileNamePrefix(JA.getOffloadingDeviceKind(),
1531*e038c9c4Sjoerg Triple.normalize());
1532*e038c9c4Sjoerg F += "-";
1533*e038c9c4Sjoerg F += JA.getOffloadingArch();
1534*e038c9c4Sjoerg }
1535*e038c9c4Sjoerg }
1536*e038c9c4Sjoerg
1537*e038c9c4Sjoerg // If we're having more than one "-arch", we should name the files
1538*e038c9c4Sjoerg // differently so that every cc1 invocation writes to a different file.
1539*e038c9c4Sjoerg // We're doing that by appending "-<arch>" with "<arch>" being the arch
1540*e038c9c4Sjoerg // name from the triple.
1541*e038c9c4Sjoerg if (hasMultipleArchs) {
1542*e038c9c4Sjoerg // First, remember the extension.
1543*e038c9c4Sjoerg SmallString<64> OldExtension = llvm::sys::path::extension(F);
1544*e038c9c4Sjoerg // then, remove it.
1545*e038c9c4Sjoerg llvm::sys::path::replace_extension(F, "");
1546*e038c9c4Sjoerg // attach -<arch> to it.
1547*e038c9c4Sjoerg F += "-";
1548*e038c9c4Sjoerg F += Triple.getArchName();
1549*e038c9c4Sjoerg // put back the extension.
1550*e038c9c4Sjoerg llvm::sys::path::replace_extension(F, OldExtension);
1551*e038c9c4Sjoerg }
1552*e038c9c4Sjoerg
1553*e038c9c4Sjoerg SmallString<32> Extension;
1554*e038c9c4Sjoerg Extension += "opt.";
1555*e038c9c4Sjoerg Extension += Format;
1556*e038c9c4Sjoerg
1557*e038c9c4Sjoerg llvm::sys::path::replace_extension(F, Extension);
1558*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(F));
1559*e038c9c4Sjoerg }
1560*e038c9c4Sjoerg
1561*e038c9c4Sjoerg if (const Arg *A =
1562*e038c9c4Sjoerg Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) {
1563*e038c9c4Sjoerg CmdArgs.push_back("-opt-record-passes");
1564*e038c9c4Sjoerg CmdArgs.push_back(A->getValue());
1565*e038c9c4Sjoerg }
1566*e038c9c4Sjoerg
1567*e038c9c4Sjoerg if (!Format.empty()) {
1568*e038c9c4Sjoerg CmdArgs.push_back("-opt-record-format");
1569*e038c9c4Sjoerg CmdArgs.push_back(Format.data());
1570*e038c9c4Sjoerg }
1571*e038c9c4Sjoerg }
1572*e038c9c4Sjoerg
AddAAPCSVolatileBitfieldArgs(const ArgList & Args,ArgStringList & CmdArgs)1573*e038c9c4Sjoerg void AddAAPCSVolatileBitfieldArgs(const ArgList &Args, ArgStringList &CmdArgs) {
1574*e038c9c4Sjoerg if (!Args.hasFlag(options::OPT_faapcs_bitfield_width,
1575*e038c9c4Sjoerg options::OPT_fno_aapcs_bitfield_width, true))
1576*e038c9c4Sjoerg CmdArgs.push_back("-fno-aapcs-bitfield-width");
1577*e038c9c4Sjoerg
1578*e038c9c4Sjoerg if (Args.getLastArg(options::OPT_ForceAAPCSBitfieldLoad))
1579*e038c9c4Sjoerg CmdArgs.push_back("-faapcs-bitfield-load");
15807330f729Sjoerg }
15817330f729Sjoerg
15827330f729Sjoerg namespace {
RenderARMABI(const llvm::Triple & Triple,const ArgList & Args,ArgStringList & CmdArgs)15837330f729Sjoerg void RenderARMABI(const llvm::Triple &Triple, const ArgList &Args,
15847330f729Sjoerg ArgStringList &CmdArgs) {
15857330f729Sjoerg // Select the ABI to use.
15867330f729Sjoerg // FIXME: Support -meabi.
15877330f729Sjoerg // FIXME: Parts of this are duplicated in the backend, unify this somehow.
15887330f729Sjoerg const char *ABIName = nullptr;
15897330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
15907330f729Sjoerg ABIName = A->getValue();
15917330f729Sjoerg } else {
15927330f729Sjoerg std::string CPU = getCPUName(Args, Triple, /*FromAs*/ false);
15937330f729Sjoerg ABIName = llvm::ARM::computeDefaultTargetABI(Triple, CPU).data();
15947330f729Sjoerg }
15957330f729Sjoerg
15967330f729Sjoerg CmdArgs.push_back("-target-abi");
15977330f729Sjoerg CmdArgs.push_back(ABIName);
15987330f729Sjoerg }
15997330f729Sjoerg }
16007330f729Sjoerg
AddARMTargetArgs(const llvm::Triple & Triple,const ArgList & Args,ArgStringList & CmdArgs,bool KernelOrKext) const16017330f729Sjoerg void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
16027330f729Sjoerg ArgStringList &CmdArgs, bool KernelOrKext) const {
16037330f729Sjoerg RenderARMABI(Triple, Args, CmdArgs);
16047330f729Sjoerg
16057330f729Sjoerg // Determine floating point ABI from the options & target defaults.
16067330f729Sjoerg arm::FloatABI ABI = arm::getARMFloatABI(getToolChain(), Args);
16077330f729Sjoerg if (ABI == arm::FloatABI::Soft) {
16087330f729Sjoerg // Floating point operations and argument passing are soft.
16097330f729Sjoerg // FIXME: This changes CPP defines, we need -target-soft-float.
16107330f729Sjoerg CmdArgs.push_back("-msoft-float");
16117330f729Sjoerg CmdArgs.push_back("-mfloat-abi");
16127330f729Sjoerg CmdArgs.push_back("soft");
16137330f729Sjoerg } else if (ABI == arm::FloatABI::SoftFP) {
16147330f729Sjoerg // Floating point operations are hard, but argument passing is soft.
16157330f729Sjoerg CmdArgs.push_back("-mfloat-abi");
16167330f729Sjoerg CmdArgs.push_back("soft");
16177330f729Sjoerg } else {
16187330f729Sjoerg // Floating point operations and argument passing are hard.
16197330f729Sjoerg assert(ABI == arm::FloatABI::Hard && "Invalid float abi!");
16207330f729Sjoerg CmdArgs.push_back("-mfloat-abi");
16217330f729Sjoerg CmdArgs.push_back("hard");
16227330f729Sjoerg }
16237330f729Sjoerg
16247330f729Sjoerg // Forward the -mglobal-merge option for explicit control over the pass.
16257330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
16267330f729Sjoerg options::OPT_mno_global_merge)) {
16277330f729Sjoerg CmdArgs.push_back("-mllvm");
16287330f729Sjoerg if (A->getOption().matches(options::OPT_mno_global_merge))
16297330f729Sjoerg CmdArgs.push_back("-arm-global-merge=false");
16307330f729Sjoerg else
16317330f729Sjoerg CmdArgs.push_back("-arm-global-merge=true");
16327330f729Sjoerg }
16337330f729Sjoerg
16347330f729Sjoerg if (!Args.hasFlag(options::OPT_mimplicit_float,
16357330f729Sjoerg options::OPT_mno_implicit_float, true))
16367330f729Sjoerg CmdArgs.push_back("-no-implicit-float");
16377330f729Sjoerg
16387330f729Sjoerg if (Args.getLastArg(options::OPT_mcmse))
16397330f729Sjoerg CmdArgs.push_back("-mcmse");
1640*e038c9c4Sjoerg
1641*e038c9c4Sjoerg AddAAPCSVolatileBitfieldArgs(Args, CmdArgs);
16427330f729Sjoerg }
16437330f729Sjoerg
RenderTargetOptions(const llvm::Triple & EffectiveTriple,const ArgList & Args,bool KernelOrKext,ArgStringList & CmdArgs) const16447330f729Sjoerg void Clang::RenderTargetOptions(const llvm::Triple &EffectiveTriple,
16457330f729Sjoerg const ArgList &Args, bool KernelOrKext,
16467330f729Sjoerg ArgStringList &CmdArgs) const {
16477330f729Sjoerg const ToolChain &TC = getToolChain();
16487330f729Sjoerg
16497330f729Sjoerg // Add the target features
1650*e038c9c4Sjoerg getTargetFeatures(TC.getDriver(), EffectiveTriple, Args, CmdArgs, false);
16517330f729Sjoerg
16527330f729Sjoerg // Add target specific flags.
16537330f729Sjoerg switch (TC.getArch()) {
16547330f729Sjoerg default:
16557330f729Sjoerg break;
16567330f729Sjoerg
16577330f729Sjoerg case llvm::Triple::arm:
16587330f729Sjoerg case llvm::Triple::armeb:
16597330f729Sjoerg case llvm::Triple::thumb:
16607330f729Sjoerg case llvm::Triple::thumbeb:
16617330f729Sjoerg // Use the effective triple, which takes into account the deployment target.
16627330f729Sjoerg AddARMTargetArgs(EffectiveTriple, Args, CmdArgs, KernelOrKext);
16637330f729Sjoerg CmdArgs.push_back("-fallow-half-arguments-and-returns");
16647330f729Sjoerg break;
16657330f729Sjoerg
16667330f729Sjoerg case llvm::Triple::aarch64:
1667*e038c9c4Sjoerg case llvm::Triple::aarch64_32:
16687330f729Sjoerg case llvm::Triple::aarch64_be:
16697330f729Sjoerg AddAArch64TargetArgs(Args, CmdArgs);
16707330f729Sjoerg CmdArgs.push_back("-fallow-half-arguments-and-returns");
16717330f729Sjoerg break;
16727330f729Sjoerg
16737330f729Sjoerg case llvm::Triple::mips:
16747330f729Sjoerg case llvm::Triple::mipsel:
16757330f729Sjoerg case llvm::Triple::mips64:
16767330f729Sjoerg case llvm::Triple::mips64el:
16777330f729Sjoerg AddMIPSTargetArgs(Args, CmdArgs);
16787330f729Sjoerg break;
16797330f729Sjoerg
16807330f729Sjoerg case llvm::Triple::ppc:
1681*e038c9c4Sjoerg case llvm::Triple::ppcle:
16827330f729Sjoerg case llvm::Triple::ppc64:
16837330f729Sjoerg case llvm::Triple::ppc64le:
16847330f729Sjoerg AddPPCTargetArgs(Args, CmdArgs);
16857330f729Sjoerg break;
16867330f729Sjoerg
16877330f729Sjoerg case llvm::Triple::riscv32:
16887330f729Sjoerg case llvm::Triple::riscv64:
16897330f729Sjoerg AddRISCVTargetArgs(Args, CmdArgs);
16907330f729Sjoerg break;
16917330f729Sjoerg
16927330f729Sjoerg case llvm::Triple::sparc:
16937330f729Sjoerg case llvm::Triple::sparcel:
16947330f729Sjoerg case llvm::Triple::sparcv9:
16957330f729Sjoerg AddSparcTargetArgs(Args, CmdArgs);
16967330f729Sjoerg break;
16977330f729Sjoerg
16987330f729Sjoerg case llvm::Triple::systemz:
16997330f729Sjoerg AddSystemZTargetArgs(Args, CmdArgs);
17007330f729Sjoerg break;
17017330f729Sjoerg
17027330f729Sjoerg case llvm::Triple::x86:
17037330f729Sjoerg case llvm::Triple::x86_64:
17047330f729Sjoerg AddX86TargetArgs(Args, CmdArgs);
17057330f729Sjoerg break;
17067330f729Sjoerg
17077330f729Sjoerg case llvm::Triple::lanai:
17087330f729Sjoerg AddLanaiTargetArgs(Args, CmdArgs);
17097330f729Sjoerg break;
17107330f729Sjoerg
17117330f729Sjoerg case llvm::Triple::hexagon:
17127330f729Sjoerg AddHexagonTargetArgs(Args, CmdArgs);
17137330f729Sjoerg break;
17147330f729Sjoerg
17157330f729Sjoerg case llvm::Triple::wasm32:
17167330f729Sjoerg case llvm::Triple::wasm64:
17177330f729Sjoerg AddWebAssemblyTargetArgs(Args, CmdArgs);
17187330f729Sjoerg break;
17197330f729Sjoerg
1720*e038c9c4Sjoerg case llvm::Triple::ve:
1721*e038c9c4Sjoerg AddVETargetArgs(Args, CmdArgs);
17227330f729Sjoerg break;
17237330f729Sjoerg }
17247330f729Sjoerg }
17257330f729Sjoerg
17267330f729Sjoerg namespace {
RenderAArch64ABI(const llvm::Triple & Triple,const ArgList & Args,ArgStringList & CmdArgs)17277330f729Sjoerg void RenderAArch64ABI(const llvm::Triple &Triple, const ArgList &Args,
17287330f729Sjoerg ArgStringList &CmdArgs) {
17297330f729Sjoerg const char *ABIName = nullptr;
17307330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
17317330f729Sjoerg ABIName = A->getValue();
17327330f729Sjoerg else if (Triple.isOSDarwin())
17337330f729Sjoerg ABIName = "darwinpcs";
17347330f729Sjoerg else
17357330f729Sjoerg ABIName = "aapcs";
17367330f729Sjoerg
17377330f729Sjoerg CmdArgs.push_back("-target-abi");
17387330f729Sjoerg CmdArgs.push_back(ABIName);
17397330f729Sjoerg }
17407330f729Sjoerg }
17417330f729Sjoerg
AddAArch64TargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const17427330f729Sjoerg void Clang::AddAArch64TargetArgs(const ArgList &Args,
17437330f729Sjoerg ArgStringList &CmdArgs) const {
17447330f729Sjoerg const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
17457330f729Sjoerg
17467330f729Sjoerg if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) ||
17477330f729Sjoerg Args.hasArg(options::OPT_mkernel) ||
17487330f729Sjoerg Args.hasArg(options::OPT_fapple_kext))
17497330f729Sjoerg CmdArgs.push_back("-disable-red-zone");
17507330f729Sjoerg
17517330f729Sjoerg if (!Args.hasFlag(options::OPT_mimplicit_float,
17527330f729Sjoerg options::OPT_mno_implicit_float, true))
17537330f729Sjoerg CmdArgs.push_back("-no-implicit-float");
17547330f729Sjoerg
17557330f729Sjoerg RenderAArch64ABI(Triple, Args, CmdArgs);
17567330f729Sjoerg
17577330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769,
17587330f729Sjoerg options::OPT_mno_fix_cortex_a53_835769)) {
17597330f729Sjoerg CmdArgs.push_back("-mllvm");
17607330f729Sjoerg if (A->getOption().matches(options::OPT_mfix_cortex_a53_835769))
17617330f729Sjoerg CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1");
17627330f729Sjoerg else
17637330f729Sjoerg CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=0");
17647330f729Sjoerg } else if (Triple.isAndroid()) {
17657330f729Sjoerg // Enabled A53 errata (835769) workaround by default on android
17667330f729Sjoerg CmdArgs.push_back("-mllvm");
17677330f729Sjoerg CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1");
17687330f729Sjoerg }
17697330f729Sjoerg
17707330f729Sjoerg // Forward the -mglobal-merge option for explicit control over the pass.
17717330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
17727330f729Sjoerg options::OPT_mno_global_merge)) {
17737330f729Sjoerg CmdArgs.push_back("-mllvm");
17747330f729Sjoerg if (A->getOption().matches(options::OPT_mno_global_merge))
17757330f729Sjoerg CmdArgs.push_back("-aarch64-enable-global-merge=false");
17767330f729Sjoerg else
17777330f729Sjoerg CmdArgs.push_back("-aarch64-enable-global-merge=true");
17787330f729Sjoerg }
17797330f729Sjoerg
17807330f729Sjoerg // Enable/disable return address signing and indirect branch targets.
17817330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_msign_return_address_EQ,
17827330f729Sjoerg options::OPT_mbranch_protection_EQ)) {
17837330f729Sjoerg
17847330f729Sjoerg const Driver &D = getToolChain().getDriver();
17857330f729Sjoerg
17867330f729Sjoerg StringRef Scope, Key;
17877330f729Sjoerg bool IndirectBranches;
17887330f729Sjoerg
17897330f729Sjoerg if (A->getOption().matches(options::OPT_msign_return_address_EQ)) {
17907330f729Sjoerg Scope = A->getValue();
17917330f729Sjoerg if (!Scope.equals("none") && !Scope.equals("non-leaf") &&
17927330f729Sjoerg !Scope.equals("all"))
17937330f729Sjoerg D.Diag(diag::err_invalid_branch_protection)
17947330f729Sjoerg << Scope << A->getAsString(Args);
17957330f729Sjoerg Key = "a_key";
17967330f729Sjoerg IndirectBranches = false;
1797*e038c9c4Sjoerg } else {
1798*e038c9c4Sjoerg StringRef Err;
1799*e038c9c4Sjoerg llvm::AArch64::ParsedBranchProtection PBP;
1800*e038c9c4Sjoerg if (!llvm::AArch64::parseBranchProtection(A->getValue(), PBP, Err))
1801*e038c9c4Sjoerg D.Diag(diag::err_invalid_branch_protection)
1802*e038c9c4Sjoerg << Err << A->getAsString(Args);
1803*e038c9c4Sjoerg Scope = PBP.Scope;
1804*e038c9c4Sjoerg Key = PBP.Key;
1805*e038c9c4Sjoerg IndirectBranches = PBP.BranchTargetEnforcement;
1806*e038c9c4Sjoerg }
18077330f729Sjoerg
18087330f729Sjoerg CmdArgs.push_back(
18097330f729Sjoerg Args.MakeArgString(Twine("-msign-return-address=") + Scope));
18107330f729Sjoerg CmdArgs.push_back(
18117330f729Sjoerg Args.MakeArgString(Twine("-msign-return-address-key=") + Key));
18127330f729Sjoerg if (IndirectBranches)
18137330f729Sjoerg CmdArgs.push_back("-mbranch-target-enforce");
18147330f729Sjoerg }
1815*e038c9c4Sjoerg
1816*e038c9c4Sjoerg // Handle -msve_vector_bits=<bits>
1817*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) {
1818*e038c9c4Sjoerg StringRef Val = A->getValue();
1819*e038c9c4Sjoerg const Driver &D = getToolChain().getDriver();
1820*e038c9c4Sjoerg if (Val.equals("128") || Val.equals("256") || Val.equals("512") ||
1821*e038c9c4Sjoerg Val.equals("1024") || Val.equals("2048"))
1822*e038c9c4Sjoerg CmdArgs.push_back(
1823*e038c9c4Sjoerg Args.MakeArgString(llvm::Twine("-msve-vector-bits=") + Val));
1824*e038c9c4Sjoerg // Silently drop requests for vector-length agnostic code as it's implied.
1825*e038c9c4Sjoerg else if (!Val.equals("scalable"))
1826*e038c9c4Sjoerg // Handle the unsupported values passed to msve-vector-bits.
1827*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_option_argument)
1828*e038c9c4Sjoerg << A->getOption().getName() << Val;
1829*e038c9c4Sjoerg }
1830*e038c9c4Sjoerg
1831*e038c9c4Sjoerg AddAAPCSVolatileBitfieldArgs(Args, CmdArgs);
18327330f729Sjoerg }
18337330f729Sjoerg
AddMIPSTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const18347330f729Sjoerg void Clang::AddMIPSTargetArgs(const ArgList &Args,
18357330f729Sjoerg ArgStringList &CmdArgs) const {
18367330f729Sjoerg const Driver &D = getToolChain().getDriver();
18377330f729Sjoerg StringRef CPUName;
18387330f729Sjoerg StringRef ABIName;
18397330f729Sjoerg const llvm::Triple &Triple = getToolChain().getTriple();
18407330f729Sjoerg mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
18417330f729Sjoerg
18427330f729Sjoerg CmdArgs.push_back("-target-abi");
18437330f729Sjoerg CmdArgs.push_back(ABIName.data());
18447330f729Sjoerg
18457330f729Sjoerg mips::FloatABI ABI = mips::getMipsFloatABI(D, Args, Triple);
18467330f729Sjoerg if (ABI == mips::FloatABI::Soft) {
18477330f729Sjoerg // Floating point operations and argument passing are soft.
18487330f729Sjoerg CmdArgs.push_back("-msoft-float");
18497330f729Sjoerg CmdArgs.push_back("-mfloat-abi");
18507330f729Sjoerg CmdArgs.push_back("soft");
18517330f729Sjoerg } else {
18527330f729Sjoerg // Floating point operations and argument passing are hard.
18537330f729Sjoerg assert(ABI == mips::FloatABI::Hard && "Invalid float abi!");
18547330f729Sjoerg CmdArgs.push_back("-mfloat-abi");
18557330f729Sjoerg CmdArgs.push_back("hard");
18567330f729Sjoerg }
18577330f729Sjoerg
18587330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mldc1_sdc1,
18597330f729Sjoerg options::OPT_mno_ldc1_sdc1)) {
18607330f729Sjoerg if (A->getOption().matches(options::OPT_mno_ldc1_sdc1)) {
18617330f729Sjoerg CmdArgs.push_back("-mllvm");
18627330f729Sjoerg CmdArgs.push_back("-mno-ldc1-sdc1");
18637330f729Sjoerg }
18647330f729Sjoerg }
18657330f729Sjoerg
18667330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mcheck_zero_division,
18677330f729Sjoerg options::OPT_mno_check_zero_division)) {
18687330f729Sjoerg if (A->getOption().matches(options::OPT_mno_check_zero_division)) {
18697330f729Sjoerg CmdArgs.push_back("-mllvm");
18707330f729Sjoerg CmdArgs.push_back("-mno-check-zero-division");
18717330f729Sjoerg }
18727330f729Sjoerg }
18737330f729Sjoerg
18747330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_G)) {
18757330f729Sjoerg StringRef v = A->getValue();
18767330f729Sjoerg CmdArgs.push_back("-mllvm");
18777330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-mips-ssection-threshold=" + v));
18787330f729Sjoerg A->claim();
18797330f729Sjoerg }
18807330f729Sjoerg
18817330f729Sjoerg Arg *GPOpt = Args.getLastArg(options::OPT_mgpopt, options::OPT_mno_gpopt);
18827330f729Sjoerg Arg *ABICalls =
18837330f729Sjoerg Args.getLastArg(options::OPT_mabicalls, options::OPT_mno_abicalls);
18847330f729Sjoerg
18857330f729Sjoerg // -mabicalls is the default for many MIPS environments, even with -fno-pic.
18867330f729Sjoerg // -mgpopt is the default for static, -fno-pic environments but these two
18877330f729Sjoerg // options conflict. We want to be certain that -mno-abicalls -mgpopt is
18887330f729Sjoerg // the only case where -mllvm -mgpopt is passed.
18897330f729Sjoerg // NOTE: We need a warning here or in the backend to warn when -mgpopt is
18907330f729Sjoerg // passed explicitly when compiling something with -mabicalls
18917330f729Sjoerg // (implictly) in affect. Currently the warning is in the backend.
18927330f729Sjoerg //
18937330f729Sjoerg // When the ABI in use is N64, we also need to determine the PIC mode that
18947330f729Sjoerg // is in use, as -fno-pic for N64 implies -mno-abicalls.
18957330f729Sjoerg bool NoABICalls =
18967330f729Sjoerg ABICalls && ABICalls->getOption().matches(options::OPT_mno_abicalls);
18977330f729Sjoerg
18987330f729Sjoerg llvm::Reloc::Model RelocationModel;
18997330f729Sjoerg unsigned PICLevel;
19007330f729Sjoerg bool IsPIE;
19017330f729Sjoerg std::tie(RelocationModel, PICLevel, IsPIE) =
19027330f729Sjoerg ParsePICArgs(getToolChain(), Args);
19037330f729Sjoerg
19047330f729Sjoerg NoABICalls = NoABICalls ||
19057330f729Sjoerg (RelocationModel == llvm::Reloc::Static && ABIName == "n64");
19067330f729Sjoerg
19077330f729Sjoerg bool WantGPOpt = GPOpt && GPOpt->getOption().matches(options::OPT_mgpopt);
19087330f729Sjoerg // We quietly ignore -mno-gpopt as the backend defaults to -mno-gpopt.
19097330f729Sjoerg if (NoABICalls && (!GPOpt || WantGPOpt)) {
19107330f729Sjoerg CmdArgs.push_back("-mllvm");
19117330f729Sjoerg CmdArgs.push_back("-mgpopt");
19127330f729Sjoerg
19137330f729Sjoerg Arg *LocalSData = Args.getLastArg(options::OPT_mlocal_sdata,
19147330f729Sjoerg options::OPT_mno_local_sdata);
19157330f729Sjoerg Arg *ExternSData = Args.getLastArg(options::OPT_mextern_sdata,
19167330f729Sjoerg options::OPT_mno_extern_sdata);
19177330f729Sjoerg Arg *EmbeddedData = Args.getLastArg(options::OPT_membedded_data,
19187330f729Sjoerg options::OPT_mno_embedded_data);
19197330f729Sjoerg if (LocalSData) {
19207330f729Sjoerg CmdArgs.push_back("-mllvm");
19217330f729Sjoerg if (LocalSData->getOption().matches(options::OPT_mlocal_sdata)) {
19227330f729Sjoerg CmdArgs.push_back("-mlocal-sdata=1");
19237330f729Sjoerg } else {
19247330f729Sjoerg CmdArgs.push_back("-mlocal-sdata=0");
19257330f729Sjoerg }
19267330f729Sjoerg LocalSData->claim();
19277330f729Sjoerg }
19287330f729Sjoerg
19297330f729Sjoerg if (ExternSData) {
19307330f729Sjoerg CmdArgs.push_back("-mllvm");
19317330f729Sjoerg if (ExternSData->getOption().matches(options::OPT_mextern_sdata)) {
19327330f729Sjoerg CmdArgs.push_back("-mextern-sdata=1");
19337330f729Sjoerg } else {
19347330f729Sjoerg CmdArgs.push_back("-mextern-sdata=0");
19357330f729Sjoerg }
19367330f729Sjoerg ExternSData->claim();
19377330f729Sjoerg }
19387330f729Sjoerg
19397330f729Sjoerg if (EmbeddedData) {
19407330f729Sjoerg CmdArgs.push_back("-mllvm");
19417330f729Sjoerg if (EmbeddedData->getOption().matches(options::OPT_membedded_data)) {
19427330f729Sjoerg CmdArgs.push_back("-membedded-data=1");
19437330f729Sjoerg } else {
19447330f729Sjoerg CmdArgs.push_back("-membedded-data=0");
19457330f729Sjoerg }
19467330f729Sjoerg EmbeddedData->claim();
19477330f729Sjoerg }
19487330f729Sjoerg
19497330f729Sjoerg } else if ((!ABICalls || (!NoABICalls && ABICalls)) && WantGPOpt)
19507330f729Sjoerg D.Diag(diag::warn_drv_unsupported_gpopt) << (ABICalls ? 0 : 1);
19517330f729Sjoerg
19527330f729Sjoerg if (GPOpt)
19537330f729Sjoerg GPOpt->claim();
19547330f729Sjoerg
19557330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mcompact_branches_EQ)) {
19567330f729Sjoerg StringRef Val = StringRef(A->getValue());
19577330f729Sjoerg if (mips::hasCompactBranches(CPUName)) {
19587330f729Sjoerg if (Val == "never" || Val == "always" || Val == "optimal") {
19597330f729Sjoerg CmdArgs.push_back("-mllvm");
19607330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-mips-compact-branches=" + Val));
19617330f729Sjoerg } else
19627330f729Sjoerg D.Diag(diag::err_drv_unsupported_option_argument)
19637330f729Sjoerg << A->getOption().getName() << Val;
19647330f729Sjoerg } else
19657330f729Sjoerg D.Diag(diag::warn_target_unsupported_compact_branches) << CPUName;
19667330f729Sjoerg }
19677330f729Sjoerg
19687330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mrelax_pic_calls,
19697330f729Sjoerg options::OPT_mno_relax_pic_calls)) {
19707330f729Sjoerg if (A->getOption().matches(options::OPT_mno_relax_pic_calls)) {
19717330f729Sjoerg CmdArgs.push_back("-mllvm");
19727330f729Sjoerg CmdArgs.push_back("-mips-jalr-reloc=0");
19737330f729Sjoerg }
19747330f729Sjoerg }
19757330f729Sjoerg }
19767330f729Sjoerg
AddPPCTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const19777330f729Sjoerg void Clang::AddPPCTargetArgs(const ArgList &Args,
19787330f729Sjoerg ArgStringList &CmdArgs) const {
19797330f729Sjoerg // Select the ABI to use.
19807330f729Sjoerg const char *ABIName = nullptr;
1981*e038c9c4Sjoerg const llvm::Triple &T = getToolChain().getTriple();
1982*e038c9c4Sjoerg if (T.isOSBinFormatELF()) {
19837330f729Sjoerg switch (getToolChain().getArch()) {
19847330f729Sjoerg case llvm::Triple::ppc64: {
1985*e038c9c4Sjoerg if ((T.isOSFreeBSD() && T.getOSMajorVersion() >= 13) ||
1986*e038c9c4Sjoerg T.isOSOpenBSD() || T.isMusl())
1987*e038c9c4Sjoerg ABIName = "elfv2";
1988*e038c9c4Sjoerg else
19897330f729Sjoerg ABIName = "elfv1";
19907330f729Sjoerg break;
19917330f729Sjoerg }
19927330f729Sjoerg case llvm::Triple::ppc64le:
19937330f729Sjoerg ABIName = "elfv2";
19947330f729Sjoerg break;
19957330f729Sjoerg default:
19967330f729Sjoerg break;
19977330f729Sjoerg }
1998*e038c9c4Sjoerg }
19997330f729Sjoerg
20007330f729Sjoerg bool IEEELongDouble = false;
20017330f729Sjoerg for (const Arg *A : Args.filtered(options::OPT_mabi_EQ)) {
20027330f729Sjoerg StringRef V = A->getValue();
20037330f729Sjoerg if (V == "ieeelongdouble")
20047330f729Sjoerg IEEELongDouble = true;
20057330f729Sjoerg else if (V == "ibmlongdouble")
20067330f729Sjoerg IEEELongDouble = false;
20077330f729Sjoerg else if (V != "altivec")
20087330f729Sjoerg // The ppc64 linux abis are all "altivec" abis by default. Accept and ignore
20097330f729Sjoerg // the option if given as we don't have backend support for any targets
20107330f729Sjoerg // that don't use the altivec abi.
20117330f729Sjoerg ABIName = A->getValue();
20127330f729Sjoerg }
20137330f729Sjoerg if (IEEELongDouble)
20147330f729Sjoerg CmdArgs.push_back("-mabi=ieeelongdouble");
20157330f729Sjoerg
20167330f729Sjoerg ppc::FloatABI FloatABI =
20177330f729Sjoerg ppc::getPPCFloatABI(getToolChain().getDriver(), Args);
20187330f729Sjoerg
20197330f729Sjoerg if (FloatABI == ppc::FloatABI::Soft) {
20207330f729Sjoerg // Floating point operations and argument passing are soft.
20217330f729Sjoerg CmdArgs.push_back("-msoft-float");
20227330f729Sjoerg CmdArgs.push_back("-mfloat-abi");
20237330f729Sjoerg CmdArgs.push_back("soft");
20247330f729Sjoerg } else {
20257330f729Sjoerg // Floating point operations and argument passing are hard.
20267330f729Sjoerg assert(FloatABI == ppc::FloatABI::Hard && "Invalid float abi!");
20277330f729Sjoerg CmdArgs.push_back("-mfloat-abi");
20287330f729Sjoerg CmdArgs.push_back("hard");
20297330f729Sjoerg }
20307330f729Sjoerg
20317330f729Sjoerg if (ABIName) {
20327330f729Sjoerg CmdArgs.push_back("-target-abi");
20337330f729Sjoerg CmdArgs.push_back(ABIName);
20347330f729Sjoerg }
20357330f729Sjoerg }
20367330f729Sjoerg
SetRISCVSmallDataLimit(const ToolChain & TC,const ArgList & Args,ArgStringList & CmdArgs)2037*e038c9c4Sjoerg static void SetRISCVSmallDataLimit(const ToolChain &TC, const ArgList &Args,
2038*e038c9c4Sjoerg ArgStringList &CmdArgs) {
2039*e038c9c4Sjoerg const Driver &D = TC.getDriver();
2040*e038c9c4Sjoerg const llvm::Triple &Triple = TC.getTriple();
2041*e038c9c4Sjoerg // Default small data limitation is eight.
2042*e038c9c4Sjoerg const char *SmallDataLimit = "8";
2043*e038c9c4Sjoerg // Get small data limitation.
2044*e038c9c4Sjoerg if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
2045*e038c9c4Sjoerg options::OPT_fPIC)) {
2046*e038c9c4Sjoerg // Not support linker relaxation for PIC.
2047*e038c9c4Sjoerg SmallDataLimit = "0";
2048*e038c9c4Sjoerg if (Args.hasArg(options::OPT_G)) {
2049*e038c9c4Sjoerg D.Diag(diag::warn_drv_unsupported_sdata);
2050*e038c9c4Sjoerg }
2051*e038c9c4Sjoerg } else if (Args.getLastArgValue(options::OPT_mcmodel_EQ)
2052*e038c9c4Sjoerg .equals_lower("large") &&
2053*e038c9c4Sjoerg (Triple.getArch() == llvm::Triple::riscv64)) {
2054*e038c9c4Sjoerg // Not support linker relaxation for RV64 with large code model.
2055*e038c9c4Sjoerg SmallDataLimit = "0";
2056*e038c9c4Sjoerg if (Args.hasArg(options::OPT_G)) {
2057*e038c9c4Sjoerg D.Diag(diag::warn_drv_unsupported_sdata);
2058*e038c9c4Sjoerg }
2059*e038c9c4Sjoerg } else if (Arg *A = Args.getLastArg(options::OPT_G)) {
2060*e038c9c4Sjoerg SmallDataLimit = A->getValue();
2061*e038c9c4Sjoerg }
2062*e038c9c4Sjoerg // Forward the -msmall-data-limit= option.
2063*e038c9c4Sjoerg CmdArgs.push_back("-msmall-data-limit");
2064*e038c9c4Sjoerg CmdArgs.push_back(SmallDataLimit);
2065*e038c9c4Sjoerg }
2066*e038c9c4Sjoerg
AddRISCVTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const20677330f729Sjoerg void Clang::AddRISCVTargetArgs(const ArgList &Args,
20687330f729Sjoerg ArgStringList &CmdArgs) const {
20697330f729Sjoerg const llvm::Triple &Triple = getToolChain().getTriple();
20707330f729Sjoerg StringRef ABIName = riscv::getRISCVABI(Args, Triple);
20717330f729Sjoerg
20727330f729Sjoerg CmdArgs.push_back("-target-abi");
20737330f729Sjoerg CmdArgs.push_back(ABIName.data());
2074*e038c9c4Sjoerg
2075*e038c9c4Sjoerg SetRISCVSmallDataLimit(getToolChain(), Args, CmdArgs);
2076*e038c9c4Sjoerg
2077*e038c9c4Sjoerg std::string TuneCPU;
2078*e038c9c4Sjoerg
2079*e038c9c4Sjoerg if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)) {
2080*e038c9c4Sjoerg StringRef Name = A->getValue();
2081*e038c9c4Sjoerg
2082*e038c9c4Sjoerg Name = llvm::RISCV::resolveTuneCPUAlias(Name, Triple.isArch64Bit());
2083*e038c9c4Sjoerg TuneCPU = std::string(Name);
2084*e038c9c4Sjoerg }
2085*e038c9c4Sjoerg
2086*e038c9c4Sjoerg if (!TuneCPU.empty()) {
2087*e038c9c4Sjoerg CmdArgs.push_back("-tune-cpu");
2088*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(TuneCPU));
2089*e038c9c4Sjoerg }
20907330f729Sjoerg }
20917330f729Sjoerg
AddSparcTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const20927330f729Sjoerg void Clang::AddSparcTargetArgs(const ArgList &Args,
20937330f729Sjoerg ArgStringList &CmdArgs) const {
20947330f729Sjoerg sparc::FloatABI FloatABI =
20957330f729Sjoerg sparc::getSparcFloatABI(getToolChain().getDriver(), Args);
20967330f729Sjoerg
20977330f729Sjoerg if (FloatABI == sparc::FloatABI::Soft) {
20987330f729Sjoerg // Floating point operations and argument passing are soft.
20997330f729Sjoerg CmdArgs.push_back("-msoft-float");
21007330f729Sjoerg CmdArgs.push_back("-mfloat-abi");
21017330f729Sjoerg CmdArgs.push_back("soft");
21027330f729Sjoerg } else {
21037330f729Sjoerg // Floating point operations and argument passing are hard.
21047330f729Sjoerg assert(FloatABI == sparc::FloatABI::Hard && "Invalid float abi!");
21057330f729Sjoerg CmdArgs.push_back("-mfloat-abi");
21067330f729Sjoerg CmdArgs.push_back("hard");
21077330f729Sjoerg }
21087330f729Sjoerg }
21097330f729Sjoerg
AddSystemZTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const21107330f729Sjoerg void Clang::AddSystemZTargetArgs(const ArgList &Args,
21117330f729Sjoerg ArgStringList &CmdArgs) const {
2112*e038c9c4Sjoerg bool HasBackchain = Args.hasFlag(options::OPT_mbackchain,
2113*e038c9c4Sjoerg options::OPT_mno_backchain, false);
2114*e038c9c4Sjoerg bool HasPackedStack = Args.hasFlag(options::OPT_mpacked_stack,
2115*e038c9c4Sjoerg options::OPT_mno_packed_stack, false);
2116*e038c9c4Sjoerg systemz::FloatABI FloatABI =
2117*e038c9c4Sjoerg systemz::getSystemZFloatABI(getToolChain().getDriver(), Args);
2118*e038c9c4Sjoerg bool HasSoftFloat = (FloatABI == systemz::FloatABI::Soft);
2119*e038c9c4Sjoerg if (HasBackchain && HasPackedStack && !HasSoftFloat) {
2120*e038c9c4Sjoerg const Driver &D = getToolChain().getDriver();
2121*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt)
2122*e038c9c4Sjoerg << "-mpacked-stack -mbackchain -mhard-float";
2123*e038c9c4Sjoerg }
2124*e038c9c4Sjoerg if (HasBackchain)
21257330f729Sjoerg CmdArgs.push_back("-mbackchain");
2126*e038c9c4Sjoerg if (HasPackedStack)
2127*e038c9c4Sjoerg CmdArgs.push_back("-mpacked-stack");
2128*e038c9c4Sjoerg if (HasSoftFloat) {
2129*e038c9c4Sjoerg // Floating point operations and argument passing are soft.
2130*e038c9c4Sjoerg CmdArgs.push_back("-msoft-float");
2131*e038c9c4Sjoerg CmdArgs.push_back("-mfloat-abi");
2132*e038c9c4Sjoerg CmdArgs.push_back("soft");
2133*e038c9c4Sjoerg }
21347330f729Sjoerg }
21357330f729Sjoerg
AddX86TargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const21367330f729Sjoerg void Clang::AddX86TargetArgs(const ArgList &Args,
21377330f729Sjoerg ArgStringList &CmdArgs) const {
2138*e038c9c4Sjoerg const Driver &D = getToolChain().getDriver();
2139*e038c9c4Sjoerg addX86AlignBranchArgs(D, Args, CmdArgs, /*IsLTO=*/false);
2140*e038c9c4Sjoerg
21417330f729Sjoerg if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) ||
21427330f729Sjoerg Args.hasArg(options::OPT_mkernel) ||
21437330f729Sjoerg Args.hasArg(options::OPT_fapple_kext))
21447330f729Sjoerg CmdArgs.push_back("-disable-red-zone");
21457330f729Sjoerg
21467330f729Sjoerg if (!Args.hasFlag(options::OPT_mtls_direct_seg_refs,
21477330f729Sjoerg options::OPT_mno_tls_direct_seg_refs, true))
21487330f729Sjoerg CmdArgs.push_back("-mno-tls-direct-seg-refs");
21497330f729Sjoerg
21507330f729Sjoerg // Default to avoid implicit floating-point for kernel/kext code, but allow
21517330f729Sjoerg // that to be overridden with -mno-soft-float.
21527330f729Sjoerg bool NoImplicitFloat = (Args.hasArg(options::OPT_mkernel) ||
21537330f729Sjoerg Args.hasArg(options::OPT_fapple_kext));
21547330f729Sjoerg if (Arg *A = Args.getLastArg(
21557330f729Sjoerg options::OPT_msoft_float, options::OPT_mno_soft_float,
21567330f729Sjoerg options::OPT_mimplicit_float, options::OPT_mno_implicit_float)) {
21577330f729Sjoerg const Option &O = A->getOption();
21587330f729Sjoerg NoImplicitFloat = (O.matches(options::OPT_mno_implicit_float) ||
21597330f729Sjoerg O.matches(options::OPT_msoft_float));
21607330f729Sjoerg }
21617330f729Sjoerg if (NoImplicitFloat)
21627330f729Sjoerg CmdArgs.push_back("-no-implicit-float");
21637330f729Sjoerg
21647330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_masm_EQ)) {
21657330f729Sjoerg StringRef Value = A->getValue();
21667330f729Sjoerg if (Value == "intel" || Value == "att") {
21677330f729Sjoerg CmdArgs.push_back("-mllvm");
21687330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-x86-asm-syntax=" + Value));
21697330f729Sjoerg } else {
2170*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_option_argument)
21717330f729Sjoerg << A->getOption().getName() << Value;
21727330f729Sjoerg }
2173*e038c9c4Sjoerg } else if (D.IsCLMode()) {
21747330f729Sjoerg CmdArgs.push_back("-mllvm");
21757330f729Sjoerg CmdArgs.push_back("-x86-asm-syntax=intel");
21767330f729Sjoerg }
21777330f729Sjoerg
21787330f729Sjoerg // Set flags to support MCU ABI.
21797330f729Sjoerg if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu, false)) {
21807330f729Sjoerg CmdArgs.push_back("-mfloat-abi");
21817330f729Sjoerg CmdArgs.push_back("soft");
21827330f729Sjoerg CmdArgs.push_back("-mstack-alignment=4");
21837330f729Sjoerg }
2184*e038c9c4Sjoerg
2185*e038c9c4Sjoerg // Handle -mtune.
2186*e038c9c4Sjoerg
2187*e038c9c4Sjoerg // Default to "generic" unless -march is present or targetting the PS4.
2188*e038c9c4Sjoerg std::string TuneCPU;
2189*e038c9c4Sjoerg if (!Args.hasArg(clang::driver::options::OPT_march_EQ) &&
2190*e038c9c4Sjoerg !getToolChain().getTriple().isPS4CPU())
2191*e038c9c4Sjoerg TuneCPU = "generic";
2192*e038c9c4Sjoerg
2193*e038c9c4Sjoerg // Override based on -mtune.
2194*e038c9c4Sjoerg if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)) {
2195*e038c9c4Sjoerg StringRef Name = A->getValue();
2196*e038c9c4Sjoerg
2197*e038c9c4Sjoerg if (Name == "native") {
2198*e038c9c4Sjoerg Name = llvm::sys::getHostCPUName();
2199*e038c9c4Sjoerg if (!Name.empty())
2200*e038c9c4Sjoerg TuneCPU = std::string(Name);
2201*e038c9c4Sjoerg } else
2202*e038c9c4Sjoerg TuneCPU = std::string(Name);
2203*e038c9c4Sjoerg }
2204*e038c9c4Sjoerg
2205*e038c9c4Sjoerg if (!TuneCPU.empty()) {
2206*e038c9c4Sjoerg CmdArgs.push_back("-tune-cpu");
2207*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(TuneCPU));
2208*e038c9c4Sjoerg }
22097330f729Sjoerg }
22107330f729Sjoerg
AddHexagonTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const22117330f729Sjoerg void Clang::AddHexagonTargetArgs(const ArgList &Args,
22127330f729Sjoerg ArgStringList &CmdArgs) const {
22137330f729Sjoerg CmdArgs.push_back("-mqdsp6-compat");
22147330f729Sjoerg CmdArgs.push_back("-Wreturn-type");
22157330f729Sjoerg
22167330f729Sjoerg if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
22177330f729Sjoerg CmdArgs.push_back("-mllvm");
22187330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-hexagon-small-data-threshold=" +
22197330f729Sjoerg Twine(G.getValue())));
22207330f729Sjoerg }
22217330f729Sjoerg
22227330f729Sjoerg if (!Args.hasArg(options::OPT_fno_short_enums))
22237330f729Sjoerg CmdArgs.push_back("-fshort-enums");
22247330f729Sjoerg if (Args.getLastArg(options::OPT_mieee_rnd_near)) {
22257330f729Sjoerg CmdArgs.push_back("-mllvm");
22267330f729Sjoerg CmdArgs.push_back("-enable-hexagon-ieee-rnd-near");
22277330f729Sjoerg }
22287330f729Sjoerg CmdArgs.push_back("-mllvm");
22297330f729Sjoerg CmdArgs.push_back("-machine-sink-split=0");
22307330f729Sjoerg }
22317330f729Sjoerg
AddLanaiTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const22327330f729Sjoerg void Clang::AddLanaiTargetArgs(const ArgList &Args,
22337330f729Sjoerg ArgStringList &CmdArgs) const {
22347330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
22357330f729Sjoerg StringRef CPUName = A->getValue();
22367330f729Sjoerg
22377330f729Sjoerg CmdArgs.push_back("-target-cpu");
22387330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(CPUName));
22397330f729Sjoerg }
22407330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
22417330f729Sjoerg StringRef Value = A->getValue();
22427330f729Sjoerg // Only support mregparm=4 to support old usage. Report error for all other
22437330f729Sjoerg // cases.
22447330f729Sjoerg int Mregparm;
22457330f729Sjoerg if (Value.getAsInteger(10, Mregparm)) {
22467330f729Sjoerg if (Mregparm != 4) {
22477330f729Sjoerg getToolChain().getDriver().Diag(
22487330f729Sjoerg diag::err_drv_unsupported_option_argument)
22497330f729Sjoerg << A->getOption().getName() << Value;
22507330f729Sjoerg }
22517330f729Sjoerg }
22527330f729Sjoerg }
22537330f729Sjoerg }
22547330f729Sjoerg
AddWebAssemblyTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const22557330f729Sjoerg void Clang::AddWebAssemblyTargetArgs(const ArgList &Args,
22567330f729Sjoerg ArgStringList &CmdArgs) const {
22577330f729Sjoerg // Default to "hidden" visibility.
22587330f729Sjoerg if (!Args.hasArg(options::OPT_fvisibility_EQ,
22597330f729Sjoerg options::OPT_fvisibility_ms_compat)) {
22607330f729Sjoerg CmdArgs.push_back("-fvisibility");
22617330f729Sjoerg CmdArgs.push_back("hidden");
22627330f729Sjoerg }
22637330f729Sjoerg }
22647330f729Sjoerg
AddVETargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const2265*e038c9c4Sjoerg void Clang::AddVETargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
2266*e038c9c4Sjoerg // Floating point operations and argument passing are hard.
2267*e038c9c4Sjoerg CmdArgs.push_back("-mfloat-abi");
2268*e038c9c4Sjoerg CmdArgs.push_back("hard");
2269*e038c9c4Sjoerg }
2270*e038c9c4Sjoerg
DumpCompilationDatabase(Compilation & C,StringRef Filename,StringRef Target,const InputInfo & Output,const InputInfo & Input,const ArgList & Args) const22717330f729Sjoerg void Clang::DumpCompilationDatabase(Compilation &C, StringRef Filename,
22727330f729Sjoerg StringRef Target, const InputInfo &Output,
22737330f729Sjoerg const InputInfo &Input, const ArgList &Args) const {
22747330f729Sjoerg // If this is a dry run, do not create the compilation database file.
22757330f729Sjoerg if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH))
22767330f729Sjoerg return;
22777330f729Sjoerg
22787330f729Sjoerg using llvm::yaml::escape;
22797330f729Sjoerg const Driver &D = getToolChain().getDriver();
22807330f729Sjoerg
22817330f729Sjoerg if (!CompilationDatabase) {
22827330f729Sjoerg std::error_code EC;
2283*e038c9c4Sjoerg auto File = std::make_unique<llvm::raw_fd_ostream>(
2284*e038c9c4Sjoerg Filename, EC, llvm::sys::fs::OF_TextWithCRLF);
22857330f729Sjoerg if (EC) {
22867330f729Sjoerg D.Diag(clang::diag::err_drv_compilationdatabase) << Filename
22877330f729Sjoerg << EC.message();
22887330f729Sjoerg return;
22897330f729Sjoerg }
22907330f729Sjoerg CompilationDatabase = std::move(File);
22917330f729Sjoerg }
22927330f729Sjoerg auto &CDB = *CompilationDatabase;
22937330f729Sjoerg auto CWD = D.getVFS().getCurrentWorkingDirectory();
22947330f729Sjoerg if (!CWD)
22957330f729Sjoerg CWD = ".";
22967330f729Sjoerg CDB << "{ \"directory\": \"" << escape(*CWD) << "\"";
22977330f729Sjoerg CDB << ", \"file\": \"" << escape(Input.getFilename()) << "\"";
22987330f729Sjoerg CDB << ", \"output\": \"" << escape(Output.getFilename()) << "\"";
22997330f729Sjoerg CDB << ", \"arguments\": [\"" << escape(D.ClangExecutable) << "\"";
23007330f729Sjoerg SmallString<128> Buf;
23017330f729Sjoerg Buf = "-x";
23027330f729Sjoerg Buf += types::getTypeName(Input.getType());
23037330f729Sjoerg CDB << ", \"" << escape(Buf) << "\"";
23047330f729Sjoerg if (!D.SysRoot.empty() && !Args.hasArg(options::OPT__sysroot_EQ)) {
23057330f729Sjoerg Buf = "--sysroot=";
23067330f729Sjoerg Buf += D.SysRoot;
23077330f729Sjoerg CDB << ", \"" << escape(Buf) << "\"";
23087330f729Sjoerg }
23097330f729Sjoerg CDB << ", \"" << escape(Input.getFilename()) << "\"";
23107330f729Sjoerg for (auto &A: Args) {
23117330f729Sjoerg auto &O = A->getOption();
23127330f729Sjoerg // Skip language selection, which is positional.
23137330f729Sjoerg if (O.getID() == options::OPT_x)
23147330f729Sjoerg continue;
23157330f729Sjoerg // Skip writing dependency output and the compilation database itself.
23167330f729Sjoerg if (O.getGroup().isValid() && O.getGroup().getID() == options::OPT_M_Group)
23177330f729Sjoerg continue;
23187330f729Sjoerg if (O.getID() == options::OPT_gen_cdb_fragment_path)
23197330f729Sjoerg continue;
23207330f729Sjoerg // Skip inputs.
23217330f729Sjoerg if (O.getKind() == Option::InputClass)
23227330f729Sjoerg continue;
23237330f729Sjoerg // All other arguments are quoted and appended.
23247330f729Sjoerg ArgStringList ASL;
23257330f729Sjoerg A->render(Args, ASL);
23267330f729Sjoerg for (auto &it: ASL)
23277330f729Sjoerg CDB << ", \"" << escape(it) << "\"";
23287330f729Sjoerg }
23297330f729Sjoerg Buf = "--target=";
23307330f729Sjoerg Buf += Target;
23317330f729Sjoerg CDB << ", \"" << escape(Buf) << "\"]},\n";
23327330f729Sjoerg }
23337330f729Sjoerg
DumpCompilationDatabaseFragmentToDir(StringRef Dir,Compilation & C,StringRef Target,const InputInfo & Output,const InputInfo & Input,const llvm::opt::ArgList & Args) const23347330f729Sjoerg void Clang::DumpCompilationDatabaseFragmentToDir(
23357330f729Sjoerg StringRef Dir, Compilation &C, StringRef Target, const InputInfo &Output,
23367330f729Sjoerg const InputInfo &Input, const llvm::opt::ArgList &Args) const {
23377330f729Sjoerg // If this is a dry run, do not create the compilation database file.
23387330f729Sjoerg if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH))
23397330f729Sjoerg return;
23407330f729Sjoerg
23417330f729Sjoerg if (CompilationDatabase)
23427330f729Sjoerg DumpCompilationDatabase(C, "", Target, Output, Input, Args);
23437330f729Sjoerg
23447330f729Sjoerg SmallString<256> Path = Dir;
23457330f729Sjoerg const auto &Driver = C.getDriver();
23467330f729Sjoerg Driver.getVFS().makeAbsolute(Path);
23477330f729Sjoerg auto Err = llvm::sys::fs::create_directory(Path, /*IgnoreExisting=*/true);
23487330f729Sjoerg if (Err) {
23497330f729Sjoerg Driver.Diag(diag::err_drv_compilationdatabase) << Dir << Err.message();
23507330f729Sjoerg return;
23517330f729Sjoerg }
23527330f729Sjoerg
23537330f729Sjoerg llvm::sys::path::append(
23547330f729Sjoerg Path,
23557330f729Sjoerg Twine(llvm::sys::path::filename(Input.getFilename())) + ".%%%%.json");
23567330f729Sjoerg int FD;
23577330f729Sjoerg SmallString<256> TempPath;
2358*e038c9c4Sjoerg Err = llvm::sys::fs::createUniqueFile(Path, FD, TempPath,
2359*e038c9c4Sjoerg llvm::sys::fs::OF_Text);
23607330f729Sjoerg if (Err) {
23617330f729Sjoerg Driver.Diag(diag::err_drv_compilationdatabase) << Path << Err.message();
23627330f729Sjoerg return;
23637330f729Sjoerg }
23647330f729Sjoerg CompilationDatabase =
23657330f729Sjoerg std::make_unique<llvm::raw_fd_ostream>(FD, /*shouldClose=*/true);
23667330f729Sjoerg DumpCompilationDatabase(C, "", Target, Output, Input, Args);
23677330f729Sjoerg }
23687330f729Sjoerg
CheckARMImplicitITArg(StringRef Value)2369*e038c9c4Sjoerg static bool CheckARMImplicitITArg(StringRef Value) {
2370*e038c9c4Sjoerg return Value == "always" || Value == "never" || Value == "arm" ||
2371*e038c9c4Sjoerg Value == "thumb";
2372*e038c9c4Sjoerg }
2373*e038c9c4Sjoerg
AddARMImplicitITArgs(const ArgList & Args,ArgStringList & CmdArgs,StringRef Value)2374*e038c9c4Sjoerg static void AddARMImplicitITArgs(const ArgList &Args, ArgStringList &CmdArgs,
2375*e038c9c4Sjoerg StringRef Value) {
2376*e038c9c4Sjoerg CmdArgs.push_back("-mllvm");
2377*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString("-arm-implicit-it=" + Value));
2378*e038c9c4Sjoerg }
2379*e038c9c4Sjoerg
CollectArgsForIntegratedAssembler(Compilation & C,const ArgList & Args,ArgStringList & CmdArgs,const Driver & D)23807330f729Sjoerg static void CollectArgsForIntegratedAssembler(Compilation &C,
23817330f729Sjoerg const ArgList &Args,
23827330f729Sjoerg ArgStringList &CmdArgs,
23837330f729Sjoerg const Driver &D) {
23847330f729Sjoerg if (UseRelaxAll(C, Args))
23857330f729Sjoerg CmdArgs.push_back("-mrelax-all");
23867330f729Sjoerg
23877330f729Sjoerg // Only default to -mincremental-linker-compatible if we think we are
23887330f729Sjoerg // targeting the MSVC linker.
23897330f729Sjoerg bool DefaultIncrementalLinkerCompatible =
23907330f729Sjoerg C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
23917330f729Sjoerg if (Args.hasFlag(options::OPT_mincremental_linker_compatible,
23927330f729Sjoerg options::OPT_mno_incremental_linker_compatible,
23937330f729Sjoerg DefaultIncrementalLinkerCompatible))
23947330f729Sjoerg CmdArgs.push_back("-mincremental-linker-compatible");
23957330f729Sjoerg
23967330f729Sjoerg // If you add more args here, also add them to the block below that
23977330f729Sjoerg // starts with "// If CollectArgsForIntegratedAssembler() isn't called below".
23987330f729Sjoerg
23997330f729Sjoerg // When passing -I arguments to the assembler we sometimes need to
24007330f729Sjoerg // unconditionally take the next argument. For example, when parsing
24017330f729Sjoerg // '-Wa,-I -Wa,foo' we need to accept the -Wa,foo arg after seeing the
24027330f729Sjoerg // -Wa,-I arg and when parsing '-Wa,-I,foo' we need to accept the 'foo'
24037330f729Sjoerg // arg after parsing the '-I' arg.
24047330f729Sjoerg bool TakeNextArg = false;
24057330f729Sjoerg
24067330f729Sjoerg bool UseRelaxRelocations = C.getDefaultToolChain().useRelaxRelocations();
24077330f729Sjoerg bool UseNoExecStack = C.getDefaultToolChain().isNoExecStackDefault();
24087330f729Sjoerg const char *MipsTargetFeature = nullptr;
2409*e038c9c4Sjoerg StringRef ImplicitIt;
24107330f729Sjoerg for (const Arg *A :
2411*e038c9c4Sjoerg Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler,
2412*e038c9c4Sjoerg options::OPT_mimplicit_it_EQ)) {
2413*e038c9c4Sjoerg if (A->getOption().getID() == options::OPT_mimplicit_it_EQ) {
2414*e038c9c4Sjoerg switch (C.getDefaultToolChain().getArch()) {
2415*e038c9c4Sjoerg case llvm::Triple::arm:
2416*e038c9c4Sjoerg case llvm::Triple::armeb:
2417*e038c9c4Sjoerg case llvm::Triple::thumb:
2418*e038c9c4Sjoerg case llvm::Triple::thumbeb:
2419*e038c9c4Sjoerg // Only store the value; the last value set takes effect.
2420*e038c9c4Sjoerg ImplicitIt = A->getValue();
2421*e038c9c4Sjoerg if (!CheckARMImplicitITArg(ImplicitIt))
2422*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_option_argument)
2423*e038c9c4Sjoerg << A->getOption().getName() << ImplicitIt;
2424*e038c9c4Sjoerg continue;
2425*e038c9c4Sjoerg default:
2426*e038c9c4Sjoerg break;
2427*e038c9c4Sjoerg }
2428*e038c9c4Sjoerg }
2429*e038c9c4Sjoerg
24307330f729Sjoerg A->claim();
24317330f729Sjoerg
24327330f729Sjoerg for (StringRef Value : A->getValues()) {
24337330f729Sjoerg if (TakeNextArg) {
24347330f729Sjoerg CmdArgs.push_back(Value.data());
24357330f729Sjoerg TakeNextArg = false;
24367330f729Sjoerg continue;
24377330f729Sjoerg }
24387330f729Sjoerg
24397330f729Sjoerg if (C.getDefaultToolChain().getTriple().isOSBinFormatCOFF() &&
24407330f729Sjoerg Value == "-mbig-obj")
24417330f729Sjoerg continue; // LLVM handles bigobj automatically
24427330f729Sjoerg
24437330f729Sjoerg switch (C.getDefaultToolChain().getArch()) {
24447330f729Sjoerg default:
24457330f729Sjoerg break;
24467330f729Sjoerg case llvm::Triple::thumb:
24477330f729Sjoerg case llvm::Triple::thumbeb:
24487330f729Sjoerg case llvm::Triple::arm:
24497330f729Sjoerg case llvm::Triple::armeb:
2450*e038c9c4Sjoerg if (Value.startswith("-mimplicit-it=")) {
2451*e038c9c4Sjoerg // Only store the value; the last value set takes effect.
2452*e038c9c4Sjoerg ImplicitIt = Value.split("=").second;
2453*e038c9c4Sjoerg if (CheckARMImplicitITArg(ImplicitIt))
2454*e038c9c4Sjoerg continue;
2455*e038c9c4Sjoerg }
24567330f729Sjoerg if (Value == "-mthumb")
24577330f729Sjoerg // -mthumb has already been processed in ComputeLLVMTriple()
24587330f729Sjoerg // recognize but skip over here.
24597330f729Sjoerg continue;
24607330f729Sjoerg break;
24617330f729Sjoerg case llvm::Triple::mips:
24627330f729Sjoerg case llvm::Triple::mipsel:
24637330f729Sjoerg case llvm::Triple::mips64:
24647330f729Sjoerg case llvm::Triple::mips64el:
24657330f729Sjoerg if (Value == "--trap") {
24667330f729Sjoerg CmdArgs.push_back("-target-feature");
24677330f729Sjoerg CmdArgs.push_back("+use-tcc-in-div");
24687330f729Sjoerg continue;
24697330f729Sjoerg }
24707330f729Sjoerg if (Value == "--break") {
24717330f729Sjoerg CmdArgs.push_back("-target-feature");
24727330f729Sjoerg CmdArgs.push_back("-use-tcc-in-div");
24737330f729Sjoerg continue;
24747330f729Sjoerg }
24757330f729Sjoerg if (Value.startswith("-msoft-float")) {
24767330f729Sjoerg CmdArgs.push_back("-target-feature");
24777330f729Sjoerg CmdArgs.push_back("+soft-float");
24787330f729Sjoerg continue;
24797330f729Sjoerg }
24807330f729Sjoerg if (Value.startswith("-mhard-float")) {
24817330f729Sjoerg CmdArgs.push_back("-target-feature");
24827330f729Sjoerg CmdArgs.push_back("-soft-float");
24837330f729Sjoerg continue;
24847330f729Sjoerg }
24857330f729Sjoerg
24867330f729Sjoerg MipsTargetFeature = llvm::StringSwitch<const char *>(Value)
24877330f729Sjoerg .Case("-mips1", "+mips1")
24887330f729Sjoerg .Case("-mips2", "+mips2")
24897330f729Sjoerg .Case("-mips3", "+mips3")
24907330f729Sjoerg .Case("-mips4", "+mips4")
24917330f729Sjoerg .Case("-mips5", "+mips5")
24927330f729Sjoerg .Case("-mips32", "+mips32")
24937330f729Sjoerg .Case("-mips32r2", "+mips32r2")
24947330f729Sjoerg .Case("-mips32r3", "+mips32r3")
24957330f729Sjoerg .Case("-mips32r5", "+mips32r5")
24967330f729Sjoerg .Case("-mips32r6", "+mips32r6")
24977330f729Sjoerg .Case("-mips64", "+mips64")
24987330f729Sjoerg .Case("-mips64r2", "+mips64r2")
24997330f729Sjoerg .Case("-mips64r3", "+mips64r3")
25007330f729Sjoerg .Case("-mips64r5", "+mips64r5")
25017330f729Sjoerg .Case("-mips64r6", "+mips64r6")
25027330f729Sjoerg .Default(nullptr);
25037330f729Sjoerg if (MipsTargetFeature)
25047330f729Sjoerg continue;
25057330f729Sjoerg }
25067330f729Sjoerg
25077330f729Sjoerg if (Value == "-force_cpusubtype_ALL") {
25087330f729Sjoerg // Do nothing, this is the default and we don't support anything else.
25097330f729Sjoerg } else if (Value == "-L") {
25107330f729Sjoerg CmdArgs.push_back("-msave-temp-labels");
25117330f729Sjoerg } else if (Value == "--fatal-warnings") {
25127330f729Sjoerg CmdArgs.push_back("-massembler-fatal-warnings");
25137330f729Sjoerg } else if (Value == "--no-warn" || Value == "-W") {
25147330f729Sjoerg CmdArgs.push_back("-massembler-no-warn");
25157330f729Sjoerg } else if (Value == "--noexecstack") {
25167330f729Sjoerg UseNoExecStack = true;
25177330f729Sjoerg } else if (Value.startswith("-compress-debug-sections") ||
25187330f729Sjoerg Value.startswith("--compress-debug-sections") ||
25197330f729Sjoerg Value == "-nocompress-debug-sections" ||
25207330f729Sjoerg Value == "--nocompress-debug-sections") {
25217330f729Sjoerg CmdArgs.push_back(Value.data());
25227330f729Sjoerg } else if (Value == "-mrelax-relocations=yes" ||
25237330f729Sjoerg Value == "--mrelax-relocations=yes") {
25247330f729Sjoerg UseRelaxRelocations = true;
25257330f729Sjoerg } else if (Value == "-mrelax-relocations=no" ||
25267330f729Sjoerg Value == "--mrelax-relocations=no") {
25277330f729Sjoerg UseRelaxRelocations = false;
25287330f729Sjoerg } else if (Value.startswith("-I")) {
25297330f729Sjoerg CmdArgs.push_back(Value.data());
25307330f729Sjoerg // We need to consume the next argument if the current arg is a plain
25317330f729Sjoerg // -I. The next arg will be the include directory.
25327330f729Sjoerg if (Value == "-I")
25337330f729Sjoerg TakeNextArg = true;
25347330f729Sjoerg } else if (Value.startswith("-gdwarf-")) {
25357330f729Sjoerg // "-gdwarf-N" options are not cc1as options.
25367330f729Sjoerg unsigned DwarfVersion = DwarfVersionNum(Value);
25377330f729Sjoerg if (DwarfVersion == 0) { // Send it onward, and let cc1as complain.
25387330f729Sjoerg CmdArgs.push_back(Value.data());
25397330f729Sjoerg } else {
25407330f729Sjoerg RenderDebugEnablingArgs(Args, CmdArgs,
25417330f729Sjoerg codegenoptions::LimitedDebugInfo,
25427330f729Sjoerg DwarfVersion, llvm::DebuggerKind::Default);
25437330f729Sjoerg }
25447330f729Sjoerg } else if (Value.startswith("-mcpu") || Value.startswith("-mfpu") ||
25457330f729Sjoerg Value.startswith("-mhwdiv") || Value.startswith("-march")) {
25467330f729Sjoerg // Do nothing, we'll validate it later.
25477330f729Sjoerg } else if (Value == "-defsym") {
25487330f729Sjoerg if (A->getNumValues() != 2) {
25497330f729Sjoerg D.Diag(diag::err_drv_defsym_invalid_format) << Value;
25507330f729Sjoerg break;
25517330f729Sjoerg }
25527330f729Sjoerg const char *S = A->getValue(1);
25537330f729Sjoerg auto Pair = StringRef(S).split('=');
25547330f729Sjoerg auto Sym = Pair.first;
25557330f729Sjoerg auto SVal = Pair.second;
25567330f729Sjoerg
25577330f729Sjoerg if (Sym.empty() || SVal.empty()) {
25587330f729Sjoerg D.Diag(diag::err_drv_defsym_invalid_format) << S;
25597330f729Sjoerg break;
25607330f729Sjoerg }
25617330f729Sjoerg int64_t IVal;
25627330f729Sjoerg if (SVal.getAsInteger(0, IVal)) {
25637330f729Sjoerg D.Diag(diag::err_drv_defsym_invalid_symval) << SVal;
25647330f729Sjoerg break;
25657330f729Sjoerg }
25667330f729Sjoerg CmdArgs.push_back(Value.data());
25677330f729Sjoerg TakeNextArg = true;
25687330f729Sjoerg } else if (Value == "-fdebug-compilation-dir") {
25697330f729Sjoerg CmdArgs.push_back("-fdebug-compilation-dir");
25707330f729Sjoerg TakeNextArg = true;
2571*e038c9c4Sjoerg } else if (Value.consume_front("-fdebug-compilation-dir=")) {
2572*e038c9c4Sjoerg // The flag is a -Wa / -Xassembler argument and Options doesn't
2573*e038c9c4Sjoerg // parse the argument, so this isn't automatically aliased to
2574*e038c9c4Sjoerg // -fdebug-compilation-dir (without '=') here.
2575*e038c9c4Sjoerg CmdArgs.push_back("-fdebug-compilation-dir");
2576*e038c9c4Sjoerg CmdArgs.push_back(Value.data());
2577*e038c9c4Sjoerg } else if (Value == "--version") {
2578*e038c9c4Sjoerg D.PrintVersion(C, llvm::outs());
25797330f729Sjoerg } else {
25807330f729Sjoerg D.Diag(diag::err_drv_unsupported_option_argument)
25817330f729Sjoerg << A->getOption().getName() << Value;
25827330f729Sjoerg }
25837330f729Sjoerg }
25847330f729Sjoerg }
2585*e038c9c4Sjoerg if (ImplicitIt.size())
2586*e038c9c4Sjoerg AddARMImplicitITArgs(Args, CmdArgs, ImplicitIt);
25877330f729Sjoerg if (UseRelaxRelocations)
25887330f729Sjoerg CmdArgs.push_back("--mrelax-relocations");
25897330f729Sjoerg if (UseNoExecStack)
25907330f729Sjoerg CmdArgs.push_back("-mnoexecstack");
25917330f729Sjoerg if (MipsTargetFeature != nullptr) {
25927330f729Sjoerg CmdArgs.push_back("-target-feature");
25937330f729Sjoerg CmdArgs.push_back(MipsTargetFeature);
25947330f729Sjoerg }
25957330f729Sjoerg
25967330f729Sjoerg // forward -fembed-bitcode to assmebler
25977330f729Sjoerg if (C.getDriver().embedBitcodeEnabled() ||
25987330f729Sjoerg C.getDriver().embedBitcodeMarkerOnly())
25997330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fembed_bitcode_EQ);
26007330f729Sjoerg }
26017330f729Sjoerg
RenderFloatingPointOptions(const ToolChain & TC,const Driver & D,bool OFastEnabled,const ArgList & Args,ArgStringList & CmdArgs,const JobAction & JA)26027330f729Sjoerg static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
26037330f729Sjoerg bool OFastEnabled, const ArgList &Args,
2604*e038c9c4Sjoerg ArgStringList &CmdArgs,
2605*e038c9c4Sjoerg const JobAction &JA) {
26067330f729Sjoerg // Handle various floating point optimization flags, mapping them to the
26077330f729Sjoerg // appropriate LLVM code generation flags. This is complicated by several
26087330f729Sjoerg // "umbrella" flags, so we do this by stepping through the flags incrementally
26097330f729Sjoerg // adjusting what we think is enabled/disabled, then at the end setting the
26107330f729Sjoerg // LLVM flags based on the final state.
26117330f729Sjoerg bool HonorINFs = true;
26127330f729Sjoerg bool HonorNaNs = true;
26137330f729Sjoerg // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes.
26147330f729Sjoerg bool MathErrno = TC.IsMathErrnoDefault();
26157330f729Sjoerg bool AssociativeMath = false;
26167330f729Sjoerg bool ReciprocalMath = false;
26177330f729Sjoerg bool SignedZeros = true;
2618*e038c9c4Sjoerg bool TrappingMath = false; // Implemented via -ffp-exception-behavior
2619*e038c9c4Sjoerg bool TrappingMathPresent = false; // Is trapping-math in args, and not
2620*e038c9c4Sjoerg // overriden by ffp-exception-behavior?
2621*e038c9c4Sjoerg bool RoundingFPMath = false;
2622*e038c9c4Sjoerg bool RoundingMathPresent = false; // Is rounding-math in args?
2623*e038c9c4Sjoerg // -ffp-model values: strict, fast, precise
2624*e038c9c4Sjoerg StringRef FPModel = "";
2625*e038c9c4Sjoerg // -ffp-exception-behavior options: strict, maytrap, ignore
2626*e038c9c4Sjoerg StringRef FPExceptionBehavior = "";
2627*e038c9c4Sjoerg const llvm::DenormalMode DefaultDenormalFPMath =
2628*e038c9c4Sjoerg TC.getDefaultDenormalModeForType(Args, JA);
2629*e038c9c4Sjoerg const llvm::DenormalMode DefaultDenormalFP32Math =
2630*e038c9c4Sjoerg TC.getDefaultDenormalModeForType(Args, JA, &llvm::APFloat::IEEEsingle());
2631*e038c9c4Sjoerg
2632*e038c9c4Sjoerg llvm::DenormalMode DenormalFPMath = DefaultDenormalFPMath;
2633*e038c9c4Sjoerg llvm::DenormalMode DenormalFP32Math = DefaultDenormalFP32Math;
26347330f729Sjoerg StringRef FPContract = "";
2635*e038c9c4Sjoerg bool StrictFPModel = false;
2636*e038c9c4Sjoerg
26377330f729Sjoerg
26387330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
26397330f729Sjoerg CmdArgs.push_back("-mlimit-float-precision");
26407330f729Sjoerg CmdArgs.push_back(A->getValue());
26417330f729Sjoerg }
26427330f729Sjoerg
26437330f729Sjoerg for (const Arg *A : Args) {
2644*e038c9c4Sjoerg auto optID = A->getOption().getID();
2645*e038c9c4Sjoerg bool PreciseFPModel = false;
2646*e038c9c4Sjoerg switch (optID) {
2647*e038c9c4Sjoerg default:
2648*e038c9c4Sjoerg break;
2649*e038c9c4Sjoerg case options::OPT_ffp_model_EQ: {
2650*e038c9c4Sjoerg // If -ffp-model= is seen, reset to fno-fast-math
2651*e038c9c4Sjoerg HonorINFs = true;
2652*e038c9c4Sjoerg HonorNaNs = true;
2653*e038c9c4Sjoerg // Turning *off* -ffast-math restores the toolchain default.
2654*e038c9c4Sjoerg MathErrno = TC.IsMathErrnoDefault();
2655*e038c9c4Sjoerg AssociativeMath = false;
2656*e038c9c4Sjoerg ReciprocalMath = false;
2657*e038c9c4Sjoerg SignedZeros = true;
2658*e038c9c4Sjoerg // -fno_fast_math restores default denormal and fpcontract handling
2659*e038c9c4Sjoerg FPContract = "";
2660*e038c9c4Sjoerg DenormalFPMath = llvm::DenormalMode::getIEEE();
2661*e038c9c4Sjoerg
2662*e038c9c4Sjoerg // FIXME: The target may have picked a non-IEEE default mode here based on
2663*e038c9c4Sjoerg // -cl-denorms-are-zero. Should the target consider -fp-model interaction?
2664*e038c9c4Sjoerg DenormalFP32Math = llvm::DenormalMode::getIEEE();
2665*e038c9c4Sjoerg
2666*e038c9c4Sjoerg StringRef Val = A->getValue();
2667*e038c9c4Sjoerg if (OFastEnabled && !Val.equals("fast")) {
2668*e038c9c4Sjoerg // Only -ffp-model=fast is compatible with OFast, ignore.
2669*e038c9c4Sjoerg D.Diag(clang::diag::warn_drv_overriding_flag_option)
2670*e038c9c4Sjoerg << Args.MakeArgString("-ffp-model=" + Val)
2671*e038c9c4Sjoerg << "-Ofast";
2672*e038c9c4Sjoerg break;
2673*e038c9c4Sjoerg }
2674*e038c9c4Sjoerg StrictFPModel = false;
2675*e038c9c4Sjoerg PreciseFPModel = true;
2676*e038c9c4Sjoerg // ffp-model= is a Driver option, it is entirely rewritten into more
2677*e038c9c4Sjoerg // granular options before being passed into cc1.
2678*e038c9c4Sjoerg // Use the gcc option in the switch below.
2679*e038c9c4Sjoerg if (!FPModel.empty() && !FPModel.equals(Val)) {
2680*e038c9c4Sjoerg D.Diag(clang::diag::warn_drv_overriding_flag_option)
2681*e038c9c4Sjoerg << Args.MakeArgString("-ffp-model=" + FPModel)
2682*e038c9c4Sjoerg << Args.MakeArgString("-ffp-model=" + Val);
2683*e038c9c4Sjoerg FPContract = "";
2684*e038c9c4Sjoerg }
2685*e038c9c4Sjoerg if (Val.equals("fast")) {
2686*e038c9c4Sjoerg optID = options::OPT_ffast_math;
2687*e038c9c4Sjoerg FPModel = Val;
2688*e038c9c4Sjoerg FPContract = "fast";
2689*e038c9c4Sjoerg } else if (Val.equals("precise")) {
2690*e038c9c4Sjoerg optID = options::OPT_ffp_contract;
2691*e038c9c4Sjoerg FPModel = Val;
2692*e038c9c4Sjoerg FPContract = "fast";
2693*e038c9c4Sjoerg PreciseFPModel = true;
2694*e038c9c4Sjoerg } else if (Val.equals("strict")) {
2695*e038c9c4Sjoerg StrictFPModel = true;
2696*e038c9c4Sjoerg optID = options::OPT_frounding_math;
2697*e038c9c4Sjoerg FPExceptionBehavior = "strict";
2698*e038c9c4Sjoerg FPModel = Val;
2699*e038c9c4Sjoerg FPContract = "off";
2700*e038c9c4Sjoerg TrappingMath = true;
2701*e038c9c4Sjoerg } else
2702*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_option_argument)
2703*e038c9c4Sjoerg << A->getOption().getName() << Val;
2704*e038c9c4Sjoerg break;
2705*e038c9c4Sjoerg }
2706*e038c9c4Sjoerg }
2707*e038c9c4Sjoerg
2708*e038c9c4Sjoerg switch (optID) {
27097330f729Sjoerg // If this isn't an FP option skip the claim below
27107330f729Sjoerg default: continue;
27117330f729Sjoerg
27127330f729Sjoerg // Options controlling individual features
27137330f729Sjoerg case options::OPT_fhonor_infinities: HonorINFs = true; break;
27147330f729Sjoerg case options::OPT_fno_honor_infinities: HonorINFs = false; break;
27157330f729Sjoerg case options::OPT_fhonor_nans: HonorNaNs = true; break;
27167330f729Sjoerg case options::OPT_fno_honor_nans: HonorNaNs = false; break;
27177330f729Sjoerg case options::OPT_fmath_errno: MathErrno = true; break;
27187330f729Sjoerg case options::OPT_fno_math_errno: MathErrno = false; break;
27197330f729Sjoerg case options::OPT_fassociative_math: AssociativeMath = true; break;
27207330f729Sjoerg case options::OPT_fno_associative_math: AssociativeMath = false; break;
27217330f729Sjoerg case options::OPT_freciprocal_math: ReciprocalMath = true; break;
27227330f729Sjoerg case options::OPT_fno_reciprocal_math: ReciprocalMath = false; break;
27237330f729Sjoerg case options::OPT_fsigned_zeros: SignedZeros = true; break;
27247330f729Sjoerg case options::OPT_fno_signed_zeros: SignedZeros = false; break;
2725*e038c9c4Sjoerg case options::OPT_ftrapping_math:
2726*e038c9c4Sjoerg if (!TrappingMathPresent && !FPExceptionBehavior.empty() &&
2727*e038c9c4Sjoerg !FPExceptionBehavior.equals("strict"))
2728*e038c9c4Sjoerg // Warn that previous value of option is overridden.
2729*e038c9c4Sjoerg D.Diag(clang::diag::warn_drv_overriding_flag_option)
2730*e038c9c4Sjoerg << Args.MakeArgString("-ffp-exception-behavior=" + FPExceptionBehavior)
2731*e038c9c4Sjoerg << "-ftrapping-math";
2732*e038c9c4Sjoerg TrappingMath = true;
2733*e038c9c4Sjoerg TrappingMathPresent = true;
2734*e038c9c4Sjoerg FPExceptionBehavior = "strict";
2735*e038c9c4Sjoerg break;
2736*e038c9c4Sjoerg case options::OPT_fno_trapping_math:
2737*e038c9c4Sjoerg if (!TrappingMathPresent && !FPExceptionBehavior.empty() &&
2738*e038c9c4Sjoerg !FPExceptionBehavior.equals("ignore"))
2739*e038c9c4Sjoerg // Warn that previous value of option is overridden.
2740*e038c9c4Sjoerg D.Diag(clang::diag::warn_drv_overriding_flag_option)
2741*e038c9c4Sjoerg << Args.MakeArgString("-ffp-exception-behavior=" + FPExceptionBehavior)
2742*e038c9c4Sjoerg << "-fno-trapping-math";
2743*e038c9c4Sjoerg TrappingMath = false;
2744*e038c9c4Sjoerg TrappingMathPresent = true;
2745*e038c9c4Sjoerg FPExceptionBehavior = "ignore";
27467330f729Sjoerg break;
27477330f729Sjoerg
2748*e038c9c4Sjoerg case options::OPT_frounding_math:
2749*e038c9c4Sjoerg RoundingFPMath = true;
2750*e038c9c4Sjoerg RoundingMathPresent = true;
2751*e038c9c4Sjoerg break;
2752*e038c9c4Sjoerg
2753*e038c9c4Sjoerg case options::OPT_fno_rounding_math:
2754*e038c9c4Sjoerg RoundingFPMath = false;
2755*e038c9c4Sjoerg RoundingMathPresent = false;
2756*e038c9c4Sjoerg break;
2757*e038c9c4Sjoerg
2758*e038c9c4Sjoerg case options::OPT_fdenormal_fp_math_EQ:
2759*e038c9c4Sjoerg DenormalFPMath = llvm::parseDenormalFPAttribute(A->getValue());
2760*e038c9c4Sjoerg if (!DenormalFPMath.isValid()) {
2761*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_value)
2762*e038c9c4Sjoerg << A->getAsString(Args) << A->getValue();
2763*e038c9c4Sjoerg }
2764*e038c9c4Sjoerg break;
2765*e038c9c4Sjoerg
2766*e038c9c4Sjoerg case options::OPT_fdenormal_fp_math_f32_EQ:
2767*e038c9c4Sjoerg DenormalFP32Math = llvm::parseDenormalFPAttribute(A->getValue());
2768*e038c9c4Sjoerg if (!DenormalFP32Math.isValid()) {
2769*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_value)
2770*e038c9c4Sjoerg << A->getAsString(Args) << A->getValue();
2771*e038c9c4Sjoerg }
2772*e038c9c4Sjoerg break;
2773*e038c9c4Sjoerg
2774*e038c9c4Sjoerg // Validate and pass through -ffp-contract option.
27757330f729Sjoerg case options::OPT_ffp_contract: {
27767330f729Sjoerg StringRef Val = A->getValue();
2777*e038c9c4Sjoerg if (PreciseFPModel) {
2778*e038c9c4Sjoerg // -ffp-model=precise enables ffp-contract=fast as a side effect
2779*e038c9c4Sjoerg // the FPContract value has already been set to a string literal
2780*e038c9c4Sjoerg // and the Val string isn't a pertinent value.
2781*e038c9c4Sjoerg ;
2782*e038c9c4Sjoerg } else if (Val.equals("fast") || Val.equals("on") || Val.equals("off"))
27837330f729Sjoerg FPContract = Val;
27847330f729Sjoerg else
27857330f729Sjoerg D.Diag(diag::err_drv_unsupported_option_argument)
27867330f729Sjoerg << A->getOption().getName() << Val;
27877330f729Sjoerg break;
27887330f729Sjoerg }
27897330f729Sjoerg
2790*e038c9c4Sjoerg // Validate and pass through -ffp-model option.
2791*e038c9c4Sjoerg case options::OPT_ffp_model_EQ:
2792*e038c9c4Sjoerg // This should only occur in the error case
2793*e038c9c4Sjoerg // since the optID has been replaced by a more granular
2794*e038c9c4Sjoerg // floating point option.
2795*e038c9c4Sjoerg break;
2796*e038c9c4Sjoerg
2797*e038c9c4Sjoerg // Validate and pass through -ffp-exception-behavior option.
2798*e038c9c4Sjoerg case options::OPT_ffp_exception_behavior_EQ: {
2799*e038c9c4Sjoerg StringRef Val = A->getValue();
2800*e038c9c4Sjoerg if (!TrappingMathPresent && !FPExceptionBehavior.empty() &&
2801*e038c9c4Sjoerg !FPExceptionBehavior.equals(Val))
2802*e038c9c4Sjoerg // Warn that previous value of option is overridden.
2803*e038c9c4Sjoerg D.Diag(clang::diag::warn_drv_overriding_flag_option)
2804*e038c9c4Sjoerg << Args.MakeArgString("-ffp-exception-behavior=" + FPExceptionBehavior)
2805*e038c9c4Sjoerg << Args.MakeArgString("-ffp-exception-behavior=" + Val);
2806*e038c9c4Sjoerg TrappingMath = TrappingMathPresent = false;
2807*e038c9c4Sjoerg if (Val.equals("ignore") || Val.equals("maytrap"))
2808*e038c9c4Sjoerg FPExceptionBehavior = Val;
2809*e038c9c4Sjoerg else if (Val.equals("strict")) {
2810*e038c9c4Sjoerg FPExceptionBehavior = Val;
2811*e038c9c4Sjoerg TrappingMath = TrappingMathPresent = true;
2812*e038c9c4Sjoerg } else
2813*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_option_argument)
2814*e038c9c4Sjoerg << A->getOption().getName() << Val;
2815*e038c9c4Sjoerg break;
2816*e038c9c4Sjoerg }
2817*e038c9c4Sjoerg
28187330f729Sjoerg case options::OPT_ffinite_math_only:
28197330f729Sjoerg HonorINFs = false;
28207330f729Sjoerg HonorNaNs = false;
28217330f729Sjoerg break;
28227330f729Sjoerg case options::OPT_fno_finite_math_only:
28237330f729Sjoerg HonorINFs = true;
28247330f729Sjoerg HonorNaNs = true;
28257330f729Sjoerg break;
28267330f729Sjoerg
28277330f729Sjoerg case options::OPT_funsafe_math_optimizations:
28287330f729Sjoerg AssociativeMath = true;
28297330f729Sjoerg ReciprocalMath = true;
28307330f729Sjoerg SignedZeros = false;
28317330f729Sjoerg TrappingMath = false;
2832*e038c9c4Sjoerg FPExceptionBehavior = "";
28337330f729Sjoerg break;
28347330f729Sjoerg case options::OPT_fno_unsafe_math_optimizations:
28357330f729Sjoerg AssociativeMath = false;
28367330f729Sjoerg ReciprocalMath = false;
28377330f729Sjoerg SignedZeros = true;
28387330f729Sjoerg TrappingMath = true;
2839*e038c9c4Sjoerg FPExceptionBehavior = "strict";
2840*e038c9c4Sjoerg
2841*e038c9c4Sjoerg // The target may have opted to flush by default, so force IEEE.
2842*e038c9c4Sjoerg DenormalFPMath = llvm::DenormalMode::getIEEE();
2843*e038c9c4Sjoerg DenormalFP32Math = llvm::DenormalMode::getIEEE();
28447330f729Sjoerg break;
28457330f729Sjoerg
28467330f729Sjoerg case options::OPT_Ofast:
28477330f729Sjoerg // If -Ofast is the optimization level, then -ffast-math should be enabled
28487330f729Sjoerg if (!OFastEnabled)
28497330f729Sjoerg continue;
28507330f729Sjoerg LLVM_FALLTHROUGH;
28517330f729Sjoerg case options::OPT_ffast_math:
28527330f729Sjoerg HonorINFs = false;
28537330f729Sjoerg HonorNaNs = false;
28547330f729Sjoerg MathErrno = false;
28557330f729Sjoerg AssociativeMath = true;
28567330f729Sjoerg ReciprocalMath = true;
28577330f729Sjoerg SignedZeros = false;
28587330f729Sjoerg TrappingMath = false;
2859*e038c9c4Sjoerg RoundingFPMath = false;
28607330f729Sjoerg // If fast-math is set then set the fp-contract mode to fast.
28617330f729Sjoerg FPContract = "fast";
28627330f729Sjoerg break;
28637330f729Sjoerg case options::OPT_fno_fast_math:
28647330f729Sjoerg HonorINFs = true;
28657330f729Sjoerg HonorNaNs = true;
28667330f729Sjoerg // Turning on -ffast-math (with either flag) removes the need for
28677330f729Sjoerg // MathErrno. However, turning *off* -ffast-math merely restores the
28687330f729Sjoerg // toolchain default (which may be false).
28697330f729Sjoerg MathErrno = TC.IsMathErrnoDefault();
28707330f729Sjoerg AssociativeMath = false;
28717330f729Sjoerg ReciprocalMath = false;
28727330f729Sjoerg SignedZeros = true;
2873*e038c9c4Sjoerg TrappingMath = false;
2874*e038c9c4Sjoerg RoundingFPMath = false;
28757330f729Sjoerg // -fno_fast_math restores default denormal and fpcontract handling
2876*e038c9c4Sjoerg DenormalFPMath = DefaultDenormalFPMath;
2877*e038c9c4Sjoerg DenormalFP32Math = llvm::DenormalMode::getIEEE();
28787330f729Sjoerg FPContract = "";
28797330f729Sjoerg break;
28807330f729Sjoerg }
2881*e038c9c4Sjoerg if (StrictFPModel) {
2882*e038c9c4Sjoerg // If -ffp-model=strict has been specified on command line but
2883*e038c9c4Sjoerg // subsequent options conflict then emit warning diagnostic.
2884*e038c9c4Sjoerg if (HonorINFs && HonorNaNs &&
2885*e038c9c4Sjoerg !AssociativeMath && !ReciprocalMath &&
2886*e038c9c4Sjoerg SignedZeros && TrappingMath && RoundingFPMath &&
2887*e038c9c4Sjoerg (FPContract.equals("off") || FPContract.empty()) &&
2888*e038c9c4Sjoerg DenormalFPMath == llvm::DenormalMode::getIEEE() &&
2889*e038c9c4Sjoerg DenormalFP32Math == llvm::DenormalMode::getIEEE())
2890*e038c9c4Sjoerg // OK: Current Arg doesn't conflict with -ffp-model=strict
2891*e038c9c4Sjoerg ;
2892*e038c9c4Sjoerg else {
2893*e038c9c4Sjoerg StrictFPModel = false;
2894*e038c9c4Sjoerg FPModel = "";
2895*e038c9c4Sjoerg D.Diag(clang::diag::warn_drv_overriding_flag_option)
2896*e038c9c4Sjoerg << "-ffp-model=strict" <<
2897*e038c9c4Sjoerg ((A->getNumValues() == 0) ? A->getSpelling()
2898*e038c9c4Sjoerg : Args.MakeArgString(A->getSpelling() + A->getValue()));
2899*e038c9c4Sjoerg }
2900*e038c9c4Sjoerg }
29017330f729Sjoerg
29027330f729Sjoerg // If we handled this option claim it
29037330f729Sjoerg A->claim();
29047330f729Sjoerg }
29057330f729Sjoerg
29067330f729Sjoerg if (!HonorINFs)
29077330f729Sjoerg CmdArgs.push_back("-menable-no-infs");
29087330f729Sjoerg
29097330f729Sjoerg if (!HonorNaNs)
29107330f729Sjoerg CmdArgs.push_back("-menable-no-nans");
29117330f729Sjoerg
29127330f729Sjoerg if (MathErrno)
29137330f729Sjoerg CmdArgs.push_back("-fmath-errno");
29147330f729Sjoerg
29157330f729Sjoerg if (!MathErrno && AssociativeMath && ReciprocalMath && !SignedZeros &&
29167330f729Sjoerg !TrappingMath)
29177330f729Sjoerg CmdArgs.push_back("-menable-unsafe-fp-math");
29187330f729Sjoerg
29197330f729Sjoerg if (!SignedZeros)
29207330f729Sjoerg CmdArgs.push_back("-fno-signed-zeros");
29217330f729Sjoerg
29227330f729Sjoerg if (AssociativeMath && !SignedZeros && !TrappingMath)
29237330f729Sjoerg CmdArgs.push_back("-mreassociate");
29247330f729Sjoerg
29257330f729Sjoerg if (ReciprocalMath)
29267330f729Sjoerg CmdArgs.push_back("-freciprocal-math");
29277330f729Sjoerg
2928*e038c9c4Sjoerg if (TrappingMath) {
2929*e038c9c4Sjoerg // FP Exception Behavior is also set to strict
2930*e038c9c4Sjoerg assert(FPExceptionBehavior.equals("strict"));
2931*e038c9c4Sjoerg }
29327330f729Sjoerg
2933*e038c9c4Sjoerg // The default is IEEE.
2934*e038c9c4Sjoerg if (DenormalFPMath != llvm::DenormalMode::getIEEE()) {
2935*e038c9c4Sjoerg llvm::SmallString<64> DenormFlag;
2936*e038c9c4Sjoerg llvm::raw_svector_ostream ArgStr(DenormFlag);
2937*e038c9c4Sjoerg ArgStr << "-fdenormal-fp-math=" << DenormalFPMath;
2938*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(ArgStr.str()));
2939*e038c9c4Sjoerg }
2940*e038c9c4Sjoerg
2941*e038c9c4Sjoerg // Add f32 specific denormal mode flag if it's different.
2942*e038c9c4Sjoerg if (DenormalFP32Math != DenormalFPMath) {
2943*e038c9c4Sjoerg llvm::SmallString<64> DenormFlag;
2944*e038c9c4Sjoerg llvm::raw_svector_ostream ArgStr(DenormFlag);
2945*e038c9c4Sjoerg ArgStr << "-fdenormal-fp-math-f32=" << DenormalFP32Math;
2946*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(ArgStr.str()));
2947*e038c9c4Sjoerg }
29487330f729Sjoerg
29497330f729Sjoerg if (!FPContract.empty())
29507330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-ffp-contract=" + FPContract));
29517330f729Sjoerg
2952*e038c9c4Sjoerg if (!RoundingFPMath)
2953*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString("-fno-rounding-math"));
2954*e038c9c4Sjoerg
2955*e038c9c4Sjoerg if (RoundingFPMath && RoundingMathPresent)
2956*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString("-frounding-math"));
2957*e038c9c4Sjoerg
2958*e038c9c4Sjoerg if (!FPExceptionBehavior.empty())
2959*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString("-ffp-exception-behavior=" +
2960*e038c9c4Sjoerg FPExceptionBehavior));
2961*e038c9c4Sjoerg
29627330f729Sjoerg ParseMRecip(D, Args, CmdArgs);
29637330f729Sjoerg
29647330f729Sjoerg // -ffast-math enables the __FAST_MATH__ preprocessor macro, but check for the
29657330f729Sjoerg // individual features enabled by -ffast-math instead of the option itself as
29667330f729Sjoerg // that's consistent with gcc's behaviour.
29677330f729Sjoerg if (!HonorINFs && !HonorNaNs && !MathErrno && AssociativeMath &&
2968*e038c9c4Sjoerg ReciprocalMath && !SignedZeros && !TrappingMath && !RoundingFPMath) {
29697330f729Sjoerg CmdArgs.push_back("-ffast-math");
2970*e038c9c4Sjoerg if (FPModel.equals("fast")) {
2971*e038c9c4Sjoerg if (FPContract.equals("fast"))
2972*e038c9c4Sjoerg // All set, do nothing.
2973*e038c9c4Sjoerg ;
2974*e038c9c4Sjoerg else if (FPContract.empty())
2975*e038c9c4Sjoerg // Enable -ffp-contract=fast
2976*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast"));
2977*e038c9c4Sjoerg else
2978*e038c9c4Sjoerg D.Diag(clang::diag::warn_drv_overriding_flag_option)
2979*e038c9c4Sjoerg << "-ffp-model=fast"
2980*e038c9c4Sjoerg << Args.MakeArgString("-ffp-contract=" + FPContract);
2981*e038c9c4Sjoerg }
2982*e038c9c4Sjoerg }
29837330f729Sjoerg
29847330f729Sjoerg // Handle __FINITE_MATH_ONLY__ similarly.
29857330f729Sjoerg if (!HonorINFs && !HonorNaNs)
29867330f729Sjoerg CmdArgs.push_back("-ffinite-math-only");
29877330f729Sjoerg
29887330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_mfpmath_EQ)) {
29897330f729Sjoerg CmdArgs.push_back("-mfpmath");
29907330f729Sjoerg CmdArgs.push_back(A->getValue());
29917330f729Sjoerg }
29927330f729Sjoerg
29937330f729Sjoerg // Disable a codegen optimization for floating-point casts.
29947330f729Sjoerg if (Args.hasFlag(options::OPT_fno_strict_float_cast_overflow,
29957330f729Sjoerg options::OPT_fstrict_float_cast_overflow, false))
29967330f729Sjoerg CmdArgs.push_back("-fno-strict-float-cast-overflow");
29977330f729Sjoerg }
29987330f729Sjoerg
RenderAnalyzerOptions(const ArgList & Args,ArgStringList & CmdArgs,const llvm::Triple & Triple,const InputInfo & Input)29997330f729Sjoerg static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs,
30007330f729Sjoerg const llvm::Triple &Triple,
30017330f729Sjoerg const InputInfo &Input) {
30027330f729Sjoerg // Enable region store model by default.
30037330f729Sjoerg CmdArgs.push_back("-analyzer-store=region");
30047330f729Sjoerg
30057330f729Sjoerg // Treat blocks as analysis entry points.
30067330f729Sjoerg CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
30077330f729Sjoerg
30087330f729Sjoerg // Add default argument set.
30097330f729Sjoerg if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
30107330f729Sjoerg CmdArgs.push_back("-analyzer-checker=core");
30117330f729Sjoerg CmdArgs.push_back("-analyzer-checker=apiModeling");
30127330f729Sjoerg
30137330f729Sjoerg if (!Triple.isWindowsMSVCEnvironment()) {
30147330f729Sjoerg CmdArgs.push_back("-analyzer-checker=unix");
30157330f729Sjoerg } else {
30167330f729Sjoerg // Enable "unix" checkers that also work on Windows.
30177330f729Sjoerg CmdArgs.push_back("-analyzer-checker=unix.API");
30187330f729Sjoerg CmdArgs.push_back("-analyzer-checker=unix.Malloc");
30197330f729Sjoerg CmdArgs.push_back("-analyzer-checker=unix.MallocSizeof");
30207330f729Sjoerg CmdArgs.push_back("-analyzer-checker=unix.MismatchedDeallocator");
30217330f729Sjoerg CmdArgs.push_back("-analyzer-checker=unix.cstring.BadSizeArg");
30227330f729Sjoerg CmdArgs.push_back("-analyzer-checker=unix.cstring.NullArg");
30237330f729Sjoerg }
30247330f729Sjoerg
30257330f729Sjoerg // Disable some unix checkers for PS4.
30267330f729Sjoerg if (Triple.isPS4CPU()) {
30277330f729Sjoerg CmdArgs.push_back("-analyzer-disable-checker=unix.API");
30287330f729Sjoerg CmdArgs.push_back("-analyzer-disable-checker=unix.Vfork");
30297330f729Sjoerg }
30307330f729Sjoerg
3031*e038c9c4Sjoerg if (Triple.isOSDarwin()) {
30327330f729Sjoerg CmdArgs.push_back("-analyzer-checker=osx");
3033*e038c9c4Sjoerg CmdArgs.push_back(
3034*e038c9c4Sjoerg "-analyzer-checker=security.insecureAPI.decodeValueOfObjCType");
3035*e038c9c4Sjoerg }
3036*e038c9c4Sjoerg else if (Triple.isOSFuchsia())
3037*e038c9c4Sjoerg CmdArgs.push_back("-analyzer-checker=fuchsia");
30387330f729Sjoerg
30397330f729Sjoerg CmdArgs.push_back("-analyzer-checker=deadcode");
30407330f729Sjoerg
30417330f729Sjoerg if (types::isCXX(Input.getType()))
30427330f729Sjoerg CmdArgs.push_back("-analyzer-checker=cplusplus");
30437330f729Sjoerg
30447330f729Sjoerg if (!Triple.isPS4CPU()) {
30457330f729Sjoerg CmdArgs.push_back("-analyzer-checker=security.insecureAPI.UncheckedReturn");
30467330f729Sjoerg CmdArgs.push_back("-analyzer-checker=security.insecureAPI.getpw");
30477330f729Sjoerg CmdArgs.push_back("-analyzer-checker=security.insecureAPI.gets");
30487330f729Sjoerg CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mktemp");
30497330f729Sjoerg CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mkstemp");
30507330f729Sjoerg CmdArgs.push_back("-analyzer-checker=security.insecureAPI.vfork");
30517330f729Sjoerg }
30527330f729Sjoerg
30537330f729Sjoerg // Default nullability checks.
30547330f729Sjoerg CmdArgs.push_back("-analyzer-checker=nullability.NullPassedToNonnull");
30557330f729Sjoerg CmdArgs.push_back("-analyzer-checker=nullability.NullReturnedFromNonnull");
30567330f729Sjoerg }
30577330f729Sjoerg
30587330f729Sjoerg // Set the output format. The default is plist, for (lame) historical reasons.
30597330f729Sjoerg CmdArgs.push_back("-analyzer-output");
30607330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT__analyzer_output))
30617330f729Sjoerg CmdArgs.push_back(A->getValue());
30627330f729Sjoerg else
30637330f729Sjoerg CmdArgs.push_back("plist");
30647330f729Sjoerg
30657330f729Sjoerg // Disable the presentation of standard compiler warnings when using
30667330f729Sjoerg // --analyze. We only want to show static analyzer diagnostics or frontend
30677330f729Sjoerg // errors.
30687330f729Sjoerg CmdArgs.push_back("-w");
30697330f729Sjoerg
30707330f729Sjoerg // Add -Xanalyzer arguments when running as analyzer.
30717330f729Sjoerg Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
30727330f729Sjoerg }
30737330f729Sjoerg
RenderSSPOptions(const Driver & D,const ToolChain & TC,const ArgList & Args,ArgStringList & CmdArgs,bool KernelOrKext)3074*e038c9c4Sjoerg static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
3075*e038c9c4Sjoerg const ArgList &Args, ArgStringList &CmdArgs,
3076*e038c9c4Sjoerg bool KernelOrKext) {
30777330f729Sjoerg const llvm::Triple &EffectiveTriple = TC.getEffectiveTriple();
30787330f729Sjoerg
30797330f729Sjoerg // NVPTX doesn't support stack protectors; from the compiler's perspective, it
30807330f729Sjoerg // doesn't even have a stack!
30817330f729Sjoerg if (EffectiveTriple.isNVPTX())
30827330f729Sjoerg return;
30837330f729Sjoerg
30847330f729Sjoerg // -stack-protector=0 is default.
3085*e038c9c4Sjoerg LangOptions::StackProtectorMode StackProtectorLevel = LangOptions::SSPOff;
3086*e038c9c4Sjoerg LangOptions::StackProtectorMode DefaultStackProtectorLevel =
30877330f729Sjoerg TC.GetDefaultStackProtectorLevel(KernelOrKext);
30887330f729Sjoerg
30897330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
30907330f729Sjoerg options::OPT_fstack_protector_all,
30917330f729Sjoerg options::OPT_fstack_protector_strong,
30927330f729Sjoerg options::OPT_fstack_protector)) {
30937330f729Sjoerg if (A->getOption().matches(options::OPT_fstack_protector))
30947330f729Sjoerg StackProtectorLevel =
3095*e038c9c4Sjoerg std::max<>(LangOptions::SSPOn, DefaultStackProtectorLevel);
30967330f729Sjoerg else if (A->getOption().matches(options::OPT_fstack_protector_strong))
30977330f729Sjoerg StackProtectorLevel = LangOptions::SSPStrong;
30987330f729Sjoerg else if (A->getOption().matches(options::OPT_fstack_protector_all))
30997330f729Sjoerg StackProtectorLevel = LangOptions::SSPReq;
31007330f729Sjoerg } else {
31017330f729Sjoerg StackProtectorLevel = DefaultStackProtectorLevel;
31027330f729Sjoerg }
31037330f729Sjoerg
31047330f729Sjoerg if (StackProtectorLevel) {
31057330f729Sjoerg CmdArgs.push_back("-stack-protector");
31067330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(Twine(StackProtectorLevel)));
31077330f729Sjoerg }
31087330f729Sjoerg
31097330f729Sjoerg // --param ssp-buffer-size=
31107330f729Sjoerg for (const Arg *A : Args.filtered(options::OPT__param)) {
31117330f729Sjoerg StringRef Str(A->getValue());
31127330f729Sjoerg if (Str.startswith("ssp-buffer-size=")) {
31137330f729Sjoerg if (StackProtectorLevel) {
31147330f729Sjoerg CmdArgs.push_back("-stack-protector-buffer-size");
31157330f729Sjoerg // FIXME: Verify the argument is a valid integer.
31167330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(Str.drop_front(16)));
31177330f729Sjoerg }
31187330f729Sjoerg A->claim();
31197330f729Sjoerg }
31207330f729Sjoerg }
3121*e038c9c4Sjoerg
3122*e038c9c4Sjoerg const std::string &TripleStr = EffectiveTriple.getTriple();
3123*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
3124*e038c9c4Sjoerg StringRef Value = A->getValue();
3125*e038c9c4Sjoerg if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
3126*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
3127*e038c9c4Sjoerg << A->getAsString(Args) << TripleStr;
3128*e038c9c4Sjoerg if (EffectiveTriple.isX86() && Value != "tls" && Value != "global") {
3129*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_value_with_suggestion)
3130*e038c9c4Sjoerg << A->getOption().getName() << Value << "tls global";
3131*e038c9c4Sjoerg return;
3132*e038c9c4Sjoerg }
3133*e038c9c4Sjoerg if (EffectiveTriple.isAArch64() && Value != "sysreg" && Value != "global") {
3134*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_value_with_suggestion)
3135*e038c9c4Sjoerg << A->getOption().getName() << Value << "sysreg global";
3136*e038c9c4Sjoerg return;
3137*e038c9c4Sjoerg }
3138*e038c9c4Sjoerg A->render(Args, CmdArgs);
3139*e038c9c4Sjoerg }
3140*e038c9c4Sjoerg
3141*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) {
3142*e038c9c4Sjoerg StringRef Value = A->getValue();
3143*e038c9c4Sjoerg if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
3144*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
3145*e038c9c4Sjoerg << A->getAsString(Args) << TripleStr;
3146*e038c9c4Sjoerg int Offset;
3147*e038c9c4Sjoerg if (Value.getAsInteger(10, Offset)) {
3148*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
3149*e038c9c4Sjoerg return;
3150*e038c9c4Sjoerg }
3151*e038c9c4Sjoerg A->render(Args, CmdArgs);
3152*e038c9c4Sjoerg }
3153*e038c9c4Sjoerg
3154*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
3155*e038c9c4Sjoerg StringRef Value = A->getValue();
3156*e038c9c4Sjoerg if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
3157*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
3158*e038c9c4Sjoerg << A->getAsString(Args) << TripleStr;
3159*e038c9c4Sjoerg if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
3160*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_value_with_suggestion)
3161*e038c9c4Sjoerg << A->getOption().getName() << Value << "fs gs";
3162*e038c9c4Sjoerg return;
3163*e038c9c4Sjoerg }
3164*e038c9c4Sjoerg if (EffectiveTriple.isAArch64() && Value != "sp_el0") {
3165*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
3166*e038c9c4Sjoerg return;
3167*e038c9c4Sjoerg }
3168*e038c9c4Sjoerg A->render(Args, CmdArgs);
3169*e038c9c4Sjoerg }
3170*e038c9c4Sjoerg }
3171*e038c9c4Sjoerg
RenderSCPOptions(const ToolChain & TC,const ArgList & Args,ArgStringList & CmdArgs)3172*e038c9c4Sjoerg static void RenderSCPOptions(const ToolChain &TC, const ArgList &Args,
3173*e038c9c4Sjoerg ArgStringList &CmdArgs) {
3174*e038c9c4Sjoerg const llvm::Triple &EffectiveTriple = TC.getEffectiveTriple();
3175*e038c9c4Sjoerg
3176*e038c9c4Sjoerg if (!EffectiveTriple.isOSLinux())
3177*e038c9c4Sjoerg return;
3178*e038c9c4Sjoerg
3179*e038c9c4Sjoerg if (!EffectiveTriple.isX86() && !EffectiveTriple.isSystemZ() &&
3180*e038c9c4Sjoerg !EffectiveTriple.isPPC64())
3181*e038c9c4Sjoerg return;
3182*e038c9c4Sjoerg
3183*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fstack_clash_protection,
3184*e038c9c4Sjoerg options::OPT_fno_stack_clash_protection, false))
3185*e038c9c4Sjoerg CmdArgs.push_back("-fstack-clash-protection");
31867330f729Sjoerg }
31877330f729Sjoerg
RenderTrivialAutoVarInitOptions(const Driver & D,const ToolChain & TC,const ArgList & Args,ArgStringList & CmdArgs)31887330f729Sjoerg static void RenderTrivialAutoVarInitOptions(const Driver &D,
31897330f729Sjoerg const ToolChain &TC,
31907330f729Sjoerg const ArgList &Args,
31917330f729Sjoerg ArgStringList &CmdArgs) {
31927330f729Sjoerg auto DefaultTrivialAutoVarInit = TC.GetDefaultTrivialAutoVarInit();
31937330f729Sjoerg StringRef TrivialAutoVarInit = "";
31947330f729Sjoerg
31957330f729Sjoerg for (const Arg *A : Args) {
31967330f729Sjoerg switch (A->getOption().getID()) {
31977330f729Sjoerg default:
31987330f729Sjoerg continue;
31997330f729Sjoerg case options::OPT_ftrivial_auto_var_init: {
32007330f729Sjoerg A->claim();
32017330f729Sjoerg StringRef Val = A->getValue();
32027330f729Sjoerg if (Val == "uninitialized" || Val == "zero" || Val == "pattern")
32037330f729Sjoerg TrivialAutoVarInit = Val;
32047330f729Sjoerg else
32057330f729Sjoerg D.Diag(diag::err_drv_unsupported_option_argument)
32067330f729Sjoerg << A->getOption().getName() << Val;
32077330f729Sjoerg break;
32087330f729Sjoerg }
32097330f729Sjoerg }
32107330f729Sjoerg }
32117330f729Sjoerg
32127330f729Sjoerg if (TrivialAutoVarInit.empty())
32137330f729Sjoerg switch (DefaultTrivialAutoVarInit) {
32147330f729Sjoerg case LangOptions::TrivialAutoVarInitKind::Uninitialized:
32157330f729Sjoerg break;
32167330f729Sjoerg case LangOptions::TrivialAutoVarInitKind::Pattern:
32177330f729Sjoerg TrivialAutoVarInit = "pattern";
32187330f729Sjoerg break;
32197330f729Sjoerg case LangOptions::TrivialAutoVarInitKind::Zero:
32207330f729Sjoerg TrivialAutoVarInit = "zero";
32217330f729Sjoerg break;
32227330f729Sjoerg }
32237330f729Sjoerg
32247330f729Sjoerg if (!TrivialAutoVarInit.empty()) {
32257330f729Sjoerg if (TrivialAutoVarInit == "zero" && !Args.hasArg(options::OPT_enable_trivial_var_init_zero))
32267330f729Sjoerg D.Diag(diag::err_drv_trivial_auto_var_init_zero_disabled);
32277330f729Sjoerg CmdArgs.push_back(
32287330f729Sjoerg Args.MakeArgString("-ftrivial-auto-var-init=" + TrivialAutoVarInit));
32297330f729Sjoerg }
3230*e038c9c4Sjoerg
3231*e038c9c4Sjoerg if (Arg *A =
3232*e038c9c4Sjoerg Args.getLastArg(options::OPT_ftrivial_auto_var_init_stop_after)) {
3233*e038c9c4Sjoerg if (!Args.hasArg(options::OPT_ftrivial_auto_var_init) ||
3234*e038c9c4Sjoerg StringRef(
3235*e038c9c4Sjoerg Args.getLastArg(options::OPT_ftrivial_auto_var_init)->getValue()) ==
3236*e038c9c4Sjoerg "uninitialized")
3237*e038c9c4Sjoerg D.Diag(diag::err_drv_trivial_auto_var_init_stop_after_missing_dependency);
3238*e038c9c4Sjoerg A->claim();
3239*e038c9c4Sjoerg StringRef Val = A->getValue();
3240*e038c9c4Sjoerg if (std::stoi(Val.str()) <= 0)
3241*e038c9c4Sjoerg D.Diag(diag::err_drv_trivial_auto_var_init_stop_after_invalid_value);
3242*e038c9c4Sjoerg CmdArgs.push_back(
3243*e038c9c4Sjoerg Args.MakeArgString("-ftrivial-auto-var-init-stop-after=" + Val));
3244*e038c9c4Sjoerg }
32457330f729Sjoerg }
32467330f729Sjoerg
RenderOpenCLOptions(const ArgList & Args,ArgStringList & CmdArgs,types::ID InputType)3247*e038c9c4Sjoerg static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs,
3248*e038c9c4Sjoerg types::ID InputType) {
3249*e038c9c4Sjoerg // cl-denorms-are-zero is not forwarded. It is translated into a generic flag
3250*e038c9c4Sjoerg // for denormal flushing handling based on the target.
32517330f729Sjoerg const unsigned ForwardedArguments[] = {
32527330f729Sjoerg options::OPT_cl_opt_disable,
32537330f729Sjoerg options::OPT_cl_strict_aliasing,
32547330f729Sjoerg options::OPT_cl_single_precision_constant,
32557330f729Sjoerg options::OPT_cl_finite_math_only,
32567330f729Sjoerg options::OPT_cl_kernel_arg_info,
32577330f729Sjoerg options::OPT_cl_unsafe_math_optimizations,
32587330f729Sjoerg options::OPT_cl_fast_relaxed_math,
32597330f729Sjoerg options::OPT_cl_mad_enable,
32607330f729Sjoerg options::OPT_cl_no_signed_zeros,
32617330f729Sjoerg options::OPT_cl_fp32_correctly_rounded_divide_sqrt,
32627330f729Sjoerg options::OPT_cl_uniform_work_group_size
32637330f729Sjoerg };
32647330f729Sjoerg
32657330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_cl_std_EQ)) {
32667330f729Sjoerg std::string CLStdStr = std::string("-cl-std=") + A->getValue();
32677330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(CLStdStr));
32687330f729Sjoerg }
32697330f729Sjoerg
32707330f729Sjoerg for (const auto &Arg : ForwardedArguments)
32717330f729Sjoerg if (const auto *A = Args.getLastArg(Arg))
32727330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(A->getOption().getPrefixedName()));
3273*e038c9c4Sjoerg
3274*e038c9c4Sjoerg // Only add the default headers if we are compiling OpenCL sources.
3275*e038c9c4Sjoerg if ((types::isOpenCL(InputType) || Args.hasArg(options::OPT_cl_std_EQ)) &&
3276*e038c9c4Sjoerg !Args.hasArg(options::OPT_cl_no_stdinc)) {
3277*e038c9c4Sjoerg CmdArgs.push_back("-finclude-default-header");
3278*e038c9c4Sjoerg CmdArgs.push_back("-fdeclare-opencl-builtins");
3279*e038c9c4Sjoerg }
32807330f729Sjoerg }
32817330f729Sjoerg
RenderARCMigrateToolOptions(const Driver & D,const ArgList & Args,ArgStringList & CmdArgs)32827330f729Sjoerg static void RenderARCMigrateToolOptions(const Driver &D, const ArgList &Args,
32837330f729Sjoerg ArgStringList &CmdArgs) {
32847330f729Sjoerg bool ARCMTEnabled = false;
32857330f729Sjoerg if (!Args.hasArg(options::OPT_fno_objc_arc, options::OPT_fobjc_arc)) {
32867330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_ccc_arcmt_check,
32877330f729Sjoerg options::OPT_ccc_arcmt_modify,
32887330f729Sjoerg options::OPT_ccc_arcmt_migrate)) {
32897330f729Sjoerg ARCMTEnabled = true;
32907330f729Sjoerg switch (A->getOption().getID()) {
32917330f729Sjoerg default: llvm_unreachable("missed a case");
32927330f729Sjoerg case options::OPT_ccc_arcmt_check:
3293*e038c9c4Sjoerg CmdArgs.push_back("-arcmt-action=check");
32947330f729Sjoerg break;
32957330f729Sjoerg case options::OPT_ccc_arcmt_modify:
3296*e038c9c4Sjoerg CmdArgs.push_back("-arcmt-action=modify");
32977330f729Sjoerg break;
32987330f729Sjoerg case options::OPT_ccc_arcmt_migrate:
3299*e038c9c4Sjoerg CmdArgs.push_back("-arcmt-action=migrate");
33007330f729Sjoerg CmdArgs.push_back("-mt-migrate-directory");
33017330f729Sjoerg CmdArgs.push_back(A->getValue());
33027330f729Sjoerg
33037330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_report_output);
33047330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_emit_arc_errors);
33057330f729Sjoerg break;
33067330f729Sjoerg }
33077330f729Sjoerg }
33087330f729Sjoerg } else {
33097330f729Sjoerg Args.ClaimAllArgs(options::OPT_ccc_arcmt_check);
33107330f729Sjoerg Args.ClaimAllArgs(options::OPT_ccc_arcmt_modify);
33117330f729Sjoerg Args.ClaimAllArgs(options::OPT_ccc_arcmt_migrate);
33127330f729Sjoerg }
33137330f729Sjoerg
33147330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_ccc_objcmt_migrate)) {
33157330f729Sjoerg if (ARCMTEnabled)
33167330f729Sjoerg D.Diag(diag::err_drv_argument_not_allowed_with)
33177330f729Sjoerg << A->getAsString(Args) << "-ccc-arcmt-migrate";
33187330f729Sjoerg
33197330f729Sjoerg CmdArgs.push_back("-mt-migrate-directory");
33207330f729Sjoerg CmdArgs.push_back(A->getValue());
33217330f729Sjoerg
33227330f729Sjoerg if (!Args.hasArg(options::OPT_objcmt_migrate_literals,
33237330f729Sjoerg options::OPT_objcmt_migrate_subscripting,
33247330f729Sjoerg options::OPT_objcmt_migrate_property)) {
33257330f729Sjoerg // None specified, means enable them all.
33267330f729Sjoerg CmdArgs.push_back("-objcmt-migrate-literals");
33277330f729Sjoerg CmdArgs.push_back("-objcmt-migrate-subscripting");
33287330f729Sjoerg CmdArgs.push_back("-objcmt-migrate-property");
33297330f729Sjoerg } else {
33307330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
33317330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
33327330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
33337330f729Sjoerg }
33347330f729Sjoerg } else {
33357330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
33367330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
33377330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
33387330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_all);
33397330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readonly_property);
33407330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readwrite_property);
33417330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property_dot_syntax);
33427330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_annotation);
33437330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_instancetype);
33447330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_nsmacros);
33457330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_protocol_conformance);
33467330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_atomic_property);
33477330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_returns_innerpointer_property);
33487330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_ns_nonatomic_iosonly);
33497330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_designated_init);
33507330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_objcmt_whitelist_dir_path);
33517330f729Sjoerg }
33527330f729Sjoerg }
33537330f729Sjoerg
RenderBuiltinOptions(const ToolChain & TC,const llvm::Triple & T,const ArgList & Args,ArgStringList & CmdArgs)33547330f729Sjoerg static void RenderBuiltinOptions(const ToolChain &TC, const llvm::Triple &T,
33557330f729Sjoerg const ArgList &Args, ArgStringList &CmdArgs) {
33567330f729Sjoerg // -fbuiltin is default unless -mkernel is used.
33577330f729Sjoerg bool UseBuiltins =
33587330f729Sjoerg Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin,
33597330f729Sjoerg !Args.hasArg(options::OPT_mkernel));
33607330f729Sjoerg if (!UseBuiltins)
33617330f729Sjoerg CmdArgs.push_back("-fno-builtin");
33627330f729Sjoerg
33637330f729Sjoerg // -ffreestanding implies -fno-builtin.
33647330f729Sjoerg if (Args.hasArg(options::OPT_ffreestanding))
33657330f729Sjoerg UseBuiltins = false;
33667330f729Sjoerg
33677330f729Sjoerg // Process the -fno-builtin-* options.
33687330f729Sjoerg for (const auto &Arg : Args) {
33697330f729Sjoerg const Option &O = Arg->getOption();
33707330f729Sjoerg if (!O.matches(options::OPT_fno_builtin_))
33717330f729Sjoerg continue;
33727330f729Sjoerg
33737330f729Sjoerg Arg->claim();
33747330f729Sjoerg
33757330f729Sjoerg // If -fno-builtin is specified, then there's no need to pass the option to
33767330f729Sjoerg // the frontend.
33777330f729Sjoerg if (!UseBuiltins)
33787330f729Sjoerg continue;
33797330f729Sjoerg
33807330f729Sjoerg StringRef FuncName = Arg->getValue();
33817330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-fno-builtin-" + FuncName));
33827330f729Sjoerg }
33837330f729Sjoerg
33847330f729Sjoerg // le32-specific flags:
33857330f729Sjoerg // -fno-math-builtin: clang should not convert math builtins to intrinsics
33867330f729Sjoerg // by default.
33877330f729Sjoerg if (TC.getArch() == llvm::Triple::le32)
33887330f729Sjoerg CmdArgs.push_back("-fno-math-builtin");
33897330f729Sjoerg }
33907330f729Sjoerg
getDefaultModuleCachePath(SmallVectorImpl<char> & Result)3391*e038c9c4Sjoerg bool Driver::getDefaultModuleCachePath(SmallVectorImpl<char> &Result) {
3392*e038c9c4Sjoerg if (llvm::sys::path::cache_directory(Result)) {
3393*e038c9c4Sjoerg llvm::sys::path::append(Result, "clang");
33947330f729Sjoerg llvm::sys::path::append(Result, "ModuleCache");
3395*e038c9c4Sjoerg return true;
3396*e038c9c4Sjoerg }
3397*e038c9c4Sjoerg return false;
33987330f729Sjoerg }
33997330f729Sjoerg
RenderModulesOptions(Compilation & C,const Driver & D,const ArgList & Args,const InputInfo & Input,const InputInfo & Output,ArgStringList & CmdArgs,bool & HaveModules)34007330f729Sjoerg static void RenderModulesOptions(Compilation &C, const Driver &D,
34017330f729Sjoerg const ArgList &Args, const InputInfo &Input,
34027330f729Sjoerg const InputInfo &Output,
34037330f729Sjoerg ArgStringList &CmdArgs, bool &HaveModules) {
34047330f729Sjoerg // -fmodules enables the use of precompiled modules (off by default).
34057330f729Sjoerg // Users can pass -fno-cxx-modules to turn off modules support for
34067330f729Sjoerg // C++/Objective-C++ programs.
34077330f729Sjoerg bool HaveClangModules = false;
34087330f729Sjoerg if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) {
34097330f729Sjoerg bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules,
34107330f729Sjoerg options::OPT_fno_cxx_modules, true);
34117330f729Sjoerg if (AllowedInCXX || !types::isCXX(Input.getType())) {
34127330f729Sjoerg CmdArgs.push_back("-fmodules");
34137330f729Sjoerg HaveClangModules = true;
34147330f729Sjoerg }
34157330f729Sjoerg }
34167330f729Sjoerg
34177330f729Sjoerg HaveModules |= HaveClangModules;
34187330f729Sjoerg if (Args.hasArg(options::OPT_fmodules_ts)) {
34197330f729Sjoerg CmdArgs.push_back("-fmodules-ts");
34207330f729Sjoerg HaveModules = true;
34217330f729Sjoerg }
34227330f729Sjoerg
34237330f729Sjoerg // -fmodule-maps enables implicit reading of module map files. By default,
34247330f729Sjoerg // this is enabled if we are using Clang's flavor of precompiled modules.
34257330f729Sjoerg if (Args.hasFlag(options::OPT_fimplicit_module_maps,
34267330f729Sjoerg options::OPT_fno_implicit_module_maps, HaveClangModules))
34277330f729Sjoerg CmdArgs.push_back("-fimplicit-module-maps");
34287330f729Sjoerg
34297330f729Sjoerg // -fmodules-decluse checks that modules used are declared so (off by default)
34307330f729Sjoerg if (Args.hasFlag(options::OPT_fmodules_decluse,
34317330f729Sjoerg options::OPT_fno_modules_decluse, false))
34327330f729Sjoerg CmdArgs.push_back("-fmodules-decluse");
34337330f729Sjoerg
34347330f729Sjoerg // -fmodules-strict-decluse is like -fmodule-decluse, but also checks that
34357330f729Sjoerg // all #included headers are part of modules.
34367330f729Sjoerg if (Args.hasFlag(options::OPT_fmodules_strict_decluse,
34377330f729Sjoerg options::OPT_fno_modules_strict_decluse, false))
34387330f729Sjoerg CmdArgs.push_back("-fmodules-strict-decluse");
34397330f729Sjoerg
34407330f729Sjoerg // -fno-implicit-modules turns off implicitly compiling modules on demand.
34417330f729Sjoerg bool ImplicitModules = false;
34427330f729Sjoerg if (!Args.hasFlag(options::OPT_fimplicit_modules,
34437330f729Sjoerg options::OPT_fno_implicit_modules, HaveClangModules)) {
34447330f729Sjoerg if (HaveModules)
34457330f729Sjoerg CmdArgs.push_back("-fno-implicit-modules");
34467330f729Sjoerg } else if (HaveModules) {
34477330f729Sjoerg ImplicitModules = true;
34487330f729Sjoerg // -fmodule-cache-path specifies where our implicitly-built module files
34497330f729Sjoerg // should be written.
34507330f729Sjoerg SmallString<128> Path;
34517330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path))
34527330f729Sjoerg Path = A->getValue();
34537330f729Sjoerg
3454*e038c9c4Sjoerg bool HasPath = true;
34557330f729Sjoerg if (C.isForDiagnostics()) {
34567330f729Sjoerg // When generating crash reports, we want to emit the modules along with
34577330f729Sjoerg // the reproduction sources, so we ignore any provided module path.
34587330f729Sjoerg Path = Output.getFilename();
34597330f729Sjoerg llvm::sys::path::replace_extension(Path, ".cache");
34607330f729Sjoerg llvm::sys::path::append(Path, "modules");
34617330f729Sjoerg } else if (Path.empty()) {
34627330f729Sjoerg // No module path was provided: use the default.
3463*e038c9c4Sjoerg HasPath = Driver::getDefaultModuleCachePath(Path);
34647330f729Sjoerg }
34657330f729Sjoerg
3466*e038c9c4Sjoerg // `HasPath` will only be false if getDefaultModuleCachePath() fails.
3467*e038c9c4Sjoerg // That being said, that failure is unlikely and not caching is harmless.
3468*e038c9c4Sjoerg if (HasPath) {
34697330f729Sjoerg const char Arg[] = "-fmodules-cache-path=";
34707330f729Sjoerg Path.insert(Path.begin(), Arg, Arg + strlen(Arg));
34717330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(Path));
34727330f729Sjoerg }
3473*e038c9c4Sjoerg }
34747330f729Sjoerg
34757330f729Sjoerg if (HaveModules) {
34767330f729Sjoerg // -fprebuilt-module-path specifies where to load the prebuilt module files.
34777330f729Sjoerg for (const Arg *A : Args.filtered(options::OPT_fprebuilt_module_path)) {
34787330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(
34797330f729Sjoerg std::string("-fprebuilt-module-path=") + A->getValue()));
34807330f729Sjoerg A->claim();
34817330f729Sjoerg }
3482*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fprebuilt_implicit_modules,
3483*e038c9c4Sjoerg options::OPT_fno_prebuilt_implicit_modules, false))
3484*e038c9c4Sjoerg CmdArgs.push_back("-fprebuilt-implicit-modules");
34857330f729Sjoerg if (Args.hasFlag(options::OPT_fmodules_validate_input_files_content,
34867330f729Sjoerg options::OPT_fno_modules_validate_input_files_content,
34877330f729Sjoerg false))
34887330f729Sjoerg CmdArgs.push_back("-fvalidate-ast-input-files-content");
34897330f729Sjoerg }
34907330f729Sjoerg
34917330f729Sjoerg // -fmodule-name specifies the module that is currently being built (or
34927330f729Sjoerg // used for header checking by -fmodule-maps).
34937330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fmodule_name_EQ);
34947330f729Sjoerg
34957330f729Sjoerg // -fmodule-map-file can be used to specify files containing module
34967330f729Sjoerg // definitions.
34977330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_fmodule_map_file);
34987330f729Sjoerg
34997330f729Sjoerg // -fbuiltin-module-map can be used to load the clang
35007330f729Sjoerg // builtin headers modulemap file.
35017330f729Sjoerg if (Args.hasArg(options::OPT_fbuiltin_module_map)) {
35027330f729Sjoerg SmallString<128> BuiltinModuleMap(D.ResourceDir);
35037330f729Sjoerg llvm::sys::path::append(BuiltinModuleMap, "include");
35047330f729Sjoerg llvm::sys::path::append(BuiltinModuleMap, "module.modulemap");
35057330f729Sjoerg if (llvm::sys::fs::exists(BuiltinModuleMap))
35067330f729Sjoerg CmdArgs.push_back(
35077330f729Sjoerg Args.MakeArgString("-fmodule-map-file=" + BuiltinModuleMap));
35087330f729Sjoerg }
35097330f729Sjoerg
35107330f729Sjoerg // The -fmodule-file=<name>=<file> form specifies the mapping of module
35117330f729Sjoerg // names to precompiled module files (the module is loaded only if used).
35127330f729Sjoerg // The -fmodule-file=<file> form can be used to unconditionally load
35137330f729Sjoerg // precompiled module files (whether used or not).
35147330f729Sjoerg if (HaveModules)
35157330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_fmodule_file);
35167330f729Sjoerg else
35177330f729Sjoerg Args.ClaimAllArgs(options::OPT_fmodule_file);
35187330f729Sjoerg
35197330f729Sjoerg // When building modules and generating crashdumps, we need to dump a module
35207330f729Sjoerg // dependency VFS alongside the output.
35217330f729Sjoerg if (HaveClangModules && C.isForDiagnostics()) {
35227330f729Sjoerg SmallString<128> VFSDir(Output.getFilename());
35237330f729Sjoerg llvm::sys::path::replace_extension(VFSDir, ".cache");
35247330f729Sjoerg // Add the cache directory as a temp so the crash diagnostics pick it up.
35257330f729Sjoerg C.addTempFile(Args.MakeArgString(VFSDir));
35267330f729Sjoerg
35277330f729Sjoerg llvm::sys::path::append(VFSDir, "vfs");
35287330f729Sjoerg CmdArgs.push_back("-module-dependency-dir");
35297330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(VFSDir));
35307330f729Sjoerg }
35317330f729Sjoerg
35327330f729Sjoerg if (HaveClangModules)
35337330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fmodules_user_build_path);
35347330f729Sjoerg
35357330f729Sjoerg // Pass through all -fmodules-ignore-macro arguments.
35367330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro);
35377330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval);
35387330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after);
35397330f729Sjoerg
35407330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fbuild_session_timestamp);
35417330f729Sjoerg
35427330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fbuild_session_file)) {
35437330f729Sjoerg if (Args.hasArg(options::OPT_fbuild_session_timestamp))
35447330f729Sjoerg D.Diag(diag::err_drv_argument_not_allowed_with)
35457330f729Sjoerg << A->getAsString(Args) << "-fbuild-session-timestamp";
35467330f729Sjoerg
35477330f729Sjoerg llvm::sys::fs::file_status Status;
35487330f729Sjoerg if (llvm::sys::fs::status(A->getValue(), Status))
35497330f729Sjoerg D.Diag(diag::err_drv_no_such_file) << A->getValue();
35507330f729Sjoerg CmdArgs.push_back(
35517330f729Sjoerg Args.MakeArgString("-fbuild-session-timestamp=" +
35527330f729Sjoerg Twine((uint64_t)Status.getLastModificationTime()
35537330f729Sjoerg .time_since_epoch()
35547330f729Sjoerg .count())));
35557330f729Sjoerg }
35567330f729Sjoerg
35577330f729Sjoerg if (Args.getLastArg(options::OPT_fmodules_validate_once_per_build_session)) {
35587330f729Sjoerg if (!Args.getLastArg(options::OPT_fbuild_session_timestamp,
35597330f729Sjoerg options::OPT_fbuild_session_file))
35607330f729Sjoerg D.Diag(diag::err_drv_modules_validate_once_requires_timestamp);
35617330f729Sjoerg
35627330f729Sjoerg Args.AddLastArg(CmdArgs,
35637330f729Sjoerg options::OPT_fmodules_validate_once_per_build_session);
35647330f729Sjoerg }
35657330f729Sjoerg
35667330f729Sjoerg if (Args.hasFlag(options::OPT_fmodules_validate_system_headers,
35677330f729Sjoerg options::OPT_fno_modules_validate_system_headers,
35687330f729Sjoerg ImplicitModules))
35697330f729Sjoerg CmdArgs.push_back("-fmodules-validate-system-headers");
35707330f729Sjoerg
35717330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fmodules_disable_diagnostic_validation);
35727330f729Sjoerg }
35737330f729Sjoerg
RenderCharacterOptions(const ArgList & Args,const llvm::Triple & T,ArgStringList & CmdArgs)35747330f729Sjoerg static void RenderCharacterOptions(const ArgList &Args, const llvm::Triple &T,
35757330f729Sjoerg ArgStringList &CmdArgs) {
35767330f729Sjoerg // -fsigned-char is default.
35777330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_fsigned_char,
35787330f729Sjoerg options::OPT_fno_signed_char,
35797330f729Sjoerg options::OPT_funsigned_char,
35807330f729Sjoerg options::OPT_fno_unsigned_char)) {
35817330f729Sjoerg if (A->getOption().matches(options::OPT_funsigned_char) ||
35827330f729Sjoerg A->getOption().matches(options::OPT_fno_signed_char)) {
35837330f729Sjoerg CmdArgs.push_back("-fno-signed-char");
35847330f729Sjoerg }
35857330f729Sjoerg } else if (!isSignedCharDefault(T)) {
35867330f729Sjoerg CmdArgs.push_back("-fno-signed-char");
35877330f729Sjoerg }
35887330f729Sjoerg
35897330f729Sjoerg // The default depends on the language standard.
35907330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fchar8__t, options::OPT_fno_char8__t);
35917330f729Sjoerg
35927330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_fshort_wchar,
35937330f729Sjoerg options::OPT_fno_short_wchar)) {
35947330f729Sjoerg if (A->getOption().matches(options::OPT_fshort_wchar)) {
35957330f729Sjoerg CmdArgs.push_back("-fwchar-type=short");
35967330f729Sjoerg CmdArgs.push_back("-fno-signed-wchar");
35977330f729Sjoerg } else {
35987330f729Sjoerg bool IsARM = T.isARM() || T.isThumb() || T.isAArch64();
35997330f729Sjoerg CmdArgs.push_back("-fwchar-type=int");
3600*e038c9c4Sjoerg if (T.isOSzOS() ||
3601*e038c9c4Sjoerg (IsARM && !(T.isOSWindows() || T.isOSNetBSD() || T.isOSOpenBSD())))
36027330f729Sjoerg CmdArgs.push_back("-fno-signed-wchar");
36037330f729Sjoerg else
36047330f729Sjoerg CmdArgs.push_back("-fsigned-wchar");
36057330f729Sjoerg }
36067330f729Sjoerg }
36077330f729Sjoerg }
36087330f729Sjoerg
RenderObjCOptions(const ToolChain & TC,const Driver & D,const llvm::Triple & T,const ArgList & Args,ObjCRuntime & Runtime,bool InferCovariantReturns,const InputInfo & Input,ArgStringList & CmdArgs)36097330f729Sjoerg static void RenderObjCOptions(const ToolChain &TC, const Driver &D,
36107330f729Sjoerg const llvm::Triple &T, const ArgList &Args,
36117330f729Sjoerg ObjCRuntime &Runtime, bool InferCovariantReturns,
36127330f729Sjoerg const InputInfo &Input, ArgStringList &CmdArgs) {
36137330f729Sjoerg const llvm::Triple::ArchType Arch = TC.getArch();
36147330f729Sjoerg
36157330f729Sjoerg // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and legacy
36167330f729Sjoerg // is the default. Except for deployment target of 10.5, next runtime is
36177330f729Sjoerg // always legacy dispatch and -fno-objc-legacy-dispatch gets ignored silently.
36187330f729Sjoerg if (Runtime.isNonFragile()) {
36197330f729Sjoerg if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch,
36207330f729Sjoerg options::OPT_fno_objc_legacy_dispatch,
36217330f729Sjoerg Runtime.isLegacyDispatchDefaultForArch(Arch))) {
36227330f729Sjoerg if (TC.UseObjCMixedDispatch())
36237330f729Sjoerg CmdArgs.push_back("-fobjc-dispatch-method=mixed");
36247330f729Sjoerg else
36257330f729Sjoerg CmdArgs.push_back("-fobjc-dispatch-method=non-legacy");
36267330f729Sjoerg }
36277330f729Sjoerg }
36287330f729Sjoerg
36297330f729Sjoerg // When ObjectiveC legacy runtime is in effect on MacOSX, turn on the option
36307330f729Sjoerg // to do Array/Dictionary subscripting by default.
36317330f729Sjoerg if (Arch == llvm::Triple::x86 && T.isMacOSX() &&
36327330f729Sjoerg Runtime.getKind() == ObjCRuntime::FragileMacOSX && Runtime.isNeXTFamily())
36337330f729Sjoerg CmdArgs.push_back("-fobjc-subscripting-legacy-runtime");
36347330f729Sjoerg
36357330f729Sjoerg // Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc.
36367330f729Sjoerg // NOTE: This logic is duplicated in ToolChains.cpp.
36377330f729Sjoerg if (isObjCAutoRefCount(Args)) {
36387330f729Sjoerg TC.CheckObjCARC();
36397330f729Sjoerg
36407330f729Sjoerg CmdArgs.push_back("-fobjc-arc");
36417330f729Sjoerg
36427330f729Sjoerg // FIXME: It seems like this entire block, and several around it should be
36437330f729Sjoerg // wrapped in isObjC, but for now we just use it here as this is where it
36447330f729Sjoerg // was being used previously.
36457330f729Sjoerg if (types::isCXX(Input.getType()) && types::isObjC(Input.getType())) {
36467330f729Sjoerg if (TC.GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
36477330f729Sjoerg CmdArgs.push_back("-fobjc-arc-cxxlib=libc++");
36487330f729Sjoerg else
36497330f729Sjoerg CmdArgs.push_back("-fobjc-arc-cxxlib=libstdc++");
36507330f729Sjoerg }
36517330f729Sjoerg
36527330f729Sjoerg // Allow the user to enable full exceptions code emission.
36537330f729Sjoerg // We default off for Objective-C, on for Objective-C++.
36547330f729Sjoerg if (Args.hasFlag(options::OPT_fobjc_arc_exceptions,
36557330f729Sjoerg options::OPT_fno_objc_arc_exceptions,
36567330f729Sjoerg /*Default=*/types::isCXX(Input.getType())))
36577330f729Sjoerg CmdArgs.push_back("-fobjc-arc-exceptions");
36587330f729Sjoerg }
36597330f729Sjoerg
36607330f729Sjoerg // Silence warning for full exception code emission options when explicitly
36617330f729Sjoerg // set to use no ARC.
36627330f729Sjoerg if (Args.hasArg(options::OPT_fno_objc_arc)) {
36637330f729Sjoerg Args.ClaimAllArgs(options::OPT_fobjc_arc_exceptions);
36647330f729Sjoerg Args.ClaimAllArgs(options::OPT_fno_objc_arc_exceptions);
36657330f729Sjoerg }
36667330f729Sjoerg
36677330f729Sjoerg // Allow the user to control whether messages can be converted to runtime
36687330f729Sjoerg // functions.
36697330f729Sjoerg if (types::isObjC(Input.getType())) {
36707330f729Sjoerg auto *Arg = Args.getLastArg(
36717330f729Sjoerg options::OPT_fobjc_convert_messages_to_runtime_calls,
36727330f729Sjoerg options::OPT_fno_objc_convert_messages_to_runtime_calls);
36737330f729Sjoerg if (Arg &&
36747330f729Sjoerg Arg->getOption().matches(
36757330f729Sjoerg options::OPT_fno_objc_convert_messages_to_runtime_calls))
36767330f729Sjoerg CmdArgs.push_back("-fno-objc-convert-messages-to-runtime-calls");
36777330f729Sjoerg }
36787330f729Sjoerg
36797330f729Sjoerg // -fobjc-infer-related-result-type is the default, except in the Objective-C
36807330f729Sjoerg // rewriter.
36817330f729Sjoerg if (InferCovariantReturns)
36827330f729Sjoerg CmdArgs.push_back("-fno-objc-infer-related-result-type");
36837330f729Sjoerg
36847330f729Sjoerg // Pass down -fobjc-weak or -fno-objc-weak if present.
36857330f729Sjoerg if (types::isObjC(Input.getType())) {
36867330f729Sjoerg auto WeakArg =
36877330f729Sjoerg Args.getLastArg(options::OPT_fobjc_weak, options::OPT_fno_objc_weak);
36887330f729Sjoerg if (!WeakArg) {
36897330f729Sjoerg // nothing to do
36907330f729Sjoerg } else if (!Runtime.allowsWeak()) {
36917330f729Sjoerg if (WeakArg->getOption().matches(options::OPT_fobjc_weak))
36927330f729Sjoerg D.Diag(diag::err_objc_weak_unsupported);
36937330f729Sjoerg } else {
36947330f729Sjoerg WeakArg->render(Args, CmdArgs);
36957330f729Sjoerg }
36967330f729Sjoerg }
3697*e038c9c4Sjoerg
3698*e038c9c4Sjoerg if (Args.hasArg(options::OPT_fobjc_disable_direct_methods_for_testing))
3699*e038c9c4Sjoerg CmdArgs.push_back("-fobjc-disable-direct-methods-for-testing");
37007330f729Sjoerg }
37017330f729Sjoerg
RenderDiagnosticsOptions(const Driver & D,const ArgList & Args,ArgStringList & CmdArgs)37027330f729Sjoerg static void RenderDiagnosticsOptions(const Driver &D, const ArgList &Args,
37037330f729Sjoerg ArgStringList &CmdArgs) {
37047330f729Sjoerg bool CaretDefault = true;
37057330f729Sjoerg bool ColumnDefault = true;
37067330f729Sjoerg
37077330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT__SLASH_diagnostics_classic,
37087330f729Sjoerg options::OPT__SLASH_diagnostics_column,
37097330f729Sjoerg options::OPT__SLASH_diagnostics_caret)) {
37107330f729Sjoerg switch (A->getOption().getID()) {
37117330f729Sjoerg case options::OPT__SLASH_diagnostics_caret:
37127330f729Sjoerg CaretDefault = true;
37137330f729Sjoerg ColumnDefault = true;
37147330f729Sjoerg break;
37157330f729Sjoerg case options::OPT__SLASH_diagnostics_column:
37167330f729Sjoerg CaretDefault = false;
37177330f729Sjoerg ColumnDefault = true;
37187330f729Sjoerg break;
37197330f729Sjoerg case options::OPT__SLASH_diagnostics_classic:
37207330f729Sjoerg CaretDefault = false;
37217330f729Sjoerg ColumnDefault = false;
37227330f729Sjoerg break;
37237330f729Sjoerg }
37247330f729Sjoerg }
37257330f729Sjoerg
37267330f729Sjoerg // -fcaret-diagnostics is default.
37277330f729Sjoerg if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
37287330f729Sjoerg options::OPT_fno_caret_diagnostics, CaretDefault))
37297330f729Sjoerg CmdArgs.push_back("-fno-caret-diagnostics");
37307330f729Sjoerg
37317330f729Sjoerg // -fdiagnostics-fixit-info is default, only pass non-default.
37327330f729Sjoerg if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info,
37337330f729Sjoerg options::OPT_fno_diagnostics_fixit_info))
37347330f729Sjoerg CmdArgs.push_back("-fno-diagnostics-fixit-info");
37357330f729Sjoerg
37367330f729Sjoerg // Enable -fdiagnostics-show-option by default.
3737*e038c9c4Sjoerg if (!Args.hasFlag(options::OPT_fdiagnostics_show_option,
3738*e038c9c4Sjoerg options::OPT_fno_diagnostics_show_option, true))
3739*e038c9c4Sjoerg CmdArgs.push_back("-fno-diagnostics-show-option");
37407330f729Sjoerg
37417330f729Sjoerg if (const Arg *A =
37427330f729Sjoerg Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) {
37437330f729Sjoerg CmdArgs.push_back("-fdiagnostics-show-category");
37447330f729Sjoerg CmdArgs.push_back(A->getValue());
37457330f729Sjoerg }
37467330f729Sjoerg
37477330f729Sjoerg if (Args.hasFlag(options::OPT_fdiagnostics_show_hotness,
37487330f729Sjoerg options::OPT_fno_diagnostics_show_hotness, false))
37497330f729Sjoerg CmdArgs.push_back("-fdiagnostics-show-hotness");
37507330f729Sjoerg
37517330f729Sjoerg if (const Arg *A =
37527330f729Sjoerg Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) {
37537330f729Sjoerg std::string Opt =
37547330f729Sjoerg std::string("-fdiagnostics-hotness-threshold=") + A->getValue();
37557330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(Opt));
37567330f729Sjoerg }
37577330f729Sjoerg
37587330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) {
37597330f729Sjoerg CmdArgs.push_back("-fdiagnostics-format");
37607330f729Sjoerg CmdArgs.push_back(A->getValue());
37617330f729Sjoerg }
37627330f729Sjoerg
37637330f729Sjoerg if (const Arg *A = Args.getLastArg(
37647330f729Sjoerg options::OPT_fdiagnostics_show_note_include_stack,
37657330f729Sjoerg options::OPT_fno_diagnostics_show_note_include_stack)) {
37667330f729Sjoerg const Option &O = A->getOption();
37677330f729Sjoerg if (O.matches(options::OPT_fdiagnostics_show_note_include_stack))
37687330f729Sjoerg CmdArgs.push_back("-fdiagnostics-show-note-include-stack");
37697330f729Sjoerg else
37707330f729Sjoerg CmdArgs.push_back("-fno-diagnostics-show-note-include-stack");
37717330f729Sjoerg }
37727330f729Sjoerg
37737330f729Sjoerg // Color diagnostics are parsed by the driver directly from argv and later
37747330f729Sjoerg // re-parsed to construct this job; claim any possible color diagnostic here
37757330f729Sjoerg // to avoid warn_drv_unused_argument and diagnose bad
37767330f729Sjoerg // OPT_fdiagnostics_color_EQ values.
37777330f729Sjoerg for (const Arg *A : Args) {
37787330f729Sjoerg const Option &O = A->getOption();
37797330f729Sjoerg if (!O.matches(options::OPT_fcolor_diagnostics) &&
37807330f729Sjoerg !O.matches(options::OPT_fdiagnostics_color) &&
37817330f729Sjoerg !O.matches(options::OPT_fno_color_diagnostics) &&
37827330f729Sjoerg !O.matches(options::OPT_fno_diagnostics_color) &&
37837330f729Sjoerg !O.matches(options::OPT_fdiagnostics_color_EQ))
37847330f729Sjoerg continue;
37857330f729Sjoerg
37867330f729Sjoerg if (O.matches(options::OPT_fdiagnostics_color_EQ)) {
37877330f729Sjoerg StringRef Value(A->getValue());
37887330f729Sjoerg if (Value != "always" && Value != "never" && Value != "auto")
37897330f729Sjoerg D.Diag(diag::err_drv_clang_unsupported)
37907330f729Sjoerg << ("-fdiagnostics-color=" + Value).str();
37917330f729Sjoerg }
37927330f729Sjoerg A->claim();
37937330f729Sjoerg }
37947330f729Sjoerg
37957330f729Sjoerg if (D.getDiags().getDiagnosticOptions().ShowColors)
37967330f729Sjoerg CmdArgs.push_back("-fcolor-diagnostics");
37977330f729Sjoerg
37987330f729Sjoerg if (Args.hasArg(options::OPT_fansi_escape_codes))
37997330f729Sjoerg CmdArgs.push_back("-fansi-escape-codes");
38007330f729Sjoerg
38017330f729Sjoerg if (!Args.hasFlag(options::OPT_fshow_source_location,
38027330f729Sjoerg options::OPT_fno_show_source_location))
38037330f729Sjoerg CmdArgs.push_back("-fno-show-source-location");
38047330f729Sjoerg
38057330f729Sjoerg if (Args.hasArg(options::OPT_fdiagnostics_absolute_paths))
38067330f729Sjoerg CmdArgs.push_back("-fdiagnostics-absolute-paths");
38077330f729Sjoerg
38087330f729Sjoerg if (!Args.hasFlag(options::OPT_fshow_column, options::OPT_fno_show_column,
38097330f729Sjoerg ColumnDefault))
38107330f729Sjoerg CmdArgs.push_back("-fno-show-column");
38117330f729Sjoerg
38127330f729Sjoerg if (!Args.hasFlag(options::OPT_fspell_checking,
38137330f729Sjoerg options::OPT_fno_spell_checking))
38147330f729Sjoerg CmdArgs.push_back("-fno-spell-checking");
38157330f729Sjoerg }
38167330f729Sjoerg
38177330f729Sjoerg enum class DwarfFissionKind { None, Split, Single };
38187330f729Sjoerg
getDebugFissionKind(const Driver & D,const ArgList & Args,Arg * & Arg)38197330f729Sjoerg static DwarfFissionKind getDebugFissionKind(const Driver &D,
38207330f729Sjoerg const ArgList &Args, Arg *&Arg) {
3821*e038c9c4Sjoerg Arg = Args.getLastArg(options::OPT_gsplit_dwarf, options::OPT_gsplit_dwarf_EQ,
3822*e038c9c4Sjoerg options::OPT_gno_split_dwarf);
3823*e038c9c4Sjoerg if (!Arg || Arg->getOption().matches(options::OPT_gno_split_dwarf))
38247330f729Sjoerg return DwarfFissionKind::None;
38257330f729Sjoerg
38267330f729Sjoerg if (Arg->getOption().matches(options::OPT_gsplit_dwarf))
38277330f729Sjoerg return DwarfFissionKind::Split;
38287330f729Sjoerg
38297330f729Sjoerg StringRef Value = Arg->getValue();
38307330f729Sjoerg if (Value == "split")
38317330f729Sjoerg return DwarfFissionKind::Split;
38327330f729Sjoerg if (Value == "single")
38337330f729Sjoerg return DwarfFissionKind::Single;
38347330f729Sjoerg
38357330f729Sjoerg D.Diag(diag::err_drv_unsupported_option_argument)
38367330f729Sjoerg << Arg->getOption().getName() << Arg->getValue();
38377330f729Sjoerg return DwarfFissionKind::None;
38387330f729Sjoerg }
38397330f729Sjoerg
renderDwarfFormat(const Driver & D,const llvm::Triple & T,const ArgList & Args,ArgStringList & CmdArgs,unsigned DwarfVersion)3840*e038c9c4Sjoerg static void renderDwarfFormat(const Driver &D, const llvm::Triple &T,
3841*e038c9c4Sjoerg const ArgList &Args, ArgStringList &CmdArgs,
3842*e038c9c4Sjoerg unsigned DwarfVersion) {
3843*e038c9c4Sjoerg auto *DwarfFormatArg =
3844*e038c9c4Sjoerg Args.getLastArg(options::OPT_gdwarf64, options::OPT_gdwarf32);
3845*e038c9c4Sjoerg if (!DwarfFormatArg)
3846*e038c9c4Sjoerg return;
3847*e038c9c4Sjoerg
3848*e038c9c4Sjoerg if (DwarfFormatArg->getOption().matches(options::OPT_gdwarf64)) {
3849*e038c9c4Sjoerg if (DwarfVersion < 3)
3850*e038c9c4Sjoerg D.Diag(diag::err_drv_argument_only_allowed_with)
3851*e038c9c4Sjoerg << DwarfFormatArg->getAsString(Args) << "DWARFv3 or greater";
3852*e038c9c4Sjoerg else if (!T.isArch64Bit())
3853*e038c9c4Sjoerg D.Diag(diag::err_drv_argument_only_allowed_with)
3854*e038c9c4Sjoerg << DwarfFormatArg->getAsString(Args) << "64 bit architecture";
3855*e038c9c4Sjoerg else if (!T.isOSBinFormatELF())
3856*e038c9c4Sjoerg D.Diag(diag::err_drv_argument_only_allowed_with)
3857*e038c9c4Sjoerg << DwarfFormatArg->getAsString(Args) << "ELF platforms";
3858*e038c9c4Sjoerg }
3859*e038c9c4Sjoerg
3860*e038c9c4Sjoerg DwarfFormatArg->render(Args, CmdArgs);
3861*e038c9c4Sjoerg }
3862*e038c9c4Sjoerg
renderDebugOptions(const ToolChain & TC,const Driver & D,const llvm::Triple & T,const ArgList & Args,bool EmitCodeView,bool IRInput,ArgStringList & CmdArgs,codegenoptions::DebugInfoKind & DebugInfoKind,DwarfFissionKind & DwarfFission)3863*e038c9c4Sjoerg static void renderDebugOptions(const ToolChain &TC, const Driver &D,
38647330f729Sjoerg const llvm::Triple &T, const ArgList &Args,
3865*e038c9c4Sjoerg bool EmitCodeView, bool IRInput,
38667330f729Sjoerg ArgStringList &CmdArgs,
38677330f729Sjoerg codegenoptions::DebugInfoKind &DebugInfoKind,
38687330f729Sjoerg DwarfFissionKind &DwarfFission) {
3869*e038c9c4Sjoerg // These two forms of profiling info can't be used together.
3870*e038c9c4Sjoerg if (const Arg *A1 = Args.getLastArg(options::OPT_fpseudo_probe_for_profiling))
3871*e038c9c4Sjoerg if (const Arg *A2 = Args.getLastArg(options::OPT_fdebug_info_for_profiling))
3872*e038c9c4Sjoerg D.Diag(diag::err_drv_argument_not_allowed_with)
3873*e038c9c4Sjoerg << A1->getAsString(Args) << A2->getAsString(Args);
3874*e038c9c4Sjoerg
38757330f729Sjoerg if (Args.hasFlag(options::OPT_fdebug_info_for_profiling,
38767330f729Sjoerg options::OPT_fno_debug_info_for_profiling, false) &&
38777330f729Sjoerg checkDebugInfoOption(
38787330f729Sjoerg Args.getLastArg(options::OPT_fdebug_info_for_profiling), Args, D, TC))
38797330f729Sjoerg CmdArgs.push_back("-fdebug-info-for-profiling");
38807330f729Sjoerg
38817330f729Sjoerg // The 'g' groups options involve a somewhat intricate sequence of decisions
38827330f729Sjoerg // about what to pass from the driver to the frontend, but by the time they
38837330f729Sjoerg // reach cc1 they've been factored into three well-defined orthogonal choices:
38847330f729Sjoerg // * what level of debug info to generate
38857330f729Sjoerg // * what dwarf version to write
38867330f729Sjoerg // * what debugger tuning to use
38877330f729Sjoerg // This avoids having to monkey around further in cc1 other than to disable
38887330f729Sjoerg // codeview if not running in a Windows environment. Perhaps even that
38897330f729Sjoerg // decision should be made in the driver as well though.
38907330f729Sjoerg llvm::DebuggerKind DebuggerTuning = TC.getDefaultDebuggerTuning();
38917330f729Sjoerg
38927330f729Sjoerg bool SplitDWARFInlining =
38937330f729Sjoerg Args.hasFlag(options::OPT_fsplit_dwarf_inlining,
3894*e038c9c4Sjoerg options::OPT_fno_split_dwarf_inlining, false);
38957330f729Sjoerg
3896*e038c9c4Sjoerg // Normally -gsplit-dwarf is only useful with -gN. For IR input, Clang does
3897*e038c9c4Sjoerg // object file generation and no IR generation, -gN should not be needed. So
3898*e038c9c4Sjoerg // allow -gsplit-dwarf with either -gN or IR input.
3899*e038c9c4Sjoerg if (IRInput || Args.hasArg(options::OPT_g_Group)) {
39007330f729Sjoerg Arg *SplitDWARFArg;
39017330f729Sjoerg DwarfFission = getDebugFissionKind(D, Args, SplitDWARFArg);
39027330f729Sjoerg if (DwarfFission != DwarfFissionKind::None &&
39037330f729Sjoerg !checkDebugInfoOption(SplitDWARFArg, Args, D, TC)) {
39047330f729Sjoerg DwarfFission = DwarfFissionKind::None;
39057330f729Sjoerg SplitDWARFInlining = false;
39067330f729Sjoerg }
3907*e038c9c4Sjoerg }
3908*e038c9c4Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) {
39097330f729Sjoerg DebugInfoKind = codegenoptions::LimitedDebugInfo;
39107330f729Sjoerg
39117330f729Sjoerg // If the last option explicitly specified a debug-info level, use it.
39127330f729Sjoerg if (checkDebugInfoOption(A, Args, D, TC) &&
39137330f729Sjoerg A->getOption().matches(options::OPT_gN_Group)) {
39147330f729Sjoerg DebugInfoKind = DebugLevelToInfoKind(*A);
39157330f729Sjoerg // For -g0 or -gline-tables-only, drop -gsplit-dwarf. This gets a bit more
39167330f729Sjoerg // complicated if you've disabled inline info in the skeleton CUs
39177330f729Sjoerg // (SplitDWARFInlining) - then there's value in composing split-dwarf and
39187330f729Sjoerg // line-tables-only, so let those compose naturally in that case.
39197330f729Sjoerg if (DebugInfoKind == codegenoptions::NoDebugInfo ||
39207330f729Sjoerg DebugInfoKind == codegenoptions::DebugDirectivesOnly ||
39217330f729Sjoerg (DebugInfoKind == codegenoptions::DebugLineTablesOnly &&
39227330f729Sjoerg SplitDWARFInlining))
39237330f729Sjoerg DwarfFission = DwarfFissionKind::None;
39247330f729Sjoerg }
39257330f729Sjoerg }
39267330f729Sjoerg
39277330f729Sjoerg // If a debugger tuning argument appeared, remember it.
39287330f729Sjoerg if (const Arg *A =
39297330f729Sjoerg Args.getLastArg(options::OPT_gTune_Group, options::OPT_ggdbN_Group)) {
39307330f729Sjoerg if (checkDebugInfoOption(A, Args, D, TC)) {
39317330f729Sjoerg if (A->getOption().matches(options::OPT_glldb))
39327330f729Sjoerg DebuggerTuning = llvm::DebuggerKind::LLDB;
39337330f729Sjoerg else if (A->getOption().matches(options::OPT_gsce))
39347330f729Sjoerg DebuggerTuning = llvm::DebuggerKind::SCE;
3935*e038c9c4Sjoerg else if (A->getOption().matches(options::OPT_gdbx))
3936*e038c9c4Sjoerg DebuggerTuning = llvm::DebuggerKind::DBX;
39377330f729Sjoerg else
39387330f729Sjoerg DebuggerTuning = llvm::DebuggerKind::GDB;
39397330f729Sjoerg }
39407330f729Sjoerg }
39417330f729Sjoerg
39427330f729Sjoerg // If a -gdwarf argument appeared, remember it.
3943*e038c9c4Sjoerg const Arg *GDwarfN = getDwarfNArg(Args);
3944*e038c9c4Sjoerg bool EmitDwarf = false;
3945*e038c9c4Sjoerg if (GDwarfN) {
3946*e038c9c4Sjoerg if (checkDebugInfoOption(GDwarfN, Args, D, TC))
3947*e038c9c4Sjoerg EmitDwarf = true;
3948*e038c9c4Sjoerg else
3949*e038c9c4Sjoerg GDwarfN = nullptr;
3950*e038c9c4Sjoerg }
39517330f729Sjoerg
39527330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_gcodeview)) {
39537330f729Sjoerg if (checkDebugInfoOption(A, Args, D, TC))
39547330f729Sjoerg EmitCodeView = true;
39557330f729Sjoerg }
39567330f729Sjoerg
39577330f729Sjoerg // If the user asked for debug info but did not explicitly specify -gcodeview
39587330f729Sjoerg // or -gdwarf, ask the toolchain for the default format.
3959*e038c9c4Sjoerg if (!EmitCodeView && !EmitDwarf &&
39607330f729Sjoerg DebugInfoKind != codegenoptions::NoDebugInfo) {
39617330f729Sjoerg switch (TC.getDefaultDebugFormat()) {
39627330f729Sjoerg case codegenoptions::DIF_CodeView:
39637330f729Sjoerg EmitCodeView = true;
39647330f729Sjoerg break;
39657330f729Sjoerg case codegenoptions::DIF_DWARF:
3966*e038c9c4Sjoerg EmitDwarf = true;
39677330f729Sjoerg break;
39687330f729Sjoerg }
39697330f729Sjoerg }
39707330f729Sjoerg
3971*e038c9c4Sjoerg unsigned RequestedDWARFVersion = 0; // DWARF version requested by the user
3972*e038c9c4Sjoerg unsigned EffectiveDWARFVersion = 0; // DWARF version TC can generate. It may
3973*e038c9c4Sjoerg // be lower than what the user wanted.
3974*e038c9c4Sjoerg unsigned DefaultDWARFVersion = ParseDebugDefaultVersion(TC, Args);
3975*e038c9c4Sjoerg if (EmitDwarf) {
3976*e038c9c4Sjoerg // Start with the platform default DWARF version
3977*e038c9c4Sjoerg RequestedDWARFVersion = TC.GetDefaultDwarfVersion();
3978*e038c9c4Sjoerg assert(RequestedDWARFVersion &&
3979*e038c9c4Sjoerg "toolchain default DWARF version must be nonzero");
3980*e038c9c4Sjoerg
3981*e038c9c4Sjoerg // If the user specified a default DWARF version, that takes precedence
3982*e038c9c4Sjoerg // over the platform default.
3983*e038c9c4Sjoerg if (DefaultDWARFVersion)
3984*e038c9c4Sjoerg RequestedDWARFVersion = DefaultDWARFVersion;
3985*e038c9c4Sjoerg
3986*e038c9c4Sjoerg // Override with a user-specified DWARF version
3987*e038c9c4Sjoerg if (GDwarfN)
3988*e038c9c4Sjoerg if (auto ExplicitVersion = DwarfVersionNum(GDwarfN->getSpelling()))
3989*e038c9c4Sjoerg RequestedDWARFVersion = ExplicitVersion;
3990*e038c9c4Sjoerg // Clamp effective DWARF version to the max supported by the toolchain.
3991*e038c9c4Sjoerg EffectiveDWARFVersion =
3992*e038c9c4Sjoerg std::min(RequestedDWARFVersion, TC.getMaxDwarfVersion());
3993*e038c9c4Sjoerg }
3994*e038c9c4Sjoerg
39957330f729Sjoerg // -gline-directives-only supported only for the DWARF debug info.
3996*e038c9c4Sjoerg if (RequestedDWARFVersion == 0 &&
3997*e038c9c4Sjoerg DebugInfoKind == codegenoptions::DebugDirectivesOnly)
39987330f729Sjoerg DebugInfoKind = codegenoptions::NoDebugInfo;
39997330f729Sjoerg
4000*e038c9c4Sjoerg // strict DWARF is set to false by default. But for DBX, we need it to be set
4001*e038c9c4Sjoerg // as true by default.
4002*e038c9c4Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_gstrict_dwarf))
4003*e038c9c4Sjoerg (void)checkDebugInfoOption(A, Args, D, TC);
4004*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_gstrict_dwarf, options::OPT_gno_strict_dwarf,
4005*e038c9c4Sjoerg DebuggerTuning == llvm::DebuggerKind::DBX))
4006*e038c9c4Sjoerg CmdArgs.push_back("-gstrict-dwarf");
4007*e038c9c4Sjoerg
40087330f729Sjoerg // And we handle flag -grecord-gcc-switches later with DWARFDebugFlags.
40097330f729Sjoerg Args.ClaimAllArgs(options::OPT_g_flags_Group);
40107330f729Sjoerg
40117330f729Sjoerg // Column info is included by default for everything except SCE and
40127330f729Sjoerg // CodeView. Clang doesn't track end columns, just starting columns, which,
40137330f729Sjoerg // in theory, is fine for CodeView (and PDB). In practice, however, the
4014*e038c9c4Sjoerg // Microsoft debuggers don't handle missing end columns well, and the AIX
4015*e038c9c4Sjoerg // debugger DBX also doesn't handle the columns well, so it's better not to
4016*e038c9c4Sjoerg // include any column info.
40177330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_gcolumn_info))
40187330f729Sjoerg (void)checkDebugInfoOption(A, Args, D, TC);
4019*e038c9c4Sjoerg if (!Args.hasFlag(options::OPT_gcolumn_info, options::OPT_gno_column_info,
4020*e038c9c4Sjoerg !EmitCodeView &&
4021*e038c9c4Sjoerg (DebuggerTuning != llvm::DebuggerKind::SCE &&
4022*e038c9c4Sjoerg DebuggerTuning != llvm::DebuggerKind::DBX)))
4023*e038c9c4Sjoerg CmdArgs.push_back("-gno-column-info");
40247330f729Sjoerg
40257330f729Sjoerg // FIXME: Move backend command line options to the module.
40267330f729Sjoerg // If -gline-tables-only or -gline-directives-only is the last option it wins.
40277330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_gmodules))
40287330f729Sjoerg if (checkDebugInfoOption(A, Args, D, TC)) {
40297330f729Sjoerg if (DebugInfoKind != codegenoptions::DebugLineTablesOnly &&
40307330f729Sjoerg DebugInfoKind != codegenoptions::DebugDirectivesOnly) {
40317330f729Sjoerg DebugInfoKind = codegenoptions::LimitedDebugInfo;
40327330f729Sjoerg CmdArgs.push_back("-dwarf-ext-refs");
40337330f729Sjoerg CmdArgs.push_back("-fmodule-format=obj");
40347330f729Sjoerg }
40357330f729Sjoerg }
40367330f729Sjoerg
4037*e038c9c4Sjoerg if (T.isOSBinFormatELF() && SplitDWARFInlining)
4038*e038c9c4Sjoerg CmdArgs.push_back("-fsplit-dwarf-inlining");
40397330f729Sjoerg
40407330f729Sjoerg // After we've dealt with all combinations of things that could
40417330f729Sjoerg // make DebugInfoKind be other than None or DebugLineTablesOnly,
40427330f729Sjoerg // figure out if we need to "upgrade" it to standalone debug info.
40437330f729Sjoerg // We parse these two '-f' options whether or not they will be used,
40447330f729Sjoerg // to claim them even if you wrote "-fstandalone-debug -gline-tables-only"
40457330f729Sjoerg bool NeedFullDebug = Args.hasFlag(
40467330f729Sjoerg options::OPT_fstandalone_debug, options::OPT_fno_standalone_debug,
40477330f729Sjoerg DebuggerTuning == llvm::DebuggerKind::LLDB ||
40487330f729Sjoerg TC.GetDefaultStandaloneDebug());
40497330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_fstandalone_debug))
40507330f729Sjoerg (void)checkDebugInfoOption(A, Args, D, TC);
4051*e038c9c4Sjoerg
4052*e038c9c4Sjoerg if (DebugInfoKind == codegenoptions::LimitedDebugInfo) {
4053*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fno_eliminate_unused_debug_types,
4054*e038c9c4Sjoerg options::OPT_feliminate_unused_debug_types, false))
4055*e038c9c4Sjoerg DebugInfoKind = codegenoptions::UnusedTypeInfo;
4056*e038c9c4Sjoerg else if (NeedFullDebug)
40577330f729Sjoerg DebugInfoKind = codegenoptions::FullDebugInfo;
4058*e038c9c4Sjoerg }
40597330f729Sjoerg
40607330f729Sjoerg if (Args.hasFlag(options::OPT_gembed_source, options::OPT_gno_embed_source,
40617330f729Sjoerg false)) {
40627330f729Sjoerg // Source embedding is a vendor extension to DWARF v5. By now we have
40637330f729Sjoerg // checked if a DWARF version was stated explicitly, and have otherwise
40647330f729Sjoerg // fallen back to the target default, so if this is still not at least 5
40657330f729Sjoerg // we emit an error.
40667330f729Sjoerg const Arg *A = Args.getLastArg(options::OPT_gembed_source);
4067*e038c9c4Sjoerg if (RequestedDWARFVersion < 5)
40687330f729Sjoerg D.Diag(diag::err_drv_argument_only_allowed_with)
40697330f729Sjoerg << A->getAsString(Args) << "-gdwarf-5";
4070*e038c9c4Sjoerg else if (EffectiveDWARFVersion < 5)
4071*e038c9c4Sjoerg // The toolchain has reduced allowed dwarf version, so we can't enable
4072*e038c9c4Sjoerg // -gembed-source.
4073*e038c9c4Sjoerg D.Diag(diag::warn_drv_dwarf_version_limited_by_target)
4074*e038c9c4Sjoerg << A->getAsString(Args) << TC.getTripleString() << 5
4075*e038c9c4Sjoerg << EffectiveDWARFVersion;
40767330f729Sjoerg else if (checkDebugInfoOption(A, Args, D, TC))
40777330f729Sjoerg CmdArgs.push_back("-gembed-source");
40787330f729Sjoerg }
40797330f729Sjoerg
40807330f729Sjoerg if (EmitCodeView) {
40817330f729Sjoerg CmdArgs.push_back("-gcodeview");
40827330f729Sjoerg
40837330f729Sjoerg // Emit codeview type hashes if requested.
40847330f729Sjoerg if (Args.hasFlag(options::OPT_gcodeview_ghash,
40857330f729Sjoerg options::OPT_gno_codeview_ghash, false)) {
40867330f729Sjoerg CmdArgs.push_back("-gcodeview-ghash");
40877330f729Sjoerg }
40887330f729Sjoerg }
40897330f729Sjoerg
4090*e038c9c4Sjoerg // Omit inline line tables if requested.
4091*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_gno_inline_line_tables,
4092*e038c9c4Sjoerg options::OPT_ginline_line_tables, false)) {
4093*e038c9c4Sjoerg CmdArgs.push_back("-gno-inline-line-tables");
4094*e038c9c4Sjoerg }
4095*e038c9c4Sjoerg
4096*e038c9c4Sjoerg // When emitting remarks, we need at least debug lines in the output.
4097*e038c9c4Sjoerg if (willEmitRemarks(Args) &&
4098*e038c9c4Sjoerg DebugInfoKind <= codegenoptions::DebugDirectivesOnly)
4099*e038c9c4Sjoerg DebugInfoKind = codegenoptions::DebugLineTablesOnly;
4100*e038c9c4Sjoerg
41017330f729Sjoerg // Adjust the debug info kind for the given toolchain.
41027330f729Sjoerg TC.adjustDebugInfoKind(DebugInfoKind, Args);
41037330f729Sjoerg
4104*e038c9c4Sjoerg RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, EffectiveDWARFVersion,
41057330f729Sjoerg DebuggerTuning);
41067330f729Sjoerg
41077330f729Sjoerg // -fdebug-macro turns on macro debug info generation.
41087330f729Sjoerg if (Args.hasFlag(options::OPT_fdebug_macro, options::OPT_fno_debug_macro,
41097330f729Sjoerg false))
41107330f729Sjoerg if (checkDebugInfoOption(Args.getLastArg(options::OPT_fdebug_macro), Args,
41117330f729Sjoerg D, TC))
41127330f729Sjoerg CmdArgs.push_back("-debug-info-macro");
41137330f729Sjoerg
41147330f729Sjoerg // -ggnu-pubnames turns on gnu style pubnames in the backend.
41157330f729Sjoerg const auto *PubnamesArg =
41167330f729Sjoerg Args.getLastArg(options::OPT_ggnu_pubnames, options::OPT_gno_gnu_pubnames,
41177330f729Sjoerg options::OPT_gpubnames, options::OPT_gno_pubnames);
41187330f729Sjoerg if (DwarfFission != DwarfFissionKind::None ||
41197330f729Sjoerg (PubnamesArg && checkDebugInfoOption(PubnamesArg, Args, D, TC)))
41207330f729Sjoerg if (!PubnamesArg ||
41217330f729Sjoerg (!PubnamesArg->getOption().matches(options::OPT_gno_gnu_pubnames) &&
41227330f729Sjoerg !PubnamesArg->getOption().matches(options::OPT_gno_pubnames)))
41237330f729Sjoerg CmdArgs.push_back(PubnamesArg && PubnamesArg->getOption().matches(
41247330f729Sjoerg options::OPT_gpubnames)
41257330f729Sjoerg ? "-gpubnames"
41267330f729Sjoerg : "-ggnu-pubnames");
41277330f729Sjoerg
41287330f729Sjoerg if (Args.hasFlag(options::OPT_fdebug_ranges_base_address,
41297330f729Sjoerg options::OPT_fno_debug_ranges_base_address, false)) {
41307330f729Sjoerg CmdArgs.push_back("-fdebug-ranges-base-address");
41317330f729Sjoerg }
41327330f729Sjoerg
41337330f729Sjoerg // -gdwarf-aranges turns on the emission of the aranges section in the
41347330f729Sjoerg // backend.
41357330f729Sjoerg // Always enabled for SCE tuning.
41367330f729Sjoerg bool NeedAranges = DebuggerTuning == llvm::DebuggerKind::SCE;
41377330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_gdwarf_aranges))
41387330f729Sjoerg NeedAranges = checkDebugInfoOption(A, Args, D, TC) || NeedAranges;
41397330f729Sjoerg if (NeedAranges) {
41407330f729Sjoerg CmdArgs.push_back("-mllvm");
41417330f729Sjoerg CmdArgs.push_back("-generate-arange-section");
41427330f729Sjoerg }
41437330f729Sjoerg
4144*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fforce_dwarf_frame,
4145*e038c9c4Sjoerg options::OPT_fno_force_dwarf_frame, false))
4146*e038c9c4Sjoerg CmdArgs.push_back("-fforce-dwarf-frame");
4147*e038c9c4Sjoerg
41487330f729Sjoerg if (Args.hasFlag(options::OPT_fdebug_types_section,
41497330f729Sjoerg options::OPT_fno_debug_types_section, false)) {
4150*e038c9c4Sjoerg if (!(T.isOSBinFormatELF() || T.isOSBinFormatWasm())) {
41517330f729Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
41527330f729Sjoerg << Args.getLastArg(options::OPT_fdebug_types_section)
41537330f729Sjoerg ->getAsString(Args)
41547330f729Sjoerg << T.getTriple();
41557330f729Sjoerg } else if (checkDebugInfoOption(
41567330f729Sjoerg Args.getLastArg(options::OPT_fdebug_types_section), Args, D,
41577330f729Sjoerg TC)) {
41587330f729Sjoerg CmdArgs.push_back("-mllvm");
41597330f729Sjoerg CmdArgs.push_back("-generate-type-units");
41607330f729Sjoerg }
41617330f729Sjoerg }
41627330f729Sjoerg
41637330f729Sjoerg // Decide how to render forward declarations of template instantiations.
41647330f729Sjoerg // SCE wants full descriptions, others just get them in the name.
41657330f729Sjoerg if (DebuggerTuning == llvm::DebuggerKind::SCE)
41667330f729Sjoerg CmdArgs.push_back("-debug-forward-template-params");
41677330f729Sjoerg
41687330f729Sjoerg // Do we need to explicitly import anonymous namespaces into the parent
41697330f729Sjoerg // scope?
41707330f729Sjoerg if (DebuggerTuning == llvm::DebuggerKind::SCE)
41717330f729Sjoerg CmdArgs.push_back("-dwarf-explicit-import");
41727330f729Sjoerg
4173*e038c9c4Sjoerg renderDwarfFormat(D, T, Args, CmdArgs, EffectiveDWARFVersion);
41747330f729Sjoerg RenderDebugInfoCompressionArgs(Args, CmdArgs, D, TC);
41757330f729Sjoerg }
41767330f729Sjoerg
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const41777330f729Sjoerg void Clang::ConstructJob(Compilation &C, const JobAction &JA,
41787330f729Sjoerg const InputInfo &Output, const InputInfoList &Inputs,
41797330f729Sjoerg const ArgList &Args, const char *LinkingOutput) const {
41807330f729Sjoerg const auto &TC = getToolChain();
41817330f729Sjoerg const llvm::Triple &RawTriple = TC.getTriple();
41827330f729Sjoerg const llvm::Triple &Triple = TC.getEffectiveTriple();
41837330f729Sjoerg const std::string &TripleStr = Triple.getTriple();
41847330f729Sjoerg
41857330f729Sjoerg bool KernelOrKext =
41867330f729Sjoerg Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
41877330f729Sjoerg const Driver &D = TC.getDriver();
41887330f729Sjoerg ArgStringList CmdArgs;
41897330f729Sjoerg
41907330f729Sjoerg // Check number of inputs for sanity. We need at least one input.
41917330f729Sjoerg assert(Inputs.size() >= 1 && "Must have at least one input.");
41927330f729Sjoerg // CUDA/HIP compilation may have multiple inputs (source file + results of
41937330f729Sjoerg // device-side compilations). OpenMP device jobs also take the host IR as a
41947330f729Sjoerg // second input. Module precompilation accepts a list of header files to
41957330f729Sjoerg // include as part of the module. All other jobs are expected to have exactly
41967330f729Sjoerg // one input.
41977330f729Sjoerg bool IsCuda = JA.isOffloading(Action::OFK_Cuda);
4198*e038c9c4Sjoerg bool IsCudaDevice = JA.isDeviceOffloading(Action::OFK_Cuda);
41997330f729Sjoerg bool IsHIP = JA.isOffloading(Action::OFK_HIP);
4200*e038c9c4Sjoerg bool IsHIPDevice = JA.isDeviceOffloading(Action::OFK_HIP);
42017330f729Sjoerg bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP);
42027330f729Sjoerg bool IsHeaderModulePrecompile = isa<HeaderModulePrecompileJobAction>(JA);
4203*e038c9c4Sjoerg bool IsDeviceOffloadAction = !(JA.isDeviceOffloading(Action::OFK_None) ||
4204*e038c9c4Sjoerg JA.isDeviceOffloading(Action::OFK_Host));
4205*e038c9c4Sjoerg bool IsUsingLTO = D.isUsingLTO(IsDeviceOffloadAction);
4206*e038c9c4Sjoerg auto LTOMode = D.getLTOMode(IsDeviceOffloadAction);
42077330f729Sjoerg
42087330f729Sjoerg // A header module compilation doesn't have a main input file, so invent a
42097330f729Sjoerg // fake one as a placeholder.
42107330f729Sjoerg const char *ModuleName = [&]{
42117330f729Sjoerg auto *ModuleNameArg = Args.getLastArg(options::OPT_fmodule_name_EQ);
42127330f729Sjoerg return ModuleNameArg ? ModuleNameArg->getValue() : "";
42137330f729Sjoerg }();
42147330f729Sjoerg InputInfo HeaderModuleInput(Inputs[0].getType(), ModuleName, ModuleName);
42157330f729Sjoerg
42167330f729Sjoerg const InputInfo &Input =
42177330f729Sjoerg IsHeaderModulePrecompile ? HeaderModuleInput : Inputs[0];
42187330f729Sjoerg
42197330f729Sjoerg InputInfoList ModuleHeaderInputs;
42207330f729Sjoerg const InputInfo *CudaDeviceInput = nullptr;
42217330f729Sjoerg const InputInfo *OpenMPDeviceInput = nullptr;
42227330f729Sjoerg for (const InputInfo &I : Inputs) {
42237330f729Sjoerg if (&I == &Input) {
42247330f729Sjoerg // This is the primary input.
42257330f729Sjoerg } else if (IsHeaderModulePrecompile &&
42267330f729Sjoerg types::getPrecompiledType(I.getType()) == types::TY_PCH) {
42277330f729Sjoerg types::ID Expected = HeaderModuleInput.getType();
42287330f729Sjoerg if (I.getType() != Expected) {
42297330f729Sjoerg D.Diag(diag::err_drv_module_header_wrong_kind)
42307330f729Sjoerg << I.getFilename() << types::getTypeName(I.getType())
42317330f729Sjoerg << types::getTypeName(Expected);
42327330f729Sjoerg }
42337330f729Sjoerg ModuleHeaderInputs.push_back(I);
42347330f729Sjoerg } else if ((IsCuda || IsHIP) && !CudaDeviceInput) {
42357330f729Sjoerg CudaDeviceInput = &I;
42367330f729Sjoerg } else if (IsOpenMPDevice && !OpenMPDeviceInput) {
42377330f729Sjoerg OpenMPDeviceInput = &I;
42387330f729Sjoerg } else {
42397330f729Sjoerg llvm_unreachable("unexpectedly given multiple inputs");
42407330f729Sjoerg }
42417330f729Sjoerg }
42427330f729Sjoerg
4243*e038c9c4Sjoerg const llvm::Triple *AuxTriple =
4244*e038c9c4Sjoerg (IsCuda || IsHIP) ? TC.getAuxTriple() : nullptr;
42457330f729Sjoerg bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment();
42467330f729Sjoerg bool IsIAMCU = RawTriple.isOSIAMCU();
42477330f729Sjoerg
42487330f729Sjoerg // Adjust IsWindowsXYZ for CUDA/HIP compilations. Even when compiling in
42497330f729Sjoerg // device mode (i.e., getToolchain().getTriple() is NVPTX/AMDGCN, not
42507330f729Sjoerg // Windows), we need to pass Windows-specific flags to cc1.
42517330f729Sjoerg if (IsCuda || IsHIP)
42527330f729Sjoerg IsWindowsMSVC |= AuxTriple && AuxTriple->isWindowsMSVCEnvironment();
42537330f729Sjoerg
42547330f729Sjoerg // C++ is not supported for IAMCU.
42557330f729Sjoerg if (IsIAMCU && types::isCXX(Input.getType()))
42567330f729Sjoerg D.Diag(diag::err_drv_clang_unsupported) << "C++ for IAMCU";
42577330f729Sjoerg
42587330f729Sjoerg // Invoke ourselves in -cc1 mode.
42597330f729Sjoerg //
42607330f729Sjoerg // FIXME: Implement custom jobs for internal actions.
42617330f729Sjoerg CmdArgs.push_back("-cc1");
42627330f729Sjoerg
42637330f729Sjoerg // Add the "effective" target triple.
42647330f729Sjoerg CmdArgs.push_back("-triple");
42657330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(TripleStr));
42667330f729Sjoerg
42677330f729Sjoerg if (const Arg *MJ = Args.getLastArg(options::OPT_MJ)) {
42687330f729Sjoerg DumpCompilationDatabase(C, MJ->getValue(), TripleStr, Output, Input, Args);
42697330f729Sjoerg Args.ClaimAllArgs(options::OPT_MJ);
42707330f729Sjoerg } else if (const Arg *GenCDBFragment =
42717330f729Sjoerg Args.getLastArg(options::OPT_gen_cdb_fragment_path)) {
42727330f729Sjoerg DumpCompilationDatabaseFragmentToDir(GenCDBFragment->getValue(), C,
42737330f729Sjoerg TripleStr, Output, Input, Args);
42747330f729Sjoerg Args.ClaimAllArgs(options::OPT_gen_cdb_fragment_path);
42757330f729Sjoerg }
42767330f729Sjoerg
42777330f729Sjoerg if (IsCuda || IsHIP) {
42787330f729Sjoerg // We have to pass the triple of the host if compiling for a CUDA/HIP device
42797330f729Sjoerg // and vice-versa.
42807330f729Sjoerg std::string NormalizedTriple;
42817330f729Sjoerg if (JA.isDeviceOffloading(Action::OFK_Cuda) ||
42827330f729Sjoerg JA.isDeviceOffloading(Action::OFK_HIP))
42837330f729Sjoerg NormalizedTriple = C.getSingleOffloadToolChain<Action::OFK_Host>()
42847330f729Sjoerg ->getTriple()
42857330f729Sjoerg .normalize();
42867330f729Sjoerg else {
42877330f729Sjoerg // Host-side compilation.
42887330f729Sjoerg NormalizedTriple =
42897330f729Sjoerg (IsCuda ? C.getSingleOffloadToolChain<Action::OFK_Cuda>()
42907330f729Sjoerg : C.getSingleOffloadToolChain<Action::OFK_HIP>())
42917330f729Sjoerg ->getTriple()
42927330f729Sjoerg .normalize();
42937330f729Sjoerg if (IsCuda) {
42947330f729Sjoerg // We need to figure out which CUDA version we're compiling for, as that
42957330f729Sjoerg // determines how we load and launch GPU kernels.
42967330f729Sjoerg auto *CTC = static_cast<const toolchains::CudaToolChain *>(
42977330f729Sjoerg C.getSingleOffloadToolChain<Action::OFK_Cuda>());
42987330f729Sjoerg assert(CTC && "Expected valid CUDA Toolchain.");
42997330f729Sjoerg if (CTC && CTC->CudaInstallation.version() != CudaVersion::UNKNOWN)
43007330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(
43017330f729Sjoerg Twine("-target-sdk-version=") +
43027330f729Sjoerg CudaVersionToString(CTC->CudaInstallation.version())));
43037330f729Sjoerg }
43047330f729Sjoerg }
43057330f729Sjoerg CmdArgs.push_back("-aux-triple");
43067330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
43077330f729Sjoerg }
43087330f729Sjoerg
4309*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false)) {
4310*e038c9c4Sjoerg CmdArgs.push_back("-fsycl-is-device");
4311*e038c9c4Sjoerg
4312*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_sycl_std_EQ)) {
4313*e038c9c4Sjoerg A->render(Args, CmdArgs);
4314*e038c9c4Sjoerg } else {
4315*e038c9c4Sjoerg // Ensure the default version in SYCL mode is 2020.
4316*e038c9c4Sjoerg CmdArgs.push_back("-sycl-std=2020");
4317*e038c9c4Sjoerg }
4318*e038c9c4Sjoerg }
4319*e038c9c4Sjoerg
43207330f729Sjoerg if (IsOpenMPDevice) {
43217330f729Sjoerg // We have to pass the triple of the host if compiling for an OpenMP device.
43227330f729Sjoerg std::string NormalizedTriple =
43237330f729Sjoerg C.getSingleOffloadToolChain<Action::OFK_Host>()
43247330f729Sjoerg ->getTriple()
43257330f729Sjoerg .normalize();
43267330f729Sjoerg CmdArgs.push_back("-aux-triple");
43277330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
43287330f729Sjoerg }
43297330f729Sjoerg
43307330f729Sjoerg if (Triple.isOSWindows() && (Triple.getArch() == llvm::Triple::arm ||
43317330f729Sjoerg Triple.getArch() == llvm::Triple::thumb)) {
43327330f729Sjoerg unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
4333*e038c9c4Sjoerg unsigned Version = 0;
4334*e038c9c4Sjoerg bool Failure =
4335*e038c9c4Sjoerg Triple.getArchName().substr(Offset).consumeInteger(10, Version);
4336*e038c9c4Sjoerg if (Failure || Version < 7)
43377330f729Sjoerg D.Diag(diag::err_target_unsupported_arch) << Triple.getArchName()
43387330f729Sjoerg << TripleStr;
43397330f729Sjoerg }
43407330f729Sjoerg
43417330f729Sjoerg // Push all default warning arguments that are specific to
43427330f729Sjoerg // the given target. These come before user provided warning options
43437330f729Sjoerg // are provided.
43447330f729Sjoerg TC.addClangWarningOptions(CmdArgs);
43457330f729Sjoerg
4346*e038c9c4Sjoerg // FIXME: Subclass ToolChain for SPIR and move this to addClangWarningOptions.
4347*e038c9c4Sjoerg if (Triple.isSPIR())
4348*e038c9c4Sjoerg CmdArgs.push_back("-Wspir-compat");
4349*e038c9c4Sjoerg
43507330f729Sjoerg // Select the appropriate action.
43517330f729Sjoerg RewriteKind rewriteKind = RK_None;
43527330f729Sjoerg
43537330f729Sjoerg // If CollectArgsForIntegratedAssembler() isn't called below, claim the args
43547330f729Sjoerg // it claims when not running an assembler. Otherwise, clang would emit
43557330f729Sjoerg // "argument unused" warnings for assembler flags when e.g. adding "-E" to
43567330f729Sjoerg // flags while debugging something. That'd be somewhat inconvenient, and it's
43577330f729Sjoerg // also inconsistent with most other flags -- we don't warn on
43587330f729Sjoerg // -ffunction-sections not being used in -E mode either for example, even
43597330f729Sjoerg // though it's not really used either.
43607330f729Sjoerg if (!isa<AssembleJobAction>(JA)) {
43617330f729Sjoerg // The args claimed here should match the args used in
43627330f729Sjoerg // CollectArgsForIntegratedAssembler().
43637330f729Sjoerg if (TC.useIntegratedAs()) {
43647330f729Sjoerg Args.ClaimAllArgs(options::OPT_mrelax_all);
43657330f729Sjoerg Args.ClaimAllArgs(options::OPT_mno_relax_all);
43667330f729Sjoerg Args.ClaimAllArgs(options::OPT_mincremental_linker_compatible);
43677330f729Sjoerg Args.ClaimAllArgs(options::OPT_mno_incremental_linker_compatible);
43687330f729Sjoerg switch (C.getDefaultToolChain().getArch()) {
43697330f729Sjoerg case llvm::Triple::arm:
43707330f729Sjoerg case llvm::Triple::armeb:
43717330f729Sjoerg case llvm::Triple::thumb:
43727330f729Sjoerg case llvm::Triple::thumbeb:
43737330f729Sjoerg Args.ClaimAllArgs(options::OPT_mimplicit_it_EQ);
43747330f729Sjoerg break;
43757330f729Sjoerg default:
43767330f729Sjoerg break;
43777330f729Sjoerg }
43787330f729Sjoerg }
43797330f729Sjoerg Args.ClaimAllArgs(options::OPT_Wa_COMMA);
43807330f729Sjoerg Args.ClaimAllArgs(options::OPT_Xassembler);
43817330f729Sjoerg }
43827330f729Sjoerg
43837330f729Sjoerg if (isa<AnalyzeJobAction>(JA)) {
43847330f729Sjoerg assert(JA.getType() == types::TY_Plist && "Invalid output type.");
43857330f729Sjoerg CmdArgs.push_back("-analyze");
43867330f729Sjoerg } else if (isa<MigrateJobAction>(JA)) {
43877330f729Sjoerg CmdArgs.push_back("-migrate");
43887330f729Sjoerg } else if (isa<PreprocessJobAction>(JA)) {
43897330f729Sjoerg if (Output.getType() == types::TY_Dependencies)
43907330f729Sjoerg CmdArgs.push_back("-Eonly");
43917330f729Sjoerg else {
43927330f729Sjoerg CmdArgs.push_back("-E");
43937330f729Sjoerg if (Args.hasArg(options::OPT_rewrite_objc) &&
43947330f729Sjoerg !Args.hasArg(options::OPT_g_Group))
43957330f729Sjoerg CmdArgs.push_back("-P");
43967330f729Sjoerg }
43977330f729Sjoerg } else if (isa<AssembleJobAction>(JA)) {
43987330f729Sjoerg CmdArgs.push_back("-emit-obj");
43997330f729Sjoerg
44007330f729Sjoerg CollectArgsForIntegratedAssembler(C, Args, CmdArgs, D);
44017330f729Sjoerg
44027330f729Sjoerg // Also ignore explicit -force_cpusubtype_ALL option.
44037330f729Sjoerg (void)Args.hasArg(options::OPT_force__cpusubtype__ALL);
44047330f729Sjoerg } else if (isa<PrecompileJobAction>(JA)) {
44057330f729Sjoerg if (JA.getType() == types::TY_Nothing)
44067330f729Sjoerg CmdArgs.push_back("-fsyntax-only");
44077330f729Sjoerg else if (JA.getType() == types::TY_ModuleFile)
44087330f729Sjoerg CmdArgs.push_back(IsHeaderModulePrecompile
44097330f729Sjoerg ? "-emit-header-module"
44107330f729Sjoerg : "-emit-module-interface");
44117330f729Sjoerg else
44127330f729Sjoerg CmdArgs.push_back("-emit-pch");
44137330f729Sjoerg } else if (isa<VerifyPCHJobAction>(JA)) {
44147330f729Sjoerg CmdArgs.push_back("-verify-pch");
44157330f729Sjoerg } else {
44167330f729Sjoerg assert((isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) &&
44177330f729Sjoerg "Invalid action for clang tool.");
44187330f729Sjoerg if (JA.getType() == types::TY_Nothing) {
44197330f729Sjoerg CmdArgs.push_back("-fsyntax-only");
44207330f729Sjoerg } else if (JA.getType() == types::TY_LLVM_IR ||
44217330f729Sjoerg JA.getType() == types::TY_LTO_IR) {
44227330f729Sjoerg CmdArgs.push_back("-emit-llvm");
44237330f729Sjoerg } else if (JA.getType() == types::TY_LLVM_BC ||
44247330f729Sjoerg JA.getType() == types::TY_LTO_BC) {
4425*e038c9c4Sjoerg // Emit textual llvm IR for AMDGPU offloading for -emit-llvm -S
4426*e038c9c4Sjoerg if (Triple.isAMDGCN() && IsOpenMPDevice && Args.hasArg(options::OPT_S) &&
4427*e038c9c4Sjoerg Args.hasArg(options::OPT_emit_llvm)) {
4428*e038c9c4Sjoerg CmdArgs.push_back("-emit-llvm");
4429*e038c9c4Sjoerg } else {
44307330f729Sjoerg CmdArgs.push_back("-emit-llvm-bc");
4431*e038c9c4Sjoerg }
44327330f729Sjoerg } else if (JA.getType() == types::TY_IFS ||
44337330f729Sjoerg JA.getType() == types::TY_IFS_CPP) {
44347330f729Sjoerg StringRef ArgStr =
44357330f729Sjoerg Args.hasArg(options::OPT_interface_stub_version_EQ)
44367330f729Sjoerg ? Args.getLastArgValue(options::OPT_interface_stub_version_EQ)
4437*e038c9c4Sjoerg : "experimental-ifs-v2";
44387330f729Sjoerg CmdArgs.push_back("-emit-interface-stubs");
44397330f729Sjoerg CmdArgs.push_back(
44407330f729Sjoerg Args.MakeArgString(Twine("-interface-stub-version=") + ArgStr.str()));
44417330f729Sjoerg } else if (JA.getType() == types::TY_PP_Asm) {
44427330f729Sjoerg CmdArgs.push_back("-S");
44437330f729Sjoerg } else if (JA.getType() == types::TY_AST) {
44447330f729Sjoerg CmdArgs.push_back("-emit-pch");
44457330f729Sjoerg } else if (JA.getType() == types::TY_ModuleFile) {
44467330f729Sjoerg CmdArgs.push_back("-module-file-info");
44477330f729Sjoerg } else if (JA.getType() == types::TY_RewrittenObjC) {
44487330f729Sjoerg CmdArgs.push_back("-rewrite-objc");
44497330f729Sjoerg rewriteKind = RK_NonFragile;
44507330f729Sjoerg } else if (JA.getType() == types::TY_RewrittenLegacyObjC) {
44517330f729Sjoerg CmdArgs.push_back("-rewrite-objc");
44527330f729Sjoerg rewriteKind = RK_Fragile;
44537330f729Sjoerg } else {
44547330f729Sjoerg assert(JA.getType() == types::TY_PP_Asm && "Unexpected output type!");
44557330f729Sjoerg }
44567330f729Sjoerg
44577330f729Sjoerg // Preserve use-list order by default when emitting bitcode, so that
44587330f729Sjoerg // loading the bitcode up in 'opt' or 'llc' and running passes gives the
44597330f729Sjoerg // same result as running passes here. For LTO, we don't need to preserve
44607330f729Sjoerg // the use-list order, since serialization to bitcode is part of the flow.
44617330f729Sjoerg if (JA.getType() == types::TY_LLVM_BC)
44627330f729Sjoerg CmdArgs.push_back("-emit-llvm-uselists");
44637330f729Sjoerg
4464*e038c9c4Sjoerg if (IsUsingLTO) {
4465*e038c9c4Sjoerg if (!IsDeviceOffloadAction) {
4466*e038c9c4Sjoerg if (Args.hasArg(options::OPT_flto))
4467*e038c9c4Sjoerg CmdArgs.push_back("-flto");
4468*e038c9c4Sjoerg else {
4469*e038c9c4Sjoerg if (D.getLTOMode() == LTOK_Thin)
4470*e038c9c4Sjoerg CmdArgs.push_back("-flto=thin");
4471*e038c9c4Sjoerg else
4472*e038c9c4Sjoerg CmdArgs.push_back("-flto=full");
4473*e038c9c4Sjoerg }
44747330f729Sjoerg CmdArgs.push_back("-flto-unit");
4475*e038c9c4Sjoerg } else if (Triple.isAMDGPU()) {
4476*e038c9c4Sjoerg // Only AMDGPU supports device-side LTO
4477*e038c9c4Sjoerg assert(LTOMode == LTOK_Full || LTOMode == LTOK_Thin);
4478*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(
4479*e038c9c4Sjoerg Twine("-flto=") + (LTOMode == LTOK_Thin ? "thin" : "full")));
4480*e038c9c4Sjoerg CmdArgs.push_back("-flto-unit");
4481*e038c9c4Sjoerg } else {
4482*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
4483*e038c9c4Sjoerg << Args.getLastArg(options::OPT_foffload_lto,
4484*e038c9c4Sjoerg options::OPT_foffload_lto_EQ)
4485*e038c9c4Sjoerg ->getAsString(Args)
4486*e038c9c4Sjoerg << Triple.getTriple();
4487*e038c9c4Sjoerg }
44887330f729Sjoerg }
44897330f729Sjoerg }
44907330f729Sjoerg
44917330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_fthinlto_index_EQ)) {
44927330f729Sjoerg if (!types::isLLVMIR(Input.getType()))
44937330f729Sjoerg D.Diag(diag::err_drv_arg_requires_bitcode_input) << A->getAsString(Args);
44947330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fthinlto_index_EQ);
44957330f729Sjoerg }
44967330f729Sjoerg
44977330f729Sjoerg if (Args.getLastArg(options::OPT_fthin_link_bitcode_EQ))
44987330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fthin_link_bitcode_EQ);
44997330f729Sjoerg
45007330f729Sjoerg if (Args.getLastArg(options::OPT_save_temps_EQ))
45017330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_save_temps_EQ);
45027330f729Sjoerg
4503*e038c9c4Sjoerg auto *MemProfArg = Args.getLastArg(options::OPT_fmemory_profile,
4504*e038c9c4Sjoerg options::OPT_fmemory_profile_EQ,
4505*e038c9c4Sjoerg options::OPT_fno_memory_profile);
4506*e038c9c4Sjoerg if (MemProfArg &&
4507*e038c9c4Sjoerg !MemProfArg->getOption().matches(options::OPT_fno_memory_profile))
4508*e038c9c4Sjoerg MemProfArg->render(Args, CmdArgs);
4509*e038c9c4Sjoerg
45107330f729Sjoerg // Embed-bitcode option.
45117330f729Sjoerg // Only white-listed flags below are allowed to be embedded.
4512*e038c9c4Sjoerg if (C.getDriver().embedBitcodeInObject() && !IsUsingLTO &&
45137330f729Sjoerg (isa<BackendJobAction>(JA) || isa<AssembleJobAction>(JA))) {
45147330f729Sjoerg // Add flags implied by -fembed-bitcode.
45157330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fembed_bitcode_EQ);
45167330f729Sjoerg // Disable all llvm IR level optimizations.
45177330f729Sjoerg CmdArgs.push_back("-disable-llvm-passes");
45187330f729Sjoerg
4519*e038c9c4Sjoerg // Render target options.
45207330f729Sjoerg TC.addClangTargetOptions(Args, CmdArgs, JA.getOffloadingDeviceKind());
45217330f729Sjoerg
45227330f729Sjoerg // reject options that shouldn't be supported in bitcode
45237330f729Sjoerg // also reject kernel/kext
45247330f729Sjoerg static const constexpr unsigned kBitcodeOptionBlacklist[] = {
45257330f729Sjoerg options::OPT_mkernel,
45267330f729Sjoerg options::OPT_fapple_kext,
45277330f729Sjoerg options::OPT_ffunction_sections,
45287330f729Sjoerg options::OPT_fno_function_sections,
45297330f729Sjoerg options::OPT_fdata_sections,
45307330f729Sjoerg options::OPT_fno_data_sections,
4531*e038c9c4Sjoerg options::OPT_fbasic_block_sections_EQ,
4532*e038c9c4Sjoerg options::OPT_funique_internal_linkage_names,
4533*e038c9c4Sjoerg options::OPT_fno_unique_internal_linkage_names,
45347330f729Sjoerg options::OPT_funique_section_names,
45357330f729Sjoerg options::OPT_fno_unique_section_names,
4536*e038c9c4Sjoerg options::OPT_funique_basic_block_section_names,
4537*e038c9c4Sjoerg options::OPT_fno_unique_basic_block_section_names,
45387330f729Sjoerg options::OPT_mrestrict_it,
45397330f729Sjoerg options::OPT_mno_restrict_it,
45407330f729Sjoerg options::OPT_mstackrealign,
45417330f729Sjoerg options::OPT_mno_stackrealign,
45427330f729Sjoerg options::OPT_mstack_alignment,
45437330f729Sjoerg options::OPT_mcmodel_EQ,
45447330f729Sjoerg options::OPT_mlong_calls,
45457330f729Sjoerg options::OPT_mno_long_calls,
45467330f729Sjoerg options::OPT_ggnu_pubnames,
45477330f729Sjoerg options::OPT_gdwarf_aranges,
45487330f729Sjoerg options::OPT_fdebug_types_section,
45497330f729Sjoerg options::OPT_fno_debug_types_section,
45507330f729Sjoerg options::OPT_fdwarf_directory_asm,
45517330f729Sjoerg options::OPT_fno_dwarf_directory_asm,
45527330f729Sjoerg options::OPT_mrelax_all,
45537330f729Sjoerg options::OPT_mno_relax_all,
45547330f729Sjoerg options::OPT_ftrap_function_EQ,
45557330f729Sjoerg options::OPT_ffixed_r9,
45567330f729Sjoerg options::OPT_mfix_cortex_a53_835769,
45577330f729Sjoerg options::OPT_mno_fix_cortex_a53_835769,
45587330f729Sjoerg options::OPT_ffixed_x18,
45597330f729Sjoerg options::OPT_mglobal_merge,
45607330f729Sjoerg options::OPT_mno_global_merge,
45617330f729Sjoerg options::OPT_mred_zone,
45627330f729Sjoerg options::OPT_mno_red_zone,
45637330f729Sjoerg options::OPT_Wa_COMMA,
45647330f729Sjoerg options::OPT_Xassembler,
45657330f729Sjoerg options::OPT_mllvm,
45667330f729Sjoerg };
45677330f729Sjoerg for (const auto &A : Args)
45687330f729Sjoerg if (llvm::find(kBitcodeOptionBlacklist, A->getOption().getID()) !=
45697330f729Sjoerg std::end(kBitcodeOptionBlacklist))
45707330f729Sjoerg D.Diag(diag::err_drv_unsupported_embed_bitcode) << A->getSpelling();
45717330f729Sjoerg
45727330f729Sjoerg // Render the CodeGen options that need to be passed.
45737330f729Sjoerg if (!Args.hasFlag(options::OPT_foptimize_sibling_calls,
45747330f729Sjoerg options::OPT_fno_optimize_sibling_calls))
45757330f729Sjoerg CmdArgs.push_back("-mdisable-tail-calls");
45767330f729Sjoerg
45777330f729Sjoerg RenderFloatingPointOptions(TC, D, isOptimizationLevelFast(Args), Args,
4578*e038c9c4Sjoerg CmdArgs, JA);
45797330f729Sjoerg
45807330f729Sjoerg // Render ABI arguments
45817330f729Sjoerg switch (TC.getArch()) {
45827330f729Sjoerg default: break;
45837330f729Sjoerg case llvm::Triple::arm:
45847330f729Sjoerg case llvm::Triple::armeb:
45857330f729Sjoerg case llvm::Triple::thumbeb:
45867330f729Sjoerg RenderARMABI(Triple, Args, CmdArgs);
45877330f729Sjoerg break;
45887330f729Sjoerg case llvm::Triple::aarch64:
4589*e038c9c4Sjoerg case llvm::Triple::aarch64_32:
45907330f729Sjoerg case llvm::Triple::aarch64_be:
45917330f729Sjoerg RenderAArch64ABI(Triple, Args, CmdArgs);
45927330f729Sjoerg break;
45937330f729Sjoerg }
45947330f729Sjoerg
45957330f729Sjoerg // Optimization level for CodeGen.
45967330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_O_Group)) {
45977330f729Sjoerg if (A->getOption().matches(options::OPT_O4)) {
45987330f729Sjoerg CmdArgs.push_back("-O3");
45997330f729Sjoerg D.Diag(diag::warn_O4_is_O3);
46007330f729Sjoerg } else {
46017330f729Sjoerg A->render(Args, CmdArgs);
46027330f729Sjoerg }
46037330f729Sjoerg }
46047330f729Sjoerg
46057330f729Sjoerg // Input/Output file.
46067330f729Sjoerg if (Output.getType() == types::TY_Dependencies) {
46077330f729Sjoerg // Handled with other dependency code.
46087330f729Sjoerg } else if (Output.isFilename()) {
46097330f729Sjoerg CmdArgs.push_back("-o");
46107330f729Sjoerg CmdArgs.push_back(Output.getFilename());
46117330f729Sjoerg } else {
46127330f729Sjoerg assert(Output.isNothing() && "Input output.");
46137330f729Sjoerg }
46147330f729Sjoerg
46157330f729Sjoerg for (const auto &II : Inputs) {
46167330f729Sjoerg addDashXForInput(Args, II, CmdArgs);
46177330f729Sjoerg if (II.isFilename())
46187330f729Sjoerg CmdArgs.push_back(II.getFilename());
46197330f729Sjoerg else
46207330f729Sjoerg II.getInputArg().renderAsInput(Args, CmdArgs);
46217330f729Sjoerg }
46227330f729Sjoerg
4623*e038c9c4Sjoerg C.addCommand(std::make_unique<Command>(
4624*e038c9c4Sjoerg JA, *this, ResponseFileSupport::AtFileUTF8(), D.getClangProgramPath(),
4625*e038c9c4Sjoerg CmdArgs, Inputs, Output));
46267330f729Sjoerg return;
46277330f729Sjoerg }
46287330f729Sjoerg
4629*e038c9c4Sjoerg if (C.getDriver().embedBitcodeMarkerOnly() && !IsUsingLTO)
46307330f729Sjoerg CmdArgs.push_back("-fembed-bitcode=marker");
46317330f729Sjoerg
46327330f729Sjoerg // We normally speed up the clang process a bit by skipping destructors at
46337330f729Sjoerg // exit, but when we're generating diagnostics we can rely on some of the
46347330f729Sjoerg // cleanup.
46357330f729Sjoerg if (!C.isForDiagnostics())
46367330f729Sjoerg CmdArgs.push_back("-disable-free");
46377330f729Sjoerg
46387330f729Sjoerg #ifdef NDEBUG
46397330f729Sjoerg const bool IsAssertBuild = false;
46407330f729Sjoerg #else
46417330f729Sjoerg const bool IsAssertBuild = true;
46427330f729Sjoerg #endif
46437330f729Sjoerg
46447330f729Sjoerg // Disable the verification pass in -asserts builds.
46457330f729Sjoerg if (!IsAssertBuild)
46467330f729Sjoerg CmdArgs.push_back("-disable-llvm-verifier");
46477330f729Sjoerg
46487330f729Sjoerg // Discard value names in assert builds unless otherwise specified.
46497330f729Sjoerg if (Args.hasFlag(options::OPT_fdiscard_value_names,
4650*e038c9c4Sjoerg options::OPT_fno_discard_value_names, !IsAssertBuild)) {
4651*e038c9c4Sjoerg if (Args.hasArg(options::OPT_fdiscard_value_names) &&
4652*e038c9c4Sjoerg (std::any_of(Inputs.begin(), Inputs.end(),
4653*e038c9c4Sjoerg [](const clang::driver::InputInfo &II) {
4654*e038c9c4Sjoerg return types::isLLVMIR(II.getType());
4655*e038c9c4Sjoerg }))) {
4656*e038c9c4Sjoerg D.Diag(diag::warn_ignoring_fdiscard_for_bitcode);
4657*e038c9c4Sjoerg }
46587330f729Sjoerg CmdArgs.push_back("-discard-value-names");
4659*e038c9c4Sjoerg }
46607330f729Sjoerg
46617330f729Sjoerg // Set the main file name, so that debug info works even with
46627330f729Sjoerg // -save-temps.
46637330f729Sjoerg CmdArgs.push_back("-main-file-name");
46647330f729Sjoerg CmdArgs.push_back(getBaseInputName(Args, Input));
46657330f729Sjoerg
46667330f729Sjoerg // Some flags which affect the language (via preprocessor
46677330f729Sjoerg // defines).
46687330f729Sjoerg if (Args.hasArg(options::OPT_static))
46697330f729Sjoerg CmdArgs.push_back("-static-define");
46707330f729Sjoerg
46717330f729Sjoerg if (Args.hasArg(options::OPT_municode))
46727330f729Sjoerg CmdArgs.push_back("-DUNICODE");
46737330f729Sjoerg
46747330f729Sjoerg if (isa<AnalyzeJobAction>(JA))
46757330f729Sjoerg RenderAnalyzerOptions(Args, CmdArgs, Triple, Input);
46767330f729Sjoerg
46777330f729Sjoerg if (isa<AnalyzeJobAction>(JA) ||
46787330f729Sjoerg (isa<PreprocessJobAction>(JA) && Args.hasArg(options::OPT__analyze)))
46797330f729Sjoerg CmdArgs.push_back("-setup-static-analyzer");
46807330f729Sjoerg
46817330f729Sjoerg // Enable compatilibily mode to avoid analyzer-config related errors.
46827330f729Sjoerg // Since we can't access frontend flags through hasArg, let's manually iterate
46837330f729Sjoerg // through them.
46847330f729Sjoerg bool FoundAnalyzerConfig = false;
46857330f729Sjoerg for (auto Arg : Args.filtered(options::OPT_Xclang))
46867330f729Sjoerg if (StringRef(Arg->getValue()) == "-analyzer-config") {
46877330f729Sjoerg FoundAnalyzerConfig = true;
46887330f729Sjoerg break;
46897330f729Sjoerg }
46907330f729Sjoerg if (!FoundAnalyzerConfig)
46917330f729Sjoerg for (auto Arg : Args.filtered(options::OPT_Xanalyzer))
46927330f729Sjoerg if (StringRef(Arg->getValue()) == "-analyzer-config") {
46937330f729Sjoerg FoundAnalyzerConfig = true;
46947330f729Sjoerg break;
46957330f729Sjoerg }
46967330f729Sjoerg if (FoundAnalyzerConfig)
46977330f729Sjoerg CmdArgs.push_back("-analyzer-config-compatibility-mode=true");
46987330f729Sjoerg
46997330f729Sjoerg CheckCodeGenerationOptions(D, Args);
47007330f729Sjoerg
47017330f729Sjoerg unsigned FunctionAlignment = ParseFunctionAlignment(TC, Args);
47027330f729Sjoerg assert(FunctionAlignment <= 31 && "function alignment will be truncated!");
47037330f729Sjoerg if (FunctionAlignment) {
47047330f729Sjoerg CmdArgs.push_back("-function-alignment");
47057330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(std::to_string(FunctionAlignment)));
47067330f729Sjoerg }
47077330f729Sjoerg
47087330f729Sjoerg llvm::Reloc::Model RelocationModel;
47097330f729Sjoerg unsigned PICLevel;
47107330f729Sjoerg bool IsPIE;
47117330f729Sjoerg std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(TC, Args);
47127330f729Sjoerg
4713*e038c9c4Sjoerg bool IsROPI = RelocationModel == llvm::Reloc::ROPI ||
4714*e038c9c4Sjoerg RelocationModel == llvm::Reloc::ROPI_RWPI;
4715*e038c9c4Sjoerg bool IsRWPI = RelocationModel == llvm::Reloc::RWPI ||
4716*e038c9c4Sjoerg RelocationModel == llvm::Reloc::ROPI_RWPI;
47177330f729Sjoerg
4718*e038c9c4Sjoerg if (Args.hasArg(options::OPT_mcmse) &&
4719*e038c9c4Sjoerg !Args.hasArg(options::OPT_fallow_unsupported)) {
4720*e038c9c4Sjoerg if (IsROPI)
4721*e038c9c4Sjoerg D.Diag(diag::err_cmse_pi_are_incompatible) << IsROPI;
4722*e038c9c4Sjoerg if (IsRWPI)
4723*e038c9c4Sjoerg D.Diag(diag::err_cmse_pi_are_incompatible) << !IsRWPI;
4724*e038c9c4Sjoerg }
4725*e038c9c4Sjoerg
4726*e038c9c4Sjoerg if (IsROPI && types::isCXX(Input.getType()) &&
47277330f729Sjoerg !Args.hasArg(options::OPT_fallow_unsupported))
47287330f729Sjoerg D.Diag(diag::err_drv_ropi_incompatible_with_cxx);
47297330f729Sjoerg
4730*e038c9c4Sjoerg const char *RMName = RelocationModelName(RelocationModel);
47317330f729Sjoerg if (RMName) {
47327330f729Sjoerg CmdArgs.push_back("-mrelocation-model");
47337330f729Sjoerg CmdArgs.push_back(RMName);
47347330f729Sjoerg }
47357330f729Sjoerg if (PICLevel > 0) {
47367330f729Sjoerg CmdArgs.push_back("-pic-level");
47377330f729Sjoerg CmdArgs.push_back(PICLevel == 1 ? "1" : "2");
47387330f729Sjoerg if (IsPIE)
47397330f729Sjoerg CmdArgs.push_back("-pic-is-pie");
47407330f729Sjoerg }
47417330f729Sjoerg
47427330f729Sjoerg if (RelocationModel == llvm::Reloc::ROPI ||
47437330f729Sjoerg RelocationModel == llvm::Reloc::ROPI_RWPI)
47447330f729Sjoerg CmdArgs.push_back("-fropi");
47457330f729Sjoerg if (RelocationModel == llvm::Reloc::RWPI ||
47467330f729Sjoerg RelocationModel == llvm::Reloc::ROPI_RWPI)
47477330f729Sjoerg CmdArgs.push_back("-frwpi");
47487330f729Sjoerg
47497330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_meabi)) {
47507330f729Sjoerg CmdArgs.push_back("-meabi");
47517330f729Sjoerg CmdArgs.push_back(A->getValue());
47527330f729Sjoerg }
47537330f729Sjoerg
4754*e038c9c4Sjoerg // -fsemantic-interposition is forwarded to CC1: set the
4755*e038c9c4Sjoerg // "SemanticInterposition" metadata to 1 (make some linkages interposable) and
4756*e038c9c4Sjoerg // make default visibility external linkage definitions dso_preemptable.
4757*e038c9c4Sjoerg //
4758*e038c9c4Sjoerg // -fno-semantic-interposition: if the target supports .Lfoo$local local
4759*e038c9c4Sjoerg // aliases (make default visibility external linkage definitions dso_local).
4760*e038c9c4Sjoerg // This is the CC1 default for ELF to match COFF/Mach-O.
4761*e038c9c4Sjoerg //
4762*e038c9c4Sjoerg // Otherwise use Clang's traditional behavior: like
4763*e038c9c4Sjoerg // -fno-semantic-interposition but local aliases are not used. So references
4764*e038c9c4Sjoerg // can be interposed if not optimized out.
4765*e038c9c4Sjoerg if (Triple.isOSBinFormatELF()) {
4766*e038c9c4Sjoerg Arg *A = Args.getLastArg(options::OPT_fsemantic_interposition,
4767*e038c9c4Sjoerg options::OPT_fno_semantic_interposition);
4768*e038c9c4Sjoerg if (RelocationModel != llvm::Reloc::Static && !IsPIE) {
4769*e038c9c4Sjoerg // The supported targets need to call AsmPrinter::getSymbolPreferLocal.
4770*e038c9c4Sjoerg bool SupportsLocalAlias =
4771*e038c9c4Sjoerg Triple.isAArch64() || Triple.isRISCV() || Triple.isX86();
4772*e038c9c4Sjoerg if (!A)
4773*e038c9c4Sjoerg CmdArgs.push_back("-fhalf-no-semantic-interposition");
4774*e038c9c4Sjoerg else if (A->getOption().matches(options::OPT_fsemantic_interposition))
4775*e038c9c4Sjoerg A->render(Args, CmdArgs);
4776*e038c9c4Sjoerg else if (!SupportsLocalAlias)
4777*e038c9c4Sjoerg CmdArgs.push_back("-fhalf-no-semantic-interposition");
4778*e038c9c4Sjoerg }
4779*e038c9c4Sjoerg }
4780*e038c9c4Sjoerg
4781*e038c9c4Sjoerg {
4782*e038c9c4Sjoerg std::string Model;
47837330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mthread_model)) {
47847330f729Sjoerg if (!TC.isThreadModelSupported(A->getValue()))
47857330f729Sjoerg D.Diag(diag::err_drv_invalid_thread_model_for_target)
47867330f729Sjoerg << A->getValue() << A->getAsString(Args);
4787*e038c9c4Sjoerg Model = A->getValue();
4788*e038c9c4Sjoerg } else
4789*e038c9c4Sjoerg Model = TC.getThreadModel();
4790*e038c9c4Sjoerg if (Model != "posix") {
4791*e038c9c4Sjoerg CmdArgs.push_back("-mthread-model");
4792*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(Model));
47937330f729Sjoerg }
4794*e038c9c4Sjoerg }
47957330f729Sjoerg
47967330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fveclib);
47977330f729Sjoerg
47987330f729Sjoerg if (Args.hasFlag(options::OPT_fmerge_all_constants,
47997330f729Sjoerg options::OPT_fno_merge_all_constants, false))
48007330f729Sjoerg CmdArgs.push_back("-fmerge-all-constants");
48017330f729Sjoerg
48027330f729Sjoerg if (Args.hasFlag(options::OPT_fno_delete_null_pointer_checks,
48037330f729Sjoerg options::OPT_fdelete_null_pointer_checks, false))
48047330f729Sjoerg CmdArgs.push_back("-fno-delete-null-pointer-checks");
48057330f729Sjoerg
48067330f729Sjoerg // LLVM Code Generator Options.
48077330f729Sjoerg
4808*e038c9c4Sjoerg for (const Arg *A : Args.filtered(options::OPT_frewrite_map_file_EQ)) {
48097330f729Sjoerg StringRef Map = A->getValue();
48107330f729Sjoerg if (!llvm::sys::fs::exists(Map)) {
48117330f729Sjoerg D.Diag(diag::err_drv_no_such_file) << Map;
48127330f729Sjoerg } else {
4813*e038c9c4Sjoerg A->render(Args, CmdArgs);
48147330f729Sjoerg A->claim();
48157330f729Sjoerg }
48167330f729Sjoerg }
4817*e038c9c4Sjoerg
4818*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ_vec_extabi,
4819*e038c9c4Sjoerg options::OPT_mabi_EQ_vec_default)) {
4820*e038c9c4Sjoerg if (!Triple.isOSAIX())
4821*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
4822*e038c9c4Sjoerg << A->getSpelling() << RawTriple.str();
4823*e038c9c4Sjoerg if (A->getOption().getID() == options::OPT_mabi_EQ_vec_extabi)
4824*e038c9c4Sjoerg CmdArgs.push_back("-mabi=vec-extabi");
4825*e038c9c4Sjoerg else
4826*e038c9c4Sjoerg D.Diag(diag::err_aix_default_altivec_abi);
48277330f729Sjoerg }
48287330f729Sjoerg
48297330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_Wframe_larger_than_EQ)) {
48307330f729Sjoerg StringRef v = A->getValue();
48317330f729Sjoerg CmdArgs.push_back("-mllvm");
48327330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-warn-stack-size=" + v));
48337330f729Sjoerg A->claim();
48347330f729Sjoerg }
48357330f729Sjoerg
48367330f729Sjoerg if (!Args.hasFlag(options::OPT_fjump_tables, options::OPT_fno_jump_tables,
48377330f729Sjoerg true))
48387330f729Sjoerg CmdArgs.push_back("-fno-jump-tables");
48397330f729Sjoerg
48407330f729Sjoerg if (Args.hasFlag(options::OPT_fprofile_sample_accurate,
48417330f729Sjoerg options::OPT_fno_profile_sample_accurate, false))
48427330f729Sjoerg CmdArgs.push_back("-fprofile-sample-accurate");
48437330f729Sjoerg
48447330f729Sjoerg if (!Args.hasFlag(options::OPT_fpreserve_as_comments,
48457330f729Sjoerg options::OPT_fno_preserve_as_comments, true))
48467330f729Sjoerg CmdArgs.push_back("-fno-preserve-as-comments");
48477330f729Sjoerg
48487330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
48497330f729Sjoerg CmdArgs.push_back("-mregparm");
48507330f729Sjoerg CmdArgs.push_back(A->getValue());
48517330f729Sjoerg }
48527330f729Sjoerg
4853*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_maix_struct_return,
4854*e038c9c4Sjoerg options::OPT_msvr4_struct_return)) {
4855*e038c9c4Sjoerg if (!TC.getTriple().isPPC32()) {
4856*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
4857*e038c9c4Sjoerg << A->getSpelling() << RawTriple.str();
4858*e038c9c4Sjoerg } else if (A->getOption().matches(options::OPT_maix_struct_return)) {
4859*e038c9c4Sjoerg CmdArgs.push_back("-maix-struct-return");
4860*e038c9c4Sjoerg } else {
4861*e038c9c4Sjoerg assert(A->getOption().matches(options::OPT_msvr4_struct_return));
4862*e038c9c4Sjoerg CmdArgs.push_back("-msvr4-struct-return");
4863*e038c9c4Sjoerg }
4864*e038c9c4Sjoerg }
4865*e038c9c4Sjoerg
48667330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,
48677330f729Sjoerg options::OPT_freg_struct_return)) {
48687330f729Sjoerg if (TC.getArch() != llvm::Triple::x86) {
48697330f729Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
48707330f729Sjoerg << A->getSpelling() << RawTriple.str();
48717330f729Sjoerg } else if (A->getOption().matches(options::OPT_fpcc_struct_return)) {
48727330f729Sjoerg CmdArgs.push_back("-fpcc-struct-return");
48737330f729Sjoerg } else {
48747330f729Sjoerg assert(A->getOption().matches(options::OPT_freg_struct_return));
48757330f729Sjoerg CmdArgs.push_back("-freg-struct-return");
48767330f729Sjoerg }
48777330f729Sjoerg }
48787330f729Sjoerg
48797330f729Sjoerg if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false))
48807330f729Sjoerg CmdArgs.push_back("-fdefault-calling-conv=stdcall");
48817330f729Sjoerg
4882*e038c9c4Sjoerg if (Args.hasArg(options::OPT_fenable_matrix)) {
4883*e038c9c4Sjoerg // enable-matrix is needed by both the LangOpts and by LLVM.
4884*e038c9c4Sjoerg CmdArgs.push_back("-fenable-matrix");
4885*e038c9c4Sjoerg CmdArgs.push_back("-mllvm");
4886*e038c9c4Sjoerg CmdArgs.push_back("-enable-matrix");
4887*e038c9c4Sjoerg }
4888*e038c9c4Sjoerg
48897330f729Sjoerg CodeGenOptions::FramePointerKind FPKeepKind =
48907330f729Sjoerg getFramePointerKind(Args, RawTriple);
48917330f729Sjoerg const char *FPKeepKindStr = nullptr;
48927330f729Sjoerg switch (FPKeepKind) {
48937330f729Sjoerg case CodeGenOptions::FramePointerKind::None:
48947330f729Sjoerg FPKeepKindStr = "-mframe-pointer=none";
48957330f729Sjoerg break;
48967330f729Sjoerg case CodeGenOptions::FramePointerKind::NonLeaf:
48977330f729Sjoerg FPKeepKindStr = "-mframe-pointer=non-leaf";
48987330f729Sjoerg break;
48997330f729Sjoerg case CodeGenOptions::FramePointerKind::All:
49007330f729Sjoerg FPKeepKindStr = "-mframe-pointer=all";
49017330f729Sjoerg break;
49027330f729Sjoerg }
49037330f729Sjoerg assert(FPKeepKindStr && "unknown FramePointerKind");
49047330f729Sjoerg CmdArgs.push_back(FPKeepKindStr);
49057330f729Sjoerg
49067330f729Sjoerg if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
4907*e038c9c4Sjoerg options::OPT_fno_zero_initialized_in_bss, true))
4908*e038c9c4Sjoerg CmdArgs.push_back("-fno-zero-initialized-in-bss");
49097330f729Sjoerg
49107330f729Sjoerg bool OFastEnabled = isOptimizationLevelFast(Args);
49117330f729Sjoerg // If -Ofast is the optimization level, then -fstrict-aliasing should be
49127330f729Sjoerg // enabled. This alias option is being used to simplify the hasFlag logic.
49137330f729Sjoerg OptSpecifier StrictAliasingAliasOption =
49147330f729Sjoerg OFastEnabled ? options::OPT_Ofast : options::OPT_fstrict_aliasing;
49157330f729Sjoerg // We turn strict aliasing off by default if we're in CL mode, since MSVC
49167330f729Sjoerg // doesn't do any TBAA.
49177330f729Sjoerg bool TBAAOnByDefault = !D.IsCLMode();
49187330f729Sjoerg if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption,
49197330f729Sjoerg options::OPT_fno_strict_aliasing, TBAAOnByDefault))
49207330f729Sjoerg CmdArgs.push_back("-relaxed-aliasing");
49217330f729Sjoerg if (!Args.hasFlag(options::OPT_fstruct_path_tbaa,
49227330f729Sjoerg options::OPT_fno_struct_path_tbaa))
49237330f729Sjoerg CmdArgs.push_back("-no-struct-path-tbaa");
49247330f729Sjoerg if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums,
49257330f729Sjoerg false))
49267330f729Sjoerg CmdArgs.push_back("-fstrict-enums");
49277330f729Sjoerg if (!Args.hasFlag(options::OPT_fstrict_return, options::OPT_fno_strict_return,
49287330f729Sjoerg true))
49297330f729Sjoerg CmdArgs.push_back("-fno-strict-return");
49307330f729Sjoerg if (Args.hasFlag(options::OPT_fallow_editor_placeholders,
49317330f729Sjoerg options::OPT_fno_allow_editor_placeholders, false))
49327330f729Sjoerg CmdArgs.push_back("-fallow-editor-placeholders");
49337330f729Sjoerg if (Args.hasFlag(options::OPT_fstrict_vtable_pointers,
49347330f729Sjoerg options::OPT_fno_strict_vtable_pointers,
49357330f729Sjoerg false))
49367330f729Sjoerg CmdArgs.push_back("-fstrict-vtable-pointers");
49377330f729Sjoerg if (Args.hasFlag(options::OPT_fforce_emit_vtables,
49387330f729Sjoerg options::OPT_fno_force_emit_vtables,
49397330f729Sjoerg false))
49407330f729Sjoerg CmdArgs.push_back("-fforce-emit-vtables");
49417330f729Sjoerg if (!Args.hasFlag(options::OPT_foptimize_sibling_calls,
49427330f729Sjoerg options::OPT_fno_optimize_sibling_calls))
49437330f729Sjoerg CmdArgs.push_back("-mdisable-tail-calls");
49447330f729Sjoerg if (Args.hasFlag(options::OPT_fno_escaping_block_tail_calls,
49457330f729Sjoerg options::OPT_fescaping_block_tail_calls, false))
49467330f729Sjoerg CmdArgs.push_back("-fno-escaping-block-tail-calls");
49477330f729Sjoerg
49487330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_ffine_grained_bitfield_accesses,
49497330f729Sjoerg options::OPT_fno_fine_grained_bitfield_accesses);
49507330f729Sjoerg
4951*e038c9c4Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fexperimental_relative_cxx_abi_vtables,
4952*e038c9c4Sjoerg options::OPT_fno_experimental_relative_cxx_abi_vtables);
49537330f729Sjoerg
4954*e038c9c4Sjoerg // Handle segmented stacks.
4955*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fsplit_stack, options::OPT_fno_split_stack,
4956*e038c9c4Sjoerg false))
4957*e038c9c4Sjoerg CmdArgs.push_back("-fsplit-stack");
4958*e038c9c4Sjoerg
4959*e038c9c4Sjoerg RenderFloatingPointOptions(TC, D, OFastEnabled, Args, CmdArgs, JA);
4960*e038c9c4Sjoerg
4961*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fextend_args_EQ)) {
4962*e038c9c4Sjoerg const llvm::Triple::ArchType Arch = TC.getArch();
4963*e038c9c4Sjoerg if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) {
4964*e038c9c4Sjoerg StringRef V = A->getValue();
4965*e038c9c4Sjoerg if (V == "64")
4966*e038c9c4Sjoerg CmdArgs.push_back("-fextend-arguments=64");
4967*e038c9c4Sjoerg else if (V != "32")
4968*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_argument_to_option)
4969*e038c9c4Sjoerg << A->getValue() << A->getOption().getName();
4970*e038c9c4Sjoerg } else
4971*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
4972*e038c9c4Sjoerg << A->getOption().getName() << TripleStr;
4973*e038c9c4Sjoerg }
4974*e038c9c4Sjoerg
4975*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mdouble_EQ)) {
4976*e038c9c4Sjoerg if (TC.getArch() == llvm::Triple::avr)
4977*e038c9c4Sjoerg A->render(Args, CmdArgs);
4978*e038c9c4Sjoerg else
4979*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
4980*e038c9c4Sjoerg << A->getAsString(Args) << TripleStr;
4981*e038c9c4Sjoerg }
49827330f729Sjoerg
49837330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_LongDouble_Group)) {
4984*e038c9c4Sjoerg if (TC.getTriple().isX86())
49857330f729Sjoerg A->render(Args, CmdArgs);
4986*e038c9c4Sjoerg else if (TC.getTriple().isPPC() &&
49877330f729Sjoerg (A->getOption().getID() != options::OPT_mlong_double_80))
49887330f729Sjoerg A->render(Args, CmdArgs);
49897330f729Sjoerg else
49907330f729Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
49917330f729Sjoerg << A->getAsString(Args) << TripleStr;
49927330f729Sjoerg }
49937330f729Sjoerg
49947330f729Sjoerg // Decide whether to use verbose asm. Verbose assembly is the default on
49957330f729Sjoerg // toolchains which have the integrated assembler on by default.
49967330f729Sjoerg bool IsIntegratedAssemblerDefault = TC.IsIntegratedAssemblerDefault();
4997*e038c9c4Sjoerg if (!Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
49987330f729Sjoerg IsIntegratedAssemblerDefault))
4999*e038c9c4Sjoerg CmdArgs.push_back("-fno-verbose-asm");
5000*e038c9c4Sjoerg
5001*e038c9c4Sjoerg // Parse 'none' or '$major.$minor'. Disallow -fbinutils-version=0 because we
5002*e038c9c4Sjoerg // use that to indicate the MC default in the backend.
5003*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fbinutils_version_EQ)) {
5004*e038c9c4Sjoerg StringRef V = A->getValue();
5005*e038c9c4Sjoerg unsigned Num;
5006*e038c9c4Sjoerg if (V == "none")
5007*e038c9c4Sjoerg A->render(Args, CmdArgs);
5008*e038c9c4Sjoerg else if (!V.consumeInteger(10, Num) && Num > 0 &&
5009*e038c9c4Sjoerg (V.empty() || (V.consume_front(".") &&
5010*e038c9c4Sjoerg !V.consumeInteger(10, Num) && V.empty())))
5011*e038c9c4Sjoerg A->render(Args, CmdArgs);
5012*e038c9c4Sjoerg else
5013*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_argument_to_option)
5014*e038c9c4Sjoerg << A->getValue() << A->getOption().getName();
5015*e038c9c4Sjoerg }
50167330f729Sjoerg
50177330f729Sjoerg if (!TC.useIntegratedAs())
50187330f729Sjoerg CmdArgs.push_back("-no-integrated-as");
50197330f729Sjoerg
50207330f729Sjoerg if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
50217330f729Sjoerg CmdArgs.push_back("-mdebug-pass");
50227330f729Sjoerg CmdArgs.push_back("Structure");
50237330f729Sjoerg }
50247330f729Sjoerg if (Args.hasArg(options::OPT_fdebug_pass_arguments)) {
50257330f729Sjoerg CmdArgs.push_back("-mdebug-pass");
50267330f729Sjoerg CmdArgs.push_back("Arguments");
50277330f729Sjoerg }
50287330f729Sjoerg
50297330f729Sjoerg // Enable -mconstructor-aliases except on darwin, where we have to work around
5030*e038c9c4Sjoerg // a linker bug (see <rdar://problem/7651567>), and CUDA/AMDGPU device code,
5031*e038c9c4Sjoerg // where aliases aren't supported. Similarly, aliases aren't yet supported
5032*e038c9c4Sjoerg // for AIX.
5033*e038c9c4Sjoerg if (!RawTriple.isOSDarwin() && !RawTriple.isNVPTX() &&
5034*e038c9c4Sjoerg !RawTriple.isAMDGPU() && !RawTriple.isOSAIX())
50357330f729Sjoerg CmdArgs.push_back("-mconstructor-aliases");
50367330f729Sjoerg
50377330f729Sjoerg // Darwin's kernel doesn't support guard variables; just die if we
50387330f729Sjoerg // try to use them.
50397330f729Sjoerg if (KernelOrKext && RawTriple.isOSDarwin())
50407330f729Sjoerg CmdArgs.push_back("-fforbid-guard-variables");
50417330f729Sjoerg
50427330f729Sjoerg if (Args.hasFlag(options::OPT_mms_bitfields, options::OPT_mno_ms_bitfields,
5043*e038c9c4Sjoerg Triple.isWindowsGNUEnvironment())) {
50447330f729Sjoerg CmdArgs.push_back("-mms-bitfields");
50457330f729Sjoerg }
50467330f729Sjoerg
5047*e038c9c4Sjoerg // Non-PIC code defaults to -fdirect-access-external-data while PIC code
5048*e038c9c4Sjoerg // defaults to -fno-direct-access-external-data. Pass the option if different
5049*e038c9c4Sjoerg // from the default.
5050*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fdirect_access_external_data,
5051*e038c9c4Sjoerg options::OPT_fno_direct_access_external_data))
5052*e038c9c4Sjoerg if (A->getOption().matches(options::OPT_fdirect_access_external_data) !=
5053*e038c9c4Sjoerg (PICLevel == 0))
5054*e038c9c4Sjoerg A->render(Args, CmdArgs);
50557330f729Sjoerg
50567330f729Sjoerg if (Args.hasFlag(options::OPT_fno_plt, options::OPT_fplt, false)) {
50577330f729Sjoerg CmdArgs.push_back("-fno-plt");
50587330f729Sjoerg }
50597330f729Sjoerg
50607330f729Sjoerg // -fhosted is default.
50617330f729Sjoerg // TODO: Audit uses of KernelOrKext and see where it'd be more appropriate to
50627330f729Sjoerg // use Freestanding.
50637330f729Sjoerg bool Freestanding =
50647330f729Sjoerg Args.hasFlag(options::OPT_ffreestanding, options::OPT_fhosted, false) ||
50657330f729Sjoerg KernelOrKext;
50667330f729Sjoerg if (Freestanding)
50677330f729Sjoerg CmdArgs.push_back("-ffreestanding");
50687330f729Sjoerg
50697330f729Sjoerg // This is a coarse approximation of what llvm-gcc actually does, both
50707330f729Sjoerg // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
50717330f729Sjoerg // complicated ways.
5072*e038c9c4Sjoerg bool UnwindTables =
50737330f729Sjoerg Args.hasFlag(options::OPT_fasynchronous_unwind_tables,
50747330f729Sjoerg options::OPT_fno_asynchronous_unwind_tables,
50757330f729Sjoerg (TC.IsUnwindTablesDefault(Args) ||
50767330f729Sjoerg TC.getSanitizerArgs().needsUnwindTables()) &&
50777330f729Sjoerg !Freestanding);
5078*e038c9c4Sjoerg UnwindTables = Args.hasFlag(options::OPT_funwind_tables,
5079*e038c9c4Sjoerg options::OPT_fno_unwind_tables, UnwindTables);
5080*e038c9c4Sjoerg if (UnwindTables)
50817330f729Sjoerg CmdArgs.push_back("-munwind-tables");
50827330f729Sjoerg
5083*e038c9c4Sjoerg // Prepare `-aux-target-cpu` and `-aux-target-feature` unless
5084*e038c9c4Sjoerg // `--gpu-use-aux-triple-only` is specified.
5085*e038c9c4Sjoerg if (!Args.getLastArg(options::OPT_gpu_use_aux_triple_only) &&
5086*e038c9c4Sjoerg (IsCudaDevice || IsHIPDevice)) {
5087*e038c9c4Sjoerg const ArgList &HostArgs =
5088*e038c9c4Sjoerg C.getArgsForToolChain(nullptr, StringRef(), Action::OFK_None);
5089*e038c9c4Sjoerg std::string HostCPU =
5090*e038c9c4Sjoerg getCPUName(HostArgs, *TC.getAuxTriple(), /*FromAs*/ false);
5091*e038c9c4Sjoerg if (!HostCPU.empty()) {
5092*e038c9c4Sjoerg CmdArgs.push_back("-aux-target-cpu");
5093*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(HostCPU));
5094*e038c9c4Sjoerg }
5095*e038c9c4Sjoerg getTargetFeatures(D, *TC.getAuxTriple(), HostArgs, CmdArgs,
5096*e038c9c4Sjoerg /*ForAS*/ false, /*IsAux*/ true);
5097*e038c9c4Sjoerg }
5098*e038c9c4Sjoerg
50997330f729Sjoerg TC.addClangTargetOptions(Args, CmdArgs, JA.getOffloadingDeviceKind());
51007330f729Sjoerg
51017330f729Sjoerg // FIXME: Handle -mtune=.
51027330f729Sjoerg (void)Args.hasArg(options::OPT_mtune_EQ);
51037330f729Sjoerg
51047330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
5105*e038c9c4Sjoerg StringRef CM = A->getValue();
5106*e038c9c4Sjoerg if (CM == "small" || CM == "kernel" || CM == "medium" || CM == "large" ||
5107*e038c9c4Sjoerg CM == "tiny")
5108*e038c9c4Sjoerg A->render(Args, CmdArgs);
5109*e038c9c4Sjoerg else
5110*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_argument_to_option)
5111*e038c9c4Sjoerg << CM << A->getOption().getName();
5112*e038c9c4Sjoerg }
5113*e038c9c4Sjoerg
5114*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mtls_size_EQ)) {
5115*e038c9c4Sjoerg StringRef Value = A->getValue();
5116*e038c9c4Sjoerg unsigned TLSSize = 0;
5117*e038c9c4Sjoerg Value.getAsInteger(10, TLSSize);
5118*e038c9c4Sjoerg if (!Triple.isAArch64() || !Triple.isOSBinFormatELF())
5119*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
5120*e038c9c4Sjoerg << A->getOption().getName() << TripleStr;
5121*e038c9c4Sjoerg if (TLSSize != 12 && TLSSize != 24 && TLSSize != 32 && TLSSize != 48)
5122*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_int_value)
5123*e038c9c4Sjoerg << A->getOption().getName() << Value;
5124*e038c9c4Sjoerg Args.AddLastArg(CmdArgs, options::OPT_mtls_size_EQ);
51257330f729Sjoerg }
51267330f729Sjoerg
51277330f729Sjoerg // Add the target cpu
51287330f729Sjoerg std::string CPU = getCPUName(Args, Triple, /*FromAs*/ false);
51297330f729Sjoerg if (!CPU.empty()) {
51307330f729Sjoerg CmdArgs.push_back("-target-cpu");
51317330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(CPU));
51327330f729Sjoerg }
51337330f729Sjoerg
51347330f729Sjoerg RenderTargetOptions(Triple, Args, KernelOrKext, CmdArgs);
51357330f729Sjoerg
5136*e038c9c4Sjoerg // FIXME: For now we want to demote any errors to warnings, when they have
5137*e038c9c4Sjoerg // been raised for asking the wrong question of scalable vectors, such as
5138*e038c9c4Sjoerg // asking for the fixed number of elements. This may happen because code that
5139*e038c9c4Sjoerg // is not yet ported to work for scalable vectors uses the wrong interfaces,
5140*e038c9c4Sjoerg // whereas the behaviour is actually correct. Emitting a warning helps bring
5141*e038c9c4Sjoerg // up scalable vector support in an incremental way. When scalable vector
5142*e038c9c4Sjoerg // support is stable enough, all uses of wrong interfaces should be considered
5143*e038c9c4Sjoerg // as errors, but until then, we can live with a warning being emitted by the
5144*e038c9c4Sjoerg // compiler. This way, Clang can be used to compile code with scalable vectors
5145*e038c9c4Sjoerg // and identify possible issues.
5146*e038c9c4Sjoerg if (isa<BackendJobAction>(JA)) {
5147*e038c9c4Sjoerg CmdArgs.push_back("-mllvm");
5148*e038c9c4Sjoerg CmdArgs.push_back("-treat-scalable-fixed-error-as-warning");
5149*e038c9c4Sjoerg }
5150*e038c9c4Sjoerg
51517330f729Sjoerg // These two are potentially updated by AddClangCLArgs.
51527330f729Sjoerg codegenoptions::DebugInfoKind DebugInfoKind = codegenoptions::NoDebugInfo;
51537330f729Sjoerg bool EmitCodeView = false;
51547330f729Sjoerg
51557330f729Sjoerg // Add clang-cl arguments.
51567330f729Sjoerg types::ID InputType = Input.getType();
51577330f729Sjoerg if (D.IsCLMode())
51587330f729Sjoerg AddClangCLArgs(Args, InputType, CmdArgs, &DebugInfoKind, &EmitCodeView);
51597330f729Sjoerg
5160*e038c9c4Sjoerg DwarfFissionKind DwarfFission = DwarfFissionKind::None;
5161*e038c9c4Sjoerg renderDebugOptions(TC, D, RawTriple, Args, EmitCodeView,
5162*e038c9c4Sjoerg types::isLLVMIR(InputType), CmdArgs, DebugInfoKind,
5163*e038c9c4Sjoerg DwarfFission);
51647330f729Sjoerg
51657330f729Sjoerg // Add the split debug info name to the command lines here so we
51667330f729Sjoerg // can propagate it to the backend.
51677330f729Sjoerg bool SplitDWARF = (DwarfFission != DwarfFissionKind::None) &&
5168*e038c9c4Sjoerg (TC.getTriple().isOSBinFormatELF() ||
5169*e038c9c4Sjoerg TC.getTriple().isOSBinFormatWasm()) &&
51707330f729Sjoerg (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA) ||
51717330f729Sjoerg isa<BackendJobAction>(JA));
51727330f729Sjoerg if (SplitDWARF) {
5173*e038c9c4Sjoerg const char *SplitDWARFOut = SplitDebugName(JA, Args, Input, Output);
51747330f729Sjoerg CmdArgs.push_back("-split-dwarf-file");
51757330f729Sjoerg CmdArgs.push_back(SplitDWARFOut);
51767330f729Sjoerg if (DwarfFission == DwarfFissionKind::Split) {
51777330f729Sjoerg CmdArgs.push_back("-split-dwarf-output");
51787330f729Sjoerg CmdArgs.push_back(SplitDWARFOut);
51797330f729Sjoerg }
51807330f729Sjoerg }
51817330f729Sjoerg
51827330f729Sjoerg // Pass the linker version in use.
51837330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
51847330f729Sjoerg CmdArgs.push_back("-target-linker-version");
51857330f729Sjoerg CmdArgs.push_back(A->getValue());
51867330f729Sjoerg }
51877330f729Sjoerg
51887330f729Sjoerg // Explicitly error on some things we know we don't support and can't just
51897330f729Sjoerg // ignore.
51907330f729Sjoerg if (!Args.hasArg(options::OPT_fallow_unsupported)) {
51917330f729Sjoerg Arg *Unsupported;
51927330f729Sjoerg if (types::isCXX(InputType) && RawTriple.isOSDarwin() &&
51937330f729Sjoerg TC.getArch() == llvm::Triple::x86) {
51947330f729Sjoerg if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext)) ||
51957330f729Sjoerg (Unsupported = Args.getLastArg(options::OPT_mkernel)))
51967330f729Sjoerg D.Diag(diag::err_drv_clang_unsupported_opt_cxx_darwin_i386)
51977330f729Sjoerg << Unsupported->getOption().getName();
51987330f729Sjoerg }
51997330f729Sjoerg // The faltivec option has been superseded by the maltivec option.
52007330f729Sjoerg if ((Unsupported = Args.getLastArg(options::OPT_faltivec)))
52017330f729Sjoerg D.Diag(diag::err_drv_clang_unsupported_opt_faltivec)
52027330f729Sjoerg << Unsupported->getOption().getName()
52037330f729Sjoerg << "please use -maltivec and include altivec.h explicitly";
52047330f729Sjoerg if ((Unsupported = Args.getLastArg(options::OPT_fno_altivec)))
52057330f729Sjoerg D.Diag(diag::err_drv_clang_unsupported_opt_faltivec)
52067330f729Sjoerg << Unsupported->getOption().getName() << "please use -mno-altivec";
52077330f729Sjoerg }
52087330f729Sjoerg
52097330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_v);
5210*e038c9c4Sjoerg
5211*e038c9c4Sjoerg if (Args.getLastArg(options::OPT_H)) {
5212*e038c9c4Sjoerg CmdArgs.push_back("-H");
5213*e038c9c4Sjoerg CmdArgs.push_back("-sys-header-deps");
5214*e038c9c4Sjoerg }
5215*e038c9c4Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_fshow_skipped_includes);
5216*e038c9c4Sjoerg
52177330f729Sjoerg if (D.CCPrintHeaders && !D.CCGenDiagnostics) {
52187330f729Sjoerg CmdArgs.push_back("-header-include-file");
5219*e038c9c4Sjoerg CmdArgs.push_back(!D.CCPrintHeadersFilename.empty()
5220*e038c9c4Sjoerg ? D.CCPrintHeadersFilename.c_str()
52217330f729Sjoerg : "-");
5222*e038c9c4Sjoerg CmdArgs.push_back("-sys-header-deps");
52237330f729Sjoerg }
52247330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_P);
52257330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout);
52267330f729Sjoerg
52277330f729Sjoerg if (D.CCLogDiagnostics && !D.CCGenDiagnostics) {
52287330f729Sjoerg CmdArgs.push_back("-diagnostic-log-file");
5229*e038c9c4Sjoerg CmdArgs.push_back(!D.CCLogDiagnosticsFilename.empty()
5230*e038c9c4Sjoerg ? D.CCLogDiagnosticsFilename.c_str()
52317330f729Sjoerg : "-");
52327330f729Sjoerg }
52337330f729Sjoerg
5234*e038c9c4Sjoerg // Give the gen diagnostics more chances to succeed, by avoiding intentional
5235*e038c9c4Sjoerg // crashes.
5236*e038c9c4Sjoerg if (D.CCGenDiagnostics)
5237*e038c9c4Sjoerg CmdArgs.push_back("-disable-pragma-debug-crash");
5238*e038c9c4Sjoerg
5239*e038c9c4Sjoerg // Allow backend to put its diagnostic files in the same place as frontend
5240*e038c9c4Sjoerg // crash diagnostics files.
5241*e038c9c4Sjoerg if (Args.hasArg(options::OPT_fcrash_diagnostics_dir)) {
5242*e038c9c4Sjoerg StringRef Dir = Args.getLastArgValue(options::OPT_fcrash_diagnostics_dir);
5243*e038c9c4Sjoerg CmdArgs.push_back("-mllvm");
5244*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString("-crash-diagnostics-dir=" + Dir));
5245*e038c9c4Sjoerg }
5246*e038c9c4Sjoerg
52477330f729Sjoerg bool UseSeparateSections = isUseSeparateSections(Triple);
52487330f729Sjoerg
52497330f729Sjoerg if (Args.hasFlag(options::OPT_ffunction_sections,
52507330f729Sjoerg options::OPT_fno_function_sections, UseSeparateSections)) {
52517330f729Sjoerg CmdArgs.push_back("-ffunction-sections");
52527330f729Sjoerg }
52537330f729Sjoerg
5254*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fbasic_block_sections_EQ)) {
5255*e038c9c4Sjoerg if (Triple.isX86() && Triple.isOSBinFormatELF()) {
5256*e038c9c4Sjoerg StringRef Val = A->getValue();
5257*e038c9c4Sjoerg if (Val != "all" && Val != "labels" && Val != "none" &&
5258*e038c9c4Sjoerg !Val.startswith("list="))
5259*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_value)
5260*e038c9c4Sjoerg << A->getAsString(Args) << A->getValue();
5261*e038c9c4Sjoerg else
5262*e038c9c4Sjoerg A->render(Args, CmdArgs);
5263*e038c9c4Sjoerg } else {
5264*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
5265*e038c9c4Sjoerg << A->getAsString(Args) << TripleStr;
5266*e038c9c4Sjoerg }
5267*e038c9c4Sjoerg }
5268*e038c9c4Sjoerg
5269*e038c9c4Sjoerg bool HasDefaultDataSections = Triple.isOSBinFormatXCOFF();
52707330f729Sjoerg if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
5271*e038c9c4Sjoerg UseSeparateSections || HasDefaultDataSections)) {
52727330f729Sjoerg CmdArgs.push_back("-fdata-sections");
52737330f729Sjoerg }
52747330f729Sjoerg
52757330f729Sjoerg if (!Args.hasFlag(options::OPT_funique_section_names,
52767330f729Sjoerg options::OPT_fno_unique_section_names, true))
52777330f729Sjoerg CmdArgs.push_back("-fno-unique-section-names");
52787330f729Sjoerg
5279*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_funique_internal_linkage_names,
5280*e038c9c4Sjoerg options::OPT_fno_unique_internal_linkage_names, false))
5281*e038c9c4Sjoerg CmdArgs.push_back("-funique-internal-linkage-names");
5282*e038c9c4Sjoerg
5283*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_funique_basic_block_section_names,
5284*e038c9c4Sjoerg options::OPT_fno_unique_basic_block_section_names, false))
5285*e038c9c4Sjoerg CmdArgs.push_back("-funique-basic-block-section-names");
5286*e038c9c4Sjoerg
5287*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fsplit_machine_functions,
5288*e038c9c4Sjoerg options::OPT_fno_split_machine_functions)) {
5289*e038c9c4Sjoerg // This codegen pass is only available on x86-elf targets.
5290*e038c9c4Sjoerg if (Triple.isX86() && Triple.isOSBinFormatELF()) {
5291*e038c9c4Sjoerg if (A->getOption().matches(options::OPT_fsplit_machine_functions))
5292*e038c9c4Sjoerg A->render(Args, CmdArgs);
5293*e038c9c4Sjoerg } else {
5294*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
5295*e038c9c4Sjoerg << A->getAsString(Args) << TripleStr;
5296*e038c9c4Sjoerg }
5297*e038c9c4Sjoerg }
5298*e038c9c4Sjoerg
52997330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_finstrument_functions,
53007330f729Sjoerg options::OPT_finstrument_functions_after_inlining,
53017330f729Sjoerg options::OPT_finstrument_function_entry_bare);
53027330f729Sjoerg
5303*e038c9c4Sjoerg // NVPTX/AMDGCN doesn't support PGO or coverage. There's no runtime support
5304*e038c9c4Sjoerg // for sampling, overhead of call arc collection is way too high and there's
5305*e038c9c4Sjoerg // no way to collect the output.
5306*e038c9c4Sjoerg if (!Triple.isNVPTX() && !Triple.isAMDGCN())
53077330f729Sjoerg addPGOAndCoverageFlags(TC, C, D, Output, Args, CmdArgs);
53087330f729Sjoerg
53097330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fclang_abi_compat_EQ);
53107330f729Sjoerg
53117330f729Sjoerg // Add runtime flag for PS4 when PGO, coverage, or sanitizers are enabled.
53127330f729Sjoerg if (RawTriple.isPS4CPU() &&
53137330f729Sjoerg !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
53147330f729Sjoerg PS4cpu::addProfileRTArgs(TC, Args, CmdArgs);
53157330f729Sjoerg PS4cpu::addSanitizerArgs(TC, CmdArgs);
53167330f729Sjoerg }
53177330f729Sjoerg
53187330f729Sjoerg // Pass options for controlling the default header search paths.
53197330f729Sjoerg if (Args.hasArg(options::OPT_nostdinc)) {
53207330f729Sjoerg CmdArgs.push_back("-nostdsysteminc");
53217330f729Sjoerg CmdArgs.push_back("-nobuiltininc");
53227330f729Sjoerg } else {
53237330f729Sjoerg if (Args.hasArg(options::OPT_nostdlibinc))
53247330f729Sjoerg CmdArgs.push_back("-nostdsysteminc");
53257330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_nostdincxx);
53267330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
53277330f729Sjoerg }
53287330f729Sjoerg
53297330f729Sjoerg // Pass the path to compiler resource files.
53307330f729Sjoerg CmdArgs.push_back("-resource-dir");
53317330f729Sjoerg CmdArgs.push_back(D.ResourceDir.c_str());
53327330f729Sjoerg
53337330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_working_directory);
53347330f729Sjoerg
53357330f729Sjoerg RenderARCMigrateToolOptions(D, Args, CmdArgs);
53367330f729Sjoerg
53377330f729Sjoerg // Add preprocessing options like -I, -D, etc. if we are using the
53387330f729Sjoerg // preprocessor.
53397330f729Sjoerg //
53407330f729Sjoerg // FIXME: Support -fpreprocessed
53417330f729Sjoerg if (types::getPreprocessedType(InputType) != types::TY_INVALID)
53427330f729Sjoerg AddPreprocessingOptions(C, JA, D, Args, CmdArgs, Output, Inputs);
53437330f729Sjoerg
53447330f729Sjoerg // Don't warn about "clang -c -DPIC -fPIC test.i" because libtool.m4 assumes
53457330f729Sjoerg // that "The compiler can only warn and ignore the option if not recognized".
53467330f729Sjoerg // When building with ccache, it will pass -D options to clang even on
53477330f729Sjoerg // preprocessed inputs and configure concludes that -fPIC is not supported.
53487330f729Sjoerg Args.ClaimAllArgs(options::OPT_D);
53497330f729Sjoerg
53507330f729Sjoerg // Manually translate -O4 to -O3; let clang reject others.
53517330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
53527330f729Sjoerg if (A->getOption().matches(options::OPT_O4)) {
53537330f729Sjoerg CmdArgs.push_back("-O3");
53547330f729Sjoerg D.Diag(diag::warn_O4_is_O3);
53557330f729Sjoerg } else {
53567330f729Sjoerg A->render(Args, CmdArgs);
53577330f729Sjoerg }
53587330f729Sjoerg }
53597330f729Sjoerg
53607330f729Sjoerg // Warn about ignored options to clang.
53617330f729Sjoerg for (const Arg *A :
53627330f729Sjoerg Args.filtered(options::OPT_clang_ignored_gcc_optimization_f_Group)) {
53637330f729Sjoerg D.Diag(diag::warn_ignored_gcc_optimization) << A->getAsString(Args);
53647330f729Sjoerg A->claim();
53657330f729Sjoerg }
53667330f729Sjoerg
53677330f729Sjoerg for (const Arg *A :
53687330f729Sjoerg Args.filtered(options::OPT_clang_ignored_legacy_options_Group)) {
53697330f729Sjoerg D.Diag(diag::warn_ignored_clang_option) << A->getAsString(Args);
53707330f729Sjoerg A->claim();
53717330f729Sjoerg }
53727330f729Sjoerg
53737330f729Sjoerg claimNoWarnArgs(Args);
53747330f729Sjoerg
53757330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_R_Group);
53767330f729Sjoerg
53777330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
53787330f729Sjoerg if (Args.hasFlag(options::OPT_pedantic, options::OPT_no_pedantic, false))
53797330f729Sjoerg CmdArgs.push_back("-pedantic");
53807330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
53817330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_w);
53827330f729Sjoerg
53837330f729Sjoerg // Fixed point flags
53847330f729Sjoerg if (Args.hasFlag(options::OPT_ffixed_point, options::OPT_fno_fixed_point,
53857330f729Sjoerg /*Default=*/false))
53867330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_ffixed_point);
53877330f729Sjoerg
5388*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fcxx_abi_EQ))
5389*e038c9c4Sjoerg A->render(Args, CmdArgs);
5390*e038c9c4Sjoerg
53917330f729Sjoerg // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
53927330f729Sjoerg // (-ansi is equivalent to -std=c89 or -std=c++98).
53937330f729Sjoerg //
53947330f729Sjoerg // If a std is supplied, only add -trigraphs if it follows the
53957330f729Sjoerg // option.
5396*e038c9c4Sjoerg bool ImplyVCPPCVer = false;
53977330f729Sjoerg bool ImplyVCPPCXXVer = false;
53987330f729Sjoerg const Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi);
53997330f729Sjoerg if (Std) {
54007330f729Sjoerg if (Std->getOption().matches(options::OPT_ansi))
54017330f729Sjoerg if (types::isCXX(InputType))
54027330f729Sjoerg CmdArgs.push_back("-std=c++98");
54037330f729Sjoerg else
54047330f729Sjoerg CmdArgs.push_back("-std=c89");
54057330f729Sjoerg else
54067330f729Sjoerg Std->render(Args, CmdArgs);
54077330f729Sjoerg
54087330f729Sjoerg // If -f(no-)trigraphs appears after the language standard flag, honor it.
54097330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi,
54107330f729Sjoerg options::OPT_ftrigraphs,
54117330f729Sjoerg options::OPT_fno_trigraphs))
54127330f729Sjoerg if (A != Std)
54137330f729Sjoerg A->render(Args, CmdArgs);
54147330f729Sjoerg } else {
54157330f729Sjoerg // Honor -std-default.
54167330f729Sjoerg //
54177330f729Sjoerg // FIXME: Clang doesn't correctly handle -std= when the input language
54187330f729Sjoerg // doesn't match. For the time being just ignore this for C++ inputs;
54197330f729Sjoerg // eventually we want to do all the standard defaulting here instead of
54207330f729Sjoerg // splitting it between the driver and clang -cc1.
5421*e038c9c4Sjoerg if (!types::isCXX(InputType)) {
5422*e038c9c4Sjoerg if (!Args.hasArg(options::OPT__SLASH_std)) {
54237330f729Sjoerg Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ, "-std=",
54247330f729Sjoerg /*Joined=*/true);
5425*e038c9c4Sjoerg } else
5426*e038c9c4Sjoerg ImplyVCPPCVer = true;
5427*e038c9c4Sjoerg }
54287330f729Sjoerg else if (IsWindowsMSVC)
54297330f729Sjoerg ImplyVCPPCXXVer = true;
54307330f729Sjoerg
54317330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_ftrigraphs,
54327330f729Sjoerg options::OPT_fno_trigraphs);
5433*e038c9c4Sjoerg
5434*e038c9c4Sjoerg // HIP headers has minimum C++ standard requirements. Therefore set the
5435*e038c9c4Sjoerg // default language standard.
5436*e038c9c4Sjoerg if (IsHIP)
5437*e038c9c4Sjoerg CmdArgs.push_back(IsWindowsMSVC ? "-std=c++14" : "-std=c++11");
54387330f729Sjoerg }
54397330f729Sjoerg
54407330f729Sjoerg // GCC's behavior for -Wwrite-strings is a bit strange:
54417330f729Sjoerg // * In C, this "warning flag" changes the types of string literals from
54427330f729Sjoerg // 'char[N]' to 'const char[N]', and thus triggers an unrelated warning
54437330f729Sjoerg // for the discarded qualifier.
54447330f729Sjoerg // * In C++, this is just a normal warning flag.
54457330f729Sjoerg //
54467330f729Sjoerg // Implementing this warning correctly in C is hard, so we follow GCC's
54477330f729Sjoerg // behavior for now. FIXME: Directly diagnose uses of a string literal as
54487330f729Sjoerg // a non-const char* in C, rather than using this crude hack.
54497330f729Sjoerg if (!types::isCXX(InputType)) {
54507330f729Sjoerg // FIXME: This should behave just like a warning flag, and thus should also
54517330f729Sjoerg // respect -Weverything, -Wno-everything, -Werror=write-strings, and so on.
54527330f729Sjoerg Arg *WriteStrings =
54537330f729Sjoerg Args.getLastArg(options::OPT_Wwrite_strings,
54547330f729Sjoerg options::OPT_Wno_write_strings, options::OPT_w);
54557330f729Sjoerg if (WriteStrings &&
54567330f729Sjoerg WriteStrings->getOption().matches(options::OPT_Wwrite_strings))
54577330f729Sjoerg CmdArgs.push_back("-fconst-strings");
54587330f729Sjoerg }
54597330f729Sjoerg
54607330f729Sjoerg // GCC provides a macro definition '__DEPRECATED' when -Wdeprecated is active
54617330f729Sjoerg // during C++ compilation, which it is by default. GCC keeps this define even
54627330f729Sjoerg // in the presence of '-w', match this behavior bug-for-bug.
54637330f729Sjoerg if (types::isCXX(InputType) &&
54647330f729Sjoerg Args.hasFlag(options::OPT_Wdeprecated, options::OPT_Wno_deprecated,
54657330f729Sjoerg true)) {
54667330f729Sjoerg CmdArgs.push_back("-fdeprecated-macro");
54677330f729Sjoerg }
54687330f729Sjoerg
54697330f729Sjoerg // Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'.
54707330f729Sjoerg if (Arg *Asm = Args.getLastArg(options::OPT_fasm, options::OPT_fno_asm)) {
54717330f729Sjoerg if (Asm->getOption().matches(options::OPT_fasm))
54727330f729Sjoerg CmdArgs.push_back("-fgnu-keywords");
54737330f729Sjoerg else
54747330f729Sjoerg CmdArgs.push_back("-fno-gnu-keywords");
54757330f729Sjoerg }
54767330f729Sjoerg
54777330f729Sjoerg if (ShouldDisableDwarfDirectory(Args, TC))
54787330f729Sjoerg CmdArgs.push_back("-fno-dwarf-directory-asm");
54797330f729Sjoerg
5480*e038c9c4Sjoerg if (!ShouldEnableAutolink(Args, TC, JA))
54817330f729Sjoerg CmdArgs.push_back("-fno-autolink");
54827330f729Sjoerg
54837330f729Sjoerg // Add in -fdebug-compilation-dir if necessary.
54847330f729Sjoerg addDebugCompDirArg(Args, CmdArgs, D.getVFS());
54857330f729Sjoerg
54867330f729Sjoerg addDebugPrefixMapArg(D, Args, CmdArgs);
54877330f729Sjoerg
54887330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_,
54897330f729Sjoerg options::OPT_ftemplate_depth_EQ)) {
54907330f729Sjoerg CmdArgs.push_back("-ftemplate-depth");
54917330f729Sjoerg CmdArgs.push_back(A->getValue());
54927330f729Sjoerg }
54937330f729Sjoerg
54947330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_foperator_arrow_depth_EQ)) {
54957330f729Sjoerg CmdArgs.push_back("-foperator-arrow-depth");
54967330f729Sjoerg CmdArgs.push_back(A->getValue());
54977330f729Sjoerg }
54987330f729Sjoerg
54997330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_depth_EQ)) {
55007330f729Sjoerg CmdArgs.push_back("-fconstexpr-depth");
55017330f729Sjoerg CmdArgs.push_back(A->getValue());
55027330f729Sjoerg }
55037330f729Sjoerg
55047330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_steps_EQ)) {
55057330f729Sjoerg CmdArgs.push_back("-fconstexpr-steps");
55067330f729Sjoerg CmdArgs.push_back(A->getValue());
55077330f729Sjoerg }
55087330f729Sjoerg
55097330f729Sjoerg if (Args.hasArg(options::OPT_fexperimental_new_constant_interpreter))
55107330f729Sjoerg CmdArgs.push_back("-fexperimental-new-constant-interpreter");
55117330f729Sjoerg
55127330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fbracket_depth_EQ)) {
55137330f729Sjoerg CmdArgs.push_back("-fbracket-depth");
55147330f729Sjoerg CmdArgs.push_back(A->getValue());
55157330f729Sjoerg }
55167330f729Sjoerg
55177330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_Wlarge_by_value_copy_EQ,
55187330f729Sjoerg options::OPT_Wlarge_by_value_copy_def)) {
55197330f729Sjoerg if (A->getNumValues()) {
55207330f729Sjoerg StringRef bytes = A->getValue();
55217330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-Wlarge-by-value-copy=" + bytes));
55227330f729Sjoerg } else
55237330f729Sjoerg CmdArgs.push_back("-Wlarge-by-value-copy=64"); // default value
55247330f729Sjoerg }
55257330f729Sjoerg
55267330f729Sjoerg if (Args.hasArg(options::OPT_relocatable_pch))
55277330f729Sjoerg CmdArgs.push_back("-relocatable-pch");
55287330f729Sjoerg
55297330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_fcf_runtime_abi_EQ)) {
55307330f729Sjoerg static const char *kCFABIs[] = {
55317330f729Sjoerg "standalone", "objc", "swift", "swift-5.0", "swift-4.2", "swift-4.1",
55327330f729Sjoerg };
55337330f729Sjoerg
55347330f729Sjoerg if (find(kCFABIs, StringRef(A->getValue())) == std::end(kCFABIs))
55357330f729Sjoerg D.Diag(diag::err_drv_invalid_cf_runtime_abi) << A->getValue();
55367330f729Sjoerg else
55377330f729Sjoerg A->render(Args, CmdArgs);
55387330f729Sjoerg }
55397330f729Sjoerg
55407330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
55417330f729Sjoerg CmdArgs.push_back("-fconstant-string-class");
55427330f729Sjoerg CmdArgs.push_back(A->getValue());
55437330f729Sjoerg }
55447330f729Sjoerg
55457330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_ftabstop_EQ)) {
55467330f729Sjoerg CmdArgs.push_back("-ftabstop");
55477330f729Sjoerg CmdArgs.push_back(A->getValue());
55487330f729Sjoerg }
55497330f729Sjoerg
55507330f729Sjoerg if (Args.hasFlag(options::OPT_fstack_size_section,
55517330f729Sjoerg options::OPT_fno_stack_size_section, RawTriple.isPS4()))
55527330f729Sjoerg CmdArgs.push_back("-fstack-size-section");
55537330f729Sjoerg
5554*e038c9c4Sjoerg if (Args.hasArg(options::OPT_fstack_usage)) {
5555*e038c9c4Sjoerg CmdArgs.push_back("-stack-usage-file");
5556*e038c9c4Sjoerg
5557*e038c9c4Sjoerg if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
5558*e038c9c4Sjoerg SmallString<128> OutputFilename(OutputOpt->getValue());
5559*e038c9c4Sjoerg llvm::sys::path::replace_extension(OutputFilename, "su");
5560*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(OutputFilename));
5561*e038c9c4Sjoerg } else
5562*e038c9c4Sjoerg CmdArgs.push_back(
5563*e038c9c4Sjoerg Args.MakeArgString(Twine(getBaseInputStem(Args, Inputs)) + ".su"));
5564*e038c9c4Sjoerg }
5565*e038c9c4Sjoerg
55667330f729Sjoerg CmdArgs.push_back("-ferror-limit");
55677330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_ferror_limit_EQ))
55687330f729Sjoerg CmdArgs.push_back(A->getValue());
55697330f729Sjoerg else
55707330f729Sjoerg CmdArgs.push_back("19");
55717330f729Sjoerg
55727330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) {
55737330f729Sjoerg CmdArgs.push_back("-fmacro-backtrace-limit");
55747330f729Sjoerg CmdArgs.push_back(A->getValue());
55757330f729Sjoerg }
55767330f729Sjoerg
55777330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ)) {
55787330f729Sjoerg CmdArgs.push_back("-ftemplate-backtrace-limit");
55797330f729Sjoerg CmdArgs.push_back(A->getValue());
55807330f729Sjoerg }
55817330f729Sjoerg
55827330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_backtrace_limit_EQ)) {
55837330f729Sjoerg CmdArgs.push_back("-fconstexpr-backtrace-limit");
55847330f729Sjoerg CmdArgs.push_back(A->getValue());
55857330f729Sjoerg }
55867330f729Sjoerg
55877330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fspell_checking_limit_EQ)) {
55887330f729Sjoerg CmdArgs.push_back("-fspell-checking-limit");
55897330f729Sjoerg CmdArgs.push_back(A->getValue());
55907330f729Sjoerg }
55917330f729Sjoerg
55927330f729Sjoerg // Pass -fmessage-length=.
5593*e038c9c4Sjoerg unsigned MessageLength = 0;
55947330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
5595*e038c9c4Sjoerg StringRef V(A->getValue());
5596*e038c9c4Sjoerg if (V.getAsInteger(0, MessageLength))
5597*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_argument_to_option)
5598*e038c9c4Sjoerg << V << A->getOption().getName();
55997330f729Sjoerg } else {
56007330f729Sjoerg // If -fmessage-length=N was not specified, determine whether this is a
56017330f729Sjoerg // terminal and, if so, implicitly define -fmessage-length appropriately.
5602*e038c9c4Sjoerg MessageLength = llvm::sys::Process::StandardErrColumns();
56037330f729Sjoerg }
5604*e038c9c4Sjoerg if (MessageLength != 0)
5605*e038c9c4Sjoerg CmdArgs.push_back(
5606*e038c9c4Sjoerg Args.MakeArgString("-fmessage-length=" + Twine(MessageLength)));
56077330f729Sjoerg
56087330f729Sjoerg // -fvisibility= and -fvisibility-ms-compat are of a piece.
56097330f729Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ,
56107330f729Sjoerg options::OPT_fvisibility_ms_compat)) {
56117330f729Sjoerg if (A->getOption().matches(options::OPT_fvisibility_EQ)) {
56127330f729Sjoerg CmdArgs.push_back("-fvisibility");
56137330f729Sjoerg CmdArgs.push_back(A->getValue());
56147330f729Sjoerg } else {
56157330f729Sjoerg assert(A->getOption().matches(options::OPT_fvisibility_ms_compat));
56167330f729Sjoerg CmdArgs.push_back("-fvisibility");
56177330f729Sjoerg CmdArgs.push_back("hidden");
56187330f729Sjoerg CmdArgs.push_back("-ftype-visibility");
56197330f729Sjoerg CmdArgs.push_back("default");
56207330f729Sjoerg }
56217330f729Sjoerg }
56227330f729Sjoerg
5623*e038c9c4Sjoerg if (!RawTriple.isPS4())
5624*e038c9c4Sjoerg if (const Arg *A =
5625*e038c9c4Sjoerg Args.getLastArg(options::OPT_fvisibility_from_dllstorageclass,
5626*e038c9c4Sjoerg options::OPT_fno_visibility_from_dllstorageclass)) {
5627*e038c9c4Sjoerg if (A->getOption().matches(
5628*e038c9c4Sjoerg options::OPT_fvisibility_from_dllstorageclass)) {
5629*e038c9c4Sjoerg CmdArgs.push_back("-fvisibility-from-dllstorageclass");
5630*e038c9c4Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fvisibility_dllexport_EQ);
5631*e038c9c4Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fvisibility_nodllstorageclass_EQ);
5632*e038c9c4Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fvisibility_externs_dllimport_EQ);
5633*e038c9c4Sjoerg Args.AddLastArg(CmdArgs,
5634*e038c9c4Sjoerg options::OPT_fvisibility_externs_nodllstorageclass_EQ);
5635*e038c9c4Sjoerg }
5636*e038c9c4Sjoerg }
5637*e038c9c4Sjoerg
5638*e038c9c4Sjoerg if (const Arg *A = Args.getLastArg(options::OPT_mignore_xcoff_visibility)) {
5639*e038c9c4Sjoerg if (Triple.isOSAIX())
5640*e038c9c4Sjoerg CmdArgs.push_back("-mignore-xcoff-visibility");
5641*e038c9c4Sjoerg else
5642*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
5643*e038c9c4Sjoerg << A->getAsString(Args) << TripleStr;
5644*e038c9c4Sjoerg }
5645*e038c9c4Sjoerg
56467330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
5647*e038c9c4Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden_static_local_var,
5648*e038c9c4Sjoerg options::OPT_fno_visibility_inlines_hidden_static_local_var);
56497330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fvisibility_global_new_delete_hidden);
56507330f729Sjoerg
56517330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
56527330f729Sjoerg
56537330f729Sjoerg // Forward -f (flag) options which we can pass directly.
56547330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
56557330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
56567330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fdigraphs, options::OPT_fno_digraphs);
56577330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
56587330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_femulated_tls,
56597330f729Sjoerg options::OPT_fno_emulated_tls);
56607330f729Sjoerg
56617330f729Sjoerg // AltiVec-like language extensions aren't relevant for assembling.
56627330f729Sjoerg if (!isa<PreprocessJobAction>(JA) || Output.getType() != types::TY_PP_Asm)
56637330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fzvector);
56647330f729Sjoerg
56657330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
56667330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
56677330f729Sjoerg
56687330f729Sjoerg // Forward flags for OpenMP. We don't do this if the current action is an
56697330f729Sjoerg // device offloading action other than OpenMP.
56707330f729Sjoerg if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
56717330f729Sjoerg options::OPT_fno_openmp, false) &&
56727330f729Sjoerg (JA.isDeviceOffloading(Action::OFK_None) ||
56737330f729Sjoerg JA.isDeviceOffloading(Action::OFK_OpenMP))) {
56747330f729Sjoerg switch (D.getOpenMPRuntime(Args)) {
56757330f729Sjoerg case Driver::OMPRT_OMP:
56767330f729Sjoerg case Driver::OMPRT_IOMP5:
56777330f729Sjoerg // Clang can generate useful OpenMP code for these two runtime libraries.
56787330f729Sjoerg CmdArgs.push_back("-fopenmp");
56797330f729Sjoerg
56807330f729Sjoerg // If no option regarding the use of TLS in OpenMP codegeneration is
56817330f729Sjoerg // given, decide a default based on the target. Otherwise rely on the
56827330f729Sjoerg // options and pass the right information to the frontend.
56837330f729Sjoerg if (!Args.hasFlag(options::OPT_fopenmp_use_tls,
56847330f729Sjoerg options::OPT_fnoopenmp_use_tls, /*Default=*/true))
56857330f729Sjoerg CmdArgs.push_back("-fnoopenmp-use-tls");
56867330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fopenmp_simd,
56877330f729Sjoerg options::OPT_fno_openmp_simd);
5688*e038c9c4Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_enable_irbuilder);
56897330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ);
56907330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_cuda_number_of_sm_EQ);
56917330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_cuda_blocks_per_sm_EQ);
56927330f729Sjoerg Args.AddAllArgs(CmdArgs,
56937330f729Sjoerg options::OPT_fopenmp_cuda_teams_reduction_recs_num_EQ);
56947330f729Sjoerg if (Args.hasFlag(options::OPT_fopenmp_optimistic_collapse,
56957330f729Sjoerg options::OPT_fno_openmp_optimistic_collapse,
56967330f729Sjoerg /*Default=*/false))
56977330f729Sjoerg CmdArgs.push_back("-fopenmp-optimistic-collapse");
56987330f729Sjoerg
56997330f729Sjoerg // When in OpenMP offloading mode with NVPTX target, forward
57007330f729Sjoerg // cuda-mode flag
57017330f729Sjoerg if (Args.hasFlag(options::OPT_fopenmp_cuda_mode,
57027330f729Sjoerg options::OPT_fno_openmp_cuda_mode, /*Default=*/false))
57037330f729Sjoerg CmdArgs.push_back("-fopenmp-cuda-mode");
57047330f729Sjoerg
5705*e038c9c4Sjoerg // When in OpenMP offloading mode with NVPTX target, forward
5706*e038c9c4Sjoerg // cuda-parallel-target-regions flag
5707*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fopenmp_cuda_parallel_target_regions,
5708*e038c9c4Sjoerg options::OPT_fno_openmp_cuda_parallel_target_regions,
5709*e038c9c4Sjoerg /*Default=*/true))
5710*e038c9c4Sjoerg CmdArgs.push_back("-fopenmp-cuda-parallel-target-regions");
5711*e038c9c4Sjoerg
57127330f729Sjoerg // When in OpenMP offloading mode with NVPTX target, check if full runtime
57137330f729Sjoerg // is required.
57147330f729Sjoerg if (Args.hasFlag(options::OPT_fopenmp_cuda_force_full_runtime,
57157330f729Sjoerg options::OPT_fno_openmp_cuda_force_full_runtime,
57167330f729Sjoerg /*Default=*/false))
57177330f729Sjoerg CmdArgs.push_back("-fopenmp-cuda-force-full-runtime");
57187330f729Sjoerg break;
57197330f729Sjoerg default:
57207330f729Sjoerg // By default, if Clang doesn't know how to generate useful OpenMP code
57217330f729Sjoerg // for a specific runtime library, we just don't pass the '-fopenmp' flag
57227330f729Sjoerg // down to the actual compilation.
57237330f729Sjoerg // FIXME: It would be better to have a mode which *only* omits IR
57247330f729Sjoerg // generation based on the OpenMP support so that we get consistent
57257330f729Sjoerg // semantic analysis, etc.
57267330f729Sjoerg break;
57277330f729Sjoerg }
57287330f729Sjoerg } else {
57297330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fopenmp_simd,
57307330f729Sjoerg options::OPT_fno_openmp_simd);
57317330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ);
57327330f729Sjoerg }
57337330f729Sjoerg
57347330f729Sjoerg const SanitizerArgs &Sanitize = TC.getSanitizerArgs();
57357330f729Sjoerg Sanitize.addArgs(TC, Args, CmdArgs, InputType);
57367330f729Sjoerg
57377330f729Sjoerg const XRayArgs &XRay = TC.getXRayArgs();
57387330f729Sjoerg XRay.addArgs(TC, Args, CmdArgs, InputType);
57397330f729Sjoerg
5740*e038c9c4Sjoerg for (const auto &Filename :
5741*e038c9c4Sjoerg Args.getAllArgValues(options::OPT_fprofile_list_EQ)) {
5742*e038c9c4Sjoerg if (D.getVFS().exists(Filename))
5743*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString("-fprofile-list=" + Filename));
5744*e038c9c4Sjoerg else
5745*e038c9c4Sjoerg D.Diag(clang::diag::err_drv_no_such_file) << Filename;
5746*e038c9c4Sjoerg }
5747*e038c9c4Sjoerg
5748*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fpatchable_function_entry_EQ)) {
5749*e038c9c4Sjoerg StringRef S0 = A->getValue(), S = S0;
5750*e038c9c4Sjoerg unsigned Size, Offset = 0;
5751*e038c9c4Sjoerg if (!Triple.isAArch64() && !Triple.isRISCV() && !Triple.isX86())
5752*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
5753*e038c9c4Sjoerg << A->getAsString(Args) << TripleStr;
5754*e038c9c4Sjoerg else if (S.consumeInteger(10, Size) ||
5755*e038c9c4Sjoerg (!S.empty() && (!S.consume_front(",") ||
5756*e038c9c4Sjoerg S.consumeInteger(10, Offset) || !S.empty())))
5757*e038c9c4Sjoerg D.Diag(diag::err_drv_invalid_argument_to_option)
5758*e038c9c4Sjoerg << S0 << A->getOption().getName();
5759*e038c9c4Sjoerg else if (Size < Offset)
5760*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_fpatchable_function_entry_argument);
5761*e038c9c4Sjoerg else {
5762*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(A->getSpelling() + Twine(Size)));
5763*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(
5764*e038c9c4Sjoerg "-fpatchable-function-entry-offset=" + Twine(Offset)));
5765*e038c9c4Sjoerg }
5766*e038c9c4Sjoerg }
5767*e038c9c4Sjoerg
5768*e038c9c4Sjoerg if (TC.SupportsProfiling()) {
57697330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_pg);
57707330f729Sjoerg
5771*e038c9c4Sjoerg llvm::Triple::ArchType Arch = TC.getArch();
5772*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mfentry)) {
5773*e038c9c4Sjoerg if (Arch == llvm::Triple::systemz || TC.getTriple().isX86())
5774*e038c9c4Sjoerg A->render(Args, CmdArgs);
5775*e038c9c4Sjoerg else
5776*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
5777*e038c9c4Sjoerg << A->getAsString(Args) << TripleStr;
5778*e038c9c4Sjoerg }
5779*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mnop_mcount)) {
5780*e038c9c4Sjoerg if (Arch == llvm::Triple::systemz)
5781*e038c9c4Sjoerg A->render(Args, CmdArgs);
5782*e038c9c4Sjoerg else
5783*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
5784*e038c9c4Sjoerg << A->getAsString(Args) << TripleStr;
5785*e038c9c4Sjoerg }
5786*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mrecord_mcount)) {
5787*e038c9c4Sjoerg if (Arch == llvm::Triple::systemz)
5788*e038c9c4Sjoerg A->render(Args, CmdArgs);
5789*e038c9c4Sjoerg else
5790*e038c9c4Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
5791*e038c9c4Sjoerg << A->getAsString(Args) << TripleStr;
5792*e038c9c4Sjoerg }
5793*e038c9c4Sjoerg }
57947330f729Sjoerg
57957330f729Sjoerg if (Args.getLastArg(options::OPT_fapple_kext) ||
57967330f729Sjoerg (Args.hasArg(options::OPT_mkernel) && types::isCXX(InputType)))
57977330f729Sjoerg CmdArgs.push_back("-fapple-kext");
57987330f729Sjoerg
57997330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_flax_vector_conversions_EQ);
58007330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
58017330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
58027330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
58037330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
5804*e038c9c4Sjoerg Args.AddLastArg(CmdArgs, options::OPT_ftime_report_EQ);
58057330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_ftime_trace);
58067330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_ftime_trace_granularity_EQ);
58077330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
58087330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_malign_double);
5809*e038c9c4Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fno_temp_file);
58107330f729Sjoerg
58117330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) {
58127330f729Sjoerg CmdArgs.push_back("-ftrapv-handler");
58137330f729Sjoerg CmdArgs.push_back(A->getValue());
58147330f729Sjoerg }
58157330f729Sjoerg
58167330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_ftrap_function_EQ);
58177330f729Sjoerg
58187330f729Sjoerg // -fno-strict-overflow implies -fwrapv if it isn't disabled, but
58197330f729Sjoerg // -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
58207330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
58217330f729Sjoerg if (A->getOption().matches(options::OPT_fwrapv))
58227330f729Sjoerg CmdArgs.push_back("-fwrapv");
58237330f729Sjoerg } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
58247330f729Sjoerg options::OPT_fno_strict_overflow)) {
58257330f729Sjoerg if (A->getOption().matches(options::OPT_fno_strict_overflow))
58267330f729Sjoerg CmdArgs.push_back("-fwrapv");
58277330f729Sjoerg }
58287330f729Sjoerg
58297330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_freroll_loops,
58307330f729Sjoerg options::OPT_fno_reroll_loops))
58317330f729Sjoerg if (A->getOption().matches(options::OPT_freroll_loops))
58327330f729Sjoerg CmdArgs.push_back("-freroll-loops");
58337330f729Sjoerg
5834*e038c9c4Sjoerg Args.AddLastArg(CmdArgs, options::OPT_ffinite_loops,
5835*e038c9c4Sjoerg options::OPT_fno_finite_loops);
5836*e038c9c4Sjoerg
58377330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
58387330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_funroll_loops,
58397330f729Sjoerg options::OPT_fno_unroll_loops);
58407330f729Sjoerg
58417330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_pthread);
58427330f729Sjoerg
5843*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_mspeculative_load_hardening,
5844*e038c9c4Sjoerg options::OPT_mno_speculative_load_hardening, false))
58457330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-mspeculative-load-hardening"));
58467330f729Sjoerg
5847*e038c9c4Sjoerg RenderSSPOptions(D, TC, Args, CmdArgs, KernelOrKext);
5848*e038c9c4Sjoerg RenderSCPOptions(TC, Args, CmdArgs);
58497330f729Sjoerg RenderTrivialAutoVarInitOptions(D, TC, Args, CmdArgs);
58507330f729Sjoerg
58517330f729Sjoerg // Translate -mstackrealign
58527330f729Sjoerg if (Args.hasFlag(options::OPT_mstackrealign, options::OPT_mno_stackrealign,
58537330f729Sjoerg false))
58547330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-mstackrealign"));
58557330f729Sjoerg
58567330f729Sjoerg if (Args.hasArg(options::OPT_mstack_alignment)) {
58577330f729Sjoerg StringRef alignment = Args.getLastArgValue(options::OPT_mstack_alignment);
58587330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment));
58597330f729Sjoerg }
58607330f729Sjoerg
58617330f729Sjoerg if (Args.hasArg(options::OPT_mstack_probe_size)) {
58627330f729Sjoerg StringRef Size = Args.getLastArgValue(options::OPT_mstack_probe_size);
58637330f729Sjoerg
58647330f729Sjoerg if (!Size.empty())
58657330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-mstack-probe-size=" + Size));
58667330f729Sjoerg else
58677330f729Sjoerg CmdArgs.push_back("-mstack-probe-size=0");
58687330f729Sjoerg }
58697330f729Sjoerg
58707330f729Sjoerg if (!Args.hasFlag(options::OPT_mstack_arg_probe,
58717330f729Sjoerg options::OPT_mno_stack_arg_probe, true))
58727330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-mno-stack-arg-probe"));
58737330f729Sjoerg
58747330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_mrestrict_it,
58757330f729Sjoerg options::OPT_mno_restrict_it)) {
58767330f729Sjoerg if (A->getOption().matches(options::OPT_mrestrict_it)) {
58777330f729Sjoerg CmdArgs.push_back("-mllvm");
58787330f729Sjoerg CmdArgs.push_back("-arm-restrict-it");
58797330f729Sjoerg } else {
58807330f729Sjoerg CmdArgs.push_back("-mllvm");
58817330f729Sjoerg CmdArgs.push_back("-arm-no-restrict-it");
58827330f729Sjoerg }
58837330f729Sjoerg } else if (Triple.isOSWindows() &&
58847330f729Sjoerg (Triple.getArch() == llvm::Triple::arm ||
58857330f729Sjoerg Triple.getArch() == llvm::Triple::thumb)) {
58867330f729Sjoerg // Windows on ARM expects restricted IT blocks
58877330f729Sjoerg CmdArgs.push_back("-mllvm");
58887330f729Sjoerg CmdArgs.push_back("-arm-restrict-it");
58897330f729Sjoerg }
58907330f729Sjoerg
58917330f729Sjoerg // Forward -cl options to -cc1
5892*e038c9c4Sjoerg RenderOpenCLOptions(Args, CmdArgs, InputType);
58937330f729Sjoerg
5894*e038c9c4Sjoerg if (IsHIP) {
58957330f729Sjoerg if (Args.hasFlag(options::OPT_fhip_new_launch_api,
5896*e038c9c4Sjoerg options::OPT_fno_hip_new_launch_api, true))
58977330f729Sjoerg CmdArgs.push_back("-fhip-new-launch-api");
5898*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fgpu_allow_device_init,
5899*e038c9c4Sjoerg options::OPT_fno_gpu_allow_device_init, false))
5900*e038c9c4Sjoerg CmdArgs.push_back("-fgpu-allow-device-init");
5901*e038c9c4Sjoerg }
5902*e038c9c4Sjoerg
5903*e038c9c4Sjoerg if (IsCuda || IsHIP) {
5904*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false))
5905*e038c9c4Sjoerg CmdArgs.push_back("-fgpu-rdc");
5906*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fgpu_defer_diag,
5907*e038c9c4Sjoerg options::OPT_fno_gpu_defer_diag, false))
5908*e038c9c4Sjoerg CmdArgs.push_back("-fgpu-defer-diag");
5909*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fgpu_exclude_wrong_side_overloads,
5910*e038c9c4Sjoerg options::OPT_fno_gpu_exclude_wrong_side_overloads,
5911*e038c9c4Sjoerg false)) {
5912*e038c9c4Sjoerg CmdArgs.push_back("-fgpu-exclude-wrong-side-overloads");
5913*e038c9c4Sjoerg CmdArgs.push_back("-fgpu-defer-diag");
5914*e038c9c4Sjoerg }
5915*e038c9c4Sjoerg }
59167330f729Sjoerg
59177330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) {
59187330f729Sjoerg CmdArgs.push_back(
59197330f729Sjoerg Args.MakeArgString(Twine("-fcf-protection=") + A->getValue()));
59207330f729Sjoerg }
59217330f729Sjoerg
5922*e038c9c4Sjoerg // Forward -f options with positive and negative forms; we translate these by
5923*e038c9c4Sjoerg // hand. Do not propagate PGO options to the GPU-side compilations as the
5924*e038c9c4Sjoerg // profile info is for the host-side compilation only.
5925*e038c9c4Sjoerg if (!(IsCudaDevice || IsHIPDevice)) {
59267330f729Sjoerg if (Arg *A = getLastProfileSampleUseArg(Args)) {
59277330f729Sjoerg auto *PGOArg = Args.getLastArg(
59287330f729Sjoerg options::OPT_fprofile_generate, options::OPT_fprofile_generate_EQ,
5929*e038c9c4Sjoerg options::OPT_fcs_profile_generate,
5930*e038c9c4Sjoerg options::OPT_fcs_profile_generate_EQ, options::OPT_fprofile_use,
5931*e038c9c4Sjoerg options::OPT_fprofile_use_EQ);
59327330f729Sjoerg if (PGOArg)
59337330f729Sjoerg D.Diag(diag::err_drv_argument_not_allowed_with)
59347330f729Sjoerg << "SampleUse with PGO options";
59357330f729Sjoerg
59367330f729Sjoerg StringRef fname = A->getValue();
59377330f729Sjoerg if (!llvm::sys::fs::exists(fname))
59387330f729Sjoerg D.Diag(diag::err_drv_no_such_file) << fname;
59397330f729Sjoerg else
59407330f729Sjoerg A->render(Args, CmdArgs);
59417330f729Sjoerg }
59427330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fprofile_remapping_file_EQ);
59437330f729Sjoerg
5944*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fpseudo_probe_for_profiling,
5945*e038c9c4Sjoerg options::OPT_fno_pseudo_probe_for_profiling, false))
5946*e038c9c4Sjoerg CmdArgs.push_back("-fpseudo-probe-for-profiling");
5947*e038c9c4Sjoerg }
59487330f729Sjoerg RenderBuiltinOptions(TC, RawTriple, Args, CmdArgs);
59497330f729Sjoerg
59507330f729Sjoerg if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
59517330f729Sjoerg options::OPT_fno_assume_sane_operator_new))
59527330f729Sjoerg CmdArgs.push_back("-fno-assume-sane-operator-new");
59537330f729Sjoerg
59547330f729Sjoerg // -fblocks=0 is default.
59557330f729Sjoerg if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
59567330f729Sjoerg TC.IsBlocksDefault()) ||
59577330f729Sjoerg (Args.hasArg(options::OPT_fgnu_runtime) &&
59587330f729Sjoerg Args.hasArg(options::OPT_fobjc_nonfragile_abi) &&
59597330f729Sjoerg !Args.hasArg(options::OPT_fno_blocks))) {
59607330f729Sjoerg CmdArgs.push_back("-fblocks");
59617330f729Sjoerg
59627330f729Sjoerg if (!Args.hasArg(options::OPT_fgnu_runtime) && !TC.hasBlocksRuntime())
59637330f729Sjoerg CmdArgs.push_back("-fblocks-runtime-optional");
59647330f729Sjoerg }
59657330f729Sjoerg
59667330f729Sjoerg // -fencode-extended-block-signature=1 is default.
59677330f729Sjoerg if (TC.IsEncodeExtendedBlockSignatureDefault())
59687330f729Sjoerg CmdArgs.push_back("-fencode-extended-block-signature");
59697330f729Sjoerg
59707330f729Sjoerg if (Args.hasFlag(options::OPT_fcoroutines_ts, options::OPT_fno_coroutines_ts,
59717330f729Sjoerg false) &&
59727330f729Sjoerg types::isCXX(InputType)) {
59737330f729Sjoerg CmdArgs.push_back("-fcoroutines-ts");
59747330f729Sjoerg }
59757330f729Sjoerg
59767330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fdouble_square_bracket_attributes,
59777330f729Sjoerg options::OPT_fno_double_square_bracket_attributes);
59787330f729Sjoerg
59797330f729Sjoerg // -faccess-control is default.
59807330f729Sjoerg if (Args.hasFlag(options::OPT_fno_access_control,
59817330f729Sjoerg options::OPT_faccess_control, false))
59827330f729Sjoerg CmdArgs.push_back("-fno-access-control");
59837330f729Sjoerg
59847330f729Sjoerg // -felide-constructors is the default.
59857330f729Sjoerg if (Args.hasFlag(options::OPT_fno_elide_constructors,
59867330f729Sjoerg options::OPT_felide_constructors, false))
59877330f729Sjoerg CmdArgs.push_back("-fno-elide-constructors");
59887330f729Sjoerg
59897330f729Sjoerg ToolChain::RTTIMode RTTIMode = TC.getRTTIMode();
59907330f729Sjoerg
59917330f729Sjoerg if (KernelOrKext || (types::isCXX(InputType) &&
59927330f729Sjoerg (RTTIMode == ToolChain::RM_Disabled)))
59937330f729Sjoerg CmdArgs.push_back("-fno-rtti");
59947330f729Sjoerg
5995*e038c9c4Sjoerg // -fshort-enums=0 is default for all architectures except Hexagon and z/OS.
59967330f729Sjoerg if (Args.hasFlag(options::OPT_fshort_enums, options::OPT_fno_short_enums,
5997*e038c9c4Sjoerg TC.getArch() == llvm::Triple::hexagon || Triple.isOSzOS()))
59987330f729Sjoerg CmdArgs.push_back("-fshort-enums");
59997330f729Sjoerg
60007330f729Sjoerg RenderCharacterOptions(Args, AuxTriple ? *AuxTriple : RawTriple, CmdArgs);
60017330f729Sjoerg
60027330f729Sjoerg // -fuse-cxa-atexit is default.
60037330f729Sjoerg if (!Args.hasFlag(
60047330f729Sjoerg options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit,
6005*e038c9c4Sjoerg !RawTriple.isOSAIX() && !RawTriple.isOSWindows() &&
60067330f729Sjoerg TC.getArch() != llvm::Triple::xcore &&
60077330f729Sjoerg ((RawTriple.getVendor() != llvm::Triple::MipsTechnologies) ||
60087330f729Sjoerg RawTriple.hasEnvironment())) ||
60097330f729Sjoerg KernelOrKext)
60107330f729Sjoerg CmdArgs.push_back("-fno-use-cxa-atexit");
60117330f729Sjoerg
60127330f729Sjoerg if (Args.hasFlag(options::OPT_fregister_global_dtors_with_atexit,
60137330f729Sjoerg options::OPT_fno_register_global_dtors_with_atexit,
60147330f729Sjoerg RawTriple.isOSDarwin() && !KernelOrKext))
60157330f729Sjoerg CmdArgs.push_back("-fregister-global-dtors-with-atexit");
60167330f729Sjoerg
60177330f729Sjoerg // -fno-use-line-directives is default.
60187330f729Sjoerg if (Args.hasFlag(options::OPT_fuse_line_directives,
60197330f729Sjoerg options::OPT_fno_use_line_directives, false))
60207330f729Sjoerg CmdArgs.push_back("-fuse-line-directives");
60217330f729Sjoerg
6022*e038c9c4Sjoerg // -fms-extensions=0 is default.
6023*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
6024*e038c9c4Sjoerg IsWindowsMSVC))
6025*e038c9c4Sjoerg CmdArgs.push_back("-fms-extensions");
6026*e038c9c4Sjoerg
60277330f729Sjoerg // -fms-compatibility=0 is default.
60287330f729Sjoerg bool IsMSVCCompat = Args.hasFlag(
60297330f729Sjoerg options::OPT_fms_compatibility, options::OPT_fno_ms_compatibility,
60307330f729Sjoerg (IsWindowsMSVC && Args.hasFlag(options::OPT_fms_extensions,
60317330f729Sjoerg options::OPT_fno_ms_extensions, true)));
60327330f729Sjoerg if (IsMSVCCompat)
60337330f729Sjoerg CmdArgs.push_back("-fms-compatibility");
60347330f729Sjoerg
60357330f729Sjoerg // Handle -fgcc-version, if present.
60367330f729Sjoerg VersionTuple GNUCVer;
60377330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fgnuc_version_EQ)) {
60387330f729Sjoerg // Check that the version has 1 to 3 components and the minor and patch
60397330f729Sjoerg // versions fit in two decimal digits.
60407330f729Sjoerg StringRef Val = A->getValue();
60417330f729Sjoerg Val = Val.empty() ? "0" : Val; // Treat "" as 0 or disable.
60427330f729Sjoerg bool Invalid = GNUCVer.tryParse(Val);
60437330f729Sjoerg unsigned Minor = GNUCVer.getMinor().getValueOr(0);
60447330f729Sjoerg unsigned Patch = GNUCVer.getSubminor().getValueOr(0);
60457330f729Sjoerg if (Invalid || GNUCVer.getBuild() || Minor >= 100 || Patch >= 100) {
60467330f729Sjoerg D.Diag(diag::err_drv_invalid_value)
60477330f729Sjoerg << A->getAsString(Args) << A->getValue();
60487330f729Sjoerg }
60497330f729Sjoerg } else if (!IsMSVCCompat) {
60507330f729Sjoerg // Imitate GCC 4.2.1 by default if -fms-compatibility is not in effect.
60517330f729Sjoerg GNUCVer = VersionTuple(4, 2, 1);
60527330f729Sjoerg }
60537330f729Sjoerg if (!GNUCVer.empty()) {
60547330f729Sjoerg CmdArgs.push_back(
60557330f729Sjoerg Args.MakeArgString("-fgnuc-version=" + GNUCVer.getAsString()));
60567330f729Sjoerg }
60577330f729Sjoerg
60587330f729Sjoerg VersionTuple MSVT = TC.computeMSVCVersion(&D, Args);
60597330f729Sjoerg if (!MSVT.empty())
60607330f729Sjoerg CmdArgs.push_back(
60617330f729Sjoerg Args.MakeArgString("-fms-compatibility-version=" + MSVT.getAsString()));
60627330f729Sjoerg
60637330f729Sjoerg bool IsMSVC2015Compatible = MSVT.getMajor() >= 19;
6064*e038c9c4Sjoerg if (ImplyVCPPCVer) {
6065*e038c9c4Sjoerg StringRef LanguageStandard;
6066*e038c9c4Sjoerg if (const Arg *StdArg = Args.getLastArg(options::OPT__SLASH_std)) {
6067*e038c9c4Sjoerg Std = StdArg;
6068*e038c9c4Sjoerg LanguageStandard = llvm::StringSwitch<StringRef>(StdArg->getValue())
6069*e038c9c4Sjoerg .Case("c11", "-std=c11")
6070*e038c9c4Sjoerg .Case("c17", "-std=c17")
6071*e038c9c4Sjoerg .Default("");
6072*e038c9c4Sjoerg if (LanguageStandard.empty())
6073*e038c9c4Sjoerg D.Diag(clang::diag::warn_drv_unused_argument)
6074*e038c9c4Sjoerg << StdArg->getAsString(Args);
6075*e038c9c4Sjoerg }
6076*e038c9c4Sjoerg CmdArgs.push_back(LanguageStandard.data());
6077*e038c9c4Sjoerg }
60787330f729Sjoerg if (ImplyVCPPCXXVer) {
60797330f729Sjoerg StringRef LanguageStandard;
60807330f729Sjoerg if (const Arg *StdArg = Args.getLastArg(options::OPT__SLASH_std)) {
60817330f729Sjoerg Std = StdArg;
60827330f729Sjoerg LanguageStandard = llvm::StringSwitch<StringRef>(StdArg->getValue())
60837330f729Sjoerg .Case("c++14", "-std=c++14")
60847330f729Sjoerg .Case("c++17", "-std=c++17")
6085*e038c9c4Sjoerg .Case("c++latest", "-std=c++20")
60867330f729Sjoerg .Default("");
60877330f729Sjoerg if (LanguageStandard.empty())
60887330f729Sjoerg D.Diag(clang::diag::warn_drv_unused_argument)
60897330f729Sjoerg << StdArg->getAsString(Args);
60907330f729Sjoerg }
60917330f729Sjoerg
60927330f729Sjoerg if (LanguageStandard.empty()) {
60937330f729Sjoerg if (IsMSVC2015Compatible)
60947330f729Sjoerg LanguageStandard = "-std=c++14";
60957330f729Sjoerg else
60967330f729Sjoerg LanguageStandard = "-std=c++11";
60977330f729Sjoerg }
60987330f729Sjoerg
60997330f729Sjoerg CmdArgs.push_back(LanguageStandard.data());
61007330f729Sjoerg }
61017330f729Sjoerg
61027330f729Sjoerg // -fno-borland-extensions is default.
61037330f729Sjoerg if (Args.hasFlag(options::OPT_fborland_extensions,
61047330f729Sjoerg options::OPT_fno_borland_extensions, false))
61057330f729Sjoerg CmdArgs.push_back("-fborland-extensions");
61067330f729Sjoerg
61077330f729Sjoerg // -fno-declspec is default, except for PS4.
61087330f729Sjoerg if (Args.hasFlag(options::OPT_fdeclspec, options::OPT_fno_declspec,
61097330f729Sjoerg RawTriple.isPS4()))
61107330f729Sjoerg CmdArgs.push_back("-fdeclspec");
61117330f729Sjoerg else if (Args.hasArg(options::OPT_fno_declspec))
61127330f729Sjoerg CmdArgs.push_back("-fno-declspec"); // Explicitly disabling __declspec.
61137330f729Sjoerg
61147330f729Sjoerg // -fthreadsafe-static is default, except for MSVC compatibility versions less
61157330f729Sjoerg // than 19.
61167330f729Sjoerg if (!Args.hasFlag(options::OPT_fthreadsafe_statics,
61177330f729Sjoerg options::OPT_fno_threadsafe_statics,
61187330f729Sjoerg !IsWindowsMSVC || IsMSVC2015Compatible))
61197330f729Sjoerg CmdArgs.push_back("-fno-threadsafe-statics");
61207330f729Sjoerg
61217330f729Sjoerg // -fno-delayed-template-parsing is default, except when targeting MSVC.
61227330f729Sjoerg // Many old Windows SDK versions require this to parse.
61237330f729Sjoerg // FIXME: MSVC introduced /Zc:twoPhase- to disable this behavior in their
61247330f729Sjoerg // compiler. We should be able to disable this by default at some point.
61257330f729Sjoerg if (Args.hasFlag(options::OPT_fdelayed_template_parsing,
61267330f729Sjoerg options::OPT_fno_delayed_template_parsing, IsWindowsMSVC))
61277330f729Sjoerg CmdArgs.push_back("-fdelayed-template-parsing");
61287330f729Sjoerg
61297330f729Sjoerg // -fgnu-keywords default varies depending on language; only pass if
61307330f729Sjoerg // specified.
61317330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fgnu_keywords,
61327330f729Sjoerg options::OPT_fno_gnu_keywords);
61337330f729Sjoerg
61347330f729Sjoerg if (Args.hasFlag(options::OPT_fgnu89_inline, options::OPT_fno_gnu89_inline,
61357330f729Sjoerg false))
61367330f729Sjoerg CmdArgs.push_back("-fgnu89-inline");
61377330f729Sjoerg
61387330f729Sjoerg if (Args.hasArg(options::OPT_fno_inline))
61397330f729Sjoerg CmdArgs.push_back("-fno-inline");
61407330f729Sjoerg
61417330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_finline_functions,
61427330f729Sjoerg options::OPT_finline_hint_functions,
61437330f729Sjoerg options::OPT_fno_inline_functions);
61447330f729Sjoerg
61457330f729Sjoerg // FIXME: Find a better way to determine whether the language has modules
61467330f729Sjoerg // support by default, or just assume that all languages do.
61477330f729Sjoerg bool HaveModules =
6148*e038c9c4Sjoerg Std && (Std->containsValue("c++2a") || Std->containsValue("c++20") ||
6149*e038c9c4Sjoerg Std->containsValue("c++latest"));
61507330f729Sjoerg RenderModulesOptions(C, D, Args, Input, Output, CmdArgs, HaveModules);
61517330f729Sjoerg
61527330f729Sjoerg if (Args.hasFlag(options::OPT_fpch_validate_input_files_content,
61537330f729Sjoerg options::OPT_fno_pch_validate_input_files_content, false))
61547330f729Sjoerg CmdArgs.push_back("-fvalidate-ast-input-files-content");
6155*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fpch_instantiate_templates,
6156*e038c9c4Sjoerg options::OPT_fno_pch_instantiate_templates, false))
6157*e038c9c4Sjoerg CmdArgs.push_back("-fpch-instantiate-templates");
6158*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fpch_codegen, options::OPT_fno_pch_codegen,
6159*e038c9c4Sjoerg false))
6160*e038c9c4Sjoerg CmdArgs.push_back("-fmodules-codegen");
6161*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fpch_debuginfo, options::OPT_fno_pch_debuginfo,
6162*e038c9c4Sjoerg false))
6163*e038c9c4Sjoerg CmdArgs.push_back("-fmodules-debuginfo");
61647330f729Sjoerg
6165*e038c9c4Sjoerg Args.AddLastArg(CmdArgs, options::OPT_flegacy_pass_manager,
6166*e038c9c4Sjoerg options::OPT_fno_legacy_pass_manager);
61677330f729Sjoerg
6168*e038c9c4Sjoerg ObjCRuntime Runtime = AddObjCRuntimeArgs(Args, Inputs, CmdArgs, rewriteKind);
61697330f729Sjoerg RenderObjCOptions(TC, D, RawTriple, Args, Runtime, rewriteKind != RK_None,
61707330f729Sjoerg Input, CmdArgs);
61717330f729Sjoerg
6172*e038c9c4Sjoerg if (types::isObjC(Input.getType()) &&
6173*e038c9c4Sjoerg Args.hasFlag(options::OPT_fobjc_encode_cxx_class_template_spec,
6174*e038c9c4Sjoerg options::OPT_fno_objc_encode_cxx_class_template_spec,
6175*e038c9c4Sjoerg !Runtime.isNeXTFamily()))
6176*e038c9c4Sjoerg CmdArgs.push_back("-fobjc-encode-cxx-class-template-spec");
6177*e038c9c4Sjoerg
61787330f729Sjoerg if (Args.hasFlag(options::OPT_fapplication_extension,
61797330f729Sjoerg options::OPT_fno_application_extension, false))
61807330f729Sjoerg CmdArgs.push_back("-fapplication-extension");
61817330f729Sjoerg
61827330f729Sjoerg // Handle GCC-style exception args.
6183*e038c9c4Sjoerg bool EH = false;
61847330f729Sjoerg if (!C.getDriver().IsCLMode())
6185*e038c9c4Sjoerg EH = addExceptionArgs(Args, InputType, TC, KernelOrKext, Runtime, CmdArgs);
61867330f729Sjoerg
61877330f729Sjoerg // Handle exception personalities
61887330f729Sjoerg Arg *A = Args.getLastArg(
61897330f729Sjoerg options::OPT_fsjlj_exceptions, options::OPT_fseh_exceptions,
61907330f729Sjoerg options::OPT_fdwarf_exceptions, options::OPT_fwasm_exceptions);
61917330f729Sjoerg if (A) {
61927330f729Sjoerg const Option &Opt = A->getOption();
61937330f729Sjoerg if (Opt.matches(options::OPT_fsjlj_exceptions))
6194*e038c9c4Sjoerg CmdArgs.push_back("-exception-model=sjlj");
61957330f729Sjoerg if (Opt.matches(options::OPT_fseh_exceptions))
6196*e038c9c4Sjoerg CmdArgs.push_back("-exception-model=seh");
61977330f729Sjoerg if (Opt.matches(options::OPT_fdwarf_exceptions))
6198*e038c9c4Sjoerg CmdArgs.push_back("-exception-model=dwarf");
61997330f729Sjoerg if (Opt.matches(options::OPT_fwasm_exceptions))
6200*e038c9c4Sjoerg CmdArgs.push_back("-exception-model=wasm");
62017330f729Sjoerg } else {
62027330f729Sjoerg switch (TC.GetExceptionModel(Args)) {
62037330f729Sjoerg default:
62047330f729Sjoerg break;
62057330f729Sjoerg case llvm::ExceptionHandling::DwarfCFI:
6206*e038c9c4Sjoerg CmdArgs.push_back("-exception-model=dwarf");
62077330f729Sjoerg break;
62087330f729Sjoerg case llvm::ExceptionHandling::SjLj:
6209*e038c9c4Sjoerg CmdArgs.push_back("-exception-model=sjlj");
62107330f729Sjoerg break;
62117330f729Sjoerg case llvm::ExceptionHandling::WinEH:
6212*e038c9c4Sjoerg CmdArgs.push_back("-exception-model=seh");
62137330f729Sjoerg break;
62147330f729Sjoerg }
62157330f729Sjoerg }
62167330f729Sjoerg
62177330f729Sjoerg // C++ "sane" operator new.
62187330f729Sjoerg if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
62197330f729Sjoerg options::OPT_fno_assume_sane_operator_new))
62207330f729Sjoerg CmdArgs.push_back("-fno-assume-sane-operator-new");
62217330f729Sjoerg
62227330f729Sjoerg // -frelaxed-template-template-args is off by default, as it is a severe
62237330f729Sjoerg // breaking change until a corresponding change to template partial ordering
62247330f729Sjoerg // is provided.
62257330f729Sjoerg if (Args.hasFlag(options::OPT_frelaxed_template_template_args,
62267330f729Sjoerg options::OPT_fno_relaxed_template_template_args, false))
62277330f729Sjoerg CmdArgs.push_back("-frelaxed-template-template-args");
62287330f729Sjoerg
62297330f729Sjoerg // -fsized-deallocation is off by default, as it is an ABI-breaking change for
62307330f729Sjoerg // most platforms.
62317330f729Sjoerg if (Args.hasFlag(options::OPT_fsized_deallocation,
62327330f729Sjoerg options::OPT_fno_sized_deallocation, false))
62337330f729Sjoerg CmdArgs.push_back("-fsized-deallocation");
62347330f729Sjoerg
62357330f729Sjoerg // -faligned-allocation is on by default in C++17 onwards and otherwise off
62367330f729Sjoerg // by default.
62377330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_faligned_allocation,
62387330f729Sjoerg options::OPT_fno_aligned_allocation,
62397330f729Sjoerg options::OPT_faligned_new_EQ)) {
62407330f729Sjoerg if (A->getOption().matches(options::OPT_fno_aligned_allocation))
62417330f729Sjoerg CmdArgs.push_back("-fno-aligned-allocation");
62427330f729Sjoerg else
62437330f729Sjoerg CmdArgs.push_back("-faligned-allocation");
62447330f729Sjoerg }
62457330f729Sjoerg
62467330f729Sjoerg // The default new alignment can be specified using a dedicated option or via
62477330f729Sjoerg // a GCC-compatible option that also turns on aligned allocation.
62487330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fnew_alignment_EQ,
62497330f729Sjoerg options::OPT_faligned_new_EQ))
62507330f729Sjoerg CmdArgs.push_back(
62517330f729Sjoerg Args.MakeArgString(Twine("-fnew-alignment=") + A->getValue()));
62527330f729Sjoerg
62537330f729Sjoerg // -fconstant-cfstrings is default, and may be subject to argument translation
62547330f729Sjoerg // on Darwin.
62557330f729Sjoerg if (!Args.hasFlag(options::OPT_fconstant_cfstrings,
62567330f729Sjoerg options::OPT_fno_constant_cfstrings) ||
62577330f729Sjoerg !Args.hasFlag(options::OPT_mconstant_cfstrings,
62587330f729Sjoerg options::OPT_mno_constant_cfstrings))
62597330f729Sjoerg CmdArgs.push_back("-fno-constant-cfstrings");
62607330f729Sjoerg
62617330f729Sjoerg // -fno-pascal-strings is default, only pass non-default.
62627330f729Sjoerg if (Args.hasFlag(options::OPT_fpascal_strings,
62637330f729Sjoerg options::OPT_fno_pascal_strings, false))
62647330f729Sjoerg CmdArgs.push_back("-fpascal-strings");
62657330f729Sjoerg
62667330f729Sjoerg // Honor -fpack-struct= and -fpack-struct, if given. Note that
62677330f729Sjoerg // -fno-pack-struct doesn't apply to -fpack-struct=.
62687330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fpack_struct_EQ)) {
62697330f729Sjoerg std::string PackStructStr = "-fpack-struct=";
62707330f729Sjoerg PackStructStr += A->getValue();
62717330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(PackStructStr));
62727330f729Sjoerg } else if (Args.hasFlag(options::OPT_fpack_struct,
62737330f729Sjoerg options::OPT_fno_pack_struct, false)) {
62747330f729Sjoerg CmdArgs.push_back("-fpack-struct=1");
62757330f729Sjoerg }
62767330f729Sjoerg
62777330f729Sjoerg // Handle -fmax-type-align=N and -fno-type-align
62787330f729Sjoerg bool SkipMaxTypeAlign = Args.hasArg(options::OPT_fno_max_type_align);
62797330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fmax_type_align_EQ)) {
62807330f729Sjoerg if (!SkipMaxTypeAlign) {
62817330f729Sjoerg std::string MaxTypeAlignStr = "-fmax-type-align=";
62827330f729Sjoerg MaxTypeAlignStr += A->getValue();
62837330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(MaxTypeAlignStr));
62847330f729Sjoerg }
62857330f729Sjoerg } else if (RawTriple.isOSDarwin()) {
62867330f729Sjoerg if (!SkipMaxTypeAlign) {
62877330f729Sjoerg std::string MaxTypeAlignStr = "-fmax-type-align=16";
62887330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(MaxTypeAlignStr));
62897330f729Sjoerg }
62907330f729Sjoerg }
62917330f729Sjoerg
62927330f729Sjoerg if (!Args.hasFlag(options::OPT_Qy, options::OPT_Qn, true))
62937330f729Sjoerg CmdArgs.push_back("-Qn");
62947330f729Sjoerg
6295*e038c9c4Sjoerg // -fno-common is the default, set -fcommon only when that flag is set.
6296*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common, false))
6297*e038c9c4Sjoerg CmdArgs.push_back("-fcommon");
62987330f729Sjoerg
62997330f729Sjoerg // -fsigned-bitfields is default, and clang doesn't yet support
63007330f729Sjoerg // -funsigned-bitfields.
63017330f729Sjoerg if (!Args.hasFlag(options::OPT_fsigned_bitfields,
63027330f729Sjoerg options::OPT_funsigned_bitfields))
63037330f729Sjoerg D.Diag(diag::warn_drv_clang_unsupported)
63047330f729Sjoerg << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args);
63057330f729Sjoerg
63067330f729Sjoerg // -fsigned-bitfields is default, and clang doesn't support -fno-for-scope.
63077330f729Sjoerg if (!Args.hasFlag(options::OPT_ffor_scope, options::OPT_fno_for_scope))
63087330f729Sjoerg D.Diag(diag::err_drv_clang_unsupported)
63097330f729Sjoerg << Args.getLastArg(options::OPT_fno_for_scope)->getAsString(Args);
63107330f729Sjoerg
63117330f729Sjoerg // -finput_charset=UTF-8 is default. Reject others
63127330f729Sjoerg if (Arg *inputCharset = Args.getLastArg(options::OPT_finput_charset_EQ)) {
63137330f729Sjoerg StringRef value = inputCharset->getValue();
63147330f729Sjoerg if (!value.equals_lower("utf-8"))
63157330f729Sjoerg D.Diag(diag::err_drv_invalid_value) << inputCharset->getAsString(Args)
63167330f729Sjoerg << value;
63177330f729Sjoerg }
63187330f729Sjoerg
63197330f729Sjoerg // -fexec_charset=UTF-8 is default. Reject others
63207330f729Sjoerg if (Arg *execCharset = Args.getLastArg(options::OPT_fexec_charset_EQ)) {
63217330f729Sjoerg StringRef value = execCharset->getValue();
63227330f729Sjoerg if (!value.equals_lower("utf-8"))
63237330f729Sjoerg D.Diag(diag::err_drv_invalid_value) << execCharset->getAsString(Args)
63247330f729Sjoerg << value;
63257330f729Sjoerg }
63267330f729Sjoerg
63277330f729Sjoerg RenderDiagnosticsOptions(D, Args, CmdArgs);
63287330f729Sjoerg
63297330f729Sjoerg // -fno-asm-blocks is default.
63307330f729Sjoerg if (Args.hasFlag(options::OPT_fasm_blocks, options::OPT_fno_asm_blocks,
63317330f729Sjoerg false))
63327330f729Sjoerg CmdArgs.push_back("-fasm-blocks");
63337330f729Sjoerg
63347330f729Sjoerg // -fgnu-inline-asm is default.
63357330f729Sjoerg if (!Args.hasFlag(options::OPT_fgnu_inline_asm,
63367330f729Sjoerg options::OPT_fno_gnu_inline_asm, true))
63377330f729Sjoerg CmdArgs.push_back("-fno-gnu-inline-asm");
63387330f729Sjoerg
63397330f729Sjoerg // Enable vectorization per default according to the optimization level
63407330f729Sjoerg // selected. For optimization levels that want vectorization we use the alias
63417330f729Sjoerg // option to simplify the hasFlag logic.
63427330f729Sjoerg bool EnableVec = shouldEnableVectorizerAtOLevel(Args, false);
63437330f729Sjoerg OptSpecifier VectorizeAliasOption =
63447330f729Sjoerg EnableVec ? options::OPT_O_Group : options::OPT_fvectorize;
63457330f729Sjoerg if (Args.hasFlag(options::OPT_fvectorize, VectorizeAliasOption,
63467330f729Sjoerg options::OPT_fno_vectorize, EnableVec))
63477330f729Sjoerg CmdArgs.push_back("-vectorize-loops");
63487330f729Sjoerg
63497330f729Sjoerg // -fslp-vectorize is enabled based on the optimization level selected.
63507330f729Sjoerg bool EnableSLPVec = shouldEnableVectorizerAtOLevel(Args, true);
63517330f729Sjoerg OptSpecifier SLPVectAliasOption =
63527330f729Sjoerg EnableSLPVec ? options::OPT_O_Group : options::OPT_fslp_vectorize;
63537330f729Sjoerg if (Args.hasFlag(options::OPT_fslp_vectorize, SLPVectAliasOption,
63547330f729Sjoerg options::OPT_fno_slp_vectorize, EnableSLPVec))
63557330f729Sjoerg CmdArgs.push_back("-vectorize-slp");
63567330f729Sjoerg
63577330f729Sjoerg ParseMPreferVectorWidth(D, Args, CmdArgs);
63587330f729Sjoerg
63597330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fshow_overloads_EQ);
63607330f729Sjoerg Args.AddLastArg(CmdArgs,
63617330f729Sjoerg options::OPT_fsanitize_undefined_strip_path_components_EQ);
63627330f729Sjoerg
63637330f729Sjoerg // -fdollars-in-identifiers default varies depending on platform and
63647330f729Sjoerg // language; only pass if specified.
63657330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
63667330f729Sjoerg options::OPT_fno_dollars_in_identifiers)) {
63677330f729Sjoerg if (A->getOption().matches(options::OPT_fdollars_in_identifiers))
63687330f729Sjoerg CmdArgs.push_back("-fdollars-in-identifiers");
63697330f729Sjoerg else
63707330f729Sjoerg CmdArgs.push_back("-fno-dollars-in-identifiers");
63717330f729Sjoerg }
63727330f729Sjoerg
63737330f729Sjoerg // -funit-at-a-time is default, and we don't support -fno-unit-at-a-time for
63747330f729Sjoerg // practical purposes.
63757330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_funit_at_a_time,
63767330f729Sjoerg options::OPT_fno_unit_at_a_time)) {
63777330f729Sjoerg if (A->getOption().matches(options::OPT_fno_unit_at_a_time))
63787330f729Sjoerg D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args);
63797330f729Sjoerg }
63807330f729Sjoerg
63817330f729Sjoerg if (Args.hasFlag(options::OPT_fapple_pragma_pack,
63827330f729Sjoerg options::OPT_fno_apple_pragma_pack, false))
63837330f729Sjoerg CmdArgs.push_back("-fapple-pragma-pack");
63847330f729Sjoerg
6385*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fxl_pragma_pack,
6386*e038c9c4Sjoerg options::OPT_fno_xl_pragma_pack, RawTriple.isOSAIX()))
6387*e038c9c4Sjoerg CmdArgs.push_back("-fxl-pragma-pack");
6388*e038c9c4Sjoerg
63897330f729Sjoerg // Remarks can be enabled with any of the `-f.*optimization-record.*` flags.
6390*e038c9c4Sjoerg if (willEmitRemarks(Args) && checkRemarksOptions(D, Args, Triple))
6391*e038c9c4Sjoerg renderRemarksOptions(Args, CmdArgs, Triple, Input, Output, JA);
63927330f729Sjoerg
63937330f729Sjoerg bool RewriteImports = Args.hasFlag(options::OPT_frewrite_imports,
63947330f729Sjoerg options::OPT_fno_rewrite_imports, false);
63957330f729Sjoerg if (RewriteImports)
63967330f729Sjoerg CmdArgs.push_back("-frewrite-imports");
63977330f729Sjoerg
63987330f729Sjoerg // Enable rewrite includes if the user's asked for it or if we're generating
63997330f729Sjoerg // diagnostics.
64007330f729Sjoerg // TODO: Once -module-dependency-dir works with -frewrite-includes it'd be
64017330f729Sjoerg // nice to enable this when doing a crashdump for modules as well.
64027330f729Sjoerg if (Args.hasFlag(options::OPT_frewrite_includes,
64037330f729Sjoerg options::OPT_fno_rewrite_includes, false) ||
64047330f729Sjoerg (C.isForDiagnostics() && !HaveModules))
64057330f729Sjoerg CmdArgs.push_back("-frewrite-includes");
64067330f729Sjoerg
64077330f729Sjoerg // Only allow -traditional or -traditional-cpp outside in preprocessing modes.
64087330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_traditional,
64097330f729Sjoerg options::OPT_traditional_cpp)) {
64107330f729Sjoerg if (isa<PreprocessJobAction>(JA))
64117330f729Sjoerg CmdArgs.push_back("-traditional-cpp");
64127330f729Sjoerg else
64137330f729Sjoerg D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
64147330f729Sjoerg }
64157330f729Sjoerg
64167330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_dM);
64177330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_dD);
64187330f729Sjoerg
6419*e038c9c4Sjoerg Args.AddLastArg(CmdArgs, options::OPT_fmax_tokens_EQ);
6420*e038c9c4Sjoerg
64217330f729Sjoerg // Handle serialized diagnostics.
64227330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT__serialize_diags)) {
64237330f729Sjoerg CmdArgs.push_back("-serialize-diagnostic-file");
64247330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(A->getValue()));
64257330f729Sjoerg }
64267330f729Sjoerg
64277330f729Sjoerg if (Args.hasArg(options::OPT_fretain_comments_from_system_headers))
64287330f729Sjoerg CmdArgs.push_back("-fretain-comments-from-system-headers");
64297330f729Sjoerg
64307330f729Sjoerg // Forward -fcomment-block-commands to -cc1.
64317330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands);
64327330f729Sjoerg // Forward -fparse-all-comments to -cc1.
64337330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_fparse_all_comments);
64347330f729Sjoerg
64357330f729Sjoerg // Turn -fplugin=name.so into -load name.so
64367330f729Sjoerg for (const Arg *A : Args.filtered(options::OPT_fplugin_EQ)) {
64377330f729Sjoerg CmdArgs.push_back("-load");
64387330f729Sjoerg CmdArgs.push_back(A->getValue());
64397330f729Sjoerg A->claim();
64407330f729Sjoerg }
64417330f729Sjoerg
64427330f729Sjoerg // Forward -fpass-plugin=name.so to -cc1.
64437330f729Sjoerg for (const Arg *A : Args.filtered(options::OPT_fpass_plugin_EQ)) {
64447330f729Sjoerg CmdArgs.push_back(
64457330f729Sjoerg Args.MakeArgString(Twine("-fpass-plugin=") + A->getValue()));
64467330f729Sjoerg A->claim();
64477330f729Sjoerg }
64487330f729Sjoerg
64497330f729Sjoerg // Setup statistics file output.
64507330f729Sjoerg SmallString<128> StatsFile = getStatsFileName(Args, Output, Input, D);
64517330f729Sjoerg if (!StatsFile.empty())
64527330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(Twine("-stats-file=") + StatsFile));
64537330f729Sjoerg
64547330f729Sjoerg // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
64557330f729Sjoerg // parser.
64567330f729Sjoerg // -finclude-default-header flag is for preprocessor,
64577330f729Sjoerg // do not pass it to other cc1 commands when save-temps is enabled
64587330f729Sjoerg if (C.getDriver().isSaveTempsEnabled() &&
64597330f729Sjoerg !isa<PreprocessJobAction>(JA)) {
64607330f729Sjoerg for (auto Arg : Args.filtered(options::OPT_Xclang)) {
64617330f729Sjoerg Arg->claim();
64627330f729Sjoerg if (StringRef(Arg->getValue()) != "-finclude-default-header")
64637330f729Sjoerg CmdArgs.push_back(Arg->getValue());
64647330f729Sjoerg }
64657330f729Sjoerg }
64667330f729Sjoerg else {
64677330f729Sjoerg Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
64687330f729Sjoerg }
64697330f729Sjoerg for (const Arg *A : Args.filtered(options::OPT_mllvm)) {
64707330f729Sjoerg A->claim();
64717330f729Sjoerg
64727330f729Sjoerg // We translate this by hand to the -cc1 argument, since nightly test uses
64737330f729Sjoerg // it and developers have been trained to spell it with -mllvm. Both
64747330f729Sjoerg // spellings are now deprecated and should be removed.
64757330f729Sjoerg if (StringRef(A->getValue(0)) == "-disable-llvm-optzns") {
64767330f729Sjoerg CmdArgs.push_back("-disable-llvm-optzns");
64777330f729Sjoerg } else {
64787330f729Sjoerg A->render(Args, CmdArgs);
64797330f729Sjoerg }
64807330f729Sjoerg }
64817330f729Sjoerg
64827330f729Sjoerg // With -save-temps, we want to save the unoptimized bitcode output from the
64837330f729Sjoerg // CompileJobAction, use -disable-llvm-passes to get pristine IR generated
64847330f729Sjoerg // by the frontend.
64857330f729Sjoerg // When -fembed-bitcode is enabled, optimized bitcode is emitted because it
64867330f729Sjoerg // has slightly different breakdown between stages.
64877330f729Sjoerg // FIXME: -fembed-bitcode -save-temps will save optimized bitcode instead of
64887330f729Sjoerg // pristine IR generated by the frontend. Ideally, a new compile action should
64897330f729Sjoerg // be added so both IR can be captured.
6490*e038c9c4Sjoerg if ((C.getDriver().isSaveTempsEnabled() ||
6491*e038c9c4Sjoerg JA.isHostOffloading(Action::OFK_OpenMP)) &&
6492*e038c9c4Sjoerg !(C.getDriver().embedBitcodeInObject() && !IsUsingLTO) &&
64937330f729Sjoerg isa<CompileJobAction>(JA))
64947330f729Sjoerg CmdArgs.push_back("-disable-llvm-passes");
64957330f729Sjoerg
64967330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_undef);
64977330f729Sjoerg
64987330f729Sjoerg const char *Exec = D.getClangProgramPath();
64997330f729Sjoerg
65007330f729Sjoerg // Optionally embed the -cc1 level arguments into the debug info or a
65017330f729Sjoerg // section, for build analysis.
65027330f729Sjoerg // Also record command line arguments into the debug info if
65037330f729Sjoerg // -grecord-gcc-switches options is set on.
65047330f729Sjoerg // By default, -gno-record-gcc-switches is set on and no recording.
65057330f729Sjoerg auto GRecordSwitches =
65067330f729Sjoerg Args.hasFlag(options::OPT_grecord_command_line,
65077330f729Sjoerg options::OPT_gno_record_command_line, false);
65087330f729Sjoerg auto FRecordSwitches =
65097330f729Sjoerg Args.hasFlag(options::OPT_frecord_command_line,
65107330f729Sjoerg options::OPT_fno_record_command_line, false);
65117330f729Sjoerg if (FRecordSwitches && !Triple.isOSBinFormatELF())
65127330f729Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
65137330f729Sjoerg << Args.getLastArg(options::OPT_frecord_command_line)->getAsString(Args)
65147330f729Sjoerg << TripleStr;
65157330f729Sjoerg if (TC.UseDwarfDebugFlags() || GRecordSwitches || FRecordSwitches) {
65167330f729Sjoerg ArgStringList OriginalArgs;
65177330f729Sjoerg for (const auto &Arg : Args)
65187330f729Sjoerg Arg->render(Args, OriginalArgs);
65197330f729Sjoerg
65207330f729Sjoerg SmallString<256> Flags;
6521*e038c9c4Sjoerg EscapeSpacesAndBackslashes(Exec, Flags);
65227330f729Sjoerg for (const char *OriginalArg : OriginalArgs) {
65237330f729Sjoerg SmallString<128> EscapedArg;
65247330f729Sjoerg EscapeSpacesAndBackslashes(OriginalArg, EscapedArg);
65257330f729Sjoerg Flags += " ";
65267330f729Sjoerg Flags += EscapedArg;
65277330f729Sjoerg }
65287330f729Sjoerg auto FlagsArgString = Args.MakeArgString(Flags);
65297330f729Sjoerg if (TC.UseDwarfDebugFlags() || GRecordSwitches) {
65307330f729Sjoerg CmdArgs.push_back("-dwarf-debug-flags");
65317330f729Sjoerg CmdArgs.push_back(FlagsArgString);
65327330f729Sjoerg }
65337330f729Sjoerg if (FRecordSwitches) {
65347330f729Sjoerg CmdArgs.push_back("-record-command-line");
65357330f729Sjoerg CmdArgs.push_back(FlagsArgString);
65367330f729Sjoerg }
65377330f729Sjoerg }
65387330f729Sjoerg
65397330f729Sjoerg // Host-side cuda compilation receives all device-side outputs in a single
65407330f729Sjoerg // fatbin as Inputs[1]. Include the binary with -fcuda-include-gpubinary.
65417330f729Sjoerg if ((IsCuda || IsHIP) && CudaDeviceInput) {
65427330f729Sjoerg CmdArgs.push_back("-fcuda-include-gpubinary");
65437330f729Sjoerg CmdArgs.push_back(CudaDeviceInput->getFilename());
65447330f729Sjoerg if (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false))
65457330f729Sjoerg CmdArgs.push_back("-fgpu-rdc");
65467330f729Sjoerg }
65477330f729Sjoerg
65487330f729Sjoerg if (IsCuda) {
65497330f729Sjoerg if (Args.hasFlag(options::OPT_fcuda_short_ptr,
65507330f729Sjoerg options::OPT_fno_cuda_short_ptr, false))
65517330f729Sjoerg CmdArgs.push_back("-fcuda-short-ptr");
65527330f729Sjoerg }
65537330f729Sjoerg
6554*e038c9c4Sjoerg if (IsCuda || IsHIP) {
6555*e038c9c4Sjoerg // Determine the original source input.
6556*e038c9c4Sjoerg const Action *SourceAction = &JA;
6557*e038c9c4Sjoerg while (SourceAction->getKind() != Action::InputClass) {
6558*e038c9c4Sjoerg assert(!SourceAction->getInputs().empty() && "unexpected root action!");
6559*e038c9c4Sjoerg SourceAction = SourceAction->getInputs()[0];
6560*e038c9c4Sjoerg }
6561*e038c9c4Sjoerg auto CUID = cast<InputAction>(SourceAction)->getId();
6562*e038c9c4Sjoerg if (!CUID.empty())
6563*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(Twine("-cuid=") + Twine(CUID)));
6564*e038c9c4Sjoerg }
6565*e038c9c4Sjoerg
65667330f729Sjoerg if (IsHIP)
65677330f729Sjoerg CmdArgs.push_back("-fcuda-allow-variadic-functions");
65687330f729Sjoerg
6569*e038c9c4Sjoerg if (IsCudaDevice || IsHIPDevice) {
6570*e038c9c4Sjoerg StringRef InlineThresh =
6571*e038c9c4Sjoerg Args.getLastArgValue(options::OPT_fgpu_inline_threshold_EQ);
6572*e038c9c4Sjoerg if (!InlineThresh.empty()) {
6573*e038c9c4Sjoerg std::string ArgStr =
6574*e038c9c4Sjoerg std::string("-inline-threshold=") + InlineThresh.str();
6575*e038c9c4Sjoerg CmdArgs.append({"-mllvm", Args.MakeArgStringRef(ArgStr)});
6576*e038c9c4Sjoerg }
6577*e038c9c4Sjoerg }
6578*e038c9c4Sjoerg
65797330f729Sjoerg // OpenMP offloading device jobs take the argument -fopenmp-host-ir-file-path
65807330f729Sjoerg // to specify the result of the compile phase on the host, so the meaningful
65817330f729Sjoerg // device declarations can be identified. Also, -fopenmp-is-device is passed
65827330f729Sjoerg // along to tell the frontend that it is generating code for a device, so that
65837330f729Sjoerg // only the relevant declarations are emitted.
65847330f729Sjoerg if (IsOpenMPDevice) {
65857330f729Sjoerg CmdArgs.push_back("-fopenmp-is-device");
65867330f729Sjoerg if (OpenMPDeviceInput) {
65877330f729Sjoerg CmdArgs.push_back("-fopenmp-host-ir-file-path");
65887330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(OpenMPDeviceInput->getFilename()));
65897330f729Sjoerg }
65907330f729Sjoerg }
65917330f729Sjoerg
6592*e038c9c4Sjoerg if (Triple.isAMDGPU()) {
6593*e038c9c4Sjoerg handleAMDGPUCodeObjectVersionOptions(D, Args, CmdArgs);
6594*e038c9c4Sjoerg
6595*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_munsafe_fp_atomics,
6596*e038c9c4Sjoerg options::OPT_mno_unsafe_fp_atomics, /*Default=*/false))
6597*e038c9c4Sjoerg CmdArgs.push_back("-munsafe-fp-atomics");
6598*e038c9c4Sjoerg }
6599*e038c9c4Sjoerg
66007330f729Sjoerg // For all the host OpenMP offloading compile jobs we need to pass the targets
66017330f729Sjoerg // information using -fopenmp-targets= option.
66027330f729Sjoerg if (JA.isHostOffloading(Action::OFK_OpenMP)) {
66037330f729Sjoerg SmallString<128> TargetInfo("-fopenmp-targets=");
66047330f729Sjoerg
66057330f729Sjoerg Arg *Tgts = Args.getLastArg(options::OPT_fopenmp_targets_EQ);
66067330f729Sjoerg assert(Tgts && Tgts->getNumValues() &&
66077330f729Sjoerg "OpenMP offloading has to have targets specified.");
66087330f729Sjoerg for (unsigned i = 0; i < Tgts->getNumValues(); ++i) {
66097330f729Sjoerg if (i)
66107330f729Sjoerg TargetInfo += ',';
66117330f729Sjoerg // We need to get the string from the triple because it may be not exactly
66127330f729Sjoerg // the same as the one we get directly from the arguments.
66137330f729Sjoerg llvm::Triple T(Tgts->getValue(i));
66147330f729Sjoerg TargetInfo += T.getTriple();
66157330f729Sjoerg }
66167330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(TargetInfo.str()));
66177330f729Sjoerg }
66187330f729Sjoerg
66197330f729Sjoerg bool VirtualFunctionElimination =
66207330f729Sjoerg Args.hasFlag(options::OPT_fvirtual_function_elimination,
66217330f729Sjoerg options::OPT_fno_virtual_function_elimination, false);
66227330f729Sjoerg if (VirtualFunctionElimination) {
66237330f729Sjoerg // VFE requires full LTO (currently, this might be relaxed to allow ThinLTO
66247330f729Sjoerg // in the future).
6625*e038c9c4Sjoerg if (LTOMode != LTOK_Full)
66267330f729Sjoerg D.Diag(diag::err_drv_argument_only_allowed_with)
66277330f729Sjoerg << "-fvirtual-function-elimination"
66287330f729Sjoerg << "-flto=full";
66297330f729Sjoerg
66307330f729Sjoerg CmdArgs.push_back("-fvirtual-function-elimination");
66317330f729Sjoerg }
66327330f729Sjoerg
66337330f729Sjoerg // VFE requires whole-program-vtables, and enables it by default.
66347330f729Sjoerg bool WholeProgramVTables = Args.hasFlag(
66357330f729Sjoerg options::OPT_fwhole_program_vtables,
66367330f729Sjoerg options::OPT_fno_whole_program_vtables, VirtualFunctionElimination);
66377330f729Sjoerg if (VirtualFunctionElimination && !WholeProgramVTables) {
66387330f729Sjoerg D.Diag(diag::err_drv_argument_not_allowed_with)
66397330f729Sjoerg << "-fno-whole-program-vtables"
66407330f729Sjoerg << "-fvirtual-function-elimination";
66417330f729Sjoerg }
66427330f729Sjoerg
66437330f729Sjoerg if (WholeProgramVTables) {
6644*e038c9c4Sjoerg if (!IsUsingLTO)
66457330f729Sjoerg D.Diag(diag::err_drv_argument_only_allowed_with)
66467330f729Sjoerg << "-fwhole-program-vtables"
66477330f729Sjoerg << "-flto";
66487330f729Sjoerg CmdArgs.push_back("-fwhole-program-vtables");
66497330f729Sjoerg }
66507330f729Sjoerg
66517330f729Sjoerg bool DefaultsSplitLTOUnit =
66527330f729Sjoerg (WholeProgramVTables || Sanitize.needsLTO()) &&
6653*e038c9c4Sjoerg (LTOMode == LTOK_Full || TC.canSplitThinLTOUnit());
66547330f729Sjoerg bool SplitLTOUnit =
66557330f729Sjoerg Args.hasFlag(options::OPT_fsplit_lto_unit,
66567330f729Sjoerg options::OPT_fno_split_lto_unit, DefaultsSplitLTOUnit);
66577330f729Sjoerg if (Sanitize.needsLTO() && !SplitLTOUnit)
66587330f729Sjoerg D.Diag(diag::err_drv_argument_not_allowed_with) << "-fno-split-lto-unit"
66597330f729Sjoerg << "-fsanitize=cfi";
66607330f729Sjoerg if (SplitLTOUnit)
66617330f729Sjoerg CmdArgs.push_back("-fsplit-lto-unit");
66627330f729Sjoerg
6663*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fglobal_isel,
6664*e038c9c4Sjoerg options::OPT_fno_global_isel)) {
66657330f729Sjoerg CmdArgs.push_back("-mllvm");
6666*e038c9c4Sjoerg if (A->getOption().matches(options::OPT_fglobal_isel)) {
66677330f729Sjoerg CmdArgs.push_back("-global-isel=1");
66687330f729Sjoerg
66697330f729Sjoerg // GISel is on by default on AArch64 -O0, so don't bother adding
66707330f729Sjoerg // the fallback remarks for it. Other combinations will add a warning of
66717330f729Sjoerg // some kind.
66727330f729Sjoerg bool IsArchSupported = Triple.getArch() == llvm::Triple::aarch64;
66737330f729Sjoerg bool IsOptLevelSupported = false;
66747330f729Sjoerg
66757330f729Sjoerg Arg *A = Args.getLastArg(options::OPT_O_Group);
66767330f729Sjoerg if (Triple.getArch() == llvm::Triple::aarch64) {
66777330f729Sjoerg if (!A || A->getOption().matches(options::OPT_O0))
66787330f729Sjoerg IsOptLevelSupported = true;
66797330f729Sjoerg }
66807330f729Sjoerg if (!IsArchSupported || !IsOptLevelSupported) {
66817330f729Sjoerg CmdArgs.push_back("-mllvm");
66827330f729Sjoerg CmdArgs.push_back("-global-isel-abort=2");
66837330f729Sjoerg
66847330f729Sjoerg if (!IsArchSupported)
6685*e038c9c4Sjoerg D.Diag(diag::warn_drv_global_isel_incomplete) << Triple.getArchName();
66867330f729Sjoerg else
6687*e038c9c4Sjoerg D.Diag(diag::warn_drv_global_isel_incomplete_opt);
66887330f729Sjoerg }
66897330f729Sjoerg } else {
66907330f729Sjoerg CmdArgs.push_back("-global-isel=0");
66917330f729Sjoerg }
66927330f729Sjoerg }
66937330f729Sjoerg
66947330f729Sjoerg if (Args.hasArg(options::OPT_forder_file_instrumentation)) {
66957330f729Sjoerg CmdArgs.push_back("-forder-file-instrumentation");
66967330f729Sjoerg // Enable order file instrumentation when ThinLTO is not on. When ThinLTO is
66977330f729Sjoerg // on, we need to pass these flags as linker flags and that will be handled
66987330f729Sjoerg // outside of the compiler.
6699*e038c9c4Sjoerg if (!IsUsingLTO) {
67007330f729Sjoerg CmdArgs.push_back("-mllvm");
67017330f729Sjoerg CmdArgs.push_back("-enable-order-file-instrumentation");
67027330f729Sjoerg }
67037330f729Sjoerg }
67047330f729Sjoerg
67057330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fforce_enable_int128,
67067330f729Sjoerg options::OPT_fno_force_enable_int128)) {
67077330f729Sjoerg if (A->getOption().matches(options::OPT_fforce_enable_int128))
67087330f729Sjoerg CmdArgs.push_back("-fforce-enable-int128");
67097330f729Sjoerg }
67107330f729Sjoerg
6711*e038c9c4Sjoerg if (Args.hasFlag(options::OPT_fkeep_static_consts,
6712*e038c9c4Sjoerg options::OPT_fno_keep_static_consts, false))
6713*e038c9c4Sjoerg CmdArgs.push_back("-fkeep-static-consts");
6714*e038c9c4Sjoerg
67157330f729Sjoerg if (Args.hasFlag(options::OPT_fcomplete_member_pointers,
67167330f729Sjoerg options::OPT_fno_complete_member_pointers, false))
67177330f729Sjoerg CmdArgs.push_back("-fcomplete-member-pointers");
67187330f729Sjoerg
67197330f729Sjoerg if (!Args.hasFlag(options::OPT_fcxx_static_destructors,
67207330f729Sjoerg options::OPT_fno_cxx_static_destructors, true))
67217330f729Sjoerg CmdArgs.push_back("-fno-c++-static-destructors");
67227330f729Sjoerg
6723*e038c9c4Sjoerg addMachineOutlinerArgs(D, Args, CmdArgs, Triple, /*IsLTO=*/false);
6724*e038c9c4Sjoerg
6725*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_moutline_atomics,
6726*e038c9c4Sjoerg options::OPT_mno_outline_atomics)) {
6727*e038c9c4Sjoerg if (A->getOption().matches(options::OPT_moutline_atomics)) {
6728*e038c9c4Sjoerg // Option -moutline-atomics supported for AArch64 target only.
6729*e038c9c4Sjoerg if (!Triple.isAArch64()) {
6730*e038c9c4Sjoerg D.Diag(diag::warn_drv_moutline_atomics_unsupported_opt)
6731*e038c9c4Sjoerg << Triple.getArchName();
67327330f729Sjoerg } else {
6733*e038c9c4Sjoerg CmdArgs.push_back("-target-feature");
6734*e038c9c4Sjoerg CmdArgs.push_back("+outline-atomics");
67357330f729Sjoerg }
67367330f729Sjoerg } else {
6737*e038c9c4Sjoerg CmdArgs.push_back("-target-feature");
6738*e038c9c4Sjoerg CmdArgs.push_back("-outline-atomics");
67397330f729Sjoerg }
6740*e038c9c4Sjoerg } else if (Triple.isAArch64() &&
6741*e038c9c4Sjoerg getToolChain().IsAArch64OutlineAtomicsDefault(Args)) {
6742*e038c9c4Sjoerg CmdArgs.push_back("-target-feature");
6743*e038c9c4Sjoerg CmdArgs.push_back("+outline-atomics");
67447330f729Sjoerg }
67457330f729Sjoerg
67467330f729Sjoerg if (Args.hasFlag(options::OPT_faddrsig, options::OPT_fno_addrsig,
67477330f729Sjoerg (TC.getTriple().isOSBinFormatELF() ||
67487330f729Sjoerg TC.getTriple().isOSBinFormatCOFF()) &&
6749*e038c9c4Sjoerg !TC.getTriple().isPS4() && !TC.getTriple().isVE() &&
67507330f729Sjoerg !TC.getTriple().isOSNetBSD() &&
6751*e038c9c4Sjoerg !Distro(D.getVFS(), TC.getTriple()).IsGentoo() &&
6752*e038c9c4Sjoerg !TC.getTriple().isAndroid() && TC.useIntegratedAs()))
67537330f729Sjoerg CmdArgs.push_back("-faddrsig");
67547330f729Sjoerg
6755*e038c9c4Sjoerg if ((Triple.isOSBinFormatELF() || Triple.isOSBinFormatMachO()) &&
6756*e038c9c4Sjoerg (EH || UnwindTables || DebugInfoKind != codegenoptions::NoDebugInfo))
6757*e038c9c4Sjoerg CmdArgs.push_back("-D__GCC_HAVE_DWARF2_CFI_ASM=1");
6758*e038c9c4Sjoerg
67597330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_fsymbol_partition_EQ)) {
67607330f729Sjoerg std::string Str = A->getAsString(Args);
67617330f729Sjoerg if (!TC.getTriple().isOSBinFormatELF())
67627330f729Sjoerg D.Diag(diag::err_drv_unsupported_opt_for_target)
67637330f729Sjoerg << Str << TC.getTripleString();
67647330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(Str));
67657330f729Sjoerg }
67667330f729Sjoerg
67677330f729Sjoerg // Add the "-o out -x type src.c" flags last. This is done primarily to make
67687330f729Sjoerg // the -cc1 command easier to edit when reproducing compiler crashes.
67697330f729Sjoerg if (Output.getType() == types::TY_Dependencies) {
67707330f729Sjoerg // Handled with other dependency code.
67717330f729Sjoerg } else if (Output.isFilename()) {
6772*e038c9c4Sjoerg if (Output.getType() == clang::driver::types::TY_IFS_CPP ||
6773*e038c9c4Sjoerg Output.getType() == clang::driver::types::TY_IFS) {
6774*e038c9c4Sjoerg SmallString<128> OutputFilename(Output.getFilename());
6775*e038c9c4Sjoerg llvm::sys::path::replace_extension(OutputFilename, "ifs");
6776*e038c9c4Sjoerg CmdArgs.push_back("-o");
6777*e038c9c4Sjoerg CmdArgs.push_back(Args.MakeArgString(OutputFilename));
6778*e038c9c4Sjoerg } else {
67797330f729Sjoerg CmdArgs.push_back("-o");
67807330f729Sjoerg CmdArgs.push_back(Output.getFilename());
6781*e038c9c4Sjoerg }
67827330f729Sjoerg } else {
67837330f729Sjoerg assert(Output.isNothing() && "Invalid output.");
67847330f729Sjoerg }
67857330f729Sjoerg
67867330f729Sjoerg addDashXForInput(Args, Input, CmdArgs);
67877330f729Sjoerg
67887330f729Sjoerg ArrayRef<InputInfo> FrontendInputs = Input;
67897330f729Sjoerg if (IsHeaderModulePrecompile)
67907330f729Sjoerg FrontendInputs = ModuleHeaderInputs;
67917330f729Sjoerg else if (Input.isNothing())
67927330f729Sjoerg FrontendInputs = {};
67937330f729Sjoerg
67947330f729Sjoerg for (const InputInfo &Input : FrontendInputs) {
67957330f729Sjoerg if (Input.isFilename())
67967330f729Sjoerg CmdArgs.push_back(Input.getFilename());
67977330f729Sjoerg else
67987330f729Sjoerg Input.getInputArg().renderAsInput(Args, CmdArgs);
67997330f729Sjoerg }
68007330f729Sjoerg
6801*e038c9c4Sjoerg if (D.CC1Main && !D.CCGenDiagnostics) {
6802*e038c9c4Sjoerg // Invoke the CC1 directly in this process
6803*e038c9c4Sjoerg C.addCommand(std::make_unique<CC1Command>(JA, *this,
6804*e038c9c4Sjoerg ResponseFileSupport::AtFileUTF8(),
6805*e038c9c4Sjoerg Exec, CmdArgs, Inputs, Output));
68067330f729Sjoerg } else {
6807*e038c9c4Sjoerg C.addCommand(std::make_unique<Command>(JA, *this,
6808*e038c9c4Sjoerg ResponseFileSupport::AtFileUTF8(),
6809*e038c9c4Sjoerg Exec, CmdArgs, Inputs, Output));
68107330f729Sjoerg }
68117330f729Sjoerg
68127330f729Sjoerg // Make the compile command echo its inputs for /showFilenames.
68137330f729Sjoerg if (Output.getType() == types::TY_Object &&
68147330f729Sjoerg Args.hasFlag(options::OPT__SLASH_showFilenames,
68157330f729Sjoerg options::OPT__SLASH_showFilenames_, false)) {
6816*e038c9c4Sjoerg C.getJobs().getJobs().back()->PrintInputFilenames = true;
68177330f729Sjoerg }
68187330f729Sjoerg
68197330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_pg))
6820*e038c9c4Sjoerg if (FPKeepKind == CodeGenOptions::FramePointerKind::None &&
6821*e038c9c4Sjoerg !Args.hasArg(options::OPT_mfentry))
68227330f729Sjoerg D.Diag(diag::err_drv_argument_not_allowed_with) << "-fomit-frame-pointer"
68237330f729Sjoerg << A->getAsString(Args);
68247330f729Sjoerg
68257330f729Sjoerg // Claim some arguments which clang supports automatically.
68267330f729Sjoerg
68277330f729Sjoerg // -fpch-preprocess is used with gcc to add a special marker in the output to
68287330f729Sjoerg // include the PCH file.
68297330f729Sjoerg Args.ClaimAllArgs(options::OPT_fpch_preprocess);
68307330f729Sjoerg
68317330f729Sjoerg // Claim some arguments which clang doesn't support, but we don't
68327330f729Sjoerg // care to warn the user about.
68337330f729Sjoerg Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group);
68347330f729Sjoerg Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group);
68357330f729Sjoerg
68367330f729Sjoerg // Disable warnings for clang -E -emit-llvm foo.c
68377330f729Sjoerg Args.ClaimAllArgs(options::OPT_emit_llvm);
68387330f729Sjoerg }
68397330f729Sjoerg
Clang(const ToolChain & TC)68407330f729Sjoerg Clang::Clang(const ToolChain &TC)
68417330f729Sjoerg // CAUTION! The first constructor argument ("clang") is not arbitrary,
68427330f729Sjoerg // as it is for other tools. Some operations on a Tool actually test
68437330f729Sjoerg // whether that tool is Clang based on the Tool's Name as a string.
6844*e038c9c4Sjoerg : Tool("clang", "clang frontend", TC) {}
68457330f729Sjoerg
~Clang()68467330f729Sjoerg Clang::~Clang() {}
68477330f729Sjoerg
68487330f729Sjoerg /// Add options related to the Objective-C runtime/ABI.
68497330f729Sjoerg ///
68507330f729Sjoerg /// Returns true if the runtime is non-fragile.
AddObjCRuntimeArgs(const ArgList & args,const InputInfoList & inputs,ArgStringList & cmdArgs,RewriteKind rewriteKind) const68517330f729Sjoerg ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
6852*e038c9c4Sjoerg const InputInfoList &inputs,
68537330f729Sjoerg ArgStringList &cmdArgs,
68547330f729Sjoerg RewriteKind rewriteKind) const {
68557330f729Sjoerg // Look for the controlling runtime option.
68567330f729Sjoerg Arg *runtimeArg =
68577330f729Sjoerg args.getLastArg(options::OPT_fnext_runtime, options::OPT_fgnu_runtime,
68587330f729Sjoerg options::OPT_fobjc_runtime_EQ);
68597330f729Sjoerg
68607330f729Sjoerg // Just forward -fobjc-runtime= to the frontend. This supercedes
68617330f729Sjoerg // options about fragility.
68627330f729Sjoerg if (runtimeArg &&
68637330f729Sjoerg runtimeArg->getOption().matches(options::OPT_fobjc_runtime_EQ)) {
68647330f729Sjoerg ObjCRuntime runtime;
68657330f729Sjoerg StringRef value = runtimeArg->getValue();
68667330f729Sjoerg if (runtime.tryParse(value)) {
68677330f729Sjoerg getToolChain().getDriver().Diag(diag::err_drv_unknown_objc_runtime)
68687330f729Sjoerg << value;
68697330f729Sjoerg }
68707330f729Sjoerg if ((runtime.getKind() == ObjCRuntime::GNUstep) &&
68717330f729Sjoerg (runtime.getVersion() >= VersionTuple(2, 0)))
68727330f729Sjoerg if (!getToolChain().getTriple().isOSBinFormatELF() &&
68737330f729Sjoerg !getToolChain().getTriple().isOSBinFormatCOFF()) {
68747330f729Sjoerg getToolChain().getDriver().Diag(
68757330f729Sjoerg diag::err_drv_gnustep_objc_runtime_incompatible_binary)
68767330f729Sjoerg << runtime.getVersion().getMajor();
68777330f729Sjoerg }
68787330f729Sjoerg
68797330f729Sjoerg runtimeArg->render(args, cmdArgs);
68807330f729Sjoerg return runtime;
68817330f729Sjoerg }
68827330f729Sjoerg
68837330f729Sjoerg // Otherwise, we'll need the ABI "version". Version numbers are
68847330f729Sjoerg // slightly confusing for historical reasons:
68857330f729Sjoerg // 1 - Traditional "fragile" ABI
68867330f729Sjoerg // 2 - Non-fragile ABI, version 1
68877330f729Sjoerg // 3 - Non-fragile ABI, version 2
68887330f729Sjoerg unsigned objcABIVersion = 1;
68897330f729Sjoerg // If -fobjc-abi-version= is present, use that to set the version.
68907330f729Sjoerg if (Arg *abiArg = args.getLastArg(options::OPT_fobjc_abi_version_EQ)) {
68917330f729Sjoerg StringRef value = abiArg->getValue();
68927330f729Sjoerg if (value == "1")
68937330f729Sjoerg objcABIVersion = 1;
68947330f729Sjoerg else if (value == "2")
68957330f729Sjoerg objcABIVersion = 2;
68967330f729Sjoerg else if (value == "3")
68977330f729Sjoerg objcABIVersion = 3;
68987330f729Sjoerg else
68997330f729Sjoerg getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) << value;
69007330f729Sjoerg } else {
69017330f729Sjoerg // Otherwise, determine if we are using the non-fragile ABI.
69027330f729Sjoerg bool nonFragileABIIsDefault =
69037330f729Sjoerg (rewriteKind == RK_NonFragile ||
69047330f729Sjoerg (rewriteKind == RK_None &&
69057330f729Sjoerg getToolChain().IsObjCNonFragileABIDefault()));
69067330f729Sjoerg if (args.hasFlag(options::OPT_fobjc_nonfragile_abi,
69077330f729Sjoerg options::OPT_fno_objc_nonfragile_abi,
69087330f729Sjoerg nonFragileABIIsDefault)) {
69097330f729Sjoerg // Determine the non-fragile ABI version to use.
69107330f729Sjoerg #ifdef DISABLE_DEFAULT_NONFRAGILEABI_TWO
69117330f729Sjoerg unsigned nonFragileABIVersion = 1;
69127330f729Sjoerg #else
69137330f729Sjoerg unsigned nonFragileABIVersion = 2;
69147330f729Sjoerg #endif
69157330f729Sjoerg
69167330f729Sjoerg if (Arg *abiArg =
69177330f729Sjoerg args.getLastArg(options::OPT_fobjc_nonfragile_abi_version_EQ)) {
69187330f729Sjoerg StringRef value = abiArg->getValue();
69197330f729Sjoerg if (value == "1")
69207330f729Sjoerg nonFragileABIVersion = 1;
69217330f729Sjoerg else if (value == "2")
69227330f729Sjoerg nonFragileABIVersion = 2;
69237330f729Sjoerg else
69247330f729Sjoerg getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
69257330f729Sjoerg << value;
69267330f729Sjoerg }
69277330f729Sjoerg
69287330f729Sjoerg objcABIVersion = 1 + nonFragileABIVersion;
69297330f729Sjoerg } else {
69307330f729Sjoerg objcABIVersion = 1;
69317330f729Sjoerg }
69327330f729Sjoerg }
69337330f729Sjoerg
69347330f729Sjoerg // We don't actually care about the ABI version other than whether
69357330f729Sjoerg // it's non-fragile.
69367330f729Sjoerg bool isNonFragile = objcABIVersion != 1;
69377330f729Sjoerg
69387330f729Sjoerg // If we have no runtime argument, ask the toolchain for its default runtime.
69397330f729Sjoerg // However, the rewriter only really supports the Mac runtime, so assume that.
69407330f729Sjoerg ObjCRuntime runtime;
69417330f729Sjoerg if (!runtimeArg) {
69427330f729Sjoerg switch (rewriteKind) {
69437330f729Sjoerg case RK_None:
69447330f729Sjoerg runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
69457330f729Sjoerg break;
69467330f729Sjoerg case RK_Fragile:
69477330f729Sjoerg runtime = ObjCRuntime(ObjCRuntime::FragileMacOSX, VersionTuple());
69487330f729Sjoerg break;
69497330f729Sjoerg case RK_NonFragile:
69507330f729Sjoerg runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
69517330f729Sjoerg break;
69527330f729Sjoerg }
69537330f729Sjoerg
69547330f729Sjoerg // -fnext-runtime
69557330f729Sjoerg } else if (runtimeArg->getOption().matches(options::OPT_fnext_runtime)) {
69567330f729Sjoerg // On Darwin, make this use the default behavior for the toolchain.
69577330f729Sjoerg if (getToolChain().getTriple().isOSDarwin()) {
69587330f729Sjoerg runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
69597330f729Sjoerg
69607330f729Sjoerg // Otherwise, build for a generic macosx port.
69617330f729Sjoerg } else {
69627330f729Sjoerg runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
69637330f729Sjoerg }
69647330f729Sjoerg
69657330f729Sjoerg // -fgnu-runtime
69667330f729Sjoerg } else {
69677330f729Sjoerg assert(runtimeArg->getOption().matches(options::OPT_fgnu_runtime));
69687330f729Sjoerg // Legacy behaviour is to target the gnustep runtime if we are in
69697330f729Sjoerg // non-fragile mode or the GCC runtime in fragile mode.
69707330f729Sjoerg if (isNonFragile)
69717330f729Sjoerg runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(2, 0));
69727330f729Sjoerg else
69737330f729Sjoerg runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple());
69747330f729Sjoerg }
69757330f729Sjoerg
6976*e038c9c4Sjoerg if (llvm::any_of(inputs, [](const InputInfo &input) {
6977*e038c9c4Sjoerg return types::isObjC(input.getType());
6978*e038c9c4Sjoerg }))
69797330f729Sjoerg cmdArgs.push_back(
69807330f729Sjoerg args.MakeArgString("-fobjc-runtime=" + runtime.getAsString()));
69817330f729Sjoerg return runtime;
69827330f729Sjoerg }
69837330f729Sjoerg
maybeConsumeDash(const std::string & EH,size_t & I)69847330f729Sjoerg static bool maybeConsumeDash(const std::string &EH, size_t &I) {
69857330f729Sjoerg bool HaveDash = (I + 1 < EH.size() && EH[I + 1] == '-');
69867330f729Sjoerg I += HaveDash;
69877330f729Sjoerg return !HaveDash;
69887330f729Sjoerg }
69897330f729Sjoerg
69907330f729Sjoerg namespace {
69917330f729Sjoerg struct EHFlags {
69927330f729Sjoerg bool Synch = false;
69937330f729Sjoerg bool Asynch = false;
69947330f729Sjoerg bool NoUnwindC = false;
69957330f729Sjoerg };
69967330f729Sjoerg } // end anonymous namespace
69977330f729Sjoerg
69987330f729Sjoerg /// /EH controls whether to run destructor cleanups when exceptions are
69997330f729Sjoerg /// thrown. There are three modifiers:
70007330f729Sjoerg /// - s: Cleanup after "synchronous" exceptions, aka C++ exceptions.
70017330f729Sjoerg /// - a: Cleanup after "asynchronous" exceptions, aka structured exceptions.
70027330f729Sjoerg /// The 'a' modifier is unimplemented and fundamentally hard in LLVM IR.
70037330f729Sjoerg /// - c: Assume that extern "C" functions are implicitly nounwind.
70047330f729Sjoerg /// The default is /EHs-c-, meaning cleanups are disabled.
parseClangCLEHFlags(const Driver & D,const ArgList & Args)70057330f729Sjoerg static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) {
70067330f729Sjoerg EHFlags EH;
70077330f729Sjoerg
70087330f729Sjoerg std::vector<std::string> EHArgs =
70097330f729Sjoerg Args.getAllArgValues(options::OPT__SLASH_EH);
70107330f729Sjoerg for (auto EHVal : EHArgs) {
70117330f729Sjoerg for (size_t I = 0, E = EHVal.size(); I != E; ++I) {
70127330f729Sjoerg switch (EHVal[I]) {
70137330f729Sjoerg case 'a':
70147330f729Sjoerg EH.Asynch = maybeConsumeDash(EHVal, I);
70157330f729Sjoerg if (EH.Asynch)
70167330f729Sjoerg EH.Synch = false;
70177330f729Sjoerg continue;
70187330f729Sjoerg case 'c':
70197330f729Sjoerg EH.NoUnwindC = maybeConsumeDash(EHVal, I);
70207330f729Sjoerg continue;
70217330f729Sjoerg case 's':
70227330f729Sjoerg EH.Synch = maybeConsumeDash(EHVal, I);
70237330f729Sjoerg if (EH.Synch)
70247330f729Sjoerg EH.Asynch = false;
70257330f729Sjoerg continue;
70267330f729Sjoerg default:
70277330f729Sjoerg break;
70287330f729Sjoerg }
70297330f729Sjoerg D.Diag(clang::diag::err_drv_invalid_value) << "/EH" << EHVal;
70307330f729Sjoerg break;
70317330f729Sjoerg }
70327330f729Sjoerg }
70337330f729Sjoerg // The /GX, /GX- flags are only processed if there are not /EH flags.
70347330f729Sjoerg // The default is that /GX is not specified.
70357330f729Sjoerg if (EHArgs.empty() &&
70367330f729Sjoerg Args.hasFlag(options::OPT__SLASH_GX, options::OPT__SLASH_GX_,
70377330f729Sjoerg /*Default=*/false)) {
70387330f729Sjoerg EH.Synch = true;
70397330f729Sjoerg EH.NoUnwindC = true;
70407330f729Sjoerg }
70417330f729Sjoerg
70427330f729Sjoerg return EH;
70437330f729Sjoerg }
70447330f729Sjoerg
AddClangCLArgs(const ArgList & Args,types::ID InputType,ArgStringList & CmdArgs,codegenoptions::DebugInfoKind * DebugInfoKind,bool * EmitCodeView) const70457330f729Sjoerg void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
70467330f729Sjoerg ArgStringList &CmdArgs,
70477330f729Sjoerg codegenoptions::DebugInfoKind *DebugInfoKind,
70487330f729Sjoerg bool *EmitCodeView) const {
70497330f729Sjoerg unsigned RTOptionID = options::OPT__SLASH_MT;
7050*e038c9c4Sjoerg bool isNVPTX = getToolChain().getTriple().isNVPTX();
70517330f729Sjoerg
70527330f729Sjoerg if (Args.hasArg(options::OPT__SLASH_LDd))
70537330f729Sjoerg // The /LDd option implies /MTd. The dependent lib part can be overridden,
70547330f729Sjoerg // but defining _DEBUG is sticky.
70557330f729Sjoerg RTOptionID = options::OPT__SLASH_MTd;
70567330f729Sjoerg
70577330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group))
70587330f729Sjoerg RTOptionID = A->getOption().getID();
70597330f729Sjoerg
70607330f729Sjoerg StringRef FlagForCRT;
70617330f729Sjoerg switch (RTOptionID) {
70627330f729Sjoerg case options::OPT__SLASH_MD:
70637330f729Sjoerg if (Args.hasArg(options::OPT__SLASH_LDd))
70647330f729Sjoerg CmdArgs.push_back("-D_DEBUG");
70657330f729Sjoerg CmdArgs.push_back("-D_MT");
70667330f729Sjoerg CmdArgs.push_back("-D_DLL");
70677330f729Sjoerg FlagForCRT = "--dependent-lib=msvcrt";
70687330f729Sjoerg break;
70697330f729Sjoerg case options::OPT__SLASH_MDd:
70707330f729Sjoerg CmdArgs.push_back("-D_DEBUG");
70717330f729Sjoerg CmdArgs.push_back("-D_MT");
70727330f729Sjoerg CmdArgs.push_back("-D_DLL");
70737330f729Sjoerg FlagForCRT = "--dependent-lib=msvcrtd";
70747330f729Sjoerg break;
70757330f729Sjoerg case options::OPT__SLASH_MT:
70767330f729Sjoerg if (Args.hasArg(options::OPT__SLASH_LDd))
70777330f729Sjoerg CmdArgs.push_back("-D_DEBUG");
70787330f729Sjoerg CmdArgs.push_back("-D_MT");
70797330f729Sjoerg CmdArgs.push_back("-flto-visibility-public-std");
70807330f729Sjoerg FlagForCRT = "--dependent-lib=libcmt";
70817330f729Sjoerg break;
70827330f729Sjoerg case options::OPT__SLASH_MTd:
70837330f729Sjoerg CmdArgs.push_back("-D_DEBUG");
70847330f729Sjoerg CmdArgs.push_back("-D_MT");
70857330f729Sjoerg CmdArgs.push_back("-flto-visibility-public-std");
70867330f729Sjoerg FlagForCRT = "--dependent-lib=libcmtd";
70877330f729Sjoerg break;
70887330f729Sjoerg default:
70897330f729Sjoerg llvm_unreachable("Unexpected option ID.");
70907330f729Sjoerg }
70917330f729Sjoerg
70927330f729Sjoerg if (Args.hasArg(options::OPT__SLASH_Zl)) {
70937330f729Sjoerg CmdArgs.push_back("-D_VC_NODEFAULTLIB");
70947330f729Sjoerg } else {
70957330f729Sjoerg CmdArgs.push_back(FlagForCRT.data());
70967330f729Sjoerg
70977330f729Sjoerg // This provides POSIX compatibility (maps 'open' to '_open'), which most
70987330f729Sjoerg // users want. The /Za flag to cl.exe turns this off, but it's not
70997330f729Sjoerg // implemented in clang.
71007330f729Sjoerg CmdArgs.push_back("--dependent-lib=oldnames");
71017330f729Sjoerg }
71027330f729Sjoerg
7103*e038c9c4Sjoerg if (Arg *ShowIncludes =
7104*e038c9c4Sjoerg Args.getLastArg(options::OPT__SLASH_showIncludes,
7105*e038c9c4Sjoerg options::OPT__SLASH_showIncludes_user)) {
7106*e038c9c4Sjoerg CmdArgs.push_back("--show-includes");
7107*e038c9c4Sjoerg if (ShowIncludes->getOption().matches(options::OPT__SLASH_showIncludes))
7108*e038c9c4Sjoerg CmdArgs.push_back("-sys-header-deps");
7109*e038c9c4Sjoerg }
71107330f729Sjoerg
71117330f729Sjoerg // This controls whether or not we emit RTTI data for polymorphic types.
71127330f729Sjoerg if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
71137330f729Sjoerg /*Default=*/false))
71147330f729Sjoerg CmdArgs.push_back("-fno-rtti-data");
71157330f729Sjoerg
71167330f729Sjoerg // This controls whether or not we emit stack-protector instrumentation.
71177330f729Sjoerg // In MSVC, Buffer Security Check (/GS) is on by default.
7118*e038c9c4Sjoerg if (!isNVPTX && Args.hasFlag(options::OPT__SLASH_GS, options::OPT__SLASH_GS_,
71197330f729Sjoerg /*Default=*/true)) {
71207330f729Sjoerg CmdArgs.push_back("-stack-protector");
71217330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(Twine(LangOptions::SSPStrong)));
71227330f729Sjoerg }
71237330f729Sjoerg
7124*e038c9c4Sjoerg // Emit CodeView if -Z7 or -gline-tables-only are present.
7125*e038c9c4Sjoerg if (Arg *DebugInfoArg = Args.getLastArg(options::OPT__SLASH_Z7,
71267330f729Sjoerg options::OPT_gline_tables_only)) {
71277330f729Sjoerg *EmitCodeView = true;
71287330f729Sjoerg if (DebugInfoArg->getOption().matches(options::OPT__SLASH_Z7))
71297330f729Sjoerg *DebugInfoKind = codegenoptions::LimitedDebugInfo;
71307330f729Sjoerg else
71317330f729Sjoerg *DebugInfoKind = codegenoptions::DebugLineTablesOnly;
71327330f729Sjoerg } else {
71337330f729Sjoerg *EmitCodeView = false;
71347330f729Sjoerg }
71357330f729Sjoerg
71367330f729Sjoerg const Driver &D = getToolChain().getDriver();
71377330f729Sjoerg EHFlags EH = parseClangCLEHFlags(D, Args);
7138*e038c9c4Sjoerg if (!isNVPTX && (EH.Synch || EH.Asynch)) {
71397330f729Sjoerg if (types::isCXX(InputType))
71407330f729Sjoerg CmdArgs.push_back("-fcxx-exceptions");
71417330f729Sjoerg CmdArgs.push_back("-fexceptions");
7142*e038c9c4Sjoerg if (EH.Asynch)
7143*e038c9c4Sjoerg CmdArgs.push_back("-fasync-exceptions");
71447330f729Sjoerg }
71457330f729Sjoerg if (types::isCXX(InputType) && EH.Synch && EH.NoUnwindC)
71467330f729Sjoerg CmdArgs.push_back("-fexternc-nounwind");
71477330f729Sjoerg
71487330f729Sjoerg // /EP should expand to -E -P.
71497330f729Sjoerg if (Args.hasArg(options::OPT__SLASH_EP)) {
71507330f729Sjoerg CmdArgs.push_back("-E");
71517330f729Sjoerg CmdArgs.push_back("-P");
71527330f729Sjoerg }
71537330f729Sjoerg
71547330f729Sjoerg unsigned VolatileOptionID;
7155*e038c9c4Sjoerg if (getToolChain().getTriple().isX86())
71567330f729Sjoerg VolatileOptionID = options::OPT__SLASH_volatile_ms;
71577330f729Sjoerg else
71587330f729Sjoerg VolatileOptionID = options::OPT__SLASH_volatile_iso;
71597330f729Sjoerg
71607330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT__SLASH_volatile_Group))
71617330f729Sjoerg VolatileOptionID = A->getOption().getID();
71627330f729Sjoerg
71637330f729Sjoerg if (VolatileOptionID == options::OPT__SLASH_volatile_ms)
71647330f729Sjoerg CmdArgs.push_back("-fms-volatile");
71657330f729Sjoerg
71667330f729Sjoerg if (Args.hasFlag(options::OPT__SLASH_Zc_dllexportInlines_,
71677330f729Sjoerg options::OPT__SLASH_Zc_dllexportInlines,
71687330f729Sjoerg false)) {
71697330f729Sjoerg CmdArgs.push_back("-fno-dllexport-inlines");
71707330f729Sjoerg }
71717330f729Sjoerg
71727330f729Sjoerg Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg);
71737330f729Sjoerg Arg *BestCaseArg = Args.getLastArg(options::OPT__SLASH_vmb);
71747330f729Sjoerg if (MostGeneralArg && BestCaseArg)
71757330f729Sjoerg D.Diag(clang::diag::err_drv_argument_not_allowed_with)
71767330f729Sjoerg << MostGeneralArg->getAsString(Args) << BestCaseArg->getAsString(Args);
71777330f729Sjoerg
71787330f729Sjoerg if (MostGeneralArg) {
71797330f729Sjoerg Arg *SingleArg = Args.getLastArg(options::OPT__SLASH_vms);
71807330f729Sjoerg Arg *MultipleArg = Args.getLastArg(options::OPT__SLASH_vmm);
71817330f729Sjoerg Arg *VirtualArg = Args.getLastArg(options::OPT__SLASH_vmv);
71827330f729Sjoerg
71837330f729Sjoerg Arg *FirstConflict = SingleArg ? SingleArg : MultipleArg;
71847330f729Sjoerg Arg *SecondConflict = VirtualArg ? VirtualArg : MultipleArg;
71857330f729Sjoerg if (FirstConflict && SecondConflict && FirstConflict != SecondConflict)
71867330f729Sjoerg D.Diag(clang::diag::err_drv_argument_not_allowed_with)
71877330f729Sjoerg << FirstConflict->getAsString(Args)
71887330f729Sjoerg << SecondConflict->getAsString(Args);
71897330f729Sjoerg
71907330f729Sjoerg if (SingleArg)
71917330f729Sjoerg CmdArgs.push_back("-fms-memptr-rep=single");
71927330f729Sjoerg else if (MultipleArg)
71937330f729Sjoerg CmdArgs.push_back("-fms-memptr-rep=multiple");
71947330f729Sjoerg else
71957330f729Sjoerg CmdArgs.push_back("-fms-memptr-rep=virtual");
71967330f729Sjoerg }
71977330f729Sjoerg
71987330f729Sjoerg // Parse the default calling convention options.
71997330f729Sjoerg if (Arg *CCArg =
72007330f729Sjoerg Args.getLastArg(options::OPT__SLASH_Gd, options::OPT__SLASH_Gr,
72017330f729Sjoerg options::OPT__SLASH_Gz, options::OPT__SLASH_Gv,
72027330f729Sjoerg options::OPT__SLASH_Gregcall)) {
72037330f729Sjoerg unsigned DCCOptId = CCArg->getOption().getID();
72047330f729Sjoerg const char *DCCFlag = nullptr;
7205*e038c9c4Sjoerg bool ArchSupported = !isNVPTX;
72067330f729Sjoerg llvm::Triple::ArchType Arch = getToolChain().getArch();
72077330f729Sjoerg switch (DCCOptId) {
72087330f729Sjoerg case options::OPT__SLASH_Gd:
72097330f729Sjoerg DCCFlag = "-fdefault-calling-conv=cdecl";
72107330f729Sjoerg break;
72117330f729Sjoerg case options::OPT__SLASH_Gr:
72127330f729Sjoerg ArchSupported = Arch == llvm::Triple::x86;
72137330f729Sjoerg DCCFlag = "-fdefault-calling-conv=fastcall";
72147330f729Sjoerg break;
72157330f729Sjoerg case options::OPT__SLASH_Gz:
72167330f729Sjoerg ArchSupported = Arch == llvm::Triple::x86;
72177330f729Sjoerg DCCFlag = "-fdefault-calling-conv=stdcall";
72187330f729Sjoerg break;
72197330f729Sjoerg case options::OPT__SLASH_Gv:
72207330f729Sjoerg ArchSupported = Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64;
72217330f729Sjoerg DCCFlag = "-fdefault-calling-conv=vectorcall";
72227330f729Sjoerg break;
72237330f729Sjoerg case options::OPT__SLASH_Gregcall:
72247330f729Sjoerg ArchSupported = Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64;
72257330f729Sjoerg DCCFlag = "-fdefault-calling-conv=regcall";
72267330f729Sjoerg break;
72277330f729Sjoerg }
72287330f729Sjoerg
72297330f729Sjoerg // MSVC doesn't warn if /Gr or /Gz is used on x64, so we don't either.
72307330f729Sjoerg if (ArchSupported && DCCFlag)
72317330f729Sjoerg CmdArgs.push_back(DCCFlag);
72327330f729Sjoerg }
72337330f729Sjoerg
72347330f729Sjoerg Args.AddLastArg(CmdArgs, options::OPT_vtordisp_mode_EQ);
72357330f729Sjoerg
72367330f729Sjoerg if (!Args.hasArg(options::OPT_fdiagnostics_format_EQ)) {
72377330f729Sjoerg CmdArgs.push_back("-fdiagnostics-format");
72387330f729Sjoerg CmdArgs.push_back("msvc");
72397330f729Sjoerg }
72407330f729Sjoerg
72417330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) {
72427330f729Sjoerg StringRef GuardArgs = A->getValue();
7243*e038c9c4Sjoerg // The only valid options are "cf", "cf,nochecks", "cf-", "ehcont" and
7244*e038c9c4Sjoerg // "ehcont-".
72457330f729Sjoerg if (GuardArgs.equals_lower("cf")) {
72467330f729Sjoerg // Emit CFG instrumentation and the table of address-taken functions.
72477330f729Sjoerg CmdArgs.push_back("-cfguard");
72487330f729Sjoerg } else if (GuardArgs.equals_lower("cf,nochecks")) {
72497330f729Sjoerg // Emit only the table of address-taken functions.
72507330f729Sjoerg CmdArgs.push_back("-cfguard-no-checks");
7251*e038c9c4Sjoerg } else if (GuardArgs.equals_lower("ehcont")) {
7252*e038c9c4Sjoerg // Emit EH continuation table.
7253*e038c9c4Sjoerg CmdArgs.push_back("-ehcontguard");
7254*e038c9c4Sjoerg } else if (GuardArgs.equals_lower("cf-") ||
7255*e038c9c4Sjoerg GuardArgs.equals_lower("ehcont-")) {
72567330f729Sjoerg // Do nothing, but we might want to emit a security warning in future.
72577330f729Sjoerg } else {
72587330f729Sjoerg D.Diag(diag::err_drv_invalid_value) << A->getSpelling() << GuardArgs;
72597330f729Sjoerg }
72607330f729Sjoerg }
72617330f729Sjoerg }
72627330f729Sjoerg
getBaseInputName(const ArgList & Args,const InputInfo & Input)72637330f729Sjoerg const char *Clang::getBaseInputName(const ArgList &Args,
72647330f729Sjoerg const InputInfo &Input) {
72657330f729Sjoerg return Args.MakeArgString(llvm::sys::path::filename(Input.getBaseInput()));
72667330f729Sjoerg }
72677330f729Sjoerg
getBaseInputStem(const ArgList & Args,const InputInfoList & Inputs)72687330f729Sjoerg const char *Clang::getBaseInputStem(const ArgList &Args,
72697330f729Sjoerg const InputInfoList &Inputs) {
72707330f729Sjoerg const char *Str = getBaseInputName(Args, Inputs[0]);
72717330f729Sjoerg
72727330f729Sjoerg if (const char *End = strrchr(Str, '.'))
72737330f729Sjoerg return Args.MakeArgString(std::string(Str, End));
72747330f729Sjoerg
72757330f729Sjoerg return Str;
72767330f729Sjoerg }
72777330f729Sjoerg
getDependencyFileName(const ArgList & Args,const InputInfoList & Inputs)72787330f729Sjoerg const char *Clang::getDependencyFileName(const ArgList &Args,
72797330f729Sjoerg const InputInfoList &Inputs) {
72807330f729Sjoerg // FIXME: Think about this more.
72817330f729Sjoerg
72827330f729Sjoerg if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
72837330f729Sjoerg SmallString<128> OutputFilename(OutputOpt->getValue());
72847330f729Sjoerg llvm::sys::path::replace_extension(OutputFilename, llvm::Twine('d'));
72857330f729Sjoerg return Args.MakeArgString(OutputFilename);
72867330f729Sjoerg }
72877330f729Sjoerg
72887330f729Sjoerg return Args.MakeArgString(Twine(getBaseInputStem(Args, Inputs)) + ".d");
72897330f729Sjoerg }
72907330f729Sjoerg
72917330f729Sjoerg // Begin ClangAs
72927330f729Sjoerg
AddMIPSTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const72937330f729Sjoerg void ClangAs::AddMIPSTargetArgs(const ArgList &Args,
72947330f729Sjoerg ArgStringList &CmdArgs) const {
72957330f729Sjoerg StringRef CPUName;
72967330f729Sjoerg StringRef ABIName;
72977330f729Sjoerg const llvm::Triple &Triple = getToolChain().getTriple();
72987330f729Sjoerg mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
72997330f729Sjoerg
73007330f729Sjoerg CmdArgs.push_back("-target-abi");
73017330f729Sjoerg CmdArgs.push_back(ABIName.data());
73027330f729Sjoerg }
73037330f729Sjoerg
AddX86TargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const73047330f729Sjoerg void ClangAs::AddX86TargetArgs(const ArgList &Args,
73057330f729Sjoerg ArgStringList &CmdArgs) const {
7306*e038c9c4Sjoerg addX86AlignBranchArgs(getToolChain().getDriver(), Args, CmdArgs,
7307*e038c9c4Sjoerg /*IsLTO=*/false);
7308*e038c9c4Sjoerg
73097330f729Sjoerg if (Arg *A = Args.getLastArg(options::OPT_masm_EQ)) {
73107330f729Sjoerg StringRef Value = A->getValue();
73117330f729Sjoerg if (Value == "intel" || Value == "att") {
73127330f729Sjoerg CmdArgs.push_back("-mllvm");
73137330f729Sjoerg CmdArgs.push_back(Args.MakeArgString("-x86-asm-syntax=" + Value));
73147330f729Sjoerg } else {
73157330f729Sjoerg getToolChain().getDriver().Diag(diag::err_drv_unsupported_option_argument)
73167330f729Sjoerg << A->getOption().getName() << Value;
73177330f729Sjoerg }
73187330f729Sjoerg }
73197330f729Sjoerg }
73207330f729Sjoerg
AddRISCVTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const73217330f729Sjoerg void ClangAs::AddRISCVTargetArgs(const ArgList &Args,
73227330f729Sjoerg ArgStringList &CmdArgs) const {
73237330f729Sjoerg const llvm::Triple &Triple = getToolChain().getTriple();
73247330f729Sjoerg StringRef ABIName = riscv::getRISCVABI(Args, Triple);
73257330f729Sjoerg
73267330f729Sjoerg CmdArgs.push_back("-target-abi");
73277330f729Sjoerg CmdArgs.push_back(ABIName.data());
73287330f729Sjoerg }
73297330f729Sjoerg
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const73307330f729Sjoerg void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
73317330f729Sjoerg const InputInfo &Output, const InputInfoList &Inputs,
73327330f729Sjoerg const ArgList &Args,
73337330f729Sjoerg const char *LinkingOutput) const {
73347330f729Sjoerg ArgStringList CmdArgs;
73357330f729Sjoerg
73367330f729Sjoerg assert(Inputs.size() == 1 && "Unexpected number of inputs.");
73377330f729Sjoerg const InputInfo &Input = Inputs[0];
73387330f729Sjoerg
73397330f729Sjoerg const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
73407330f729Sjoerg const std::string &TripleStr = Triple.getTriple();
73417330f729Sjoerg const auto &D = getToolChain().getDriver();
73427330f729Sjoerg
73437330f729Sjoerg // Don't warn about "clang -w -c foo.s"
73447330f729Sjoerg Args.ClaimAllArgs(options::OPT_w);
73457330f729Sjoerg // and "clang -emit-llvm -c foo.s"
73467330f729Sjoerg Args.ClaimAllArgs(options::OPT_emit_llvm);
73477330f729Sjoerg
73487330f729Sjoerg claimNoWarnArgs(Args);
73497330f729Sjoerg
73507330f729Sjoerg // Invoke ourselves in -cc1as mode.
73517330f729Sjoerg //
73527330f729Sjoerg // FIXME: Implement custom jobs for internal actions.
73537330f729Sjoerg CmdArgs.push_back("-cc1as");
73547330f729Sjoerg
73557330f729Sjoerg // Add the "effective" target triple.
73567330f729Sjoerg CmdArgs.push_back("-triple");
73577330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(TripleStr));
73587330f729Sjoerg
73597330f729Sjoerg // Set the output mode, we currently only expect to be used as a real
73607330f729Sjoerg // assembler.
73617330f729Sjoerg CmdArgs.push_back("-filetype");
73627330f729Sjoerg CmdArgs.push_back("obj");
73637330f729Sjoerg
73647330f729Sjoerg // Set the main file name, so that debug info works even with
73657330f729Sjoerg // -save-temps or preprocessed assembly.
73667330f729Sjoerg CmdArgs.push_back("-main-file-name");
73677330f729Sjoerg CmdArgs.push_back(Clang::getBaseInputName(Args, Input));
73687330f729Sjoerg
73697330f729Sjoerg // Add the target cpu
73707330f729Sjoerg std::string CPU = getCPUName(Args, Triple, /*FromAs*/ true);
73717330f729Sjoerg if (!CPU.empty()) {
73727330f729Sjoerg CmdArgs.push_back("-target-cpu");
73737330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(CPU));
73747330f729Sjoerg }
73757330f729Sjoerg
73767330f729Sjoerg // Add the target features
7377*e038c9c4Sjoerg getTargetFeatures(D, Triple, Args, CmdArgs, true);
73787330f729Sjoerg
73797330f729Sjoerg // Ignore explicit -force_cpusubtype_ALL option.
73807330f729Sjoerg (void)Args.hasArg(options::OPT_force__cpusubtype__ALL);
73817330f729Sjoerg
73827330f729Sjoerg // Pass along any -I options so we get proper .include search paths.
73837330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_I_Group);
73847330f729Sjoerg
73857330f729Sjoerg // Determine the original source input.
73867330f729Sjoerg const Action *SourceAction = &JA;
73877330f729Sjoerg while (SourceAction->getKind() != Action::InputClass) {
73887330f729Sjoerg assert(!SourceAction->getInputs().empty() && "unexpected root action!");
73897330f729Sjoerg SourceAction = SourceAction->getInputs()[0];
73907330f729Sjoerg }
73917330f729Sjoerg
73927330f729Sjoerg // Forward -g and handle debug info related flags, assuming we are dealing
73937330f729Sjoerg // with an actual assembly file.
73947330f729Sjoerg bool WantDebug = false;
73957330f729Sjoerg Args.ClaimAllArgs(options::OPT_g_Group);
7396*e038c9c4Sjoerg if (Arg *A = Args.getLastArg(options::OPT_g_Group))
73977330f729Sjoerg WantDebug = !A->getOption().matches(options::OPT_g0) &&
73987330f729Sjoerg !A->getOption().matches(options::OPT_ggdb0);
7399*e038c9c4Sjoerg
7400*e038c9c4Sjoerg unsigned DwarfVersion = ParseDebugDefaultVersion(getToolChain(), Args);
7401*e038c9c4Sjoerg if (const Arg *GDwarfN = getDwarfNArg(Args))
7402*e038c9c4Sjoerg DwarfVersion = DwarfVersionNum(GDwarfN->getSpelling());
7403*e038c9c4Sjoerg
74047330f729Sjoerg if (DwarfVersion == 0)
74057330f729Sjoerg DwarfVersion = getToolChain().GetDefaultDwarfVersion();
74067330f729Sjoerg
74077330f729Sjoerg codegenoptions::DebugInfoKind DebugInfoKind = codegenoptions::NoDebugInfo;
74087330f729Sjoerg
74097330f729Sjoerg if (SourceAction->getType() == types::TY_Asm ||
74107330f729Sjoerg SourceAction->getType() == types::TY_PP_Asm) {
74117330f729Sjoerg // You might think that it would be ok to set DebugInfoKind outside of
74127330f729Sjoerg // the guard for source type, however there is a test which asserts
74137330f729Sjoerg // that some assembler invocation receives no -debug-info-kind,
74147330f729Sjoerg // and it's not clear whether that test is just overly restrictive.
74157330f729Sjoerg DebugInfoKind = (WantDebug ? codegenoptions::LimitedDebugInfo
74167330f729Sjoerg : codegenoptions::NoDebugInfo);
74177330f729Sjoerg // Add the -fdebug-compilation-dir flag if needed.
74187330f729Sjoerg addDebugCompDirArg(Args, CmdArgs, C.getDriver().getVFS());
74197330f729Sjoerg
74207330f729Sjoerg addDebugPrefixMapArg(getToolChain().getDriver(), Args, CmdArgs);
74217330f729Sjoerg
74227330f729Sjoerg // Set the AT_producer to the clang version when using the integrated
74237330f729Sjoerg // assembler on assembly source files.
74247330f729Sjoerg CmdArgs.push_back("-dwarf-debug-producer");
74257330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(getClangFullVersion()));
74267330f729Sjoerg
74277330f729Sjoerg // And pass along -I options
74287330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_I);
74297330f729Sjoerg }
74307330f729Sjoerg RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion,
74317330f729Sjoerg llvm::DebuggerKind::Default);
7432*e038c9c4Sjoerg renderDwarfFormat(D, Triple, Args, CmdArgs, DwarfVersion);
74337330f729Sjoerg RenderDebugInfoCompressionArgs(Args, CmdArgs, D, getToolChain());
74347330f729Sjoerg
74357330f729Sjoerg
74367330f729Sjoerg // Handle -fPIC et al -- the relocation-model affects the assembler
74377330f729Sjoerg // for some targets.
74387330f729Sjoerg llvm::Reloc::Model RelocationModel;
74397330f729Sjoerg unsigned PICLevel;
74407330f729Sjoerg bool IsPIE;
74417330f729Sjoerg std::tie(RelocationModel, PICLevel, IsPIE) =
74427330f729Sjoerg ParsePICArgs(getToolChain(), Args);
74437330f729Sjoerg
74447330f729Sjoerg const char *RMName = RelocationModelName(RelocationModel);
74457330f729Sjoerg if (RMName) {
74467330f729Sjoerg CmdArgs.push_back("-mrelocation-model");
74477330f729Sjoerg CmdArgs.push_back(RMName);
74487330f729Sjoerg }
74497330f729Sjoerg
74507330f729Sjoerg // Optionally embed the -cc1as level arguments into the debug info, for build
74517330f729Sjoerg // analysis.
74527330f729Sjoerg if (getToolChain().UseDwarfDebugFlags()) {
74537330f729Sjoerg ArgStringList OriginalArgs;
74547330f729Sjoerg for (const auto &Arg : Args)
74557330f729Sjoerg Arg->render(Args, OriginalArgs);
74567330f729Sjoerg
74577330f729Sjoerg SmallString<256> Flags;
74587330f729Sjoerg const char *Exec = getToolChain().getDriver().getClangProgramPath();
7459*e038c9c4Sjoerg EscapeSpacesAndBackslashes(Exec, Flags);
74607330f729Sjoerg for (const char *OriginalArg : OriginalArgs) {
74617330f729Sjoerg SmallString<128> EscapedArg;
74627330f729Sjoerg EscapeSpacesAndBackslashes(OriginalArg, EscapedArg);
74637330f729Sjoerg Flags += " ";
74647330f729Sjoerg Flags += EscapedArg;
74657330f729Sjoerg }
74667330f729Sjoerg CmdArgs.push_back("-dwarf-debug-flags");
74677330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(Flags));
74687330f729Sjoerg }
74697330f729Sjoerg
74707330f729Sjoerg // FIXME: Add -static support, once we have it.
74717330f729Sjoerg
74727330f729Sjoerg // Add target specific flags.
74737330f729Sjoerg switch (getToolChain().getArch()) {
74747330f729Sjoerg default:
74757330f729Sjoerg break;
74767330f729Sjoerg
74777330f729Sjoerg case llvm::Triple::mips:
74787330f729Sjoerg case llvm::Triple::mipsel:
74797330f729Sjoerg case llvm::Triple::mips64:
74807330f729Sjoerg case llvm::Triple::mips64el:
74817330f729Sjoerg AddMIPSTargetArgs(Args, CmdArgs);
74827330f729Sjoerg break;
74837330f729Sjoerg
74847330f729Sjoerg case llvm::Triple::x86:
74857330f729Sjoerg case llvm::Triple::x86_64:
74867330f729Sjoerg AddX86TargetArgs(Args, CmdArgs);
74877330f729Sjoerg break;
74887330f729Sjoerg
74897330f729Sjoerg case llvm::Triple::arm:
74907330f729Sjoerg case llvm::Triple::armeb:
74917330f729Sjoerg case llvm::Triple::thumb:
74927330f729Sjoerg case llvm::Triple::thumbeb:
74937330f729Sjoerg // This isn't in AddARMTargetArgs because we want to do this for assembly
74947330f729Sjoerg // only, not C/C++.
74957330f729Sjoerg if (Args.hasFlag(options::OPT_mdefault_build_attributes,
74967330f729Sjoerg options::OPT_mno_default_build_attributes, true)) {
74977330f729Sjoerg CmdArgs.push_back("-mllvm");
74987330f729Sjoerg CmdArgs.push_back("-arm-add-build-attributes");
74997330f729Sjoerg }
75007330f729Sjoerg break;
75017330f729Sjoerg
7502*e038c9c4Sjoerg case llvm::Triple::aarch64:
7503*e038c9c4Sjoerg case llvm::Triple::aarch64_32:
7504*e038c9c4Sjoerg case llvm::Triple::aarch64_be:
7505*e038c9c4Sjoerg if (Args.hasArg(options::OPT_mmark_bti_property)) {
7506*e038c9c4Sjoerg CmdArgs.push_back("-mllvm");
7507*e038c9c4Sjoerg CmdArgs.push_back("-aarch64-mark-bti-property");
7508*e038c9c4Sjoerg }
7509*e038c9c4Sjoerg break;
7510*e038c9c4Sjoerg
75117330f729Sjoerg case llvm::Triple::riscv32:
75127330f729Sjoerg case llvm::Triple::riscv64:
75137330f729Sjoerg AddRISCVTargetArgs(Args, CmdArgs);
75147330f729Sjoerg break;
75157330f729Sjoerg }
75167330f729Sjoerg
75177330f729Sjoerg // Consume all the warning flags. Usually this would be handled more
75187330f729Sjoerg // gracefully by -cc1 (warning about unknown warning flags, etc) but -cc1as
75197330f729Sjoerg // doesn't handle that so rather than warning about unused flags that are
75207330f729Sjoerg // actually used, we'll lie by omission instead.
75217330f729Sjoerg // FIXME: Stop lying and consume only the appropriate driver flags
75227330f729Sjoerg Args.ClaimAllArgs(options::OPT_W_Group);
75237330f729Sjoerg
75247330f729Sjoerg CollectArgsForIntegratedAssembler(C, Args, CmdArgs,
75257330f729Sjoerg getToolChain().getDriver());
75267330f729Sjoerg
75277330f729Sjoerg Args.AddAllArgs(CmdArgs, options::OPT_mllvm);
75287330f729Sjoerg
75297330f729Sjoerg assert(Output.isFilename() && "Unexpected lipo output.");
75307330f729Sjoerg CmdArgs.push_back("-o");
75317330f729Sjoerg CmdArgs.push_back(Output.getFilename());
75327330f729Sjoerg
75337330f729Sjoerg const llvm::Triple &T = getToolChain().getTriple();
75347330f729Sjoerg Arg *A;
75357330f729Sjoerg if (getDebugFissionKind(D, Args, A) == DwarfFissionKind::Split &&
75367330f729Sjoerg T.isOSBinFormatELF()) {
75377330f729Sjoerg CmdArgs.push_back("-split-dwarf-output");
7538*e038c9c4Sjoerg CmdArgs.push_back(SplitDebugName(JA, Args, Input, Output));
75397330f729Sjoerg }
75407330f729Sjoerg
7541*e038c9c4Sjoerg if (Triple.isAMDGPU())
7542*e038c9c4Sjoerg handleAMDGPUCodeObjectVersionOptions(D, Args, CmdArgs);
7543*e038c9c4Sjoerg
75447330f729Sjoerg assert(Input.isFilename() && "Invalid input.");
75457330f729Sjoerg CmdArgs.push_back(Input.getFilename());
75467330f729Sjoerg
75477330f729Sjoerg const char *Exec = getToolChain().getDriver().getClangProgramPath();
7548*e038c9c4Sjoerg if (D.CC1Main && !D.CCGenDiagnostics) {
7549*e038c9c4Sjoerg // Invoke cc1as directly in this process.
7550*e038c9c4Sjoerg C.addCommand(std::make_unique<CC1Command>(JA, *this,
7551*e038c9c4Sjoerg ResponseFileSupport::AtFileUTF8(),
7552*e038c9c4Sjoerg Exec, CmdArgs, Inputs, Output));
7553*e038c9c4Sjoerg } else {
7554*e038c9c4Sjoerg C.addCommand(std::make_unique<Command>(JA, *this,
7555*e038c9c4Sjoerg ResponseFileSupport::AtFileUTF8(),
7556*e038c9c4Sjoerg Exec, CmdArgs, Inputs, Output));
7557*e038c9c4Sjoerg }
75587330f729Sjoerg }
75597330f729Sjoerg
75607330f729Sjoerg // Begin OffloadBundler
75617330f729Sjoerg
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const llvm::opt::ArgList & TCArgs,const char * LinkingOutput) const75627330f729Sjoerg void OffloadBundler::ConstructJob(Compilation &C, const JobAction &JA,
75637330f729Sjoerg const InputInfo &Output,
75647330f729Sjoerg const InputInfoList &Inputs,
75657330f729Sjoerg const llvm::opt::ArgList &TCArgs,
75667330f729Sjoerg const char *LinkingOutput) const {
75677330f729Sjoerg // The version with only one output is expected to refer to a bundling job.
75687330f729Sjoerg assert(isa<OffloadBundlingJobAction>(JA) && "Expecting bundling job!");
75697330f729Sjoerg
75707330f729Sjoerg // The bundling command looks like this:
75717330f729Sjoerg // clang-offload-bundler -type=bc
75727330f729Sjoerg // -targets=host-triple,openmp-triple1,openmp-triple2
75737330f729Sjoerg // -outputs=input_file
75747330f729Sjoerg // -inputs=unbundle_file_host,unbundle_file_tgt1,unbundle_file_tgt2"
75757330f729Sjoerg
75767330f729Sjoerg ArgStringList CmdArgs;
75777330f729Sjoerg
75787330f729Sjoerg // Get the type.
75797330f729Sjoerg CmdArgs.push_back(TCArgs.MakeArgString(
75807330f729Sjoerg Twine("-type=") + types::getTypeTempSuffix(Output.getType())));
75817330f729Sjoerg
75827330f729Sjoerg assert(JA.getInputs().size() == Inputs.size() &&
75837330f729Sjoerg "Not have inputs for all dependence actions??");
75847330f729Sjoerg
75857330f729Sjoerg // Get the targets.
75867330f729Sjoerg SmallString<128> Triples;
75877330f729Sjoerg Triples += "-targets=";
75887330f729Sjoerg for (unsigned I = 0; I < Inputs.size(); ++I) {
75897330f729Sjoerg if (I)
75907330f729Sjoerg Triples += ',';
75917330f729Sjoerg
75927330f729Sjoerg // Find ToolChain for this input.
75937330f729Sjoerg Action::OffloadKind CurKind = Action::OFK_Host;
75947330f729Sjoerg const ToolChain *CurTC = &getToolChain();
75957330f729Sjoerg const Action *CurDep = JA.getInputs()[I];
75967330f729Sjoerg
75977330f729Sjoerg if (const auto *OA = dyn_cast<OffloadAction>(CurDep)) {
75987330f729Sjoerg CurTC = nullptr;
75997330f729Sjoerg OA->doOnEachDependence([&](Action *A, const ToolChain *TC, const char *) {
76007330f729Sjoerg assert(CurTC == nullptr && "Expected one dependence!");
76017330f729Sjoerg CurKind = A->getOffloadingDeviceKind();
76027330f729Sjoerg CurTC = TC;
76037330f729Sjoerg });
76047330f729Sjoerg }
76057330f729Sjoerg Triples += Action::GetOffloadKindName(CurKind);
76067330f729Sjoerg Triples += '-';
76077330f729Sjoerg Triples += CurTC->getTriple().normalize();
76087330f729Sjoerg if (CurKind == Action::OFK_HIP && CurDep->getOffloadingArch()) {
76097330f729Sjoerg Triples += '-';
76107330f729Sjoerg Triples += CurDep->getOffloadingArch();
76117330f729Sjoerg }
76127330f729Sjoerg }
76137330f729Sjoerg CmdArgs.push_back(TCArgs.MakeArgString(Triples));
76147330f729Sjoerg
76157330f729Sjoerg // Get bundled file command.
76167330f729Sjoerg CmdArgs.push_back(
76177330f729Sjoerg TCArgs.MakeArgString(Twine("-outputs=") + Output.getFilename()));
76187330f729Sjoerg
76197330f729Sjoerg // Get unbundled files command.
76207330f729Sjoerg SmallString<128> UB;
76217330f729Sjoerg UB += "-inputs=";
76227330f729Sjoerg for (unsigned I = 0; I < Inputs.size(); ++I) {
76237330f729Sjoerg if (I)
76247330f729Sjoerg UB += ',';
76257330f729Sjoerg
76267330f729Sjoerg // Find ToolChain for this input.
76277330f729Sjoerg const ToolChain *CurTC = &getToolChain();
76287330f729Sjoerg if (const auto *OA = dyn_cast<OffloadAction>(JA.getInputs()[I])) {
76297330f729Sjoerg CurTC = nullptr;
76307330f729Sjoerg OA->doOnEachDependence([&](Action *, const ToolChain *TC, const char *) {
76317330f729Sjoerg assert(CurTC == nullptr && "Expected one dependence!");
76327330f729Sjoerg CurTC = TC;
76337330f729Sjoerg });
76347330f729Sjoerg }
76357330f729Sjoerg UB += CurTC->getInputFilename(Inputs[I]);
76367330f729Sjoerg }
76377330f729Sjoerg CmdArgs.push_back(TCArgs.MakeArgString(UB));
76387330f729Sjoerg
76397330f729Sjoerg // All the inputs are encoded as commands.
76407330f729Sjoerg C.addCommand(std::make_unique<Command>(
7641*e038c9c4Sjoerg JA, *this, ResponseFileSupport::None(),
76427330f729Sjoerg TCArgs.MakeArgString(getToolChain().GetProgramPath(getShortName())),
7643*e038c9c4Sjoerg CmdArgs, None, Output));
76447330f729Sjoerg }
76457330f729Sjoerg
ConstructJobMultipleOutputs(Compilation & C,const JobAction & JA,const InputInfoList & Outputs,const InputInfoList & Inputs,const llvm::opt::ArgList & TCArgs,const char * LinkingOutput) const76467330f729Sjoerg void OffloadBundler::ConstructJobMultipleOutputs(
76477330f729Sjoerg Compilation &C, const JobAction &JA, const InputInfoList &Outputs,
76487330f729Sjoerg const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs,
76497330f729Sjoerg const char *LinkingOutput) const {
76507330f729Sjoerg // The version with multiple outputs is expected to refer to a unbundling job.
76517330f729Sjoerg auto &UA = cast<OffloadUnbundlingJobAction>(JA);
76527330f729Sjoerg
76537330f729Sjoerg // The unbundling command looks like this:
76547330f729Sjoerg // clang-offload-bundler -type=bc
76557330f729Sjoerg // -targets=host-triple,openmp-triple1,openmp-triple2
76567330f729Sjoerg // -inputs=input_file
76577330f729Sjoerg // -outputs=unbundle_file_host,unbundle_file_tgt1,unbundle_file_tgt2"
76587330f729Sjoerg // -unbundle
76597330f729Sjoerg
76607330f729Sjoerg ArgStringList CmdArgs;
76617330f729Sjoerg
76627330f729Sjoerg assert(Inputs.size() == 1 && "Expecting to unbundle a single file!");
76637330f729Sjoerg InputInfo Input = Inputs.front();
76647330f729Sjoerg
76657330f729Sjoerg // Get the type.
76667330f729Sjoerg CmdArgs.push_back(TCArgs.MakeArgString(
76677330f729Sjoerg Twine("-type=") + types::getTypeTempSuffix(Input.getType())));
76687330f729Sjoerg
76697330f729Sjoerg // Get the targets.
76707330f729Sjoerg SmallString<128> Triples;
76717330f729Sjoerg Triples += "-targets=";
76727330f729Sjoerg auto DepInfo = UA.getDependentActionsInfo();
76737330f729Sjoerg for (unsigned I = 0; I < DepInfo.size(); ++I) {
76747330f729Sjoerg if (I)
76757330f729Sjoerg Triples += ',';
76767330f729Sjoerg
76777330f729Sjoerg auto &Dep = DepInfo[I];
76787330f729Sjoerg Triples += Action::GetOffloadKindName(Dep.DependentOffloadKind);
76797330f729Sjoerg Triples += '-';
76807330f729Sjoerg Triples += Dep.DependentToolChain->getTriple().normalize();
76817330f729Sjoerg if (Dep.DependentOffloadKind == Action::OFK_HIP &&
76827330f729Sjoerg !Dep.DependentBoundArch.empty()) {
76837330f729Sjoerg Triples += '-';
76847330f729Sjoerg Triples += Dep.DependentBoundArch;
76857330f729Sjoerg }
76867330f729Sjoerg }
76877330f729Sjoerg
76887330f729Sjoerg CmdArgs.push_back(TCArgs.MakeArgString(Triples));
76897330f729Sjoerg
76907330f729Sjoerg // Get bundled file command.
76917330f729Sjoerg CmdArgs.push_back(
76927330f729Sjoerg TCArgs.MakeArgString(Twine("-inputs=") + Input.getFilename()));
76937330f729Sjoerg
76947330f729Sjoerg // Get unbundled files command.
76957330f729Sjoerg SmallString<128> UB;
76967330f729Sjoerg UB += "-outputs=";
76977330f729Sjoerg for (unsigned I = 0; I < Outputs.size(); ++I) {
76987330f729Sjoerg if (I)
76997330f729Sjoerg UB += ',';
77007330f729Sjoerg UB += DepInfo[I].DependentToolChain->getInputFilename(Outputs[I]);
77017330f729Sjoerg }
77027330f729Sjoerg CmdArgs.push_back(TCArgs.MakeArgString(UB));
77037330f729Sjoerg CmdArgs.push_back("-unbundle");
7704*e038c9c4Sjoerg CmdArgs.push_back("-allow-missing-bundles");
77057330f729Sjoerg
77067330f729Sjoerg // All the inputs are encoded as commands.
77077330f729Sjoerg C.addCommand(std::make_unique<Command>(
7708*e038c9c4Sjoerg JA, *this, ResponseFileSupport::None(),
77097330f729Sjoerg TCArgs.MakeArgString(getToolChain().GetProgramPath(getShortName())),
7710*e038c9c4Sjoerg CmdArgs, None, Outputs));
77117330f729Sjoerg }
77127330f729Sjoerg
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const77137330f729Sjoerg void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA,
77147330f729Sjoerg const InputInfo &Output,
77157330f729Sjoerg const InputInfoList &Inputs,
77167330f729Sjoerg const ArgList &Args,
77177330f729Sjoerg const char *LinkingOutput) const {
77187330f729Sjoerg ArgStringList CmdArgs;
77197330f729Sjoerg
77207330f729Sjoerg const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
77217330f729Sjoerg
77227330f729Sjoerg // Add the "effective" target triple.
77237330f729Sjoerg CmdArgs.push_back("-target");
77247330f729Sjoerg CmdArgs.push_back(Args.MakeArgString(Triple.getTriple()));
77257330f729Sjoerg
77267330f729Sjoerg // Add the output file name.
77277330f729Sjoerg assert(Output.isFilename() && "Invalid output.");
77287330f729Sjoerg CmdArgs.push_back("-o");
77297330f729Sjoerg CmdArgs.push_back(Output.getFilename());
77307330f729Sjoerg
77317330f729Sjoerg // Add inputs.
77327330f729Sjoerg for (const InputInfo &I : Inputs) {
77337330f729Sjoerg assert(I.isFilename() && "Invalid input.");
77347330f729Sjoerg CmdArgs.push_back(I.getFilename());
77357330f729Sjoerg }
77367330f729Sjoerg
77377330f729Sjoerg C.addCommand(std::make_unique<Command>(
7738*e038c9c4Sjoerg JA, *this, ResponseFileSupport::None(),
77397330f729Sjoerg Args.MakeArgString(getToolChain().GetProgramPath(getShortName())),
7740*e038c9c4Sjoerg CmdArgs, Inputs, Output));
77417330f729Sjoerg }
7742