xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/Driver/ToolChains/Clang.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
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