1//===-- Clang.cpp - Clang+LLVM ToolChain Implementations --------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "Clang.h"
10#include "AMDGPU.h"
11#include "Arch/AArch64.h"
12#include "Arch/ARM.h"
13#include "Arch/CSKY.h"
14#include "Arch/LoongArch.h"
15#include "Arch/M68k.h"
16#include "Arch/Mips.h"
17#include "Arch/PPC.h"
18#include "Arch/RISCV.h"
19#include "Arch/Sparc.h"
20#include "Arch/SystemZ.h"
21#include "Arch/VE.h"
22#include "Arch/X86.h"
23#include "CommonArgs.h"
24#include "Hexagon.h"
25#include "MSP430.h"
26#include "PS4CPU.h"
27#include "clang/Basic/CLWarnings.h"
28#include "clang/Basic/CharInfo.h"
29#include "clang/Basic/CodeGenOptions.h"
30#include "clang/Basic/HeaderInclude.h"
31#include "clang/Basic/LangOptions.h"
32#include "clang/Basic/MakeSupport.h"
33#include "clang/Basic/ObjCRuntime.h"
34#include "clang/Basic/Version.h"
35#include "clang/Config/config.h"
36#include "clang/Driver/Action.h"
37#include "clang/Driver/Distro.h"
38#include "clang/Driver/DriverDiagnostic.h"
39#include "clang/Driver/InputInfo.h"
40#include "clang/Driver/Options.h"
41#include "clang/Driver/SanitizerArgs.h"
42#include "clang/Driver/Types.h"
43#include "clang/Driver/XRayArgs.h"
44#include "llvm/ADT/SmallSet.h"
45#include "llvm/ADT/StringExtras.h"
46#include "llvm/BinaryFormat/Magic.h"
47#include "llvm/Config/llvm-config.h"
48#include "llvm/Object/ObjectFile.h"
49#include "llvm/Option/ArgList.h"
50#include "llvm/Support/CodeGen.h"
51#include "llvm/Support/Compiler.h"
52#include "llvm/Support/Compression.h"
53#include "llvm/Support/Error.h"
54#include "llvm/Support/FileSystem.h"
55#include "llvm/Support/Path.h"
56#include "llvm/Support/Process.h"
57#include "llvm/Support/YAMLParser.h"
58#include "llvm/TargetParser/ARMTargetParserCommon.h"
59#include "llvm/TargetParser/Host.h"
60#include "llvm/TargetParser/LoongArchTargetParser.h"
61#include "llvm/TargetParser/RISCVISAInfo.h"
62#include "llvm/TargetParser/RISCVTargetParser.h"
63#include <cctype>
64
65using namespace clang::driver;
66using namespace clang::driver::tools;
67using namespace clang;
68using namespace llvm::opt;
69
70static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
71 if (Arg *A = Args.getLastArg(clang::driver::options::OPT_C, options::OPT_CC,
72 options::OPT_fminimize_whitespace,
73 options::OPT_fno_minimize_whitespace,
74 options::OPT_fkeep_system_includes,
75 options::OPT_fno_keep_system_includes)) {
76 if (!Args.hasArg(options::OPT_E) && !Args.hasArg(options::OPT__SLASH_P) &&
77 !Args.hasArg(options::OPT__SLASH_EP) && !D.CCCIsCPP()) {
78 D.Diag(clang::diag::DiagID: err_drv_argument_only_allowed_with)
79 << A->getBaseArg().getAsString(Args)
80 << (D.IsCLMode() ? "/E, /P or /EP" : "-E");
81 }
82 }
83}
84
85static void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) {
86 // In gcc, only ARM checks this, but it seems reasonable to check universally.
87 if (Args.hasArg(options::OPT_static))
88 if (const Arg *A =
89 Args.getLastArg(options::OPT_dynamic, options::OPT_mdynamic_no_pic))
90 D.Diag(diag::DiagID: err_drv_argument_not_allowed_with) << A->getAsString(Args)
91 << "-static";
92}
93
94// Add backslashes to escape spaces and other backslashes.
95// This is used for the space-separated argument list specified with
96// the -dwarf-debug-flags option.
97static void EscapeSpacesAndBackslashes(const char *Arg,
98 SmallVectorImpl<char> &Res) {
99 for (; *Arg; ++Arg) {
100 switch (*Arg) {
101 default:
102 break;
103 case ' ':
104 case '\\':
105 Res.push_back(Elt: '\\');
106 break;
107 }
108 Res.push_back(Elt: *Arg);
109 }
110}
111
112/// Apply \a Work on the current tool chain \a RegularToolChain and any other
113/// offloading tool chain that is associated with the current action \a JA.
114static void
115forAllAssociatedToolChains(Compilation &C, const JobAction &JA,
116 const ToolChain &RegularToolChain,
117 llvm::function_ref<void(const ToolChain &)> Work) {
118 // Apply Work on the current/regular tool chain.
119 Work(RegularToolChain);
120
121 // Apply Work on all the offloading tool chains associated with the current
122 // action.
123 if (JA.isHostOffloading(OKind: Action::OFK_Cuda))
124 Work(*C.getSingleOffloadToolChain<Action::OFK_Cuda>());
125 else if (JA.isDeviceOffloading(OKind: Action::OFK_Cuda))
126 Work(*C.getSingleOffloadToolChain<Action::OFK_Host>());
127 else if (JA.isHostOffloading(OKind: Action::OFK_HIP))
128 Work(*C.getSingleOffloadToolChain<Action::OFK_HIP>());
129 else if (JA.isDeviceOffloading(OKind: Action::OFK_HIP))
130 Work(*C.getSingleOffloadToolChain<Action::OFK_Host>());
131
132 if (JA.isHostOffloading(OKind: Action::OFK_OpenMP)) {
133 auto TCs = C.getOffloadToolChains<Action::OFK_OpenMP>();
134 for (auto II = TCs.first, IE = TCs.second; II != IE; ++II)
135 Work(*II->second);
136 } else if (JA.isDeviceOffloading(OKind: Action::OFK_OpenMP))
137 Work(*C.getSingleOffloadToolChain<Action::OFK_Host>());
138
139 //
140 // TODO: Add support for other offloading programming models here.
141 //
142}
143
144/// This is a helper function for validating the optional refinement step
145/// parameter in reciprocal argument strings. Return false if there is an error
146/// parsing the refinement step. Otherwise, return true and set the Position
147/// of the refinement step in the input string.
148static bool getRefinementStep(StringRef In, const Driver &D,
149 const Arg &A, size_t &Position) {
150 const char RefinementStepToken = ':';
151 Position = In.find(C: RefinementStepToken);
152 if (Position != StringRef::npos) {
153 StringRef Option = A.getOption().getName();
154 StringRef RefStep = In.substr(Start: Position + 1);
155 // Allow exactly one numeric character for the additional refinement
156 // step parameter. This is reasonable for all currently-supported
157 // operations and architectures because we would expect that a larger value
158 // of refinement steps would cause the estimate "optimization" to
159 // under-perform the native operation. Also, if the estimate does not
160 // converge quickly, it probably will not ever converge, so further
161 // refinement steps will not produce a better answer.
162 if (RefStep.size() != 1) {
163 D.Diag(diag::DiagID: err_drv_invalid_value) << Option << RefStep;
164 return false;
165 }
166 char RefStepChar = RefStep[0];
167 if (RefStepChar < '0' || RefStepChar > '9') {
168 D.Diag(diag::DiagID: err_drv_invalid_value) << Option << RefStep;
169 return false;
170 }
171 }
172 return true;
173}
174
175/// The -mrecip flag requires processing of many optional parameters.
176static void ParseMRecip(const Driver &D, const ArgList &Args,
177 ArgStringList &OutStrings) {
178 StringRef DisabledPrefixIn = "!";
179 StringRef DisabledPrefixOut = "!";
180 StringRef EnabledPrefixOut = "";
181 StringRef Out = "-mrecip=";
182
183 Arg *A = Args.getLastArg(options::OPT_mrecip, options::OPT_mrecip_EQ);
184 if (!A)
185 return;
186
187 unsigned NumOptions = A->getNumValues();
188 if (NumOptions == 0) {
189 // No option is the same as "all".
190 OutStrings.push_back(Elt: Args.MakeArgString(Str: Out + "all"));
191 return;
192 }
193
194 // Pass through "all", "none", or "default" with an optional refinement step.
195 if (NumOptions == 1) {
196 StringRef Val = A->getValue(N: 0);
197 size_t RefStepLoc;
198 if (!getRefinementStep(In: Val, D, A: *A, Position&: RefStepLoc))
199 return;
200 StringRef ValBase = Val.slice(Start: 0, End: RefStepLoc);
201 if (ValBase == "all" || ValBase == "none" || ValBase == "default") {
202 OutStrings.push_back(Elt: Args.MakeArgString(Str: Out + Val));
203 return;
204 }
205 }
206
207 // Each reciprocal type may be enabled or disabled individually.
208 // Check each input value for validity, concatenate them all back together,
209 // and pass through.
210
211 llvm::StringMap<bool> OptionStrings;
212 OptionStrings.insert(KV: std::make_pair(x: "divd", y: false));
213 OptionStrings.insert(KV: std::make_pair(x: "divf", y: false));
214 OptionStrings.insert(KV: std::make_pair(x: "divh", y: false));
215 OptionStrings.insert(KV: std::make_pair(x: "vec-divd", y: false));
216 OptionStrings.insert(KV: std::make_pair(x: "vec-divf", y: false));
217 OptionStrings.insert(KV: std::make_pair(x: "vec-divh", y: false));
218 OptionStrings.insert(KV: std::make_pair(x: "sqrtd", y: false));
219 OptionStrings.insert(KV: std::make_pair(x: "sqrtf", y: false));
220 OptionStrings.insert(KV: std::make_pair(x: "sqrth", y: false));
221 OptionStrings.insert(KV: std::make_pair(x: "vec-sqrtd", y: false));
222 OptionStrings.insert(KV: std::make_pair(x: "vec-sqrtf", y: false));
223 OptionStrings.insert(KV: std::make_pair(x: "vec-sqrth", y: false));
224
225 for (unsigned i = 0; i != NumOptions; ++i) {
226 StringRef Val = A->getValue(N: i);
227
228 bool IsDisabled = Val.starts_with(Prefix: DisabledPrefixIn);
229 // Ignore the disablement token for string matching.
230 if (IsDisabled)
231 Val = Val.substr(Start: 1);
232
233 size_t RefStep;
234 if (!getRefinementStep(In: Val, D, A: *A, Position&: RefStep))
235 return;
236
237 StringRef ValBase = Val.slice(Start: 0, End: RefStep);
238 llvm::StringMap<bool>::iterator OptionIter = OptionStrings.find(Key: ValBase);
239 if (OptionIter == OptionStrings.end()) {
240 // Try again specifying float suffix.
241 OptionIter = OptionStrings.find(Key: ValBase.str() + 'f');
242 if (OptionIter == OptionStrings.end()) {
243 // The input name did not match any known option string.
244 D.Diag(diag::DiagID: err_drv_unknown_argument) << Val;
245 return;
246 }
247 // The option was specified without a half or float or double suffix.
248 // Make sure that the double or half entry was not already specified.
249 // The float entry will be checked below.
250 if (OptionStrings[ValBase.str() + 'd'] ||
251 OptionStrings[ValBase.str() + 'h']) {
252 D.Diag(diag::DiagID: err_drv_invalid_value) << A->getOption().getName() << Val;
253 return;
254 }
255 }
256
257 if (OptionIter->second == true) {
258 // Duplicate option specified.
259 D.Diag(diag::DiagID: err_drv_invalid_value) << A->getOption().getName() << Val;
260 return;
261 }
262
263 // Mark the matched option as found. Do not allow duplicate specifiers.
264 OptionIter->second = true;
265
266 // If the precision was not specified, also mark the double and half entry
267 // as found.
268 if (ValBase.back() != 'f' && ValBase.back() != 'd' && ValBase.back() != 'h') {
269 OptionStrings[ValBase.str() + 'd'] = true;
270 OptionStrings[ValBase.str() + 'h'] = true;
271 }
272
273 // Build the output string.
274 StringRef Prefix = IsDisabled ? DisabledPrefixOut : EnabledPrefixOut;
275 Out = Args.MakeArgString(Str: Out + Prefix + Val);
276 if (i != NumOptions - 1)
277 Out = Args.MakeArgString(Str: Out + ",");
278 }
279
280 OutStrings.push_back(Elt: Args.MakeArgString(Str: Out));
281}
282
283/// The -mprefer-vector-width option accepts either a positive integer
284/// or the string "none".
285static void ParseMPreferVectorWidth(const Driver &D, const ArgList &Args,
286 ArgStringList &CmdArgs) {
287 Arg *A = Args.getLastArg(options::OPT_mprefer_vector_width_EQ);
288 if (!A)
289 return;
290
291 StringRef Value = A->getValue();
292 if (Value == "none") {
293 CmdArgs.push_back(Elt: "-mprefer-vector-width=none");
294 } else {
295 unsigned Width;
296 if (Value.getAsInteger(Radix: 10, Result&: Width)) {
297 D.Diag(diag::DiagID: err_drv_invalid_value) << A->getOption().getName() << Value;
298 return;
299 }
300 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-mprefer-vector-width=" + Value));
301 }
302}
303
304static bool
305shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime,
306 const llvm::Triple &Triple) {
307 // We use the zero-cost exception tables for Objective-C if the non-fragile
308 // ABI is enabled or when compiling for x86_64 and ARM on Snow Leopard and
309 // later.
310 if (runtime.isNonFragile())
311 return true;
312
313 if (!Triple.isMacOSX())
314 return false;
315
316 return (!Triple.isMacOSXVersionLT(Major: 10, Minor: 5) &&
317 (Triple.getArch() == llvm::Triple::x86_64 ||
318 Triple.getArch() == llvm::Triple::arm));
319}
320
321/// Adds exception related arguments to the driver command arguments. There's a
322/// main flag, -fexceptions and also language specific flags to enable/disable
323/// C++ and Objective-C exceptions. This makes it possible to for example
324/// disable C++ exceptions but enable Objective-C exceptions.
325static bool addExceptionArgs(const ArgList &Args, types::ID InputType,
326 const ToolChain &TC, bool KernelOrKext,
327 const ObjCRuntime &objcRuntime,
328 ArgStringList &CmdArgs) {
329 const llvm::Triple &Triple = TC.getTriple();
330
331 if (KernelOrKext) {
332 // -mkernel and -fapple-kext imply no exceptions, so claim exception related
333 // arguments now to avoid warnings about unused arguments.
334 Args.ClaimAllArgs(options::OPT_fexceptions);
335 Args.ClaimAllArgs(options::OPT_fno_exceptions);
336 Args.ClaimAllArgs(options::OPT_fobjc_exceptions);
337 Args.ClaimAllArgs(options::OPT_fno_objc_exceptions);
338 Args.ClaimAllArgs(options::OPT_fcxx_exceptions);
339 Args.ClaimAllArgs(options::OPT_fno_cxx_exceptions);
340 Args.ClaimAllArgs(options::OPT_fasync_exceptions);
341 Args.ClaimAllArgs(options::OPT_fno_async_exceptions);
342 return false;
343 }
344
345 // See if the user explicitly enabled exceptions.
346 bool EH = Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
347 false);
348
349 // Async exceptions are Windows MSVC only.
350 if (Triple.isWindowsMSVCEnvironment()) {
351 bool EHa = Args.hasFlag(options::OPT_fasync_exceptions,
352 options::OPT_fno_async_exceptions, false);
353 if (EHa) {
354 CmdArgs.push_back(Elt: "-fasync-exceptions");
355 EH = true;
356 }
357 }
358
359 // Obj-C exceptions are enabled by default, regardless of -fexceptions. This
360 // is not necessarily sensible, but follows GCC.
361 if (types::isObjC(Id: InputType) &&
362 Args.hasFlag(options::OPT_fobjc_exceptions,
363 options::OPT_fno_objc_exceptions, true)) {
364 CmdArgs.push_back(Elt: "-fobjc-exceptions");
365
366 EH |= shouldUseExceptionTablesForObjCExceptions(runtime: objcRuntime, Triple);
367 }
368
369 if (types::isCXX(Id: InputType)) {
370 // Disable C++ EH by default on XCore and PS4/PS5.
371 bool CXXExceptionsEnabled = Triple.getArch() != llvm::Triple::xcore &&
372 !Triple.isPS() && !Triple.isDriverKit();
373 Arg *ExceptionArg = Args.getLastArg(
374 options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions,
375 options::OPT_fexceptions, options::OPT_fno_exceptions);
376 if (ExceptionArg)
377 CXXExceptionsEnabled =
378 ExceptionArg->getOption().matches(options::ID: OPT_fcxx_exceptions) ||
379 ExceptionArg->getOption().matches(options::ID: OPT_fexceptions);
380
381 if (CXXExceptionsEnabled) {
382 CmdArgs.push_back(Elt: "-fcxx-exceptions");
383
384 EH = true;
385 }
386 }
387
388 // OPT_fignore_exceptions means exception could still be thrown,
389 // but no clean up or catch would happen in current module.
390 // So we do not set EH to false.
391 Args.AddLastArg(CmdArgs, options::OPT_fignore_exceptions);
392
393 Args.addOptInFlag(Output&: CmdArgs, options::Pos: OPT_fassume_nothrow_exception_dtor,
394 options::Neg: OPT_fno_assume_nothrow_exception_dtor);
395
396 if (EH)
397 CmdArgs.push_back(Elt: "-fexceptions");
398 return EH;
399}
400
401static bool ShouldEnableAutolink(const ArgList &Args, const ToolChain &TC,
402 const JobAction &JA) {
403 bool Default = true;
404 if (TC.getTriple().isOSDarwin()) {
405 // The native darwin assembler doesn't support the linker_option directives,
406 // so we disable them if we think the .s file will be passed to it.
407 Default = TC.useIntegratedAs();
408 }
409 // The linker_option directives are intended for host compilation.
410 if (JA.isDeviceOffloading(OKind: Action::OFK_Cuda) ||
411 JA.isDeviceOffloading(OKind: Action::OFK_HIP))
412 Default = false;
413 return Args.hasFlag(options::OPT_fautolink, options::OPT_fno_autolink,
414 Default);
415}
416
417/// Add a CC1 option to specify the debug compilation directory.
418static const char *addDebugCompDirArg(const ArgList &Args,
419 ArgStringList &CmdArgs,
420 const llvm::vfs::FileSystem &VFS) {
421 if (Arg *A = Args.getLastArg(options::OPT_ffile_compilation_dir_EQ,
422 options::OPT_fdebug_compilation_dir_EQ)) {
423 if (A->getOption().matches(options::OPT_ffile_compilation_dir_EQ))
424 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Twine("-fdebug-compilation-dir=") +
425 A->getValue()));
426 else
427 A->render(Args, Output&: CmdArgs);
428 } else if (llvm::ErrorOr<std::string> CWD =
429 VFS.getCurrentWorkingDirectory()) {
430 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-fdebug-compilation-dir=" + *CWD));
431 }
432 StringRef Path(CmdArgs.back());
433 return Path.substr(Start: Path.find(C: '=') + 1).data();
434}
435
436static void addDebugObjectName(const ArgList &Args, ArgStringList &CmdArgs,
437 const char *DebugCompilationDir,
438 const char *OutputFileName) {
439 // No need to generate a value for -object-file-name if it was provided.
440 for (auto *Arg : Args.filtered(options::OPT_Xclang))
441 if (StringRef(Arg->getValue()).starts_with("-object-file-name"))
442 return;
443
444 if (Args.hasArg(options::OPT_object_file_name_EQ))
445 return;
446
447 SmallString<128> ObjFileNameForDebug(OutputFileName);
448 if (ObjFileNameForDebug != "-" &&
449 !llvm::sys::path::is_absolute(path: ObjFileNameForDebug) &&
450 (!DebugCompilationDir ||
451 llvm::sys::path::is_absolute(path: DebugCompilationDir))) {
452 // Make the path absolute in the debug infos like MSVC does.
453 llvm::sys::fs::make_absolute(path&: ObjFileNameForDebug);
454 }
455 // If the object file name is a relative path, then always use Windows
456 // backslash style as -object-file-name is used for embedding object file path
457 // in codeview and it can only be generated when targeting on Windows.
458 // Otherwise, just use native absolute path.
459 llvm::sys::path::Style Style =
460 llvm::sys::path::is_absolute(path: ObjFileNameForDebug)
461 ? llvm::sys::path::Style::native
462 : llvm::sys::path::Style::windows_backslash;
463 llvm::sys::path::remove_dots(path&: ObjFileNameForDebug, /*remove_dot_dot=*/true,
464 style: Style);
465 CmdArgs.push_back(
466 Elt: Args.MakeArgString(Str: Twine("-object-file-name=") + ObjFileNameForDebug));
467}
468
469/// Add a CC1 and CC1AS option to specify the debug file path prefix map.
470static void addDebugPrefixMapArg(const Driver &D, const ToolChain &TC,
471 const ArgList &Args, ArgStringList &CmdArgs) {
472 auto AddOneArg = [&](StringRef Map, StringRef Name) {
473 if (!Map.contains(C: '='))
474 D.Diag(diag::err_drv_invalid_argument_to_option) << Map << Name;
475 else
476 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-fdebug-prefix-map=" + Map));
477 };
478
479 for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ,
480 options::OPT_fdebug_prefix_map_EQ)) {
481 AddOneArg(A->getValue(), A->getOption().getName());
482 A->claim();
483 }
484 std::string GlobalRemapEntry = TC.GetGlobalDebugPathRemapping();
485 if (GlobalRemapEntry.empty())
486 return;
487 AddOneArg(GlobalRemapEntry, "environment");
488}
489
490/// Add a CC1 and CC1AS option to specify the macro file path prefix map.
491static void addMacroPrefixMapArg(const Driver &D, const ArgList &Args,
492 ArgStringList &CmdArgs) {
493 for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ,
494 options::OPT_fmacro_prefix_map_EQ)) {
495 StringRef Map = A->getValue();
496 if (!Map.contains('='))
497 D.Diag(diag::err_drv_invalid_argument_to_option)
498 << Map << A->getOption().getName();
499 else
500 CmdArgs.push_back(Args.MakeArgString("-fmacro-prefix-map=" + Map));
501 A->claim();
502 }
503}
504
505/// Add a CC1 and CC1AS option to specify the coverage file path prefix map.
506static void addCoveragePrefixMapArg(const Driver &D, const ArgList &Args,
507 ArgStringList &CmdArgs) {
508 for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ,
509 options::OPT_fcoverage_prefix_map_EQ)) {
510 StringRef Map = A->getValue();
511 if (!Map.contains('='))
512 D.Diag(diag::err_drv_invalid_argument_to_option)
513 << Map << A->getOption().getName();
514 else
515 CmdArgs.push_back(Args.MakeArgString("-fcoverage-prefix-map=" + Map));
516 A->claim();
517 }
518}
519
520/// Vectorize at all optimization levels greater than 1 except for -Oz.
521/// For -Oz the loop vectorizer is disabled, while the slp vectorizer is
522/// enabled.
523static bool shouldEnableVectorizerAtOLevel(const ArgList &Args, bool isSlpVec) {
524 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
525 if (A->getOption().matches(options::OPT_O4) ||
526 A->getOption().matches(options::OPT_Ofast))
527 return true;
528
529 if (A->getOption().matches(options::OPT_O0))
530 return false;
531
532 assert(A->getOption().matches(options::OPT_O) && "Must have a -O flag");
533
534 // Vectorize -Os.
535 StringRef S(A->getValue());
536 if (S == "s")
537 return true;
538
539 // Don't vectorize -Oz, unless it's the slp vectorizer.
540 if (S == "z")
541 return isSlpVec;
542
543 unsigned OptLevel = 0;
544 if (S.getAsInteger(Radix: 10, Result&: OptLevel))
545 return false;
546
547 return OptLevel > 1;
548 }
549
550 return false;
551}
552
553/// Add -x lang to \p CmdArgs for \p Input.
554static void addDashXForInput(const ArgList &Args, const InputInfo &Input,
555 ArgStringList &CmdArgs) {
556 // When using -verify-pch, we don't want to provide the type
557 // 'precompiled-header' if it was inferred from the file extension
558 if (Args.hasArg(options::OPT_verify_pch) && Input.getType() == types::TY_PCH)
559 return;
560
561 CmdArgs.push_back(Elt: "-x");
562 if (Args.hasArg(options::OPT_rewrite_objc))
563 CmdArgs.push_back(Elt: types::getTypeName(Id: types::TY_PP_ObjCXX));
564 else {
565 // Map the driver type to the frontend type. This is mostly an identity
566 // mapping, except that the distinction between module interface units
567 // and other source files does not exist at the frontend layer.
568 const char *ClangType;
569 switch (Input.getType()) {
570 case types::TY_CXXModule:
571 ClangType = "c++";
572 break;
573 case types::TY_PP_CXXModule:
574 ClangType = "c++-cpp-output";
575 break;
576 default:
577 ClangType = types::getTypeName(Id: Input.getType());
578 break;
579 }
580 CmdArgs.push_back(Elt: ClangType);
581 }
582}
583
584static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C,
585 const JobAction &JA, const InputInfo &Output,
586 const ArgList &Args, SanitizerArgs &SanArgs,
587 ArgStringList &CmdArgs) {
588 const Driver &D = TC.getDriver();
589 auto *PGOGenerateArg = Args.getLastArg(options::OPT_fprofile_generate,
590 options::OPT_fprofile_generate_EQ,
591 options::OPT_fno_profile_generate);
592 if (PGOGenerateArg &&
593 PGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate))
594 PGOGenerateArg = nullptr;
595
596 auto *CSPGOGenerateArg = getLastCSProfileGenerateArg(Args);
597
598 auto *ProfileGenerateArg = Args.getLastArg(
599 options::OPT_fprofile_instr_generate,
600 options::OPT_fprofile_instr_generate_EQ,
601 options::OPT_fno_profile_instr_generate);
602 if (ProfileGenerateArg &&
603 ProfileGenerateArg->getOption().matches(
604 options::OPT_fno_profile_instr_generate))
605 ProfileGenerateArg = nullptr;
606
607 if (PGOGenerateArg && ProfileGenerateArg)
608 D.Diag(diag::err_drv_argument_not_allowed_with)
609 << PGOGenerateArg->getSpelling() << ProfileGenerateArg->getSpelling();
610
611 auto *ProfileUseArg = getLastProfileUseArg(Args);
612
613 if (PGOGenerateArg && ProfileUseArg)
614 D.Diag(diag::err_drv_argument_not_allowed_with)
615 << ProfileUseArg->getSpelling() << PGOGenerateArg->getSpelling();
616
617 if (ProfileGenerateArg && ProfileUseArg)
618 D.Diag(diag::err_drv_argument_not_allowed_with)
619 << ProfileGenerateArg->getSpelling() << ProfileUseArg->getSpelling();
620
621 if (CSPGOGenerateArg && PGOGenerateArg) {
622 D.Diag(diag::err_drv_argument_not_allowed_with)
623 << CSPGOGenerateArg->getSpelling() << PGOGenerateArg->getSpelling();
624 PGOGenerateArg = nullptr;
625 }
626
627 if (TC.getTriple().isOSAIX()) {
628 if (Arg *ProfileSampleUseArg = getLastProfileSampleUseArg(Args))
629 D.Diag(diag::err_drv_unsupported_opt_for_target)
630 << ProfileSampleUseArg->getSpelling() << TC.getTriple().str();
631 }
632
633 if (ProfileGenerateArg) {
634 if (ProfileGenerateArg->getOption().matches(
635 options::OPT_fprofile_instr_generate_EQ))
636 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Twine("-fprofile-instrument-path=") +
637 ProfileGenerateArg->getValue()));
638 // The default is to use Clang Instrumentation.
639 CmdArgs.push_back(Elt: "-fprofile-instrument=clang");
640 if (TC.getTriple().isWindowsMSVCEnvironment() &&
641 Args.hasFlag(options::OPT_frtlib_defaultlib,
642 options::OPT_fno_rtlib_defaultlib, true)) {
643 // Add dependent lib for clang_rt.profile
644 CmdArgs.push_back(Elt: Args.MakeArgString(
645 Str: "--dependent-lib=" + TC.getCompilerRTBasename(Args, Component: "profile")));
646 }
647 }
648
649 Arg *PGOGenArg = nullptr;
650 if (PGOGenerateArg) {
651 assert(!CSPGOGenerateArg);
652 PGOGenArg = PGOGenerateArg;
653 CmdArgs.push_back(Elt: "-fprofile-instrument=llvm");
654 }
655 if (CSPGOGenerateArg) {
656 assert(!PGOGenerateArg);
657 PGOGenArg = CSPGOGenerateArg;
658 CmdArgs.push_back(Elt: "-fprofile-instrument=csllvm");
659 }
660 if (PGOGenArg) {
661 if (TC.getTriple().isWindowsMSVCEnvironment() &&
662 Args.hasFlag(options::OPT_frtlib_defaultlib,
663 options::OPT_fno_rtlib_defaultlib, true)) {
664 // Add dependent lib for clang_rt.profile
665 CmdArgs.push_back(Elt: Args.MakeArgString(
666 Str: "--dependent-lib=" + TC.getCompilerRTBasename(Args, Component: "profile")));
667 }
668 if (PGOGenArg->getOption().matches(
669 PGOGenerateArg ? options::OPT_fprofile_generate_EQ
670 : options::OPT_fcs_profile_generate_EQ)) {
671 SmallString<128> Path(PGOGenArg->getValue());
672 llvm::sys::path::append(path&: Path, a: "default_%m.profraw");
673 CmdArgs.push_back(
674 Elt: Args.MakeArgString(Str: Twine("-fprofile-instrument-path=") + Path));
675 }
676 }
677
678 if (ProfileUseArg) {
679 if (ProfileUseArg->getOption().matches(options::OPT_fprofile_instr_use_EQ))
680 CmdArgs.push_back(Elt: Args.MakeArgString(
681 Str: Twine("-fprofile-instrument-use-path=") + ProfileUseArg->getValue()));
682 else if ((ProfileUseArg->getOption().matches(
683 options::OPT_fprofile_use_EQ) ||
684 ProfileUseArg->getOption().matches(
685 options::OPT_fprofile_instr_use))) {
686 SmallString<128> Path(
687 ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue());
688 if (Path.empty() || llvm::sys::fs::is_directory(Path))
689 llvm::sys::path::append(path&: Path, a: "default.profdata");
690 CmdArgs.push_back(
691 Elt: Args.MakeArgString(Str: Twine("-fprofile-instrument-use-path=") + Path));
692 }
693 }
694
695 bool EmitCovNotes = Args.hasFlag(options::OPT_ftest_coverage,
696 options::OPT_fno_test_coverage, false) ||
697 Args.hasArg(options::OPT_coverage);
698 bool EmitCovData = TC.needsGCovInstrumentation(Args);
699
700 if (Args.hasFlag(options::OPT_fcoverage_mapping,
701 options::OPT_fno_coverage_mapping, false)) {
702 if (!ProfileGenerateArg)
703 D.Diag(clang::diag::err_drv_argument_only_allowed_with)
704 << "-fcoverage-mapping"
705 << "-fprofile-instr-generate";
706
707 CmdArgs.push_back(Elt: "-fcoverage-mapping");
708 }
709
710 if (Args.hasFlag(options::OPT_fmcdc_coverage, options::OPT_fno_mcdc_coverage,
711 false)) {
712 if (!Args.hasFlag(options::OPT_fcoverage_mapping,
713 options::OPT_fno_coverage_mapping, false))
714 D.Diag(clang::diag::err_drv_argument_only_allowed_with)
715 << "-fcoverage-mcdc"
716 << "-fcoverage-mapping";
717
718 CmdArgs.push_back(Elt: "-fcoverage-mcdc");
719 }
720
721 if (Arg *A = Args.getLastArg(options::OPT_ffile_compilation_dir_EQ,
722 options::OPT_fcoverage_compilation_dir_EQ)) {
723 if (A->getOption().matches(options::OPT_ffile_compilation_dir_EQ))
724 CmdArgs.push_back(Elt: Args.MakeArgString(
725 Str: Twine("-fcoverage-compilation-dir=") + A->getValue()));
726 else
727 A->render(Args, Output&: CmdArgs);
728 } else if (llvm::ErrorOr<std::string> CWD =
729 D.getVFS().getCurrentWorkingDirectory()) {
730 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-fcoverage-compilation-dir=" + *CWD));
731 }
732
733 if (Args.hasArg(options::OPT_fprofile_exclude_files_EQ)) {
734 auto *Arg = Args.getLastArg(options::OPT_fprofile_exclude_files_EQ);
735 if (!Args.hasArg(options::OPT_coverage))
736 D.Diag(clang::diag::err_drv_argument_only_allowed_with)
737 << "-fprofile-exclude-files="
738 << "--coverage";
739
740 StringRef v = Arg->getValue();
741 CmdArgs.push_back(
742 Elt: Args.MakeArgString(Str: Twine("-fprofile-exclude-files=" + v)));
743 }
744
745 if (Args.hasArg(options::OPT_fprofile_filter_files_EQ)) {
746 auto *Arg = Args.getLastArg(options::OPT_fprofile_filter_files_EQ);
747 if (!Args.hasArg(options::OPT_coverage))
748 D.Diag(clang::diag::err_drv_argument_only_allowed_with)
749 << "-fprofile-filter-files="
750 << "--coverage";
751
752 StringRef v = Arg->getValue();
753 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Twine("-fprofile-filter-files=" + v)));
754 }
755
756 if (const auto *A = Args.getLastArg(options::OPT_fprofile_update_EQ)) {
757 StringRef Val = A->getValue();
758 if (Val == "atomic" || Val == "prefer-atomic")
759 CmdArgs.push_back(Elt: "-fprofile-update=atomic");
760 else if (Val != "single")
761 D.Diag(diag::err_drv_unsupported_option_argument)
762 << A->getSpelling() << Val;
763 }
764
765 int FunctionGroups = 1;
766 int SelectedFunctionGroup = 0;
767 if (const auto *A = Args.getLastArg(options::OPT_fprofile_function_groups)) {
768 StringRef Val = A->getValue();
769 if (Val.getAsInteger(0, FunctionGroups) || FunctionGroups < 1)
770 D.Diag(diag::err_drv_invalid_int_value) << A->getAsString(Args) << Val;
771 }
772 if (const auto *A =
773 Args.getLastArg(options::OPT_fprofile_selected_function_group)) {
774 StringRef Val = A->getValue();
775 if (Val.getAsInteger(0, SelectedFunctionGroup) ||
776 SelectedFunctionGroup < 0 || SelectedFunctionGroup >= FunctionGroups)
777 D.Diag(diag::err_drv_invalid_int_value) << A->getAsString(Args) << Val;
778 }
779 if (FunctionGroups != 1)
780 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-fprofile-function-groups=" +
781 Twine(FunctionGroups)));
782 if (SelectedFunctionGroup != 0)
783 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-fprofile-selected-function-group=" +
784 Twine(SelectedFunctionGroup)));
785
786 // Leave -fprofile-dir= an unused argument unless .gcda emission is
787 // enabled. To be polite, with '-fprofile-arcs -fno-profile-arcs' consider
788 // the flag used. There is no -fno-profile-dir, so the user has no
789 // targeted way to suppress the warning.
790 Arg *FProfileDir = nullptr;
791 if (Args.hasArg(options::OPT_fprofile_arcs) ||
792 Args.hasArg(options::OPT_coverage))
793 FProfileDir = Args.getLastArg(options::OPT_fprofile_dir);
794
795 // TODO: Don't claim -c/-S to warn about -fsyntax-only -c/-S, -E -c/-S,
796 // like we warn about -fsyntax-only -E.
797 (void)(Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S));
798
799 // Put the .gcno and .gcda files (if needed) next to the primary output file,
800 // or fall back to a file in the current directory for `clang -c --coverage
801 // d/a.c` in the absence of -o.
802 if (EmitCovNotes || EmitCovData) {
803 SmallString<128> CoverageFilename;
804 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
805 // Form ${dumpdir}${basename}.gcno. Note that dumpdir may not end with a
806 // path separator.
807 CoverageFilename = DumpDir->getValue();
808 CoverageFilename += llvm::sys::path::filename(path: Output.getBaseInput());
809 } else if (Arg *FinalOutput =
810 C.getArgs().getLastArg(options::OPT__SLASH_Fo)) {
811 CoverageFilename = FinalOutput->getValue();
812 } else if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o)) {
813 CoverageFilename = FinalOutput->getValue();
814 } else {
815 CoverageFilename = llvm::sys::path::filename(path: Output.getBaseInput());
816 }
817 if (llvm::sys::path::is_relative(path: CoverageFilename))
818 (void)D.getVFS().makeAbsolute(Path&: CoverageFilename);
819 llvm::sys::path::replace_extension(path&: CoverageFilename, extension: "gcno");
820 if (EmitCovNotes) {
821 CmdArgs.push_back(
822 Elt: Args.MakeArgString(Str: "-coverage-notes-file=" + CoverageFilename));
823 }
824
825 if (EmitCovData) {
826 if (FProfileDir) {
827 SmallString<128> Gcno = std::move(CoverageFilename);
828 CoverageFilename = FProfileDir->getValue();
829 llvm::sys::path::append(path&: CoverageFilename, a: Gcno);
830 }
831 llvm::sys::path::replace_extension(path&: CoverageFilename, extension: "gcda");
832 CmdArgs.push_back(
833 Elt: Args.MakeArgString(Str: "-coverage-data-file=" + CoverageFilename));
834 }
835 }
836}
837
838/// Check whether the given input tree contains any compilation actions.
839static bool ContainsCompileAction(const Action *A) {
840 if (isa<CompileJobAction>(Val: A) || isa<BackendJobAction>(Val: A))
841 return true;
842
843 return llvm::any_of(Range: A->inputs(), P: ContainsCompileAction);
844}
845
846/// Check if -relax-all should be passed to the internal assembler.
847/// This is done by default when compiling non-assembler source with -O0.
848static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
849 bool RelaxDefault = true;
850
851 if (Arg *A = Args.getLastArg(options::OPT_O_Group))
852 RelaxDefault = A->getOption().matches(options::OPT_O0);
853
854 // RISC-V requires an indirect jump for offsets larger than 1MiB. This cannot
855 // be done by assembler branch relaxation as it needs a free temporary
856 // register. Because of this, branch relaxation is handled by a MachineIR
857 // pass before the assembler. Forcing assembler branch relaxation for -O0
858 // makes the MachineIR branch relaxation inaccurate and it will miss cases
859 // where an indirect branch is necessary. To avoid this issue we are
860 // sacrificing the compile time improvement of using -mrelax-all for -O0.
861 if (C.getDefaultToolChain().getTriple().isRISCV())
862 RelaxDefault = false;
863
864 if (RelaxDefault) {
865 RelaxDefault = false;
866 for (const auto &Act : C.getActions()) {
867 if (ContainsCompileAction(A: Act)) {
868 RelaxDefault = true;
869 break;
870 }
871 }
872 }
873
874 return Args.hasFlag(options::OPT_mrelax_all, options::OPT_mno_relax_all,
875 RelaxDefault);
876}
877
878static void
879RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs,
880 llvm::codegenoptions::DebugInfoKind DebugInfoKind,
881 unsigned DwarfVersion,
882 llvm::DebuggerKind DebuggerTuning) {
883 addDebugInfoKind(CmdArgs, DebugInfoKind);
884 if (DwarfVersion > 0)
885 CmdArgs.push_back(
886 Elt: Args.MakeArgString(Str: "-dwarf-version=" + Twine(DwarfVersion)));
887 switch (DebuggerTuning) {
888 case llvm::DebuggerKind::GDB:
889 CmdArgs.push_back(Elt: "-debugger-tuning=gdb");
890 break;
891 case llvm::DebuggerKind::LLDB:
892 CmdArgs.push_back(Elt: "-debugger-tuning=lldb");
893 break;
894 case llvm::DebuggerKind::SCE:
895 CmdArgs.push_back(Elt: "-debugger-tuning=sce");
896 break;
897 case llvm::DebuggerKind::DBX:
898 CmdArgs.push_back(Elt: "-debugger-tuning=dbx");
899 break;
900 default:
901 break;
902 }
903}
904
905static bool checkDebugInfoOption(const Arg *A, const ArgList &Args,
906 const Driver &D, const ToolChain &TC) {
907 assert(A && "Expected non-nullptr argument.");
908 if (TC.supportsDebugInfoOption(A))
909 return true;
910 D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target)
911 << A->getAsString(Args) << TC.getTripleString();
912 return false;
913}
914
915static void RenderDebugInfoCompressionArgs(const ArgList &Args,
916 ArgStringList &CmdArgs,
917 const Driver &D,
918 const ToolChain &TC) {
919 const Arg *A = Args.getLastArg(options::OPT_gz_EQ);
920 if (!A)
921 return;
922 if (checkDebugInfoOption(A, Args, D, TC)) {
923 StringRef Value = A->getValue();
924 if (Value == "none") {
925 CmdArgs.push_back(Elt: "--compress-debug-sections=none");
926 } else if (Value == "zlib") {
927 if (llvm::compression::zlib::isAvailable()) {
928 CmdArgs.push_back(
929 Elt: Args.MakeArgString(Str: "--compress-debug-sections=" + Twine(Value)));
930 } else {
931 D.Diag(diag::warn_debug_compression_unavailable) << "zlib";
932 }
933 } else if (Value == "zstd") {
934 if (llvm::compression::zstd::isAvailable()) {
935 CmdArgs.push_back(
936 Elt: Args.MakeArgString(Str: "--compress-debug-sections=" + Twine(Value)));
937 } else {
938 D.Diag(diag::warn_debug_compression_unavailable) << "zstd";
939 }
940 } else {
941 D.Diag(diag::err_drv_unsupported_option_argument)
942 << A->getSpelling() << Value;
943 }
944 }
945}
946
947static void handleAMDGPUCodeObjectVersionOptions(const Driver &D,
948 const ArgList &Args,
949 ArgStringList &CmdArgs,
950 bool IsCC1As = false) {
951 // If no version was requested by the user, use the default value from the
952 // back end. This is consistent with the value returned from
953 // getAMDGPUCodeObjectVersion. This lets clang emit IR for amdgpu without
954 // requiring the corresponding llvm to have the AMDGPU target enabled,
955 // provided the user (e.g. front end tests) can use the default.
956 if (haveAMDGPUCodeObjectVersionArgument(D, Args)) {
957 unsigned CodeObjVer = getAMDGPUCodeObjectVersion(D, Args);
958 CmdArgs.insert(I: CmdArgs.begin() + 1,
959 Elt: Args.MakeArgString(Str: Twine("--amdhsa-code-object-version=") +
960 Twine(CodeObjVer)));
961 CmdArgs.insert(I: CmdArgs.begin() + 1, Elt: "-mllvm");
962 // -cc1as does not accept -mcode-object-version option.
963 if (!IsCC1As)
964 CmdArgs.insert(I: CmdArgs.begin() + 1,
965 Elt: Args.MakeArgString(Str: Twine("-mcode-object-version=") +
966 Twine(CodeObjVer)));
967 }
968}
969
970static bool maybeHasClangPchSignature(const Driver &D, StringRef Path) {
971 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MemBuf =
972 D.getVFS().getBufferForFile(Name: Path);
973 if (!MemBuf)
974 return false;
975 llvm::file_magic Magic = llvm::identify_magic(magic: (*MemBuf)->getBuffer());
976 if (Magic == llvm::file_magic::unknown)
977 return false;
978 // Return true for both raw Clang AST files and object files which may
979 // contain a __clangast section.
980 if (Magic == llvm::file_magic::clang_ast)
981 return true;
982 Expected<std::unique_ptr<llvm::object::ObjectFile>> Obj =
983 llvm::object::ObjectFile::createObjectFile(Object: **MemBuf, Type: Magic);
984 return !Obj.takeError();
985}
986
987static bool gchProbe(const Driver &D, StringRef Path) {
988 llvm::ErrorOr<llvm::vfs::Status> Status = D.getVFS().status(Path);
989 if (!Status)
990 return false;
991
992 if (Status->isDirectory()) {
993 std::error_code EC;
994 for (llvm::vfs::directory_iterator DI = D.getVFS().dir_begin(Dir: Path, EC), DE;
995 !EC && DI != DE; DI = DI.increment(EC)) {
996 if (maybeHasClangPchSignature(D, Path: DI->path()))
997 return true;
998 }
999 D.Diag(diag::warn_drv_pch_ignoring_gch_dir) << Path;
1000 return false;
1001 }
1002
1003 if (maybeHasClangPchSignature(D, Path))
1004 return true;
1005 D.Diag(diag::warn_drv_pch_ignoring_gch_file) << Path;
1006 return false;
1007}
1008
1009void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
1010 const Driver &D, const ArgList &Args,
1011 ArgStringList &CmdArgs,
1012 const InputInfo &Output,
1013 const InputInfoList &Inputs) const {
1014 const bool IsIAMCU = getToolChain().getTriple().isOSIAMCU();
1015
1016 CheckPreprocessingOptions(D, Args);
1017
1018 Args.AddLastArg(CmdArgs, options::OPT_C);
1019 Args.AddLastArg(CmdArgs, options::OPT_CC);
1020
1021 // Handle dependency file generation.
1022 Arg *ArgM = Args.getLastArg(options::OPT_MM);
1023 if (!ArgM)
1024 ArgM = Args.getLastArg(options::OPT_M);
1025 Arg *ArgMD = Args.getLastArg(options::OPT_MMD);
1026 if (!ArgMD)
1027 ArgMD = Args.getLastArg(options::OPT_MD);
1028
1029 // -M and -MM imply -w.
1030 if (ArgM)
1031 CmdArgs.push_back(Elt: "-w");
1032 else
1033 ArgM = ArgMD;
1034
1035 if (ArgM) {
1036 // Determine the output location.
1037 const char *DepFile;
1038 if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
1039 DepFile = MF->getValue();
1040 C.addFailureResultFile(Name: DepFile, JA: &JA);
1041 } else if (Output.getType() == types::TY_Dependencies) {
1042 DepFile = Output.getFilename();
1043 } else if (!ArgMD) {
1044 DepFile = "-";
1045 } else {
1046 DepFile = getDependencyFileName(Args, Inputs);
1047 C.addFailureResultFile(Name: DepFile, JA: &JA);
1048 }
1049 CmdArgs.push_back(Elt: "-dependency-file");
1050 CmdArgs.push_back(Elt: DepFile);
1051
1052 bool HasTarget = false;
1053 for (const Arg *A : Args.filtered(options::OPT_MT, options::OPT_MQ)) {
1054 HasTarget = true;
1055 A->claim();
1056 if (A->getOption().matches(options::OPT_MT)) {
1057 A->render(Args, CmdArgs);
1058 } else {
1059 CmdArgs.push_back("-MT");
1060 SmallString<128> Quoted;
1061 quoteMakeTarget(A->getValue(), Quoted);
1062 CmdArgs.push_back(Args.MakeArgString(Quoted));
1063 }
1064 }
1065
1066 // Add a default target if one wasn't specified.
1067 if (!HasTarget) {
1068 const char *DepTarget;
1069
1070 // If user provided -o, that is the dependency target, except
1071 // when we are only generating a dependency file.
1072 Arg *OutputOpt = Args.getLastArg(options::OPT_o);
1073 if (OutputOpt && Output.getType() != types::TY_Dependencies) {
1074 DepTarget = OutputOpt->getValue();
1075 } else {
1076 // Otherwise derive from the base input.
1077 //
1078 // FIXME: This should use the computed output file location.
1079 SmallString<128> P(Inputs[0].getBaseInput());
1080 llvm::sys::path::replace_extension(path&: P, extension: "o");
1081 DepTarget = Args.MakeArgString(Str: llvm::sys::path::filename(path: P));
1082 }
1083
1084 CmdArgs.push_back(Elt: "-MT");
1085 SmallString<128> Quoted;
1086 quoteMakeTarget(Target: DepTarget, Res&: Quoted);
1087 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Quoted));
1088 }
1089
1090 if (ArgM->getOption().matches(options::OPT_M) ||
1091 ArgM->getOption().matches(options::OPT_MD))
1092 CmdArgs.push_back(Elt: "-sys-header-deps");
1093 if ((isa<PrecompileJobAction>(JA) &&
1094 !Args.hasArg(options::OPT_fno_module_file_deps)) ||
1095 Args.hasArg(options::OPT_fmodule_file_deps))
1096 CmdArgs.push_back(Elt: "-module-file-deps");
1097 }
1098
1099 if (Args.hasArg(options::OPT_MG)) {
1100 if (!ArgM || ArgM->getOption().matches(options::OPT_MD) ||
1101 ArgM->getOption().matches(options::OPT_MMD))
1102 D.Diag(diag::err_drv_mg_requires_m_or_mm);
1103 CmdArgs.push_back(Elt: "-MG");
1104 }
1105
1106 Args.AddLastArg(CmdArgs, options::OPT_MP);
1107 Args.AddLastArg(CmdArgs, options::OPT_MV);
1108
1109 // Add offload include arguments specific for CUDA/HIP. This must happen
1110 // before we -I or -include anything else, because we must pick up the
1111 // CUDA/HIP headers from the particular CUDA/ROCm installation, rather than
1112 // from e.g. /usr/local/include.
1113 if (JA.isOffloading(OKind: Action::OFK_Cuda))
1114 getToolChain().AddCudaIncludeArgs(DriverArgs: Args, CC1Args&: CmdArgs);
1115 if (JA.isOffloading(OKind: Action::OFK_HIP))
1116 getToolChain().AddHIPIncludeArgs(DriverArgs: Args, CC1Args&: CmdArgs);
1117
1118 // If we are compiling for a GPU target we want to override the system headers
1119 // with ones created by the 'libc' project if present.
1120 if (!Args.hasArg(options::OPT_nostdinc) &&
1121 !Args.hasArg(options::OPT_nogpuinc) &&
1122 !Args.hasArg(options::OPT_nobuiltininc)) {
1123 // Without an offloading language we will include these headers directly.
1124 // Offloading languages will instead only use the declarations stored in
1125 // the resource directory at clang/lib/Headers/llvm_libc_wrappers.
1126 if ((getToolChain().getTriple().isNVPTX() ||
1127 getToolChain().getTriple().isAMDGCN()) &&
1128 C.getActiveOffloadKinds() == Action::OFK_None) {
1129 SmallString<128> P(llvm::sys::path::parent_path(path: D.Dir));
1130 llvm::sys::path::append(path&: P, a: "include");
1131 llvm::sys::path::append(path&: P, a: getToolChain().getTripleString());
1132 CmdArgs.push_back(Elt: "-internal-isystem");
1133 CmdArgs.push_back(Elt: Args.MakeArgString(Str: P));
1134 } else if (C.getActiveOffloadKinds() == Action::OFK_OpenMP) {
1135 // TODO: CUDA / HIP include their own headers for some common functions
1136 // implemented here. We'll need to clean those up so they do not conflict.
1137 SmallString<128> P(D.ResourceDir);
1138 llvm::sys::path::append(path&: P, a: "include");
1139 llvm::sys::path::append(path&: P, a: "llvm_libc_wrappers");
1140 CmdArgs.push_back(Elt: "-internal-isystem");
1141 CmdArgs.push_back(Elt: Args.MakeArgString(Str: P));
1142 }
1143 }
1144
1145 // If we are offloading to a target via OpenMP we need to include the
1146 // openmp_wrappers folder which contains alternative system headers.
1147 if (JA.isDeviceOffloading(Action::OFK_OpenMP) &&
1148 !Args.hasArg(options::OPT_nostdinc) &&
1149 !Args.hasArg(options::OPT_nogpuinc) &&
1150 (getToolChain().getTriple().isNVPTX() ||
1151 getToolChain().getTriple().isAMDGCN())) {
1152 if (!Args.hasArg(options::OPT_nobuiltininc)) {
1153 // Add openmp_wrappers/* to our system include path. This lets us wrap
1154 // standard library headers.
1155 SmallString<128> P(D.ResourceDir);
1156 llvm::sys::path::append(path&: P, a: "include");
1157 llvm::sys::path::append(path&: P, a: "openmp_wrappers");
1158 CmdArgs.push_back(Elt: "-internal-isystem");
1159 CmdArgs.push_back(Elt: Args.MakeArgString(Str: P));
1160 }
1161
1162 CmdArgs.push_back(Elt: "-include");
1163 CmdArgs.push_back(Elt: "__clang_openmp_device_functions.h");
1164 }
1165
1166 // Add -i* options, and automatically translate to
1167 // -include-pch/-include-pth for transparent PCH support. It's
1168 // wonky, but we include looking for .gch so we can support seamless
1169 // replacement into a build system already set up to be generating
1170 // .gch files.
1171
1172 if (getToolChain().getDriver().IsCLMode()) {
1173 const Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
1174 const Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
1175 if (YcArg && JA.getKind() >= Action::PrecompileJobClass &&
1176 JA.getKind() <= Action::AssembleJobClass) {
1177 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-building-pch-with-obj"));
1178 // -fpch-instantiate-templates is the default when creating
1179 // precomp using /Yc
1180 if (Args.hasFlag(options::OPT_fpch_instantiate_templates,
1181 options::OPT_fno_pch_instantiate_templates, true))
1182 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-fpch-instantiate-templates"));
1183 }
1184 if (YcArg || YuArg) {
1185 StringRef ThroughHeader = YcArg ? YcArg->getValue() : YuArg->getValue();
1186 if (!isa<PrecompileJobAction>(Val: JA)) {
1187 CmdArgs.push_back(Elt: "-include-pch");
1188 CmdArgs.push_back(Elt: Args.MakeArgString(Str: D.GetClPchPath(
1189 C, BaseName: !ThroughHeader.empty()
1190 ? ThroughHeader
1191 : llvm::sys::path::filename(path: Inputs[0].getBaseInput()))));
1192 }
1193
1194 if (ThroughHeader.empty()) {
1195 CmdArgs.push_back(Elt: Args.MakeArgString(
1196 Str: Twine("-pch-through-hdrstop-") + (YcArg ? "create" : "use")));
1197 } else {
1198 CmdArgs.push_back(
1199 Elt: Args.MakeArgString(Str: Twine("-pch-through-header=") + ThroughHeader));
1200 }
1201 }
1202 }
1203
1204 bool RenderedImplicitInclude = false;
1205 for (const Arg *A : Args.filtered(options::OPT_clang_i_Group)) {
1206 if (A->getOption().matches(options::OPT_include) &&
1207 D.getProbePrecompiled()) {
1208 // Handling of gcc-style gch precompiled headers.
1209 bool IsFirstImplicitInclude = !RenderedImplicitInclude;
1210 RenderedImplicitInclude = true;
1211
1212 bool FoundPCH = false;
1213 SmallString<128> P(A->getValue());
1214 // We want the files to have a name like foo.h.pch. Add a dummy extension
1215 // so that replace_extension does the right thing.
1216 P += ".dummy";
1217 llvm::sys::path::replace_extension(P, "pch");
1218 if (D.getVFS().exists(P))
1219 FoundPCH = true;
1220
1221 if (!FoundPCH) {
1222 // For GCC compat, probe for a file or directory ending in .gch instead.
1223 llvm::sys::path::replace_extension(P, "gch");
1224 FoundPCH = gchProbe(D, P.str());
1225 }
1226
1227 if (FoundPCH) {
1228 if (IsFirstImplicitInclude) {
1229 A->claim();
1230 CmdArgs.push_back("-include-pch");
1231 CmdArgs.push_back(Args.MakeArgString(P));
1232 continue;
1233 } else {
1234 // Ignore the PCH if not first on command line and emit warning.
1235 D.Diag(diag::warn_drv_pch_not_first_include) << P
1236 << A->getAsString(Args);
1237 }
1238 }
1239 } else if (A->getOption().matches(options::OPT_isystem_after)) {
1240 // Handling of paths which must come late. These entries are handled by
1241 // the toolchain itself after the resource dir is inserted in the right
1242 // search order.
1243 // Do not claim the argument so that the use of the argument does not
1244 // silently go unnoticed on toolchains which do not honour the option.
1245 continue;
1246 } else if (A->getOption().matches(options::OPT_stdlibxx_isystem)) {
1247 // Translated to -internal-isystem by the driver, no need to pass to cc1.
1248 continue;
1249 } else if (A->getOption().matches(options::OPT_ibuiltininc)) {
1250 // This is used only by the driver. No need to pass to cc1.
1251 continue;
1252 }
1253
1254 // Not translated, render as usual.
1255 A->claim();
1256 A->render(Args, CmdArgs);
1257 }
1258
1259 Args.addAllArgs(CmdArgs,
1260 {options::OPT_D, options::OPT_U, options::OPT_I_Group,
1261 options::OPT_F, options::OPT_index_header_map});
1262
1263 // Add -Wp, and -Xpreprocessor if using the preprocessor.
1264
1265 // FIXME: There is a very unfortunate problem here, some troubled
1266 // souls abuse -Wp, to pass preprocessor options in gcc syntax. To
1267 // really support that we would have to parse and then translate
1268 // those options. :(
1269 Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
1270 options::OPT_Xpreprocessor);
1271
1272 // -I- is a deprecated GCC feature, reject it.
1273 if (Arg *A = Args.getLastArg(options::OPT_I_))
1274 D.Diag(diag::err_drv_I_dash_not_supported) << A->getAsString(Args);
1275
1276 // If we have a --sysroot, and don't have an explicit -isysroot flag, add an
1277 // -isysroot to the CC1 invocation.
1278 StringRef sysroot = C.getSysRoot();
1279 if (sysroot != "") {
1280 if (!Args.hasArg(options::OPT_isysroot)) {
1281 CmdArgs.push_back(Elt: "-isysroot");
1282 CmdArgs.push_back(Elt: C.getArgs().MakeArgString(Str: sysroot));
1283 }
1284 }
1285
1286 // Parse additional include paths from environment variables.
1287 // FIXME: We should probably sink the logic for handling these from the
1288 // frontend into the driver. It will allow deleting 4 otherwise unused flags.
1289 // CPATH - included following the user specified includes (but prior to
1290 // builtin and standard includes).
1291 addDirectoryList(Args, CmdArgs, ArgName: "-I", EnvVar: "CPATH");
1292 // C_INCLUDE_PATH - system includes enabled when compiling C.
1293 addDirectoryList(Args, CmdArgs, ArgName: "-c-isystem", EnvVar: "C_INCLUDE_PATH");
1294 // CPLUS_INCLUDE_PATH - system includes enabled when compiling C++.
1295 addDirectoryList(Args, CmdArgs, ArgName: "-cxx-isystem", EnvVar: "CPLUS_INCLUDE_PATH");
1296 // OBJC_INCLUDE_PATH - system includes enabled when compiling ObjC.
1297 addDirectoryList(Args, CmdArgs, ArgName: "-objc-isystem", EnvVar: "OBJC_INCLUDE_PATH");
1298 // OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++.
1299 addDirectoryList(Args, CmdArgs, ArgName: "-objcxx-isystem", EnvVar: "OBJCPLUS_INCLUDE_PATH");
1300
1301 // While adding the include arguments, we also attempt to retrieve the
1302 // arguments of related offloading toolchains or arguments that are specific
1303 // of an offloading programming model.
1304
1305 // Add C++ include arguments, if needed.
1306 if (types::isCXX(Id: Inputs[0].getType())) {
1307 bool HasStdlibxxIsystem = Args.hasArg(options::OPT_stdlibxx_isystem);
1308 forAllAssociatedToolChains(
1309 C, JA, RegularToolChain: getToolChain(),
1310 Work: [&Args, &CmdArgs, HasStdlibxxIsystem](const ToolChain &TC) {
1311 HasStdlibxxIsystem ? TC.AddClangCXXStdlibIsystemArgs(DriverArgs: Args, CC1Args&: CmdArgs)
1312 : TC.AddClangCXXStdlibIncludeArgs(DriverArgs: Args, CC1Args&: CmdArgs);
1313 });
1314 }
1315
1316 // Add system include arguments for all targets but IAMCU.
1317 if (!IsIAMCU)
1318 forAllAssociatedToolChains(C, JA, RegularToolChain: getToolChain(),
1319 Work: [&Args, &CmdArgs](const ToolChain &TC) {
1320 TC.AddClangSystemIncludeArgs(DriverArgs: Args, CC1Args&: CmdArgs);
1321 });
1322 else {
1323 // For IAMCU add special include arguments.
1324 getToolChain().AddIAMCUIncludeArgs(DriverArgs: Args, CC1Args&: CmdArgs);
1325 }
1326
1327 addMacroPrefixMapArg(D, Args, CmdArgs);
1328 addCoveragePrefixMapArg(D, Args, CmdArgs);
1329
1330 Args.AddLastArg(CmdArgs, options::OPT_ffile_reproducible,
1331 options::OPT_fno_file_reproducible);
1332
1333 if (const char *Epoch = std::getenv(name: "SOURCE_DATE_EPOCH")) {
1334 CmdArgs.push_back(Elt: "-source-date-epoch");
1335 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Epoch));
1336 }
1337
1338 Args.addOptInFlag(CmdArgs, options::OPT_fdefine_target_os_macros,
1339 options::OPT_fno_define_target_os_macros);
1340}
1341
1342// FIXME: Move to target hook.
1343static bool isSignedCharDefault(const llvm::Triple &Triple) {
1344 switch (Triple.getArch()) {
1345 default:
1346 return true;
1347
1348 case llvm::Triple::aarch64:
1349 case llvm::Triple::aarch64_32:
1350 case llvm::Triple::aarch64_be:
1351 case llvm::Triple::arm:
1352 case llvm::Triple::armeb:
1353 case llvm::Triple::thumb:
1354 case llvm::Triple::thumbeb:
1355 if (Triple.isOSDarwin() || Triple.isOSWindows())
1356 return true;
1357 return false;
1358
1359 case llvm::Triple::ppc:
1360 case llvm::Triple::ppc64:
1361 if (Triple.isOSDarwin())
1362 return true;
1363 return false;
1364
1365 case llvm::Triple::hexagon:
1366 case llvm::Triple::ppcle:
1367 case llvm::Triple::ppc64le:
1368 case llvm::Triple::riscv32:
1369 case llvm::Triple::riscv64:
1370 case llvm::Triple::systemz:
1371 case llvm::Triple::xcore:
1372 return false;
1373 }
1374}
1375
1376static bool hasMultipleInvocations(const llvm::Triple &Triple,
1377 const ArgList &Args) {
1378 // Supported only on Darwin where we invoke the compiler multiple times
1379 // followed by an invocation to lipo.
1380 if (!Triple.isOSDarwin())
1381 return false;
1382 // If more than one "-arch <arch>" is specified, we're targeting multiple
1383 // architectures resulting in a fat binary.
1384 return Args.getAllArgValues(options::OPT_arch).size() > 1;
1385}
1386
1387static bool checkRemarksOptions(const Driver &D, const ArgList &Args,
1388 const llvm::Triple &Triple) {
1389 // When enabling remarks, we need to error if:
1390 // * The remark file is specified but we're targeting multiple architectures,
1391 // which means more than one remark file is being generated.
1392 bool hasMultipleInvocations = ::hasMultipleInvocations(Triple, Args);
1393 bool hasExplicitOutputFile =
1394 Args.getLastArg(options::OPT_foptimization_record_file_EQ);
1395 if (hasMultipleInvocations && hasExplicitOutputFile) {
1396 D.Diag(diag::err_drv_invalid_output_with_multiple_archs)
1397 << "-foptimization-record-file";
1398 return false;
1399 }
1400 return true;
1401}
1402
1403static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs,
1404 const llvm::Triple &Triple,
1405 const InputInfo &Input,
1406 const InputInfo &Output, const JobAction &JA) {
1407 StringRef Format = "yaml";
1408 if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ))
1409 Format = A->getValue();
1410
1411 CmdArgs.push_back(Elt: "-opt-record-file");
1412
1413 const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ);
1414 if (A) {
1415 CmdArgs.push_back(Elt: A->getValue());
1416 } else {
1417 bool hasMultipleArchs =
1418 Triple.isOSDarwin() && // Only supported on Darwin platforms.
1419 Args.getAllArgValues(options::OPT_arch).size() > 1;
1420
1421 SmallString<128> F;
1422
1423 if (Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S)) {
1424 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
1425 F = FinalOutput->getValue();
1426 } else {
1427 if (Format != "yaml" && // For YAML, keep the original behavior.
1428 Triple.isOSDarwin() && // Enable this only on darwin, since it's the only platform supporting .dSYM bundles.
1429 Output.isFilename())
1430 F = Output.getFilename();
1431 }
1432
1433 if (F.empty()) {
1434 // Use the input filename.
1435 F = llvm::sys::path::stem(path: Input.getBaseInput());
1436
1437 // If we're compiling for an offload architecture (i.e. a CUDA device),
1438 // we need to make the file name for the device compilation different
1439 // from the host compilation.
1440 if (!JA.isDeviceOffloading(OKind: Action::OFK_None) &&
1441 !JA.isDeviceOffloading(OKind: Action::OFK_Host)) {
1442 llvm::sys::path::replace_extension(path&: F, extension: "");
1443 F += Action::GetOffloadingFileNamePrefix(Kind: JA.getOffloadingDeviceKind(),
1444 NormalizedTriple: Triple.normalize());
1445 F += "-";
1446 F += JA.getOffloadingArch();
1447 }
1448 }
1449
1450 // If we're having more than one "-arch", we should name the files
1451 // differently so that every cc1 invocation writes to a different file.
1452 // We're doing that by appending "-<arch>" with "<arch>" being the arch
1453 // name from the triple.
1454 if (hasMultipleArchs) {
1455 // First, remember the extension.
1456 SmallString<64> OldExtension = llvm::sys::path::extension(path: F);
1457 // then, remove it.
1458 llvm::sys::path::replace_extension(path&: F, extension: "");
1459 // attach -<arch> to it.
1460 F += "-";
1461 F += Triple.getArchName();
1462 // put back the extension.
1463 llvm::sys::path::replace_extension(path&: F, extension: OldExtension);
1464 }
1465
1466 SmallString<32> Extension;
1467 Extension += "opt.";
1468 Extension += Format;
1469
1470 llvm::sys::path::replace_extension(path&: F, extension: Extension);
1471 CmdArgs.push_back(Elt: Args.MakeArgString(Str: F));
1472 }
1473
1474 if (const Arg *A =
1475 Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) {
1476 CmdArgs.push_back(Elt: "-opt-record-passes");
1477 CmdArgs.push_back(Elt: A->getValue());
1478 }
1479
1480 if (!Format.empty()) {
1481 CmdArgs.push_back(Elt: "-opt-record-format");
1482 CmdArgs.push_back(Elt: Format.data());
1483 }
1484}
1485
1486void AddAAPCSVolatileBitfieldArgs(const ArgList &Args, ArgStringList &CmdArgs) {
1487 if (!Args.hasFlag(options::OPT_faapcs_bitfield_width,
1488 options::OPT_fno_aapcs_bitfield_width, true))
1489 CmdArgs.push_back(Elt: "-fno-aapcs-bitfield-width");
1490
1491 if (Args.getLastArg(options::OPT_ForceAAPCSBitfieldLoad))
1492 CmdArgs.push_back(Elt: "-faapcs-bitfield-load");
1493}
1494
1495namespace {
1496void RenderARMABI(const Driver &D, const llvm::Triple &Triple,
1497 const ArgList &Args, ArgStringList &CmdArgs) {
1498 // Select the ABI to use.
1499 // FIXME: Support -meabi.
1500 // FIXME: Parts of this are duplicated in the backend, unify this somehow.
1501 const char *ABIName = nullptr;
1502 if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
1503 ABIName = A->getValue();
1504 } else {
1505 std::string CPU = getCPUName(D, Args, T: Triple, /*FromAs*/ false);
1506 ABIName = llvm::ARM::computeDefaultTargetABI(TT: Triple, CPU).data();
1507 }
1508
1509 CmdArgs.push_back(Elt: "-target-abi");
1510 CmdArgs.push_back(Elt: ABIName);
1511}
1512
1513void AddUnalignedAccessWarning(ArgStringList &CmdArgs) {
1514 auto StrictAlignIter =
1515 llvm::find_if(Range: llvm::reverse(C&: CmdArgs), P: [](StringRef Arg) {
1516 return Arg == "+strict-align" || Arg == "-strict-align";
1517 });
1518 if (StrictAlignIter != CmdArgs.rend() &&
1519 StringRef(*StrictAlignIter) == "+strict-align")
1520 CmdArgs.push_back(Elt: "-Wunaligned-access");
1521}
1522}
1523
1524static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
1525 ArgStringList &CmdArgs, bool isAArch64) {
1526 const Arg *A = isAArch64
1527 ? Args.getLastArg(options::OPT_msign_return_address_EQ,
1528 options::OPT_mbranch_protection_EQ)
1529 : Args.getLastArg(options::OPT_mbranch_protection_EQ);
1530 if (!A)
1531 return;
1532
1533 const Driver &D = TC.getDriver();
1534 const llvm::Triple &Triple = TC.getEffectiveTriple();
1535 if (!(isAArch64 || (Triple.isArmT32() && Triple.isArmMClass())))
1536 D.Diag(diag::warn_incompatible_branch_protection_option)
1537 << Triple.getArchName();
1538
1539 StringRef Scope, Key;
1540 bool IndirectBranches, BranchProtectionPAuthLR, GuardedControlStack;
1541
1542 if (A->getOption().matches(options::OPT_msign_return_address_EQ)) {
1543 Scope = A->getValue();
1544 if (Scope != "none" && Scope != "non-leaf" && Scope != "all")
1545 D.Diag(diag::err_drv_unsupported_option_argument)
1546 << A->getSpelling() << Scope;
1547 Key = "a_key";
1548 IndirectBranches = false;
1549 BranchProtectionPAuthLR = false;
1550 GuardedControlStack = false;
1551 } else {
1552 StringRef DiagMsg;
1553 llvm::ARM::ParsedBranchProtection PBP;
1554 if (!llvm::ARM::parseBranchProtection(A->getValue(), PBP, DiagMsg))
1555 D.Diag(diag::err_drv_unsupported_option_argument)
1556 << A->getSpelling() << DiagMsg;
1557 if (!isAArch64 && PBP.Key == "b_key")
1558 D.Diag(diag::warn_unsupported_branch_protection)
1559 << "b-key" << A->getAsString(Args);
1560 Scope = PBP.Scope;
1561 Key = PBP.Key;
1562 BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
1563 IndirectBranches = PBP.BranchTargetEnforcement;
1564 GuardedControlStack = PBP.GuardedControlStack;
1565 }
1566
1567 CmdArgs.push_back(
1568 Elt: Args.MakeArgString(Str: Twine("-msign-return-address=") + Scope));
1569 if (!Scope.equals(RHS: "none"))
1570 CmdArgs.push_back(
1571 Elt: Args.MakeArgString(Str: Twine("-msign-return-address-key=") + Key));
1572 if (BranchProtectionPAuthLR)
1573 CmdArgs.push_back(
1574 Elt: Args.MakeArgString(Str: Twine("-mbranch-protection-pauth-lr")));
1575 if (IndirectBranches)
1576 CmdArgs.push_back(Elt: "-mbranch-target-enforce");
1577 if (GuardedControlStack)
1578 CmdArgs.push_back(Elt: "-mguarded-control-stack");
1579}
1580
1581void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
1582 ArgStringList &CmdArgs, bool KernelOrKext) const {
1583 RenderARMABI(D: getToolChain().getDriver(), Triple, Args, CmdArgs);
1584
1585 // Determine floating point ABI from the options & target defaults.
1586 arm::FloatABI ABI = arm::getARMFloatABI(TC: getToolChain(), Args);
1587 if (ABI == arm::FloatABI::Soft) {
1588 // Floating point operations and argument passing are soft.
1589 // FIXME: This changes CPP defines, we need -target-soft-float.
1590 CmdArgs.push_back(Elt: "-msoft-float");
1591 CmdArgs.push_back(Elt: "-mfloat-abi");
1592 CmdArgs.push_back(Elt: "soft");
1593 } else if (ABI == arm::FloatABI::SoftFP) {
1594 // Floating point operations are hard, but argument passing is soft.
1595 CmdArgs.push_back(Elt: "-mfloat-abi");
1596 CmdArgs.push_back(Elt: "soft");
1597 } else {
1598 // Floating point operations and argument passing are hard.
1599 assert(ABI == arm::FloatABI::Hard && "Invalid float abi!");
1600 CmdArgs.push_back(Elt: "-mfloat-abi");
1601 CmdArgs.push_back(Elt: "hard");
1602 }
1603
1604 // Forward the -mglobal-merge option for explicit control over the pass.
1605 if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
1606 options::OPT_mno_global_merge)) {
1607 CmdArgs.push_back(Elt: "-mllvm");
1608 if (A->getOption().matches(options::OPT_mno_global_merge))
1609 CmdArgs.push_back(Elt: "-arm-global-merge=false");
1610 else
1611 CmdArgs.push_back(Elt: "-arm-global-merge=true");
1612 }
1613
1614 if (!Args.hasFlag(options::OPT_mimplicit_float,
1615 options::OPT_mno_implicit_float, true))
1616 CmdArgs.push_back(Elt: "-no-implicit-float");
1617
1618 if (Args.getLastArg(options::OPT_mcmse))
1619 CmdArgs.push_back(Elt: "-mcmse");
1620
1621 AddAAPCSVolatileBitfieldArgs(Args, CmdArgs);
1622
1623 // Enable/disable return address signing and indirect branch targets.
1624 CollectARMPACBTIOptions(TC: getToolChain(), Args, CmdArgs, isAArch64: false /*isAArch64*/);
1625
1626 AddUnalignedAccessWarning(CmdArgs);
1627}
1628
1629void Clang::RenderTargetOptions(const llvm::Triple &EffectiveTriple,
1630 const ArgList &Args, bool KernelOrKext,
1631 ArgStringList &CmdArgs) const {
1632 const ToolChain &TC = getToolChain();
1633
1634 // Add the target features
1635 getTargetFeatures(D: TC.getDriver(), Triple: EffectiveTriple, Args, CmdArgs, ForAS: false);
1636
1637 // Add target specific flags.
1638 switch (TC.getArch()) {
1639 default:
1640 break;
1641
1642 case llvm::Triple::arm:
1643 case llvm::Triple::armeb:
1644 case llvm::Triple::thumb:
1645 case llvm::Triple::thumbeb:
1646 // Use the effective triple, which takes into account the deployment target.
1647 AddARMTargetArgs(Triple: EffectiveTriple, Args, CmdArgs, KernelOrKext);
1648 break;
1649
1650 case llvm::Triple::aarch64:
1651 case llvm::Triple::aarch64_32:
1652 case llvm::Triple::aarch64_be:
1653 AddAArch64TargetArgs(Args, CmdArgs);
1654 break;
1655
1656 case llvm::Triple::loongarch32:
1657 case llvm::Triple::loongarch64:
1658 AddLoongArchTargetArgs(Args, CmdArgs);
1659 break;
1660
1661 case llvm::Triple::mips:
1662 case llvm::Triple::mipsel:
1663 case llvm::Triple::mips64:
1664 case llvm::Triple::mips64el:
1665 AddMIPSTargetArgs(Args, CmdArgs);
1666 break;
1667
1668 case llvm::Triple::ppc:
1669 case llvm::Triple::ppcle:
1670 case llvm::Triple::ppc64:
1671 case llvm::Triple::ppc64le:
1672 AddPPCTargetArgs(Args, CmdArgs);
1673 break;
1674
1675 case llvm::Triple::riscv32:
1676 case llvm::Triple::riscv64:
1677 AddRISCVTargetArgs(Args, CmdArgs);
1678 break;
1679
1680 case llvm::Triple::sparc:
1681 case llvm::Triple::sparcel:
1682 case llvm::Triple::sparcv9:
1683 AddSparcTargetArgs(Args, CmdArgs);
1684 break;
1685
1686 case llvm::Triple::systemz:
1687 AddSystemZTargetArgs(Args, CmdArgs);
1688 break;
1689
1690 case llvm::Triple::x86:
1691 case llvm::Triple::x86_64:
1692 AddX86TargetArgs(Args, CmdArgs);
1693 break;
1694
1695 case llvm::Triple::lanai:
1696 AddLanaiTargetArgs(Args, CmdArgs);
1697 break;
1698
1699 case llvm::Triple::hexagon:
1700 AddHexagonTargetArgs(Args, CmdArgs);
1701 break;
1702
1703 case llvm::Triple::wasm32:
1704 case llvm::Triple::wasm64:
1705 AddWebAssemblyTargetArgs(Args, CmdArgs);
1706 break;
1707
1708 case llvm::Triple::ve:
1709 AddVETargetArgs(Args, CmdArgs);
1710 break;
1711 }
1712}
1713
1714namespace {
1715void RenderAArch64ABI(const llvm::Triple &Triple, const ArgList &Args,
1716 ArgStringList &CmdArgs) {
1717 const char *ABIName = nullptr;
1718 if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
1719 ABIName = A->getValue();
1720 else if (Triple.isOSDarwin())
1721 ABIName = "darwinpcs";
1722 else
1723 ABIName = "aapcs";
1724
1725 CmdArgs.push_back(Elt: "-target-abi");
1726 CmdArgs.push_back(Elt: ABIName);
1727}
1728}
1729
1730void Clang::AddAArch64TargetArgs(const ArgList &Args,
1731 ArgStringList &CmdArgs) const {
1732 const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
1733
1734 if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) ||
1735 Args.hasArg(options::OPT_mkernel) ||
1736 Args.hasArg(options::OPT_fapple_kext))
1737 CmdArgs.push_back(Elt: "-disable-red-zone");
1738
1739 if (!Args.hasFlag(options::OPT_mimplicit_float,
1740 options::OPT_mno_implicit_float, true))
1741 CmdArgs.push_back(Elt: "-no-implicit-float");
1742
1743 RenderAArch64ABI(Triple, Args, CmdArgs);
1744
1745 // Forward the -mglobal-merge option for explicit control over the pass.
1746 if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
1747 options::OPT_mno_global_merge)) {
1748 CmdArgs.push_back(Elt: "-mllvm");
1749 if (A->getOption().matches(options::OPT_mno_global_merge))
1750 CmdArgs.push_back(Elt: "-aarch64-enable-global-merge=false");
1751 else
1752 CmdArgs.push_back(Elt: "-aarch64-enable-global-merge=true");
1753 }
1754
1755 // Enable/disable return address signing and indirect branch targets.
1756 CollectARMPACBTIOptions(TC: getToolChain(), Args, CmdArgs, isAArch64: true /*isAArch64*/);
1757
1758 // Handle -msve_vector_bits=<bits>
1759 if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) {
1760 StringRef Val = A->getValue();
1761 const Driver &D = getToolChain().getDriver();
1762 if (Val.equals(RHS: "128") || Val.equals(RHS: "256") || Val.equals(RHS: "512") ||
1763 Val.equals(RHS: "1024") || Val.equals(RHS: "2048") || Val.equals(RHS: "128+") ||
1764 Val.equals(RHS: "256+") || Val.equals(RHS: "512+") || Val.equals(RHS: "1024+") ||
1765 Val.equals(RHS: "2048+")) {
1766 unsigned Bits = 0;
1767 if (!Val.consume_back(Suffix: "+")) {
1768 bool Invalid = Val.getAsInteger(Radix: 10, Result&: Bits); (void)Invalid;
1769 assert(!Invalid && "Failed to parse value");
1770 CmdArgs.push_back(
1771 Elt: Args.MakeArgString(Str: "-mvscale-max=" + llvm::Twine(Bits / 128)));
1772 }
1773
1774 bool Invalid = Val.getAsInteger(Radix: 10, Result&: Bits); (void)Invalid;
1775 assert(!Invalid && "Failed to parse value");
1776 CmdArgs.push_back(
1777 Elt: Args.MakeArgString(Str: "-mvscale-min=" + llvm::Twine(Bits / 128)));
1778 // Silently drop requests for vector-length agnostic code as it's implied.
1779 } else if (!Val.equals("scalable"))
1780 // Handle the unsupported values passed to msve-vector-bits.
1781 D.Diag(diag::err_drv_unsupported_option_argument)
1782 << A->getSpelling() << Val;
1783 }
1784
1785 AddAAPCSVolatileBitfieldArgs(Args, CmdArgs);
1786
1787 if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)) {
1788 CmdArgs.push_back(Elt: "-tune-cpu");
1789 if (strcmp(s1: A->getValue(), s2: "native") == 0)
1790 CmdArgs.push_back(Elt: Args.MakeArgString(Str: llvm::sys::getHostCPUName()));
1791 else
1792 CmdArgs.push_back(Elt: A->getValue());
1793 }
1794
1795 AddUnalignedAccessWarning(CmdArgs);
1796
1797 Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_intrinsics,
1798 options::OPT_fno_ptrauth_intrinsics);
1799}
1800
1801void Clang::AddLoongArchTargetArgs(const ArgList &Args,
1802 ArgStringList &CmdArgs) const {
1803 const llvm::Triple &Triple = getToolChain().getTriple();
1804
1805 CmdArgs.push_back(Elt: "-target-abi");
1806 CmdArgs.push_back(
1807 Elt: loongarch::getLoongArchABI(D: getToolChain().getDriver(), Args, Triple)
1808 .data());
1809
1810 // Handle -mtune.
1811 if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
1812 std::string TuneCPU = A->getValue();
1813 TuneCPU = loongarch::postProcessTargetCPUString(CPU: TuneCPU, Triple);
1814 CmdArgs.push_back(Elt: "-tune-cpu");
1815 CmdArgs.push_back(Elt: Args.MakeArgString(Str: TuneCPU));
1816 }
1817}
1818
1819void Clang::AddMIPSTargetArgs(const ArgList &Args,
1820 ArgStringList &CmdArgs) const {
1821 const Driver &D = getToolChain().getDriver();
1822 StringRef CPUName;
1823 StringRef ABIName;
1824 const llvm::Triple &Triple = getToolChain().getTriple();
1825 mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
1826
1827 CmdArgs.push_back(Elt: "-target-abi");
1828 CmdArgs.push_back(Elt: ABIName.data());
1829
1830 mips::FloatABI ABI = mips::getMipsFloatABI(D, Args, Triple);
1831 if (ABI == mips::FloatABI::Soft) {
1832 // Floating point operations and argument passing are soft.
1833 CmdArgs.push_back(Elt: "-msoft-float");
1834 CmdArgs.push_back(Elt: "-mfloat-abi");
1835 CmdArgs.push_back(Elt: "soft");
1836 } else {
1837 // Floating point operations and argument passing are hard.
1838 assert(ABI == mips::FloatABI::Hard && "Invalid float abi!");
1839 CmdArgs.push_back(Elt: "-mfloat-abi");
1840 CmdArgs.push_back(Elt: "hard");
1841 }
1842
1843 if (Arg *A = Args.getLastArg(options::OPT_mldc1_sdc1,
1844 options::OPT_mno_ldc1_sdc1)) {
1845 if (A->getOption().matches(options::OPT_mno_ldc1_sdc1)) {
1846 CmdArgs.push_back(Elt: "-mllvm");
1847 CmdArgs.push_back(Elt: "-mno-ldc1-sdc1");
1848 }
1849 }
1850
1851 if (Arg *A = Args.getLastArg(options::OPT_mcheck_zero_division,
1852 options::OPT_mno_check_zero_division)) {
1853 if (A->getOption().matches(options::OPT_mno_check_zero_division)) {
1854 CmdArgs.push_back(Elt: "-mllvm");
1855 CmdArgs.push_back(Elt: "-mno-check-zero-division");
1856 }
1857 }
1858
1859 if (Args.getLastArg(options::OPT_mfix4300)) {
1860 CmdArgs.push_back(Elt: "-mllvm");
1861 CmdArgs.push_back(Elt: "-mfix4300");
1862 }
1863
1864 if (Arg *A = Args.getLastArg(options::OPT_G)) {
1865 StringRef v = A->getValue();
1866 CmdArgs.push_back(Elt: "-mllvm");
1867 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-mips-ssection-threshold=" + v));
1868 A->claim();
1869 }
1870
1871 Arg *GPOpt = Args.getLastArg(options::OPT_mgpopt, options::OPT_mno_gpopt);
1872 Arg *ABICalls =
1873 Args.getLastArg(options::OPT_mabicalls, options::OPT_mno_abicalls);
1874
1875 // -mabicalls is the default for many MIPS environments, even with -fno-pic.
1876 // -mgpopt is the default for static, -fno-pic environments but these two
1877 // options conflict. We want to be certain that -mno-abicalls -mgpopt is
1878 // the only case where -mllvm -mgpopt is passed.
1879 // NOTE: We need a warning here or in the backend to warn when -mgpopt is
1880 // passed explicitly when compiling something with -mabicalls
1881 // (implictly) in affect. Currently the warning is in the backend.
1882 //
1883 // When the ABI in use is N64, we also need to determine the PIC mode that
1884 // is in use, as -fno-pic for N64 implies -mno-abicalls.
1885 bool NoABICalls =
1886 ABICalls && ABICalls->getOption().matches(options::OPT_mno_abicalls);
1887
1888 llvm::Reloc::Model RelocationModel;
1889 unsigned PICLevel;
1890 bool IsPIE;
1891 std::tie(args&: RelocationModel, args&: PICLevel, args&: IsPIE) =
1892 ParsePICArgs(ToolChain: getToolChain(), Args);
1893
1894 NoABICalls = NoABICalls ||
1895 (RelocationModel == llvm::Reloc::Static && ABIName == "n64");
1896
1897 bool WantGPOpt = GPOpt && GPOpt->getOption().matches(options::OPT_mgpopt);
1898 // We quietly ignore -mno-gpopt as the backend defaults to -mno-gpopt.
1899 if (NoABICalls && (!GPOpt || WantGPOpt)) {
1900 CmdArgs.push_back(Elt: "-mllvm");
1901 CmdArgs.push_back(Elt: "-mgpopt");
1902
1903 Arg *LocalSData = Args.getLastArg(options::OPT_mlocal_sdata,
1904 options::OPT_mno_local_sdata);
1905 Arg *ExternSData = Args.getLastArg(options::OPT_mextern_sdata,
1906 options::OPT_mno_extern_sdata);
1907 Arg *EmbeddedData = Args.getLastArg(options::OPT_membedded_data,
1908 options::OPT_mno_embedded_data);
1909 if (LocalSData) {
1910 CmdArgs.push_back(Elt: "-mllvm");
1911 if (LocalSData->getOption().matches(options::OPT_mlocal_sdata)) {
1912 CmdArgs.push_back(Elt: "-mlocal-sdata=1");
1913 } else {
1914 CmdArgs.push_back(Elt: "-mlocal-sdata=0");
1915 }
1916 LocalSData->claim();
1917 }
1918
1919 if (ExternSData) {
1920 CmdArgs.push_back(Elt: "-mllvm");
1921 if (ExternSData->getOption().matches(options::OPT_mextern_sdata)) {
1922 CmdArgs.push_back(Elt: "-mextern-sdata=1");
1923 } else {
1924 CmdArgs.push_back(Elt: "-mextern-sdata=0");
1925 }
1926 ExternSData->claim();
1927 }
1928
1929 if (EmbeddedData) {
1930 CmdArgs.push_back(Elt: "-mllvm");
1931 if (EmbeddedData->getOption().matches(options::OPT_membedded_data)) {
1932 CmdArgs.push_back(Elt: "-membedded-data=1");
1933 } else {
1934 CmdArgs.push_back(Elt: "-membedded-data=0");
1935 }
1936 EmbeddedData->claim();
1937 }
1938
1939 } else if ((!ABICalls || (!NoABICalls && ABICalls)) && WantGPOpt)
1940 D.Diag(diag::warn_drv_unsupported_gpopt) << (ABICalls ? 0 : 1);
1941
1942 if (GPOpt)
1943 GPOpt->claim();
1944
1945 if (Arg *A = Args.getLastArg(options::OPT_mcompact_branches_EQ)) {
1946 StringRef Val = StringRef(A->getValue());
1947 if (mips::hasCompactBranches(CPU&: CPUName)) {
1948 if (Val == "never" || Val == "always" || Val == "optimal") {
1949 CmdArgs.push_back(Elt: "-mllvm");
1950 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-mips-compact-branches=" + Val));
1951 } else
1952 D.Diag(diag::err_drv_unsupported_option_argument)
1953 << A->getSpelling() << Val;
1954 } else
1955 D.Diag(diag::warn_target_unsupported_compact_branches) << CPUName;
1956 }
1957
1958 if (Arg *A = Args.getLastArg(options::OPT_mrelax_pic_calls,
1959 options::OPT_mno_relax_pic_calls)) {
1960 if (A->getOption().matches(options::OPT_mno_relax_pic_calls)) {
1961 CmdArgs.push_back(Elt: "-mllvm");
1962 CmdArgs.push_back(Elt: "-mips-jalr-reloc=0");
1963 }
1964 }
1965}
1966
1967void Clang::AddPPCTargetArgs(const ArgList &Args,
1968 ArgStringList &CmdArgs) const {
1969 const Driver &D = getToolChain().getDriver();
1970 const llvm::Triple &T = getToolChain().getTriple();
1971 if (Args.getLastArg(options::OPT_mtune_EQ)) {
1972 CmdArgs.push_back(Elt: "-tune-cpu");
1973 std::string CPU = ppc::getPPCTuneCPU(Args, T);
1974 CmdArgs.push_back(Elt: Args.MakeArgString(Str: CPU));
1975 }
1976
1977 // Select the ABI to use.
1978 const char *ABIName = nullptr;
1979 if (T.isOSBinFormatELF()) {
1980 switch (getToolChain().getArch()) {
1981 case llvm::Triple::ppc64: {
1982 if (T.isPPC64ELFv2ABI())
1983 ABIName = "elfv2";
1984 else
1985 ABIName = "elfv1";
1986 break;
1987 }
1988 case llvm::Triple::ppc64le:
1989 ABIName = "elfv2";
1990 break;
1991 default:
1992 break;
1993 }
1994 }
1995
1996 bool IEEELongDouble = getToolChain().defaultToIEEELongDouble();
1997 bool VecExtabi = false;
1998 for (const Arg *A : Args.filtered(options::OPT_mabi_EQ)) {
1999 StringRef V = A->getValue();
2000 if (V == "ieeelongdouble") {
2001 IEEELongDouble = true;
2002 A->claim();
2003 } else if (V == "ibmlongdouble") {
2004 IEEELongDouble = false;
2005 A->claim();
2006 } else if (V == "vec-default") {
2007 VecExtabi = false;
2008 A->claim();
2009 } else if (V == "vec-extabi") {
2010 VecExtabi = true;
2011 A->claim();
2012 } else if (V == "elfv1") {
2013 ABIName = "elfv1";
2014 A->claim();
2015 } else if (V == "elfv2") {
2016 ABIName = "elfv2";
2017 A->claim();
2018 } else if (V != "altivec")
2019 // The ppc64 linux abis are all "altivec" abis by default. Accept and ignore
2020 // the option if given as we don't have backend support for any targets
2021 // that don't use the altivec abi.
2022 ABIName = A->getValue();
2023 }
2024 if (IEEELongDouble)
2025 CmdArgs.push_back(Elt: "-mabi=ieeelongdouble");
2026 if (VecExtabi) {
2027 if (!T.isOSAIX())
2028 D.Diag(diag::err_drv_unsupported_opt_for_target)
2029 << "-mabi=vec-extabi" << T.str();
2030 CmdArgs.push_back(Elt: "-mabi=vec-extabi");
2031 }
2032
2033 ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args);
2034 if (FloatABI == ppc::FloatABI::Soft) {
2035 // Floating point operations and argument passing are soft.
2036 CmdArgs.push_back(Elt: "-msoft-float");
2037 CmdArgs.push_back(Elt: "-mfloat-abi");
2038 CmdArgs.push_back(Elt: "soft");
2039 } else {
2040 // Floating point operations and argument passing are hard.
2041 assert(FloatABI == ppc::FloatABI::Hard && "Invalid float abi!");
2042 CmdArgs.push_back(Elt: "-mfloat-abi");
2043 CmdArgs.push_back(Elt: "hard");
2044 }
2045
2046 if (ABIName) {
2047 CmdArgs.push_back(Elt: "-target-abi");
2048 CmdArgs.push_back(Elt: ABIName);
2049 }
2050}
2051
2052static void SetRISCVSmallDataLimit(const ToolChain &TC, const ArgList &Args,
2053 ArgStringList &CmdArgs) {
2054 const Driver &D = TC.getDriver();
2055 const llvm::Triple &Triple = TC.getTriple();
2056 // Default small data limitation is eight.
2057 const char *SmallDataLimit = "8";
2058 // Get small data limitation.
2059 if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
2060 options::OPT_fPIC)) {
2061 // Not support linker relaxation for PIC.
2062 SmallDataLimit = "0";
2063 if (Args.hasArg(options::OPT_G)) {
2064 D.Diag(diag::warn_drv_unsupported_sdata);
2065 }
2066 } else if (Args.getLastArgValue(options::OPT_mcmodel_EQ)
2067 .equals_insensitive("large") &&
2068 (Triple.getArch() == llvm::Triple::riscv64)) {
2069 // Not support linker relaxation for RV64 with large code model.
2070 SmallDataLimit = "0";
2071 if (Args.hasArg(options::OPT_G)) {
2072 D.Diag(diag::warn_drv_unsupported_sdata);
2073 }
2074 } else if (Triple.isAndroid()) {
2075 // GP relaxation is not supported on Android.
2076 SmallDataLimit = "0";
2077 if (Args.hasArg(options::OPT_G)) {
2078 D.Diag(diag::warn_drv_unsupported_sdata);
2079 }
2080 } else if (Arg *A = Args.getLastArg(options::OPT_G)) {
2081 SmallDataLimit = A->getValue();
2082 }
2083 // Forward the -msmall-data-limit= option.
2084 CmdArgs.push_back(Elt: "-msmall-data-limit");
2085 CmdArgs.push_back(Elt: SmallDataLimit);
2086}
2087
2088void Clang::AddRISCVTargetArgs(const ArgList &Args,
2089 ArgStringList &CmdArgs) const {
2090 const llvm::Triple &Triple = getToolChain().getTriple();
2091 StringRef ABIName = riscv::getRISCVABI(Args, Triple);
2092
2093 CmdArgs.push_back(Elt: "-target-abi");
2094 CmdArgs.push_back(Elt: ABIName.data());
2095
2096 SetRISCVSmallDataLimit(TC: getToolChain(), Args, CmdArgs);
2097
2098 if (!Args.hasFlag(options::OPT_mimplicit_float,
2099 options::OPT_mno_implicit_float, true))
2100 CmdArgs.push_back(Elt: "-no-implicit-float");
2101
2102 if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
2103 CmdArgs.push_back(Elt: "-tune-cpu");
2104 if (strcmp(s1: A->getValue(), s2: "native") == 0)
2105 CmdArgs.push_back(Elt: Args.MakeArgString(Str: llvm::sys::getHostCPUName()));
2106 else
2107 CmdArgs.push_back(Elt: A->getValue());
2108 }
2109
2110 // Handle -mrvv-vector-bits=<bits>
2111 if (Arg *A = Args.getLastArg(options::OPT_mrvv_vector_bits_EQ)) {
2112 StringRef Val = A->getValue();
2113 const Driver &D = getToolChain().getDriver();
2114
2115 // Get minimum VLen from march.
2116 unsigned MinVLen = 0;
2117 StringRef Arch = riscv::getRISCVArch(Args, Triple);
2118 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
2119 Arch, /*EnableExperimentalExtensions*/ EnableExperimentalExtension: true);
2120 // Ignore parsing error.
2121 if (!errorToBool(Err: ISAInfo.takeError()))
2122 MinVLen = (*ISAInfo)->getMinVLen();
2123
2124 // If the value is "zvl", use MinVLen from march. Otherwise, try to parse
2125 // as integer as long as we have a MinVLen.
2126 unsigned Bits = 0;
2127 if (Val.equals(RHS: "zvl") && MinVLen >= llvm::RISCV::RVVBitsPerBlock) {
2128 Bits = MinVLen;
2129 } else if (!Val.getAsInteger(Radix: 10, Result&: Bits)) {
2130 // Only accept power of 2 values beteen RVVBitsPerBlock and 65536 that
2131 // at least MinVLen.
2132 if (Bits < MinVLen || Bits < llvm::RISCV::RVVBitsPerBlock ||
2133 Bits > 65536 || !llvm::isPowerOf2_32(Value: Bits))
2134 Bits = 0;
2135 }
2136
2137 // If we got a valid value try to use it.
2138 if (Bits != 0) {
2139 unsigned VScaleMin = Bits / llvm::RISCV::RVVBitsPerBlock;
2140 CmdArgs.push_back(
2141 Elt: Args.MakeArgString(Str: "-mvscale-max=" + llvm::Twine(VScaleMin)));
2142 CmdArgs.push_back(
2143 Elt: Args.MakeArgString(Str: "-mvscale-min=" + llvm::Twine(VScaleMin)));
2144 } else if (!Val.equals(RHS: "scalable")) {
2145 // Handle the unsupported values passed to mrvv-vector-bits.
2146 D.Diag(diag::err_drv_unsupported_option_argument)
2147 << A->getSpelling() << Val;
2148 }
2149 }
2150}
2151
2152void Clang::AddSparcTargetArgs(const ArgList &Args,
2153 ArgStringList &CmdArgs) const {
2154 sparc::FloatABI FloatABI =
2155 sparc::getSparcFloatABI(D: getToolChain().getDriver(), Args);
2156
2157 if (FloatABI == sparc::FloatABI::Soft) {
2158 // Floating point operations and argument passing are soft.
2159 CmdArgs.push_back(Elt: "-msoft-float");
2160 CmdArgs.push_back(Elt: "-mfloat-abi");
2161 CmdArgs.push_back(Elt: "soft");
2162 } else {
2163 // Floating point operations and argument passing are hard.
2164 assert(FloatABI == sparc::FloatABI::Hard && "Invalid float abi!");
2165 CmdArgs.push_back(Elt: "-mfloat-abi");
2166 CmdArgs.push_back(Elt: "hard");
2167 }
2168
2169 if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)) {
2170 StringRef Name = A->getValue();
2171 std::string TuneCPU;
2172 if (Name == "native")
2173 TuneCPU = std::string(llvm::sys::getHostCPUName());
2174 else
2175 TuneCPU = std::string(Name);
2176
2177 CmdArgs.push_back(Elt: "-tune-cpu");
2178 CmdArgs.push_back(Elt: Args.MakeArgString(Str: TuneCPU));
2179 }
2180}
2181
2182void Clang::AddSystemZTargetArgs(const ArgList &Args,
2183 ArgStringList &CmdArgs) const {
2184 if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
2185 CmdArgs.push_back(Elt: "-tune-cpu");
2186 if (strcmp(s1: A->getValue(), s2: "native") == 0)
2187 CmdArgs.push_back(Elt: Args.MakeArgString(Str: llvm::sys::getHostCPUName()));
2188 else
2189 CmdArgs.push_back(Elt: A->getValue());
2190 }
2191
2192 bool HasBackchain =
2193 Args.hasFlag(options::OPT_mbackchain, options::OPT_mno_backchain, false);
2194 bool HasPackedStack = Args.hasFlag(options::OPT_mpacked_stack,
2195 options::OPT_mno_packed_stack, false);
2196 systemz::FloatABI FloatABI =
2197 systemz::getSystemZFloatABI(D: getToolChain().getDriver(), Args);
2198 bool HasSoftFloat = (FloatABI == systemz::FloatABI::Soft);
2199 if (HasBackchain && HasPackedStack && !HasSoftFloat) {
2200 const Driver &D = getToolChain().getDriver();
2201 D.Diag(diag::err_drv_unsupported_opt)
2202 << "-mpacked-stack -mbackchain -mhard-float";
2203 }
2204 if (HasBackchain)
2205 CmdArgs.push_back(Elt: "-mbackchain");
2206 if (HasPackedStack)
2207 CmdArgs.push_back(Elt: "-mpacked-stack");
2208 if (HasSoftFloat) {
2209 // Floating point operations and argument passing are soft.
2210 CmdArgs.push_back(Elt: "-msoft-float");
2211 CmdArgs.push_back(Elt: "-mfloat-abi");
2212 CmdArgs.push_back(Elt: "soft");
2213 }
2214}
2215
2216void Clang::AddX86TargetArgs(const ArgList &Args,
2217 ArgStringList &CmdArgs) const {
2218 const Driver &D = getToolChain().getDriver();
2219 addX86AlignBranchArgs(D, Args, CmdArgs, /*IsLTO=*/false);
2220
2221 if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) ||
2222 Args.hasArg(options::OPT_mkernel) ||
2223 Args.hasArg(options::OPT_fapple_kext))
2224 CmdArgs.push_back(Elt: "-disable-red-zone");
2225
2226 if (!Args.hasFlag(options::OPT_mtls_direct_seg_refs,
2227 options::OPT_mno_tls_direct_seg_refs, true))
2228 CmdArgs.push_back(Elt: "-mno-tls-direct-seg-refs");
2229
2230 // Default to avoid implicit floating-point for kernel/kext code, but allow
2231 // that to be overridden with -mno-soft-float.
2232 bool NoImplicitFloat = (Args.hasArg(options::OPT_mkernel) ||
2233 Args.hasArg(options::OPT_fapple_kext));
2234 if (Arg *A = Args.getLastArg(
2235 options::OPT_msoft_float, options::OPT_mno_soft_float,
2236 options::OPT_mimplicit_float, options::OPT_mno_implicit_float)) {
2237 const Option &O = A->getOption();
2238 NoImplicitFloat = (O.matches(options::OPT_mno_implicit_float) ||
2239 O.matches(options::OPT_msoft_float));
2240 }
2241 if (NoImplicitFloat)
2242 CmdArgs.push_back(Elt: "-no-implicit-float");
2243
2244 if (Arg *A = Args.getLastArg(options::OPT_masm_EQ)) {
2245 StringRef Value = A->getValue();
2246 if (Value == "intel" || Value == "att") {
2247 CmdArgs.push_back(Elt: "-mllvm");
2248 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-x86-asm-syntax=" + Value));
2249 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-inline-asm=" + Value));
2250 } else {
2251 D.Diag(diag::err_drv_unsupported_option_argument)
2252 << A->getSpelling() << Value;
2253 }
2254 } else if (D.IsCLMode()) {
2255 CmdArgs.push_back(Elt: "-mllvm");
2256 CmdArgs.push_back(Elt: "-x86-asm-syntax=intel");
2257 }
2258
2259 if (Arg *A = Args.getLastArg(options::OPT_mskip_rax_setup,
2260 options::OPT_mno_skip_rax_setup))
2261 if (A->getOption().matches(options::OPT_mskip_rax_setup))
2262 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-mskip-rax-setup"));
2263
2264 // Set flags to support MCU ABI.
2265 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu, false)) {
2266 CmdArgs.push_back(Elt: "-mfloat-abi");
2267 CmdArgs.push_back(Elt: "soft");
2268 CmdArgs.push_back(Elt: "-mstack-alignment=4");
2269 }
2270
2271 // Handle -mtune.
2272
2273 // Default to "generic" unless -march is present or targetting the PS4/PS5.
2274 std::string TuneCPU;
2275 if (!Args.hasArg(clang::driver::options::OPT_march_EQ) &&
2276 !getToolChain().getTriple().isPS())
2277 TuneCPU = "generic";
2278
2279 // Override based on -mtune.
2280 if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)) {
2281 StringRef Name = A->getValue();
2282
2283 if (Name == "native") {
2284 Name = llvm::sys::getHostCPUName();
2285 if (!Name.empty())
2286 TuneCPU = std::string(Name);
2287 } else
2288 TuneCPU = std::string(Name);
2289 }
2290
2291 if (!TuneCPU.empty()) {
2292 CmdArgs.push_back(Elt: "-tune-cpu");
2293 CmdArgs.push_back(Elt: Args.MakeArgString(Str: TuneCPU));
2294 }
2295}
2296
2297void Clang::AddHexagonTargetArgs(const ArgList &Args,
2298 ArgStringList &CmdArgs) const {
2299 CmdArgs.push_back(Elt: "-mqdsp6-compat");
2300 CmdArgs.push_back(Elt: "-Wreturn-type");
2301
2302 if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
2303 CmdArgs.push_back(Elt: "-mllvm");
2304 CmdArgs.push_back(
2305 Elt: Args.MakeArgString(Str: "-hexagon-small-data-threshold=" + Twine(*G)));
2306 }
2307
2308 if (!Args.hasArg(options::OPT_fno_short_enums))
2309 CmdArgs.push_back(Elt: "-fshort-enums");
2310 if (Args.getLastArg(options::OPT_mieee_rnd_near)) {
2311 CmdArgs.push_back(Elt: "-mllvm");
2312 CmdArgs.push_back(Elt: "-enable-hexagon-ieee-rnd-near");
2313 }
2314 CmdArgs.push_back(Elt: "-mllvm");
2315 CmdArgs.push_back(Elt: "-machine-sink-split=0");
2316}
2317
2318void Clang::AddLanaiTargetArgs(const ArgList &Args,
2319 ArgStringList &CmdArgs) const {
2320 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
2321 StringRef CPUName = A->getValue();
2322
2323 CmdArgs.push_back(Elt: "-target-cpu");
2324 CmdArgs.push_back(Elt: Args.MakeArgString(Str: CPUName));
2325 }
2326 if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
2327 StringRef Value = A->getValue();
2328 // Only support mregparm=4 to support old usage. Report error for all other
2329 // cases.
2330 int Mregparm;
2331 if (Value.getAsInteger(Radix: 10, Result&: Mregparm)) {
2332 if (Mregparm != 4) {
2333 getToolChain().getDriver().Diag(
2334 diag::err_drv_unsupported_option_argument)
2335 << A->getSpelling() << Value;
2336 }
2337 }
2338 }
2339}
2340
2341void Clang::AddWebAssemblyTargetArgs(const ArgList &Args,
2342 ArgStringList &CmdArgs) const {
2343 // Default to "hidden" visibility.
2344 if (!Args.hasArg(options::OPT_fvisibility_EQ,
2345 options::OPT_fvisibility_ms_compat))
2346 CmdArgs.push_back(Elt: "-fvisibility=hidden");
2347}
2348
2349void Clang::AddVETargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
2350 // Floating point operations and argument passing are hard.
2351 CmdArgs.push_back(Elt: "-mfloat-abi");
2352 CmdArgs.push_back(Elt: "hard");
2353}
2354
2355void Clang::DumpCompilationDatabase(Compilation &C, StringRef Filename,
2356 StringRef Target, const InputInfo &Output,
2357 const InputInfo &Input, const ArgList &Args) const {
2358 // If this is a dry run, do not create the compilation database file.
2359 if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH))
2360 return;
2361
2362 using llvm::yaml::escape;
2363 const Driver &D = getToolChain().getDriver();
2364
2365 if (!CompilationDatabase) {
2366 std::error_code EC;
2367 auto File = std::make_unique<llvm::raw_fd_ostream>(
2368 args&: Filename, args&: EC,
2369 args: llvm::sys::fs::OF_TextWithCRLF | llvm::sys::fs::OF_Append);
2370 if (EC) {
2371 D.Diag(clang::diag::err_drv_compilationdatabase) << Filename
2372 << EC.message();
2373 return;
2374 }
2375 CompilationDatabase = std::move(File);
2376 }
2377 auto &CDB = *CompilationDatabase;
2378 auto CWD = D.getVFS().getCurrentWorkingDirectory();
2379 if (!CWD)
2380 CWD = ".";
2381 CDB << "{ \"directory\": \"" << escape(Input: *CWD) << "\"";
2382 CDB << ", \"file\": \"" << escape(Input: Input.getFilename()) << "\"";
2383 if (Output.isFilename())
2384 CDB << ", \"output\": \"" << escape(Input: Output.getFilename()) << "\"";
2385 CDB << ", \"arguments\": [\"" << escape(Input: D.ClangExecutable) << "\"";
2386 SmallString<128> Buf;
2387 Buf = "-x";
2388 Buf += types::getTypeName(Id: Input.getType());
2389 CDB << ", \"" << escape(Input: Buf) << "\"";
2390 if (!D.SysRoot.empty() && !Args.hasArg(options::OPT__sysroot_EQ)) {
2391 Buf = "--sysroot=";
2392 Buf += D.SysRoot;
2393 CDB << ", \"" << escape(Input: Buf) << "\"";
2394 }
2395 CDB << ", \"" << escape(Input: Input.getFilename()) << "\"";
2396 if (Output.isFilename())
2397 CDB << ", \"-o\", \"" << escape(Input: Output.getFilename()) << "\"";
2398 for (auto &A: Args) {
2399 auto &O = A->getOption();
2400 // Skip language selection, which is positional.
2401 if (O.getID() == options::OPT_x)
2402 continue;
2403 // Skip writing dependency output and the compilation database itself.
2404 if (O.getGroup().isValid() && O.getGroup().getID() == options::OPT_M_Group)
2405 continue;
2406 if (O.getID() == options::OPT_gen_cdb_fragment_path)
2407 continue;
2408 // Skip inputs.
2409 if (O.getKind() == Option::InputClass)
2410 continue;
2411 // Skip output.
2412 if (O.getID() == options::OPT_o)
2413 continue;
2414 // All other arguments are quoted and appended.
2415 ArgStringList ASL;
2416 A->render(Args, Output&: ASL);
2417 for (auto &it: ASL)
2418 CDB << ", \"" << escape(Input: it) << "\"";
2419 }
2420 Buf = "--target=";
2421 Buf += Target;
2422 CDB << ", \"" << escape(Input: Buf) << "\"]},\n";
2423}
2424
2425void Clang::DumpCompilationDatabaseFragmentToDir(
2426 StringRef Dir, Compilation &C, StringRef Target, const InputInfo &Output,
2427 const InputInfo &Input, const llvm::opt::ArgList &Args) const {
2428 // If this is a dry run, do not create the compilation database file.
2429 if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH))
2430 return;
2431
2432 if (CompilationDatabase)
2433 DumpCompilationDatabase(C, Filename: "", Target, Output, Input, Args);
2434
2435 SmallString<256> Path = Dir;
2436 const auto &Driver = C.getDriver();
2437 Driver.getVFS().makeAbsolute(Path);
2438 auto Err = llvm::sys::fs::create_directory(path: Path, /*IgnoreExisting=*/true);
2439 if (Err) {
2440 Driver.Diag(diag::err_drv_compilationdatabase) << Dir << Err.message();
2441 return;
2442 }
2443
2444 llvm::sys::path::append(
2445 path&: Path,
2446 a: Twine(llvm::sys::path::filename(path: Input.getFilename())) + ".%%%%.json");
2447 int FD;
2448 SmallString<256> TempPath;
2449 Err = llvm::sys::fs::createUniqueFile(Model: Path, ResultFD&: FD, ResultPath&: TempPath,
2450 Flags: llvm::sys::fs::OF_Text);
2451 if (Err) {
2452 Driver.Diag(diag::err_drv_compilationdatabase) << Path << Err.message();
2453 return;
2454 }
2455 CompilationDatabase =
2456 std::make_unique<llvm::raw_fd_ostream>(args&: FD, /*shouldClose=*/args: true);
2457 DumpCompilationDatabase(C, Filename: "", Target, Output, Input, Args);
2458}
2459
2460static bool CheckARMImplicitITArg(StringRef Value) {
2461 return Value == "always" || Value == "never" || Value == "arm" ||
2462 Value == "thumb";
2463}
2464
2465static void AddARMImplicitITArgs(const ArgList &Args, ArgStringList &CmdArgs,
2466 StringRef Value) {
2467 CmdArgs.push_back(Elt: "-mllvm");
2468 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-arm-implicit-it=" + Value));
2469}
2470
2471static void CollectArgsForIntegratedAssembler(Compilation &C,
2472 const ArgList &Args,
2473 ArgStringList &CmdArgs,
2474 const Driver &D) {
2475 if (UseRelaxAll(C, Args))
2476 CmdArgs.push_back(Elt: "-mrelax-all");
2477
2478 // Only default to -mincremental-linker-compatible if we think we are
2479 // targeting the MSVC linker.
2480 bool DefaultIncrementalLinkerCompatible =
2481 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
2482 if (Args.hasFlag(options::OPT_mincremental_linker_compatible,
2483 options::OPT_mno_incremental_linker_compatible,
2484 DefaultIncrementalLinkerCompatible))
2485 CmdArgs.push_back(Elt: "-mincremental-linker-compatible");
2486
2487 Args.AddLastArg(CmdArgs, options::OPT_femit_dwarf_unwind_EQ);
2488
2489 Args.addOptInFlag(CmdArgs, options::OPT_femit_compact_unwind_non_canonical,
2490 options::OPT_fno_emit_compact_unwind_non_canonical);
2491
2492 // If you add more args here, also add them to the block below that
2493 // starts with "// If CollectArgsForIntegratedAssembler() isn't called below".
2494
2495 // When passing -I arguments to the assembler we sometimes need to
2496 // unconditionally take the next argument. For example, when parsing
2497 // '-Wa,-I -Wa,foo' we need to accept the -Wa,foo arg after seeing the
2498 // -Wa,-I arg and when parsing '-Wa,-I,foo' we need to accept the 'foo'
2499 // arg after parsing the '-I' arg.
2500 bool TakeNextArg = false;
2501
2502 bool UseRelaxRelocations = C.getDefaultToolChain().useRelaxRelocations();
2503 bool UseNoExecStack = false;
2504 const char *MipsTargetFeature = nullptr;
2505 StringRef ImplicitIt;
2506 for (const Arg *A :
2507 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler,
2508 options::OPT_mimplicit_it_EQ)) {
2509 A->claim();
2510
2511 if (A->getOption().getID() == options::OPT_mimplicit_it_EQ) {
2512 switch (C.getDefaultToolChain().getArch()) {
2513 case llvm::Triple::arm:
2514 case llvm::Triple::armeb:
2515 case llvm::Triple::thumb:
2516 case llvm::Triple::thumbeb:
2517 // Only store the value; the last value set takes effect.
2518 ImplicitIt = A->getValue();
2519 if (!CheckARMImplicitITArg(ImplicitIt))
2520 D.Diag(diag::err_drv_unsupported_option_argument)
2521 << A->getSpelling() << ImplicitIt;
2522 continue;
2523 default:
2524 break;
2525 }
2526 }
2527
2528 for (StringRef Value : A->getValues()) {
2529 if (TakeNextArg) {
2530 CmdArgs.push_back(Value.data());
2531 TakeNextArg = false;
2532 continue;
2533 }
2534
2535 if (C.getDefaultToolChain().getTriple().isOSBinFormatCOFF() &&
2536 Value == "-mbig-obj")
2537 continue; // LLVM handles bigobj automatically
2538
2539 switch (C.getDefaultToolChain().getArch()) {
2540 default:
2541 break;
2542 case llvm::Triple::wasm32:
2543 case llvm::Triple::wasm64:
2544 if (Value == "--no-type-check") {
2545 CmdArgs.push_back("-mno-type-check");
2546 continue;
2547 }
2548 break;
2549 case llvm::Triple::thumb:
2550 case llvm::Triple::thumbeb:
2551 case llvm::Triple::arm:
2552 case llvm::Triple::armeb:
2553 if (Value.starts_with("-mimplicit-it=")) {
2554 // Only store the value; the last value set takes effect.
2555 ImplicitIt = Value.split("=").second;
2556 if (CheckARMImplicitITArg(ImplicitIt))
2557 continue;
2558 }
2559 if (Value == "-mthumb")
2560 // -mthumb has already been processed in ComputeLLVMTriple()
2561 // recognize but skip over here.
2562 continue;
2563 break;
2564 case llvm::Triple::mips:
2565 case llvm::Triple::mipsel:
2566 case llvm::Triple::mips64:
2567 case llvm::Triple::mips64el:
2568 if (Value == "--trap") {
2569 CmdArgs.push_back("-target-feature");
2570 CmdArgs.push_back("+use-tcc-in-div");
2571 continue;
2572 }
2573 if (Value == "--break") {
2574 CmdArgs.push_back("-target-feature");
2575 CmdArgs.push_back("-use-tcc-in-div");
2576 continue;
2577 }
2578 if (Value.starts_with("-msoft-float")) {
2579 CmdArgs.push_back("-target-feature");
2580 CmdArgs.push_back("+soft-float");
2581 continue;
2582 }
2583 if (Value.starts_with("-mhard-float")) {
2584 CmdArgs.push_back("-target-feature");
2585 CmdArgs.push_back("-soft-float");
2586 continue;
2587 }
2588
2589 MipsTargetFeature = llvm::StringSwitch<const char *>(Value)
2590 .Case("-mips1", "+mips1")
2591 .Case("-mips2", "+mips2")
2592 .Case("-mips3", "+mips3")
2593 .Case("-mips4", "+mips4")
2594 .Case("-mips5", "+mips5")
2595 .Case("-mips32", "+mips32")
2596 .Case("-mips32r2", "+mips32r2")
2597 .Case("-mips32r3", "+mips32r3")
2598 .Case("-mips32r5", "+mips32r5")
2599 .Case("-mips32r6", "+mips32r6")
2600 .Case("-mips64", "+mips64")
2601 .Case("-mips64r2", "+mips64r2")
2602 .Case("-mips64r3", "+mips64r3")
2603 .Case("-mips64r5", "+mips64r5")
2604 .Case("-mips64r6", "+mips64r6")
2605 .Default(nullptr);
2606 if (MipsTargetFeature)
2607 continue;
2608 }
2609
2610 if (Value == "-force_cpusubtype_ALL") {
2611 // Do nothing, this is the default and we don't support anything else.
2612 } else if (Value == "-L") {
2613 CmdArgs.push_back("-msave-temp-labels");
2614 } else if (Value == "--fatal-warnings") {
2615 CmdArgs.push_back("-massembler-fatal-warnings");
2616 } else if (Value == "--no-warn" || Value == "-W") {
2617 CmdArgs.push_back("-massembler-no-warn");
2618 } else if (Value == "--noexecstack") {
2619 UseNoExecStack = true;
2620 } else if (Value.starts_with("-compress-debug-sections") ||
2621 Value.starts_with("--compress-debug-sections") ||
2622 Value == "-nocompress-debug-sections" ||
2623 Value == "--nocompress-debug-sections") {
2624 CmdArgs.push_back(Value.data());
2625 } else if (Value == "-mrelax-relocations=yes" ||
2626 Value == "--mrelax-relocations=yes") {
2627 UseRelaxRelocations = true;
2628 } else if (Value == "-mrelax-relocations=no" ||
2629 Value == "--mrelax-relocations=no") {
2630 UseRelaxRelocations = false;
2631 } else if (Value.starts_with("-I")) {
2632 CmdArgs.push_back(Value.data());
2633 // We need to consume the next argument if the current arg is a plain
2634 // -I. The next arg will be the include directory.
2635 if (Value == "-I")
2636 TakeNextArg = true;
2637 } else if (Value.starts_with("-gdwarf-")) {
2638 // "-gdwarf-N" options are not cc1as options.
2639 unsigned DwarfVersion = DwarfVersionNum(Value);
2640 if (DwarfVersion == 0) { // Send it onward, and let cc1as complain.
2641 CmdArgs.push_back(Value.data());
2642 } else {
2643 RenderDebugEnablingArgs(Args, CmdArgs,
2644 llvm::codegenoptions::DebugInfoConstructor,
2645 DwarfVersion, llvm::DebuggerKind::Default);
2646 }
2647 } else if (Value.starts_with("-mcpu") || Value.starts_with("-mfpu") ||
2648 Value.starts_with("-mhwdiv") || Value.starts_with("-march")) {
2649 // Do nothing, we'll validate it later.
2650 } else if (Value == "-defsym") {
2651 if (A->getNumValues() != 2) {
2652 D.Diag(diag::err_drv_defsym_invalid_format) << Value;
2653 break;
2654 }
2655 const char *S = A->getValue(1);
2656 auto Pair = StringRef(S).split('=');
2657 auto Sym = Pair.first;
2658 auto SVal = Pair.second;
2659
2660 if (Sym.empty() || SVal.empty()) {
2661 D.Diag(diag::err_drv_defsym_invalid_format) << S;
2662 break;
2663 }
2664 int64_t IVal;
2665 if (SVal.getAsInteger(0, IVal)) {
2666 D.Diag(diag::err_drv_defsym_invalid_symval) << SVal;
2667 break;
2668 }
2669 CmdArgs.push_back(Value.data());
2670 TakeNextArg = true;
2671 } else if (Value == "-fdebug-compilation-dir") {
2672 CmdArgs.push_back("-fdebug-compilation-dir");
2673 TakeNextArg = true;
2674 } else if (Value.consume_front("-fdebug-compilation-dir=")) {
2675 // The flag is a -Wa / -Xassembler argument and Options doesn't
2676 // parse the argument, so this isn't automatically aliased to
2677 // -fdebug-compilation-dir (without '=') here.
2678 CmdArgs.push_back("-fdebug-compilation-dir");
2679 CmdArgs.push_back(Value.data());
2680 } else if (Value == "--version") {
2681 D.PrintVersion(C, llvm::outs());
2682 } else {
2683 D.Diag(diag::err_drv_unsupported_option_argument)
2684 << A->getSpelling() << Value;
2685 }
2686 }
2687 }
2688 if (ImplicitIt.size())
2689 AddARMImplicitITArgs(Args, CmdArgs, Value: ImplicitIt);
2690 if (!UseRelaxRelocations)
2691 CmdArgs.push_back(Elt: "-mrelax-relocations=no");
2692 if (UseNoExecStack)
2693 CmdArgs.push_back(Elt: "-mnoexecstack");
2694 if (MipsTargetFeature != nullptr) {
2695 CmdArgs.push_back(Elt: "-target-feature");
2696 CmdArgs.push_back(Elt: MipsTargetFeature);
2697 }
2698
2699 // forward -fembed-bitcode to assmebler
2700 if (C.getDriver().embedBitcodeEnabled() ||
2701 C.getDriver().embedBitcodeMarkerOnly())
2702 Args.AddLastArg(CmdArgs, options::OPT_fembed_bitcode_EQ);
2703
2704 if (const char *AsSecureLogFile = getenv(name: "AS_SECURE_LOG_FILE")) {
2705 CmdArgs.push_back(Elt: "-as-secure-log-file");
2706 CmdArgs.push_back(Elt: Args.MakeArgString(Str: AsSecureLogFile));
2707 }
2708}
2709
2710static std::string ComplexRangeKindToStr(LangOptions::ComplexRangeKind Range) {
2711 switch (Range) {
2712 case LangOptions::ComplexRangeKind::CX_Full:
2713 return "full";
2714 break;
2715 case LangOptions::ComplexRangeKind::CX_Basic:
2716 return "basic";
2717 break;
2718 case LangOptions::ComplexRangeKind::CX_Improved:
2719 return "improved";
2720 break;
2721 case LangOptions::ComplexRangeKind::CX_Promoted:
2722 return "promoted";
2723 break;
2724 default:
2725 return "";
2726 }
2727}
2728
2729static std::string ComplexArithmeticStr(LangOptions::ComplexRangeKind Range) {
2730 return (Range == LangOptions::ComplexRangeKind::CX_None)
2731 ? ""
2732 : "-fcomplex-arithmetic=" + ComplexRangeKindToStr(Range);
2733}
2734
2735static void EmitComplexRangeDiag(const Driver &D, std::string str1,
2736 std::string str2) {
2737 if ((str1.compare(str: str2) != 0) && !str2.empty() && !str1.empty()) {
2738 D.Diag(clang::diag::warn_drv_overriding_option) << str1 << str2;
2739 }
2740}
2741
2742static std::string
2743RenderComplexRangeOption(LangOptions::ComplexRangeKind Range) {
2744 std::string ComplexRangeStr = ComplexRangeKindToStr(Range);
2745 if (!ComplexRangeStr.empty())
2746 return "-complex-range=" + ComplexRangeStr;
2747 return ComplexRangeStr;
2748}
2749
2750static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
2751 bool OFastEnabled, const ArgList &Args,
2752 ArgStringList &CmdArgs,
2753 const JobAction &JA) {
2754 // Handle various floating point optimization flags, mapping them to the
2755 // appropriate LLVM code generation flags. This is complicated by several
2756 // "umbrella" flags, so we do this by stepping through the flags incrementally
2757 // adjusting what we think is enabled/disabled, then at the end setting the
2758 // LLVM flags based on the final state.
2759 bool HonorINFs = true;
2760 bool HonorNaNs = true;
2761 bool ApproxFunc = false;
2762 // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes.
2763 bool MathErrno = TC.IsMathErrnoDefault();
2764 bool AssociativeMath = false;
2765 bool ReciprocalMath = false;
2766 bool SignedZeros = true;
2767 bool TrappingMath = false; // Implemented via -ffp-exception-behavior
2768 bool TrappingMathPresent = false; // Is trapping-math in args, and not
2769 // overriden by ffp-exception-behavior?
2770 bool RoundingFPMath = false;
2771 bool RoundingMathPresent = false; // Is rounding-math in args?
2772 // -ffp-model values: strict, fast, precise
2773 StringRef FPModel = "";
2774 // -ffp-exception-behavior options: strict, maytrap, ignore
2775 StringRef FPExceptionBehavior = "";
2776 // -ffp-eval-method options: double, extended, source
2777 StringRef FPEvalMethod = "";
2778 const llvm::DenormalMode DefaultDenormalFPMath =
2779 TC.getDefaultDenormalModeForType(DriverArgs: Args, JA);
2780 const llvm::DenormalMode DefaultDenormalFP32Math =
2781 TC.getDefaultDenormalModeForType(DriverArgs: Args, JA, FPType: &llvm::APFloat::IEEEsingle());
2782
2783 llvm::DenormalMode DenormalFPMath = DefaultDenormalFPMath;
2784 llvm::DenormalMode DenormalFP32Math = DefaultDenormalFP32Math;
2785 // CUDA and HIP don't rely on the frontend to pass an ffp-contract option.
2786 // If one wasn't given by the user, don't pass it here.
2787 StringRef FPContract;
2788 StringRef LastSeenFfpContractOption;
2789 bool SeenUnsafeMathModeOption = false;
2790 if (!JA.isDeviceOffloading(OKind: Action::OFK_Cuda) &&
2791 !JA.isOffloading(OKind: Action::OFK_HIP))
2792 FPContract = "on";
2793 bool StrictFPModel = false;
2794 StringRef Float16ExcessPrecision = "";
2795 StringRef BFloat16ExcessPrecision = "";
2796 LangOptions::ComplexRangeKind Range = LangOptions::ComplexRangeKind::CX_None;
2797 std::string ComplexRangeStr = "";
2798 std::string GccRangeComplexOption = "";
2799
2800 // Lambda to set fast-math options. This is also used by -ffp-model=fast
2801 auto applyFastMath = [&]() {
2802 HonorINFs = false;
2803 HonorNaNs = false;
2804 MathErrno = false;
2805 AssociativeMath = true;
2806 ReciprocalMath = true;
2807 ApproxFunc = true;
2808 SignedZeros = false;
2809 TrappingMath = false;
2810 RoundingFPMath = false;
2811 FPExceptionBehavior = "";
2812 // If fast-math is set then set the fp-contract mode to fast.
2813 FPContract = "fast";
2814 // ffast-math enables basic range rules for complex multiplication and
2815 // division.
2816 // Warn if user expects to perform full implementation of complex
2817 // multiplication or division in the presence of nan or ninf flags.
2818 if (Range == LangOptions::ComplexRangeKind::CX_Full ||
2819 Range == LangOptions::ComplexRangeKind::CX_Improved ||
2820 Range == LangOptions::ComplexRangeKind::CX_Promoted)
2821 EmitComplexRangeDiag(
2822 D, str1: ComplexArithmeticStr(Range),
2823 str2: !GccRangeComplexOption.empty()
2824 ? GccRangeComplexOption
2825 : ComplexArithmeticStr(Range: LangOptions::ComplexRangeKind::CX_Basic));
2826 Range = LangOptions::ComplexRangeKind::CX_Basic;
2827 SeenUnsafeMathModeOption = true;
2828 };
2829
2830 if (const Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
2831 CmdArgs.push_back(Elt: "-mlimit-float-precision");
2832 CmdArgs.push_back(Elt: A->getValue());
2833 }
2834
2835 for (const Arg *A : Args) {
2836 auto optID = A->getOption().getID();
2837 bool PreciseFPModel = false;
2838 switch (optID) {
2839 default:
2840 break;
2841 case options::OPT_fcx_limited_range:
2842 if (GccRangeComplexOption.empty()) {
2843 if (Range != LangOptions::ComplexRangeKind::CX_Basic)
2844 EmitComplexRangeDiag(D, str1: RenderComplexRangeOption(Range),
2845 str2: "-fcx-limited-range");
2846 } else {
2847 if (GccRangeComplexOption != "-fno-cx-limited-range")
2848 EmitComplexRangeDiag(D, str1: GccRangeComplexOption, str2: "-fcx-limited-range");
2849 }
2850 GccRangeComplexOption = "-fcx-limited-range";
2851 Range = LangOptions::ComplexRangeKind::CX_Basic;
2852 break;
2853 case options::OPT_fno_cx_limited_range:
2854 if (GccRangeComplexOption.empty()) {
2855 EmitComplexRangeDiag(D, str1: RenderComplexRangeOption(Range),
2856 str2: "-fno-cx-limited-range");
2857 } else {
2858 if (GccRangeComplexOption.compare(s: "-fcx-limited-range") != 0 &&
2859 GccRangeComplexOption.compare(s: "-fno-cx-fortran-rules") != 0)
2860 EmitComplexRangeDiag(D, str1: GccRangeComplexOption,
2861 str2: "-fno-cx-limited-range");
2862 }
2863 GccRangeComplexOption = "-fno-cx-limited-range";
2864 Range = LangOptions::ComplexRangeKind::CX_Full;
2865 break;
2866 case options::OPT_fcx_fortran_rules:
2867 if (GccRangeComplexOption.empty())
2868 EmitComplexRangeDiag(D, str1: RenderComplexRangeOption(Range),
2869 str2: "-fcx-fortran-rules");
2870 else
2871 EmitComplexRangeDiag(D, str1: GccRangeComplexOption, str2: "-fcx-fortran-rules");
2872 GccRangeComplexOption = "-fcx-fortran-rules";
2873 Range = LangOptions::ComplexRangeKind::CX_Improved;
2874 break;
2875 case options::OPT_fno_cx_fortran_rules:
2876 if (GccRangeComplexOption.empty()) {
2877 EmitComplexRangeDiag(D, str1: RenderComplexRangeOption(Range),
2878 str2: "-fno-cx-fortran-rules");
2879 } else {
2880 if (GccRangeComplexOption != "-fno-cx-limited-range")
2881 EmitComplexRangeDiag(D, str1: GccRangeComplexOption,
2882 str2: "-fno-cx-fortran-rules");
2883 }
2884 GccRangeComplexOption = "-fno-cx-fortran-rules";
2885 Range = LangOptions::ComplexRangeKind::CX_Full;
2886 break;
2887 case options::OPT_fcomplex_arithmetic_EQ: {
2888 LangOptions::ComplexRangeKind RangeVal;
2889 StringRef Val = A->getValue();
2890 if (Val.equals(RHS: "full"))
2891 RangeVal = LangOptions::ComplexRangeKind::CX_Full;
2892 else if (Val.equals(RHS: "improved"))
2893 RangeVal = LangOptions::ComplexRangeKind::CX_Improved;
2894 else if (Val.equals(RHS: "promoted"))
2895 RangeVal = LangOptions::ComplexRangeKind::CX_Promoted;
2896 else if (Val.equals(RHS: "basic"))
2897 RangeVal = LangOptions::ComplexRangeKind::CX_Basic;
2898 else {
2899 D.Diag(diag::err_drv_unsupported_option_argument)
2900 << A->getSpelling() << Val;
2901 break;
2902 }
2903 if (!GccRangeComplexOption.empty()) {
2904 if (GccRangeComplexOption.compare(s: "-fcx-limited-range") != 0) {
2905 if (GccRangeComplexOption.compare(s: "-fcx-fortran-rules") != 0) {
2906 if (RangeVal != LangOptions::ComplexRangeKind::CX_Improved)
2907 EmitComplexRangeDiag(D, str1: GccRangeComplexOption,
2908 str2: ComplexArithmeticStr(Range: RangeVal));
2909 } else {
2910 EmitComplexRangeDiag(D, str1: GccRangeComplexOption,
2911 str2: ComplexArithmeticStr(Range: RangeVal));
2912 }
2913 } else {
2914 if (RangeVal != LangOptions::ComplexRangeKind::CX_Basic)
2915 EmitComplexRangeDiag(D, str1: GccRangeComplexOption,
2916 str2: ComplexArithmeticStr(Range: RangeVal));
2917 }
2918 }
2919 Range = RangeVal;
2920 break;
2921 }
2922 case options::OPT_ffp_model_EQ: {
2923 // If -ffp-model= is seen, reset to fno-fast-math
2924 HonorINFs = true;
2925 HonorNaNs = true;
2926 ApproxFunc = false;
2927 // Turning *off* -ffast-math restores the toolchain default.
2928 MathErrno = TC.IsMathErrnoDefault();
2929 AssociativeMath = false;
2930 ReciprocalMath = false;
2931 SignedZeros = true;
2932 // -fno_fast_math restores default denormal and fpcontract handling
2933 FPContract = "on";
2934 DenormalFPMath = llvm::DenormalMode::getIEEE();
2935
2936 // FIXME: The target may have picked a non-IEEE default mode here based on
2937 // -cl-denorms-are-zero. Should the target consider -fp-model interaction?
2938 DenormalFP32Math = llvm::DenormalMode::getIEEE();
2939
2940 StringRef Val = A->getValue();
2941 if (OFastEnabled && !Val.equals(RHS: "fast")) {
2942 // Only -ffp-model=fast is compatible with OFast, ignore.
2943 D.Diag(clang::diag::warn_drv_overriding_option)
2944 << Args.MakeArgString("-ffp-model=" + Val) << "-Ofast";
2945 break;
2946 }
2947 StrictFPModel = false;
2948 PreciseFPModel = true;
2949 // ffp-model= is a Driver option, it is entirely rewritten into more
2950 // granular options before being passed into cc1.
2951 // Use the gcc option in the switch below.
2952 if (!FPModel.empty() && !FPModel.equals(Val))
2953 D.Diag(clang::diag::warn_drv_overriding_option)
2954 << Args.MakeArgString("-ffp-model=" + FPModel)
2955 << Args.MakeArgString("-ffp-model=" + Val);
2956 if (Val.equals(RHS: "fast")) {
2957 FPModel = Val;
2958 applyFastMath();
2959 } else if (Val.equals(RHS: "precise")) {
2960 optID = options::OPT_ffp_contract;
2961 FPModel = Val;
2962 FPContract = "on";
2963 PreciseFPModel = true;
2964 } else if (Val.equals(RHS: "strict")) {
2965 StrictFPModel = true;
2966 optID = options::OPT_frounding_math;
2967 FPExceptionBehavior = "strict";
2968 FPModel = Val;
2969 FPContract = "off";
2970 TrappingMath = true;
2971 } else
2972 D.Diag(diag::err_drv_unsupported_option_argument)
2973 << A->getSpelling() << Val;
2974 break;
2975 }
2976 }
2977
2978 switch (optID) {
2979 // If this isn't an FP option skip the claim below
2980 default: continue;
2981
2982 // Options controlling individual features
2983 case options::OPT_fhonor_infinities: HonorINFs = true; break;
2984 case options::OPT_fno_honor_infinities: HonorINFs = false; break;
2985 case options::OPT_fhonor_nans: HonorNaNs = true; break;
2986 case options::OPT_fno_honor_nans: HonorNaNs = false; break;
2987 case options::OPT_fapprox_func: ApproxFunc = true; break;
2988 case options::OPT_fno_approx_func: ApproxFunc = false; break;
2989 case options::OPT_fmath_errno: MathErrno = true; break;
2990 case options::OPT_fno_math_errno: MathErrno = false; break;
2991 case options::OPT_fassociative_math: AssociativeMath = true; break;
2992 case options::OPT_fno_associative_math: AssociativeMath = false; break;
2993 case options::OPT_freciprocal_math: ReciprocalMath = true; break;
2994 case options::OPT_fno_reciprocal_math: ReciprocalMath = false; break;
2995 case options::OPT_fsigned_zeros: SignedZeros = true; break;
2996 case options::OPT_fno_signed_zeros: SignedZeros = false; break;
2997 case options::OPT_ftrapping_math:
2998 if (!TrappingMathPresent && !FPExceptionBehavior.empty() &&
2999 !FPExceptionBehavior.equals("strict"))
3000 // Warn that previous value of option is overridden.
3001 D.Diag(clang::diag::warn_drv_overriding_option)
3002 << Args.MakeArgString("-ffp-exception-behavior=" +
3003 FPExceptionBehavior)
3004 << "-ftrapping-math";
3005 TrappingMath = true;
3006 TrappingMathPresent = true;
3007 FPExceptionBehavior = "strict";
3008 break;
3009 case options::OPT_fno_trapping_math:
3010 if (!TrappingMathPresent && !FPExceptionBehavior.empty() &&
3011 !FPExceptionBehavior.equals("ignore"))
3012 // Warn that previous value of option is overridden.
3013 D.Diag(clang::diag::warn_drv_overriding_option)
3014 << Args.MakeArgString("-ffp-exception-behavior=" +
3015 FPExceptionBehavior)
3016 << "-fno-trapping-math";
3017 TrappingMath = false;
3018 TrappingMathPresent = true;
3019 FPExceptionBehavior = "ignore";
3020 break;
3021
3022 case options::OPT_frounding_math:
3023 RoundingFPMath = true;
3024 RoundingMathPresent = true;
3025 break;
3026
3027 case options::OPT_fno_rounding_math:
3028 RoundingFPMath = false;
3029 RoundingMathPresent = false;
3030 break;
3031
3032 case options::OPT_fdenormal_fp_math_EQ:
3033 DenormalFPMath = llvm::parseDenormalFPAttribute(Str: A->getValue());
3034 DenormalFP32Math = DenormalFPMath;
3035 if (!DenormalFPMath.isValid()) {
3036 D.Diag(diag::err_drv_invalid_value)
3037 << A->getAsString(Args) << A->getValue();
3038 }
3039 break;
3040
3041 case options::OPT_fdenormal_fp_math_f32_EQ:
3042 DenormalFP32Math = llvm::parseDenormalFPAttribute(Str: A->getValue());
3043 if (!DenormalFP32Math.isValid()) {
3044 D.Diag(diag::err_drv_invalid_value)
3045 << A->getAsString(Args) << A->getValue();
3046 }
3047 break;
3048
3049 // Validate and pass through -ffp-contract option.
3050 case options::OPT_ffp_contract: {
3051 StringRef Val = A->getValue();
3052 if (PreciseFPModel) {
3053 // -ffp-model=precise enables ffp-contract=on.
3054 // -ffp-model=precise sets PreciseFPModel to on and Val to
3055 // "precise". FPContract is set.
3056 ;
3057 } else if (Val.equals(RHS: "fast") || Val.equals(RHS: "on") || Val.equals(RHS: "off") ||
3058 Val.equals(RHS: "fast-honor-pragmas")) {
3059 FPContract = Val;
3060 LastSeenFfpContractOption = Val;
3061 } else
3062 D.Diag(diag::err_drv_unsupported_option_argument)
3063 << A->getSpelling() << Val;
3064 break;
3065 }
3066
3067 // Validate and pass through -ffp-model option.
3068 case options::OPT_ffp_model_EQ:
3069 // This should only occur in the error case
3070 // since the optID has been replaced by a more granular
3071 // floating point option.
3072 break;
3073
3074 // Validate and pass through -ffp-exception-behavior option.
3075 case options::OPT_ffp_exception_behavior_EQ: {
3076 StringRef Val = A->getValue();
3077 if (!TrappingMathPresent && !FPExceptionBehavior.empty() &&
3078 !FPExceptionBehavior.equals(Val))
3079 // Warn that previous value of option is overridden.
3080 D.Diag(clang::diag::warn_drv_overriding_option)
3081 << Args.MakeArgString("-ffp-exception-behavior=" +
3082 FPExceptionBehavior)
3083 << Args.MakeArgString("-ffp-exception-behavior=" + Val);
3084 TrappingMath = TrappingMathPresent = false;
3085 if (Val.equals(RHS: "ignore") || Val.equals(RHS: "maytrap"))
3086 FPExceptionBehavior = Val;
3087 else if (Val.equals(RHS: "strict")) {
3088 FPExceptionBehavior = Val;
3089 TrappingMath = TrappingMathPresent = true;
3090 } else
3091 D.Diag(diag::err_drv_unsupported_option_argument)
3092 << A->getSpelling() << Val;
3093 break;
3094 }
3095
3096 // Validate and pass through -ffp-eval-method option.
3097 case options::OPT_ffp_eval_method_EQ: {
3098 StringRef Val = A->getValue();
3099 if (Val.equals(RHS: "double") || Val.equals(RHS: "extended") ||
3100 Val.equals(RHS: "source"))
3101 FPEvalMethod = Val;
3102 else
3103 D.Diag(diag::err_drv_unsupported_option_argument)
3104 << A->getSpelling() << Val;
3105 break;
3106 }
3107
3108 case options::OPT_fexcess_precision_EQ: {
3109 StringRef Val = A->getValue();
3110 const llvm::Triple::ArchType Arch = TC.getArch();
3111 if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) {
3112 if (Val.equals(RHS: "standard") || Val.equals(RHS: "fast"))
3113 Float16ExcessPrecision = Val;
3114 // To make it GCC compatible, allow the value of "16" which
3115 // means disable excess precision, the same meaning than clang's
3116 // equivalent value "none".
3117 else if (Val.equals(RHS: "16"))
3118 Float16ExcessPrecision = "none";
3119 else
3120 D.Diag(diag::err_drv_unsupported_option_argument)
3121 << A->getSpelling() << Val;
3122 } else {
3123 if (!(Val.equals("standard") || Val.equals("fast")))
3124 D.Diag(diag::err_drv_unsupported_option_argument)
3125 << A->getSpelling() << Val;
3126 }
3127 BFloat16ExcessPrecision = Float16ExcessPrecision;
3128 break;
3129 }
3130 case options::OPT_ffinite_math_only:
3131 HonorINFs = false;
3132 HonorNaNs = false;
3133 break;
3134 case options::OPT_fno_finite_math_only:
3135 HonorINFs = true;
3136 HonorNaNs = true;
3137 break;
3138
3139 case options::OPT_funsafe_math_optimizations:
3140 AssociativeMath = true;
3141 ReciprocalMath = true;
3142 SignedZeros = false;
3143 ApproxFunc = true;
3144 TrappingMath = false;
3145 FPExceptionBehavior = "";
3146 FPContract = "fast";
3147 SeenUnsafeMathModeOption = true;
3148 break;
3149 case options::OPT_fno_unsafe_math_optimizations:
3150 AssociativeMath = false;
3151 ReciprocalMath = false;
3152 SignedZeros = true;
3153 ApproxFunc = false;
3154 TrappingMath = true;
3155 FPExceptionBehavior = "strict";
3156
3157 // The target may have opted to flush by default, so force IEEE.
3158 DenormalFPMath = llvm::DenormalMode::getIEEE();
3159 DenormalFP32Math = llvm::DenormalMode::getIEEE();
3160 if (!JA.isDeviceOffloading(OKind: Action::OFK_Cuda) &&
3161 !JA.isOffloading(OKind: Action::OFK_HIP)) {
3162 if (LastSeenFfpContractOption != "") {
3163 FPContract = LastSeenFfpContractOption;
3164 } else if (SeenUnsafeMathModeOption)
3165 FPContract = "on";
3166 }
3167 break;
3168
3169 case options::OPT_Ofast:
3170 // If -Ofast is the optimization level, then -ffast-math should be enabled
3171 if (!OFastEnabled)
3172 continue;
3173 [[fallthrough]];
3174 case options::OPT_ffast_math: {
3175 applyFastMath();
3176 break;
3177 }
3178 case options::OPT_fno_fast_math:
3179 HonorINFs = true;
3180 HonorNaNs = true;
3181 // Turning on -ffast-math (with either flag) removes the need for
3182 // MathErrno. However, turning *off* -ffast-math merely restores the
3183 // toolchain default (which may be false).
3184 MathErrno = TC.IsMathErrnoDefault();
3185 AssociativeMath = false;
3186 ReciprocalMath = false;
3187 ApproxFunc = false;
3188 SignedZeros = true;
3189 // -fno_fast_math restores default denormal and fpcontract handling
3190 DenormalFPMath = DefaultDenormalFPMath;
3191 DenormalFP32Math = llvm::DenormalMode::getIEEE();
3192 if (!JA.isDeviceOffloading(OKind: Action::OFK_Cuda) &&
3193 !JA.isOffloading(OKind: Action::OFK_HIP)) {
3194 if (LastSeenFfpContractOption != "") {
3195 FPContract = LastSeenFfpContractOption;
3196 } else if (SeenUnsafeMathModeOption)
3197 FPContract = "on";
3198 }
3199 break;
3200 }
3201 if (StrictFPModel) {
3202 // If -ffp-model=strict has been specified on command line but
3203 // subsequent options conflict then emit warning diagnostic.
3204 if (HonorINFs && HonorNaNs && !AssociativeMath && !ReciprocalMath &&
3205 SignedZeros && TrappingMath && RoundingFPMath && !ApproxFunc &&
3206 DenormalFPMath == llvm::DenormalMode::getIEEE() &&
3207 DenormalFP32Math == llvm::DenormalMode::getIEEE() &&
3208 FPContract.equals(RHS: "off"))
3209 // OK: Current Arg doesn't conflict with -ffp-model=strict
3210 ;
3211 else {
3212 StrictFPModel = false;
3213 FPModel = "";
3214 auto RHS = (A->getNumValues() == 0)
3215 ? A->getSpelling()
3216 : Args.MakeArgString(Str: A->getSpelling() + A->getValue());
3217 if (RHS != "-ffp-model=strict")
3218 D.Diag(clang::diag::warn_drv_overriding_option)
3219 << "-ffp-model=strict" << RHS;
3220 }
3221 }
3222
3223 // If we handled this option claim it
3224 A->claim();
3225 }
3226
3227 if (!HonorINFs)
3228 CmdArgs.push_back(Elt: "-menable-no-infs");
3229
3230 if (!HonorNaNs)
3231 CmdArgs.push_back(Elt: "-menable-no-nans");
3232
3233 if (ApproxFunc)
3234 CmdArgs.push_back(Elt: "-fapprox-func");
3235
3236 if (MathErrno)
3237 CmdArgs.push_back(Elt: "-fmath-errno");
3238
3239 if (AssociativeMath && ReciprocalMath && !SignedZeros && ApproxFunc &&
3240 !TrappingMath)
3241 CmdArgs.push_back(Elt: "-funsafe-math-optimizations");
3242
3243 if (!SignedZeros)
3244 CmdArgs.push_back(Elt: "-fno-signed-zeros");
3245
3246 if (AssociativeMath && !SignedZeros && !TrappingMath)
3247 CmdArgs.push_back(Elt: "-mreassociate");
3248
3249 if (ReciprocalMath)
3250 CmdArgs.push_back(Elt: "-freciprocal-math");
3251
3252 if (TrappingMath) {
3253 // FP Exception Behavior is also set to strict
3254 assert(FPExceptionBehavior.equals("strict"));
3255 }
3256
3257 // The default is IEEE.
3258 if (DenormalFPMath != llvm::DenormalMode::getIEEE()) {
3259 llvm::SmallString<64> DenormFlag;
3260 llvm::raw_svector_ostream ArgStr(DenormFlag);
3261 ArgStr << "-fdenormal-fp-math=" << DenormalFPMath;
3262 CmdArgs.push_back(Elt: Args.MakeArgString(Str: ArgStr.str()));
3263 }
3264
3265 // Add f32 specific denormal mode flag if it's different.
3266 if (DenormalFP32Math != DenormalFPMath) {
3267 llvm::SmallString<64> DenormFlag;
3268 llvm::raw_svector_ostream ArgStr(DenormFlag);
3269 ArgStr << "-fdenormal-fp-math-f32=" << DenormalFP32Math;
3270 CmdArgs.push_back(Elt: Args.MakeArgString(Str: ArgStr.str()));
3271 }
3272
3273 if (!FPContract.empty())
3274 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-ffp-contract=" + FPContract));
3275
3276 if (!RoundingFPMath)
3277 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-fno-rounding-math"));
3278
3279 if (RoundingFPMath && RoundingMathPresent)
3280 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-frounding-math"));
3281
3282 if (!FPExceptionBehavior.empty())
3283 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-ffp-exception-behavior=" +
3284 FPExceptionBehavior));
3285
3286 if (!FPEvalMethod.empty())
3287 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-ffp-eval-method=" + FPEvalMethod));
3288
3289 if (!Float16ExcessPrecision.empty())
3290 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-ffloat16-excess-precision=" +
3291 Float16ExcessPrecision));
3292 if (!BFloat16ExcessPrecision.empty())
3293 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-fbfloat16-excess-precision=" +
3294 BFloat16ExcessPrecision));
3295
3296 ParseMRecip(D, Args, OutStrings&: CmdArgs);
3297
3298 // -ffast-math enables the __FAST_MATH__ preprocessor macro, but check for the
3299 // individual features enabled by -ffast-math instead of the option itself as
3300 // that's consistent with gcc's behaviour.
3301 if (!HonorINFs && !HonorNaNs && !MathErrno && AssociativeMath && ApproxFunc &&
3302 ReciprocalMath && !SignedZeros && !TrappingMath && !RoundingFPMath) {
3303 CmdArgs.push_back(Elt: "-ffast-math");
3304 if (FPModel.equals(RHS: "fast")) {
3305 if (FPContract.equals(RHS: "fast"))
3306 // All set, do nothing.
3307 ;
3308 else if (FPContract.empty())
3309 // Enable -ffp-contract=fast
3310 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-ffp-contract=fast"));
3311 else
3312 D.Diag(clang::diag::warn_drv_overriding_option)
3313 << "-ffp-model=fast"
3314 << Args.MakeArgString("-ffp-contract=" + FPContract);
3315 }
3316 }
3317
3318 // Handle __FINITE_MATH_ONLY__ similarly.
3319 if (!HonorINFs && !HonorNaNs)
3320 CmdArgs.push_back(Elt: "-ffinite-math-only");
3321
3322 if (const Arg *A = Args.getLastArg(options::OPT_mfpmath_EQ)) {
3323 CmdArgs.push_back(Elt: "-mfpmath");
3324 CmdArgs.push_back(Elt: A->getValue());
3325 }
3326
3327 // Disable a codegen optimization for floating-point casts.
3328 if (Args.hasFlag(options::OPT_fno_strict_float_cast_overflow,
3329 options::OPT_fstrict_float_cast_overflow, false))
3330 CmdArgs.push_back(Elt: "-fno-strict-float-cast-overflow");
3331
3332 if (Range != LangOptions::ComplexRangeKind::CX_None)
3333 ComplexRangeStr = RenderComplexRangeOption(Range);
3334 if (!ComplexRangeStr.empty()) {
3335 CmdArgs.push_back(Elt: Args.MakeArgString(Str: ComplexRangeStr));
3336 if (Args.hasArg(options::OPT_fcomplex_arithmetic_EQ))
3337 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-fcomplex-arithmetic=" +
3338 ComplexRangeKindToStr(Range)));
3339 }
3340 if (Args.hasArg(options::OPT_fcx_limited_range))
3341 CmdArgs.push_back(Elt: "-fcx-limited-range");
3342 if (Args.hasArg(options::OPT_fcx_fortran_rules))
3343 CmdArgs.push_back(Elt: "-fcx-fortran-rules");
3344 if (Args.hasArg(options::OPT_fno_cx_limited_range))
3345 CmdArgs.push_back(Elt: "-fno-cx-limited-range");
3346 if (Args.hasArg(options::OPT_fno_cx_fortran_rules))
3347 CmdArgs.push_back(Elt: "-fno-cx-fortran-rules");
3348}
3349
3350static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs,
3351 const llvm::Triple &Triple,
3352 const InputInfo &Input) {
3353 // Add default argument set.
3354 if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
3355 CmdArgs.push_back(Elt: "-analyzer-checker=core");
3356 CmdArgs.push_back(Elt: "-analyzer-checker=apiModeling");
3357
3358 if (!Triple.isWindowsMSVCEnvironment()) {
3359 CmdArgs.push_back(Elt: "-analyzer-checker=unix");
3360 } else {
3361 // Enable "unix" checkers that also work on Windows.
3362 CmdArgs.push_back(Elt: "-analyzer-checker=unix.API");
3363 CmdArgs.push_back(Elt: "-analyzer-checker=unix.Malloc");
3364 CmdArgs.push_back(Elt: "-analyzer-checker=unix.MallocSizeof");
3365 CmdArgs.push_back(Elt: "-analyzer-checker=unix.MismatchedDeallocator");
3366 CmdArgs.push_back(Elt: "-analyzer-checker=unix.cstring.BadSizeArg");
3367 CmdArgs.push_back(Elt: "-analyzer-checker=unix.cstring.NullArg");
3368 }
3369
3370 // Disable some unix checkers for PS4/PS5.
3371 if (Triple.isPS()) {
3372 CmdArgs.push_back(Elt: "-analyzer-disable-checker=unix.API");
3373 CmdArgs.push_back(Elt: "-analyzer-disable-checker=unix.Vfork");
3374 }
3375
3376 if (Triple.isOSDarwin()) {
3377 CmdArgs.push_back(Elt: "-analyzer-checker=osx");
3378 CmdArgs.push_back(
3379 Elt: "-analyzer-checker=security.insecureAPI.decodeValueOfObjCType");
3380 }
3381 else if (Triple.isOSFuchsia())
3382 CmdArgs.push_back(Elt: "-analyzer-checker=fuchsia");
3383
3384 CmdArgs.push_back(Elt: "-analyzer-checker=deadcode");
3385
3386 if (types::isCXX(Id: Input.getType()))
3387 CmdArgs.push_back(Elt: "-analyzer-checker=cplusplus");
3388
3389 if (!Triple.isPS()) {
3390 CmdArgs.push_back(Elt: "-analyzer-checker=security.insecureAPI.UncheckedReturn");
3391 CmdArgs.push_back(Elt: "-analyzer-checker=security.insecureAPI.getpw");
3392 CmdArgs.push_back(Elt: "-analyzer-checker=security.insecureAPI.gets");
3393 CmdArgs.push_back(Elt: "-analyzer-checker=security.insecureAPI.mktemp");
3394 CmdArgs.push_back(Elt: "-analyzer-checker=security.insecureAPI.mkstemp");
3395 CmdArgs.push_back(Elt: "-analyzer-checker=security.insecureAPI.vfork");
3396 }
3397
3398 // Default nullability checks.
3399 CmdArgs.push_back(Elt: "-analyzer-checker=nullability.NullPassedToNonnull");
3400 CmdArgs.push_back(Elt: "-analyzer-checker=nullability.NullReturnedFromNonnull");
3401 }
3402
3403 // Set the output format. The default is plist, for (lame) historical reasons.
3404 CmdArgs.push_back(Elt: "-analyzer-output");
3405 if (Arg *A = Args.getLastArg(options::OPT__analyzer_output))
3406 CmdArgs.push_back(Elt: A->getValue());
3407 else
3408 CmdArgs.push_back(Elt: "plist");
3409
3410 // Disable the presentation of standard compiler warnings when using
3411 // --analyze. We only want to show static analyzer diagnostics or frontend
3412 // errors.
3413 CmdArgs.push_back(Elt: "-w");
3414
3415 // Add -Xanalyzer arguments when running as analyzer.
3416 Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
3417}
3418
3419static bool isValidSymbolName(StringRef S) {
3420 if (S.empty())
3421 return false;
3422
3423 if (std::isdigit(S[0]))
3424 return false;
3425
3426 return llvm::all_of(Range&: S, P: [](char C) { return std::isalnum(C) || C == '_'; });
3427}
3428
3429static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
3430 const ArgList &Args, ArgStringList &CmdArgs,
3431 bool KernelOrKext) {
3432 const llvm::Triple &EffectiveTriple = TC.getEffectiveTriple();
3433
3434 // NVPTX doesn't support stack protectors; from the compiler's perspective, it
3435 // doesn't even have a stack!
3436 if (EffectiveTriple.isNVPTX())
3437 return;
3438
3439 // -stack-protector=0 is default.
3440 LangOptions::StackProtectorMode StackProtectorLevel = LangOptions::SSPOff;
3441 LangOptions::StackProtectorMode DefaultStackProtectorLevel =
3442 TC.GetDefaultStackProtectorLevel(KernelOrKext);
3443
3444 if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
3445 options::OPT_fstack_protector_all,
3446 options::OPT_fstack_protector_strong,
3447 options::OPT_fstack_protector)) {
3448 if (A->getOption().matches(options::OPT_fstack_protector))
3449 StackProtectorLevel =
3450 std::max<>(a: LangOptions::SSPOn, b: DefaultStackProtectorLevel);
3451 else if (A->getOption().matches(options::OPT_fstack_protector_strong))
3452 StackProtectorLevel = LangOptions::SSPStrong;
3453 else if (A->getOption().matches(options::OPT_fstack_protector_all))
3454 StackProtectorLevel = LangOptions::SSPReq;
3455
3456 if (EffectiveTriple.isBPF() && StackProtectorLevel != LangOptions::SSPOff) {
3457 D.Diag(diag::warn_drv_unsupported_option_for_target)
3458 << A->getSpelling() << EffectiveTriple.getTriple();
3459 StackProtectorLevel = DefaultStackProtectorLevel;
3460 }
3461 } else {
3462 StackProtectorLevel = DefaultStackProtectorLevel;
3463 }
3464
3465 if (StackProtectorLevel) {
3466 CmdArgs.push_back(Elt: "-stack-protector");
3467 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Twine(StackProtectorLevel)));
3468 }
3469
3470 // --param ssp-buffer-size=
3471 for (const Arg *A : Args.filtered(options::OPT__param)) {
3472 StringRef Str(A->getValue());
3473 if (Str.starts_with("ssp-buffer-size=")) {
3474 if (StackProtectorLevel) {
3475 CmdArgs.push_back("-stack-protector-buffer-size");
3476 // FIXME: Verify the argument is a valid integer.
3477 CmdArgs.push_back(Args.MakeArgString(Str.drop_front(16)));
3478 }
3479 A->claim();
3480 }
3481 }
3482
3483 const std::string &TripleStr = EffectiveTriple.getTriple();
3484 if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
3485 StringRef Value = A->getValue();
3486 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
3487 !EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
3488 D.Diag(diag::err_drv_unsupported_opt_for_target)
3489 << A->getAsString(Args) << TripleStr;
3490 if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
3491 EffectiveTriple.isThumb()) &&
3492 Value != "tls" && Value != "global") {
3493 D.Diag(diag::err_drv_invalid_value_with_suggestion)
3494 << A->getOption().getName() << Value << "tls global";
3495 return;
3496 }
3497 if ((EffectiveTriple.isARM() || EffectiveTriple.isThumb()) &&
3498 Value == "tls") {
3499 if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
3500 D.Diag(diag::err_drv_ssp_missing_offset_argument)
3501 << A->getAsString(Args);
3502 return;
3503 }
3504 // Check whether the target subarch supports the hardware TLS register
3505 if (!arm::isHardTPSupported(Triple: EffectiveTriple)) {
3506 D.Diag(diag::err_target_unsupported_tp_hard)
3507 << EffectiveTriple.getArchName();
3508 return;
3509 }
3510 // Check whether the user asked for something other than -mtp=cp15
3511 if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
3512 StringRef Value = A->getValue();
3513 if (Value != "cp15") {
3514 D.Diag(diag::err_drv_argument_not_allowed_with)
3515 << A->getAsString(Args) << "-mstack-protector-guard=tls";
3516 return;
3517 }
3518 }
3519 CmdArgs.push_back(Elt: "-target-feature");
3520 CmdArgs.push_back(Elt: "+read-tp-tpidruro");
3521 }
3522 if (EffectiveTriple.isAArch64() && Value != "sysreg" && Value != "global") {
3523 D.Diag(diag::err_drv_invalid_value_with_suggestion)
3524 << A->getOption().getName() << Value << "sysreg global";
3525 return;
3526 }
3527 A->render(Args, Output&: CmdArgs);
3528 }
3529
3530 if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) {
3531 StringRef Value = A->getValue();
3532 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
3533 !EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
3534 D.Diag(diag::err_drv_unsupported_opt_for_target)
3535 << A->getAsString(Args) << TripleStr;
3536 int Offset;
3537 if (Value.getAsInteger(Radix: 10, Result&: Offset)) {
3538 D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
3539 return;
3540 }
3541 if ((EffectiveTriple.isARM() || EffectiveTriple.isThumb()) &&
3542 (Offset < 0 || Offset > 0xfffff)) {
3543 D.Diag(diag::err_drv_invalid_int_value)
3544 << A->getOption().getName() << Value;
3545 return;
3546 }
3547 A->render(Args, Output&: CmdArgs);
3548 }
3549
3550 if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
3551 StringRef Value = A->getValue();
3552 if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
3553 D.Diag(diag::err_drv_unsupported_opt_for_target)
3554 << A->getAsString(Args) << TripleStr;
3555 if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
3556 D.Diag(diag::err_drv_invalid_value_with_suggestion)
3557 << A->getOption().getName() << Value << "fs gs";
3558 return;
3559 }
3560 if (EffectiveTriple.isAArch64() && Value != "sp_el0") {
3561 D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
3562 return;
3563 }
3564 A->render(Args, Output&: CmdArgs);
3565 }
3566
3567 if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_symbol_EQ)) {
3568 StringRef Value = A->getValue();
3569 if (!isValidSymbolName(S: Value)) {
3570 D.Diag(diag::err_drv_argument_only_allowed_with)
3571 << A->getOption().getName() << "legal symbol name";
3572 return;
3573 }
3574 A->render(Args, Output&: CmdArgs);
3575 }
3576}
3577
3578static void RenderSCPOptions(const ToolChain &TC, const ArgList &Args,
3579 ArgStringList &CmdArgs) {
3580 const llvm::Triple &EffectiveTriple = TC.getEffectiveTriple();
3581
3582 if (!EffectiveTriple.isOSFreeBSD() && !EffectiveTriple.isOSLinux())
3583 return;
3584
3585 if (!EffectiveTriple.isX86() && !EffectiveTriple.isSystemZ() &&
3586 !EffectiveTriple.isPPC64() && !EffectiveTriple.isAArch64())
3587 return;
3588
3589 Args.addOptInFlag(CmdArgs, options::OPT_fstack_clash_protection,
3590 options::OPT_fno_stack_clash_protection);
3591}
3592
3593static void RenderTrivialAutoVarInitOptions(const Driver &D,
3594 const ToolChain &TC,
3595 const ArgList &Args,
3596 ArgStringList &CmdArgs) {
3597 auto DefaultTrivialAutoVarInit = TC.GetDefaultTrivialAutoVarInit();
3598 StringRef TrivialAutoVarInit = "";
3599
3600 for (const Arg *A : Args) {
3601 switch (A->getOption().getID()) {
3602 default:
3603 continue;
3604 case options::OPT_ftrivial_auto_var_init: {
3605 A->claim();
3606 StringRef Val = A->getValue();
3607 if (Val == "uninitialized" || Val == "zero" || Val == "pattern")
3608 TrivialAutoVarInit = Val;
3609 else
3610 D.Diag(diag::err_drv_unsupported_option_argument)
3611 << A->getSpelling() << Val;
3612 break;
3613 }
3614 }
3615 }
3616
3617 if (TrivialAutoVarInit.empty())
3618 switch (DefaultTrivialAutoVarInit) {
3619 case LangOptions::TrivialAutoVarInitKind::Uninitialized:
3620 break;
3621 case LangOptions::TrivialAutoVarInitKind::Pattern:
3622 TrivialAutoVarInit = "pattern";
3623 break;
3624 case LangOptions::TrivialAutoVarInitKind::Zero:
3625 TrivialAutoVarInit = "zero";
3626 break;
3627 }
3628
3629 if (!TrivialAutoVarInit.empty()) {
3630 CmdArgs.push_back(
3631 Elt: Args.MakeArgString(Str: "-ftrivial-auto-var-init=" + TrivialAutoVarInit));
3632 }
3633
3634 if (Arg *A =
3635 Args.getLastArg(options::OPT_ftrivial_auto_var_init_stop_after)) {
3636 if (!Args.hasArg(options::OPT_ftrivial_auto_var_init) ||
3637 StringRef(
3638 Args.getLastArg(options::OPT_ftrivial_auto_var_init)->getValue()) ==
3639 "uninitialized")
3640 D.Diag(diag::err_drv_trivial_auto_var_init_stop_after_missing_dependency);
3641 A->claim();
3642 StringRef Val = A->getValue();
3643 if (std::stoi(Val.str()) <= 0)
3644 D.Diag(diag::err_drv_trivial_auto_var_init_stop_after_invalid_value);
3645 CmdArgs.push_back(
3646 Elt: Args.MakeArgString(Str: "-ftrivial-auto-var-init-stop-after=" + Val));
3647 }
3648
3649 if (Arg *A = Args.getLastArg(options::OPT_ftrivial_auto_var_init_max_size)) {
3650 if (!Args.hasArg(options::OPT_ftrivial_auto_var_init) ||
3651 StringRef(
3652 Args.getLastArg(options::OPT_ftrivial_auto_var_init)->getValue()) ==
3653 "uninitialized")
3654 D.Diag(diag::err_drv_trivial_auto_var_init_max_size_missing_dependency);
3655 A->claim();
3656 StringRef Val = A->getValue();
3657 if (std::stoi(Val.str()) <= 0)
3658 D.Diag(diag::err_drv_trivial_auto_var_init_max_size_invalid_value);
3659 CmdArgs.push_back(
3660 Elt: Args.MakeArgString(Str: "-ftrivial-auto-var-init-max-size=" + Val));
3661 }
3662}
3663
3664static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs,
3665 types::ID InputType) {
3666 // cl-denorms-are-zero is not forwarded. It is translated into a generic flag
3667 // for denormal flushing handling based on the target.
3668 const unsigned ForwardedArguments[] = {
3669 options::OPT_cl_opt_disable,
3670 options::OPT_cl_strict_aliasing,
3671 options::OPT_cl_single_precision_constant,
3672 options::OPT_cl_finite_math_only,
3673 options::OPT_cl_kernel_arg_info,
3674 options::OPT_cl_unsafe_math_optimizations,
3675 options::OPT_cl_fast_relaxed_math,
3676 options::OPT_cl_mad_enable,
3677 options::OPT_cl_no_signed_zeros,
3678 options::OPT_cl_fp32_correctly_rounded_divide_sqrt,
3679 options::OPT_cl_uniform_work_group_size
3680 };
3681
3682 if (Arg *A = Args.getLastArg(options::OPT_cl_std_EQ)) {
3683 std::string CLStdStr = std::string("-cl-std=") + A->getValue();
3684 CmdArgs.push_back(Elt: Args.MakeArgString(Str: CLStdStr));
3685 } else if (Arg *A = Args.getLastArg(options::OPT_cl_ext_EQ)) {
3686 std::string CLExtStr = std::string("-cl-ext=") + A->getValue();
3687 CmdArgs.push_back(Elt: Args.MakeArgString(Str: CLExtStr));
3688 }
3689
3690 for (const auto &Arg : ForwardedArguments)
3691 if (const auto *A = Args.getLastArg(Arg))
3692 CmdArgs.push_back(Args.MakeArgString(A->getOption().getPrefixedName()));
3693
3694 // Only add the default headers if we are compiling OpenCL sources.
3695 if ((types::isOpenCL(InputType) ||
3696 (Args.hasArg(options::OPT_cl_std_EQ) && types::isSrcFile(InputType))) &&
3697 !Args.hasArg(options::OPT_cl_no_stdinc)) {
3698 CmdArgs.push_back(Elt: "-finclude-default-header");
3699 CmdArgs.push_back(Elt: "-fdeclare-opencl-builtins");
3700 }
3701}
3702
3703static void RenderHLSLOptions(const ArgList &Args, ArgStringList &CmdArgs,
3704 types::ID InputType) {
3705 const unsigned ForwardedArguments[] = {options::OPT_dxil_validator_version,
3706 options::OPT_D,
3707 options::OPT_I,
3708 options::OPT_S,
3709 options::OPT_O,
3710 options::OPT_emit_llvm,
3711 options::OPT_emit_obj,
3712 options::OPT_disable_llvm_passes,
3713 options::OPT_fnative_half_type,
3714 options::OPT_hlsl_entrypoint};
3715 if (!types::isHLSL(Id: InputType))
3716 return;
3717 for (const auto &Arg : ForwardedArguments)
3718 if (const auto *A = Args.getLastArg(Arg))
3719 A->renderAsInput(Args, CmdArgs);
3720 // Add the default headers if dxc_no_stdinc is not set.
3721 if (!Args.hasArg(options::OPT_dxc_no_stdinc) &&
3722 !Args.hasArg(options::OPT_nostdinc))
3723 CmdArgs.push_back(Elt: "-finclude-default-header");
3724}
3725
3726static void RenderOpenACCOptions(const Driver &D, const ArgList &Args,
3727 ArgStringList &CmdArgs, types::ID InputType) {
3728 if (!Args.hasArg(options::OPT_fopenacc))
3729 return;
3730
3731 CmdArgs.push_back(Elt: "-fopenacc");
3732
3733 if (Arg *A = Args.getLastArg(options::OPT_openacc_macro_override)) {
3734 StringRef Value = A->getValue();
3735 int Version;
3736 if (!Value.getAsInteger(Radix: 10, Result&: Version))
3737 A->renderAsInput(Args, Output&: CmdArgs);
3738 else
3739 D.Diag(diag::err_drv_clang_unsupported) << Value;
3740 }
3741}
3742
3743static void RenderARCMigrateToolOptions(const Driver &D, const ArgList &Args,
3744 ArgStringList &CmdArgs) {
3745 bool ARCMTEnabled = false;
3746 if (!Args.hasArg(options::OPT_fno_objc_arc, options::OPT_fobjc_arc)) {
3747 if (const Arg *A = Args.getLastArg(options::OPT_ccc_arcmt_check,
3748 options::OPT_ccc_arcmt_modify,
3749 options::OPT_ccc_arcmt_migrate)) {
3750 ARCMTEnabled = true;
3751 switch (A->getOption().getID()) {
3752 default: llvm_unreachable("missed a case");
3753 case options::OPT_ccc_arcmt_check:
3754 CmdArgs.push_back(Elt: "-arcmt-action=check");
3755 break;
3756 case options::OPT_ccc_arcmt_modify:
3757 CmdArgs.push_back(Elt: "-arcmt-action=modify");
3758 break;
3759 case options::OPT_ccc_arcmt_migrate:
3760 CmdArgs.push_back(Elt: "-arcmt-action=migrate");
3761 CmdArgs.push_back(Elt: "-mt-migrate-directory");
3762 CmdArgs.push_back(Elt: A->getValue());
3763
3764 Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_report_output);
3765 Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_emit_arc_errors);
3766 break;
3767 }
3768 }
3769 } else {
3770 Args.ClaimAllArgs(options::OPT_ccc_arcmt_check);
3771 Args.ClaimAllArgs(options::OPT_ccc_arcmt_modify);
3772 Args.ClaimAllArgs(options::OPT_ccc_arcmt_migrate);
3773 }
3774
3775 if (const Arg *A = Args.getLastArg(options::OPT_ccc_objcmt_migrate)) {
3776 if (ARCMTEnabled)
3777 D.Diag(diag::err_drv_argument_not_allowed_with)
3778 << A->getAsString(Args) << "-ccc-arcmt-migrate";
3779
3780 CmdArgs.push_back(Elt: "-mt-migrate-directory");
3781 CmdArgs.push_back(Elt: A->getValue());
3782
3783 if (!Args.hasArg(options::OPT_objcmt_migrate_literals,
3784 options::OPT_objcmt_migrate_subscripting,
3785 options::OPT_objcmt_migrate_property)) {
3786 // None specified, means enable them all.
3787 CmdArgs.push_back(Elt: "-objcmt-migrate-literals");
3788 CmdArgs.push_back(Elt: "-objcmt-migrate-subscripting");
3789 CmdArgs.push_back(Elt: "-objcmt-migrate-property");
3790 } else {
3791 Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
3792 Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
3793 Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
3794 }
3795 } else {
3796 Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
3797 Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
3798 Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
3799 Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_all);
3800 Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readonly_property);
3801 Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readwrite_property);
3802 Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property_dot_syntax);
3803 Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_annotation);
3804 Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_instancetype);
3805 Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_nsmacros);
3806 Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_protocol_conformance);
3807 Args.AddLastArg(CmdArgs, options::OPT_objcmt_atomic_property);
3808 Args.AddLastArg(CmdArgs, options::OPT_objcmt_returns_innerpointer_property);
3809 Args.AddLastArg(CmdArgs, options::OPT_objcmt_ns_nonatomic_iosonly);
3810 Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_designated_init);
3811 Args.AddLastArg(CmdArgs, options::OPT_objcmt_allowlist_dir_path);
3812 }
3813}
3814
3815static void RenderBuiltinOptions(const ToolChain &TC, const llvm::Triple &T,
3816 const ArgList &Args, ArgStringList &CmdArgs) {
3817 // -fbuiltin is default unless -mkernel is used.
3818 bool UseBuiltins =
3819 Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin,
3820 !Args.hasArg(options::OPT_mkernel));
3821 if (!UseBuiltins)
3822 CmdArgs.push_back(Elt: "-fno-builtin");
3823
3824 // -ffreestanding implies -fno-builtin.
3825 if (Args.hasArg(options::OPT_ffreestanding))
3826 UseBuiltins = false;
3827
3828 // Process the -fno-builtin-* options.
3829 for (const Arg *A : Args.filtered(options::OPT_fno_builtin_)) {
3830 A->claim();
3831
3832 // If -fno-builtin is specified, then there's no need to pass the option to
3833 // the frontend.
3834 if (UseBuiltins)
3835 A->render(Args, CmdArgs);
3836 }
3837
3838 // le32-specific flags:
3839 // -fno-math-builtin: clang should not convert math builtins to intrinsics
3840 // by default.
3841 if (TC.getArch() == llvm::Triple::le32)
3842 CmdArgs.push_back(Elt: "-fno-math-builtin");
3843}
3844
3845bool Driver::getDefaultModuleCachePath(SmallVectorImpl<char> &Result) {
3846 if (const char *Str = std::getenv(name: "CLANG_MODULE_CACHE_PATH")) {
3847 Twine Path{Str};
3848 Path.toVector(Out&: Result);
3849 return Path.getSingleStringRef() != "";
3850 }
3851 if (llvm::sys::path::cache_directory(result&: Result)) {
3852 llvm::sys::path::append(path&: Result, a: "clang");
3853 llvm::sys::path::append(path&: Result, a: "ModuleCache");
3854 return true;
3855 }
3856 return false;
3857}
3858
3859llvm::SmallString<256>
3860clang::driver::tools::getCXX20NamedModuleOutputPath(const ArgList &Args,
3861 const char *BaseInput) {
3862 if (Arg *ModuleOutputEQ = Args.getLastArg(options::OPT_fmodule_output_EQ))
3863 return StringRef(ModuleOutputEQ->getValue());
3864
3865 SmallString<256> OutputPath;
3866 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o);
3867 FinalOutput && Args.hasArg(options::OPT_c))
3868 OutputPath = FinalOutput->getValue();
3869 else
3870 OutputPath = BaseInput;
3871
3872 const char *Extension = types::getTypeTempSuffix(Id: types::TY_ModuleFile);
3873 llvm::sys::path::replace_extension(path&: OutputPath, extension: Extension);
3874 return OutputPath;
3875}
3876
3877static bool RenderModulesOptions(Compilation &C, const Driver &D,
3878 const ArgList &Args, const InputInfo &Input,
3879 const InputInfo &Output, bool HaveStd20,
3880 ArgStringList &CmdArgs) {
3881 bool IsCXX = types::isCXX(Id: Input.getType());
3882 bool HaveStdCXXModules = IsCXX && HaveStd20;
3883 bool HaveModules = HaveStdCXXModules;
3884
3885 // -fmodules enables the use of precompiled modules (off by default).
3886 // Users can pass -fno-cxx-modules to turn off modules support for
3887 // C++/Objective-C++ programs.
3888 bool HaveClangModules = false;
3889 if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) {
3890 bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules,
3891 options::OPT_fno_cxx_modules, true);
3892 if (AllowedInCXX || !IsCXX) {
3893 CmdArgs.push_back(Elt: "-fmodules");
3894 HaveClangModules = true;
3895 }
3896 }
3897
3898 HaveModules |= HaveClangModules;
3899
3900 // -fmodule-maps enables implicit reading of module map files. By default,
3901 // this is enabled if we are using Clang's flavor of precompiled modules.
3902 if (Args.hasFlag(options::OPT_fimplicit_module_maps,
3903 options::OPT_fno_implicit_module_maps, HaveClangModules))
3904 CmdArgs.push_back(Elt: "-fimplicit-module-maps");
3905
3906 // -fmodules-decluse checks that modules used are declared so (off by default)
3907 Args.addOptInFlag(CmdArgs, options::OPT_fmodules_decluse,
3908 options::OPT_fno_modules_decluse);
3909
3910 // -fmodules-strict-decluse is like -fmodule-decluse, but also checks that
3911 // all #included headers are part of modules.
3912 if (Args.hasFlag(options::OPT_fmodules_strict_decluse,
3913 options::OPT_fno_modules_strict_decluse, false))
3914 CmdArgs.push_back(Elt: "-fmodules-strict-decluse");
3915
3916 // -fno-implicit-modules turns off implicitly compiling modules on demand.
3917 bool ImplicitModules = false;
3918 if (!Args.hasFlag(options::OPT_fimplicit_modules,
3919 options::OPT_fno_implicit_modules, HaveClangModules)) {
3920 if (HaveModules)
3921 CmdArgs.push_back(Elt: "-fno-implicit-modules");
3922 } else if (HaveModules) {
3923 ImplicitModules = true;
3924 // -fmodule-cache-path specifies where our implicitly-built module files
3925 // should be written.
3926 SmallString<128> Path;
3927 if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path))
3928 Path = A->getValue();
3929
3930 bool HasPath = true;
3931 if (C.isForDiagnostics()) {
3932 // When generating crash reports, we want to emit the modules along with
3933 // the reproduction sources, so we ignore any provided module path.
3934 Path = Output.getFilename();
3935 llvm::sys::path::replace_extension(path&: Path, extension: ".cache");
3936 llvm::sys::path::append(path&: Path, a: "modules");
3937 } else if (Path.empty()) {
3938 // No module path was provided: use the default.
3939 HasPath = Driver::getDefaultModuleCachePath(Result&: Path);
3940 }
3941
3942 // `HasPath` will only be false if getDefaultModuleCachePath() fails.
3943 // That being said, that failure is unlikely and not caching is harmless.
3944 if (HasPath) {
3945 const char Arg[] = "-fmodules-cache-path=";
3946 Path.insert(I: Path.begin(), From: Arg, To: Arg + strlen(s: Arg));
3947 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Path));
3948 }
3949 }
3950
3951 if (HaveModules) {
3952 if (Args.hasFlag(options::OPT_fprebuilt_implicit_modules,
3953 options::OPT_fno_prebuilt_implicit_modules, false))
3954 CmdArgs.push_back(Elt: "-fprebuilt-implicit-modules");
3955 if (Args.hasFlag(options::OPT_fmodules_validate_input_files_content,
3956 options::OPT_fno_modules_validate_input_files_content,
3957 false))
3958 CmdArgs.push_back(Elt: "-fvalidate-ast-input-files-content");
3959 }
3960
3961 // -fmodule-name specifies the module that is currently being built (or
3962 // used for header checking by -fmodule-maps).
3963 Args.AddLastArg(CmdArgs, options::OPT_fmodule_name_EQ);
3964
3965 // -fmodule-map-file can be used to specify files containing module
3966 // definitions.
3967 Args.AddAllArgs(CmdArgs, options::OPT_fmodule_map_file);
3968
3969 // -fbuiltin-module-map can be used to load the clang
3970 // builtin headers modulemap file.
3971 if (Args.hasArg(options::OPT_fbuiltin_module_map)) {
3972 SmallString<128> BuiltinModuleMap(D.ResourceDir);
3973 llvm::sys::path::append(path&: BuiltinModuleMap, a: "include");
3974 llvm::sys::path::append(path&: BuiltinModuleMap, a: "module.modulemap");
3975 if (llvm::sys::fs::exists(Path: BuiltinModuleMap))
3976 CmdArgs.push_back(
3977 Elt: Args.MakeArgString(Str: "-fmodule-map-file=" + BuiltinModuleMap));
3978 }
3979
3980 // The -fmodule-file=<name>=<file> form specifies the mapping of module
3981 // names to precompiled module files (the module is loaded only if used).
3982 // The -fmodule-file=<file> form can be used to unconditionally load
3983 // precompiled module files (whether used or not).
3984 if (HaveModules || Input.getType() == clang::driver::types::TY_ModuleFile) {
3985 Args.AddAllArgs(CmdArgs, options::OPT_fmodule_file);
3986
3987 // -fprebuilt-module-path specifies where to load the prebuilt module files.
3988 for (const Arg *A : Args.filtered(options::OPT_fprebuilt_module_path)) {
3989 CmdArgs.push_back(Args.MakeArgString(
3990 std::string("-fprebuilt-module-path=") + A->getValue()));
3991 A->claim();
3992 }
3993 } else
3994 Args.ClaimAllArgs(options::OPT_fmodule_file);
3995
3996 // When building modules and generating crashdumps, we need to dump a module
3997 // dependency VFS alongside the output.
3998 if (HaveClangModules && C.isForDiagnostics()) {
3999 SmallString<128> VFSDir(Output.getFilename());
4000 llvm::sys::path::replace_extension(path&: VFSDir, extension: ".cache");
4001 // Add the cache directory as a temp so the crash diagnostics pick it up.
4002 C.addTempFile(Name: Args.MakeArgString(Str: VFSDir));
4003
4004 llvm::sys::path::append(path&: VFSDir, a: "vfs");
4005 CmdArgs.push_back(Elt: "-module-dependency-dir");
4006 CmdArgs.push_back(Elt: Args.MakeArgString(Str: VFSDir));
4007 }
4008
4009 if (HaveClangModules)
4010 Args.AddLastArg(CmdArgs, options::OPT_fmodules_user_build_path);
4011
4012 // Pass through all -fmodules-ignore-macro arguments.
4013 Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro);
4014 Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval);
4015 Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after);
4016
4017 if (HaveClangModules) {
4018 Args.AddLastArg(CmdArgs, options::OPT_fbuild_session_timestamp);
4019
4020 if (Arg *A = Args.getLastArg(options::OPT_fbuild_session_file)) {
4021 if (Args.hasArg(options::OPT_fbuild_session_timestamp))
4022 D.Diag(diag::err_drv_argument_not_allowed_with)
4023 << A->getAsString(Args) << "-fbuild-session-timestamp";
4024
4025 llvm::sys::fs::file_status Status;
4026 if (llvm::sys::fs::status(A->getValue(), Status))
4027 D.Diag(diag::err_drv_no_such_file) << A->getValue();
4028 CmdArgs.push_back(Elt: Args.MakeArgString(
4029 Str: "-fbuild-session-timestamp=" +
4030 Twine((uint64_t)std::chrono::duration_cast<std::chrono::seconds>(
4031 d: Status.getLastModificationTime().time_since_epoch())
4032 .count())));
4033 }
4034
4035 if (Args.getLastArg(
4036 options::OPT_fmodules_validate_once_per_build_session)) {
4037 if (!Args.getLastArg(options::OPT_fbuild_session_timestamp,
4038 options::OPT_fbuild_session_file))
4039 D.Diag(diag::err_drv_modules_validate_once_requires_timestamp);
4040
4041 Args.AddLastArg(CmdArgs,
4042 options::OPT_fmodules_validate_once_per_build_session);
4043 }
4044
4045 if (Args.hasFlag(options::OPT_fmodules_validate_system_headers,
4046 options::OPT_fno_modules_validate_system_headers,
4047 ImplicitModules))
4048 CmdArgs.push_back(Elt: "-fmodules-validate-system-headers");
4049
4050 Args.AddLastArg(CmdArgs,
4051 options::OPT_fmodules_disable_diagnostic_validation);
4052 } else {
4053 Args.ClaimAllArgs(options::OPT_fbuild_session_timestamp);
4054 Args.ClaimAllArgs(options::OPT_fbuild_session_file);
4055 Args.ClaimAllArgs(options::OPT_fmodules_validate_once_per_build_session);
4056 Args.ClaimAllArgs(options::OPT_fmodules_validate_system_headers);
4057 Args.ClaimAllArgs(options::OPT_fno_modules_validate_system_headers);
4058 Args.ClaimAllArgs(options::OPT_fmodules_disable_diagnostic_validation);
4059 }
4060
4061 // FIXME: We provisionally don't check ODR violations for decls in the global
4062 // module fragment.
4063 CmdArgs.push_back(Elt: "-fskip-odr-check-in-gmf");
4064
4065 if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
4066 (Input.getType() == driver::types::TY_CXXModule ||
4067 Input.getType() == driver::types::TY_PP_CXXModule)) {
4068 CmdArgs.push_back(Elt: "-fexperimental-modules-reduced-bmi");
4069
4070 if (Args.hasArg(options::OPT_fmodule_output_EQ))
4071 Args.AddLastArg(CmdArgs, options::OPT_fmodule_output_EQ);
4072 else
4073 CmdArgs.push_back(Elt: Args.MakeArgString(
4074 Str: "-fmodule-output=" +
4075 getCXX20NamedModuleOutputPath(Args, BaseInput: Input.getBaseInput())));
4076 }
4077
4078 // Noop if we see '-fexperimental-modules-reduced-bmi' with other translation
4079 // units than module units. This is more user friendly to allow end uers to
4080 // enable this feature without asking for help from build systems.
4081 Args.ClaimAllArgs(options::OPT_modules_reduced_bmi);
4082
4083 // We need to include the case the input file is a module file here.
4084 // Since the default compilation model for C++ module interface unit will
4085 // create temporary module file and compile the temporary module file
4086 // to get the object file. Then the `-fmodule-output` flag will be
4087 // brought to the second compilation process. So we have to claim it for
4088 // the case too.
4089 if (Input.getType() == driver::types::TY_CXXModule ||
4090 Input.getType() == driver::types::TY_PP_CXXModule ||
4091 Input.getType() == driver::types::TY_ModuleFile) {
4092 Args.ClaimAllArgs(options::OPT_fmodule_output);
4093 Args.ClaimAllArgs(options::OPT_fmodule_output_EQ);
4094 }
4095
4096 return HaveModules;
4097}
4098
4099static void RenderCharacterOptions(const ArgList &Args, const llvm::Triple &T,
4100 ArgStringList &CmdArgs) {
4101 // -fsigned-char is default.
4102 if (const Arg *A = Args.getLastArg(options::OPT_fsigned_char,
4103 options::OPT_fno_signed_char,
4104 options::OPT_funsigned_char,
4105 options::OPT_fno_unsigned_char)) {
4106 if (A->getOption().matches(options::OPT_funsigned_char) ||
4107 A->getOption().matches(options::OPT_fno_signed_char)) {
4108 CmdArgs.push_back(Elt: "-fno-signed-char");
4109 }
4110 } else if (!isSignedCharDefault(Triple: T)) {
4111 CmdArgs.push_back(Elt: "-fno-signed-char");
4112 }
4113
4114 // The default depends on the language standard.
4115 Args.AddLastArg(CmdArgs, options::OPT_fchar8__t, options::OPT_fno_char8__t);
4116
4117 if (const Arg *A = Args.getLastArg(options::OPT_fshort_wchar,
4118 options::OPT_fno_short_wchar)) {
4119 if (A->getOption().matches(options::OPT_fshort_wchar)) {
4120 CmdArgs.push_back(Elt: "-fwchar-type=short");
4121 CmdArgs.push_back(Elt: "-fno-signed-wchar");
4122 } else {
4123 bool IsARM = T.isARM() || T.isThumb() || T.isAArch64();
4124 CmdArgs.push_back(Elt: "-fwchar-type=int");
4125 if (T.isOSzOS() ||
4126 (IsARM && !(T.isOSWindows() || T.isOSNetBSD() || T.isOSOpenBSD())))
4127 CmdArgs.push_back(Elt: "-fno-signed-wchar");
4128 else
4129 CmdArgs.push_back(Elt: "-fsigned-wchar");
4130 }
4131 } else if (T.isOSzOS())
4132 CmdArgs.push_back(Elt: "-fno-signed-wchar");
4133}
4134
4135static void RenderObjCOptions(const ToolChain &TC, const Driver &D,
4136 const llvm::Triple &T, const ArgList &Args,
4137 ObjCRuntime &Runtime, bool InferCovariantReturns,
4138 const InputInfo &Input, ArgStringList &CmdArgs) {
4139 const llvm::Triple::ArchType Arch = TC.getArch();
4140
4141 // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and legacy
4142 // is the default. Except for deployment target of 10.5, next runtime is
4143 // always legacy dispatch and -fno-objc-legacy-dispatch gets ignored silently.
4144 if (Runtime.isNonFragile()) {
4145 if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch,
4146 options::OPT_fno_objc_legacy_dispatch,
4147 Runtime.isLegacyDispatchDefaultForArch(Arch))) {
4148 if (TC.UseObjCMixedDispatch())
4149 CmdArgs.push_back(Elt: "-fobjc-dispatch-method=mixed");
4150 else
4151 CmdArgs.push_back(Elt: "-fobjc-dispatch-method=non-legacy");
4152 }
4153 }
4154
4155 // When ObjectiveC legacy runtime is in effect on MacOSX, turn on the option
4156 // to do Array/Dictionary subscripting by default.
4157 if (Arch == llvm::Triple::x86 && T.isMacOSX() &&
4158 Runtime.getKind() == ObjCRuntime::FragileMacOSX && Runtime.isNeXTFamily())
4159 CmdArgs.push_back(Elt: "-fobjc-subscripting-legacy-runtime");
4160
4161 // Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc.
4162 // NOTE: This logic is duplicated in ToolChains.cpp.
4163 if (isObjCAutoRefCount(Args)) {
4164 TC.CheckObjCARC();
4165
4166 CmdArgs.push_back(Elt: "-fobjc-arc");
4167
4168 // FIXME: It seems like this entire block, and several around it should be
4169 // wrapped in isObjC, but for now we just use it here as this is where it
4170 // was being used previously.
4171 if (types::isCXX(Id: Input.getType()) && types::isObjC(Id: Input.getType())) {
4172 if (TC.GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
4173 CmdArgs.push_back(Elt: "-fobjc-arc-cxxlib=libc++");
4174 else
4175 CmdArgs.push_back(Elt: "-fobjc-arc-cxxlib=libstdc++");
4176 }
4177
4178 // Allow the user to enable full exceptions code emission.
4179 // We default off for Objective-C, on for Objective-C++.
4180 if (Args.hasFlag(options::OPT_fobjc_arc_exceptions,
4181 options::OPT_fno_objc_arc_exceptions,
4182 /*Default=*/types::isCXX(Input.getType())))
4183 CmdArgs.push_back(Elt: "-fobjc-arc-exceptions");
4184 }
4185
4186 // Silence warning for full exception code emission options when explicitly
4187 // set to use no ARC.
4188 if (Args.hasArg(options::OPT_fno_objc_arc)) {
4189 Args.ClaimAllArgs(options::OPT_fobjc_arc_exceptions);
4190 Args.ClaimAllArgs(options::OPT_fno_objc_arc_exceptions);
4191 }
4192
4193 // Allow the user to control whether messages can be converted to runtime
4194 // functions.
4195 if (types::isObjC(Id: Input.getType())) {
4196 auto *Arg = Args.getLastArg(
4197 options::OPT_fobjc_convert_messages_to_runtime_calls,
4198 options::OPT_fno_objc_convert_messages_to_runtime_calls);
4199 if (Arg &&
4200 Arg->getOption().matches(
4201 options::OPT_fno_objc_convert_messages_to_runtime_calls))
4202 CmdArgs.push_back(Elt: "-fno-objc-convert-messages-to-runtime-calls");
4203 }
4204
4205 // -fobjc-infer-related-result-type is the default, except in the Objective-C
4206 // rewriter.
4207 if (InferCovariantReturns)
4208 CmdArgs.push_back(Elt: "-fno-objc-infer-related-result-type");
4209
4210 // Pass down -fobjc-weak or -fno-objc-weak if present.
4211 if (types::isObjC(Id: Input.getType())) {
4212 auto WeakArg =
4213 Args.getLastArg(options::OPT_fobjc_weak, options::OPT_fno_objc_weak);
4214 if (!WeakArg) {
4215 // nothing to do
4216 } else if (!Runtime.allowsWeak()) {
4217 if (WeakArg->getOption().matches(options::OPT_fobjc_weak))
4218 D.Diag(diag::err_objc_weak_unsupported);
4219 } else {
4220 WeakArg->render(Args, CmdArgs);
4221 }
4222 }
4223
4224 if (Args.hasArg(options::OPT_fobjc_disable_direct_methods_for_testing))
4225 CmdArgs.push_back(Elt: "-fobjc-disable-direct-methods-for-testing");
4226}
4227
4228static void RenderDiagnosticsOptions(const Driver &D, const ArgList &Args,
4229 ArgStringList &CmdArgs) {
4230 bool CaretDefault = true;
4231 bool ColumnDefault = true;
4232
4233 if (const Arg *A = Args.getLastArg(options::OPT__SLASH_diagnostics_classic,
4234 options::OPT__SLASH_diagnostics_column,
4235 options::OPT__SLASH_diagnostics_caret)) {
4236 switch (A->getOption().getID()) {
4237 case options::OPT__SLASH_diagnostics_caret:
4238 CaretDefault = true;
4239 ColumnDefault = true;
4240 break;
4241 case options::OPT__SLASH_diagnostics_column:
4242 CaretDefault = false;
4243 ColumnDefault = true;
4244 break;
4245 case options::OPT__SLASH_diagnostics_classic:
4246 CaretDefault = false;
4247 ColumnDefault = false;
4248 break;
4249 }
4250 }
4251
4252 // -fcaret-diagnostics is default.
4253 if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
4254 options::OPT_fno_caret_diagnostics, CaretDefault))
4255 CmdArgs.push_back(Elt: "-fno-caret-diagnostics");
4256
4257 Args.addOptOutFlag(CmdArgs, options::OPT_fdiagnostics_fixit_info,
4258 options::OPT_fno_diagnostics_fixit_info);
4259 Args.addOptOutFlag(CmdArgs, options::OPT_fdiagnostics_show_option,
4260 options::OPT_fno_diagnostics_show_option);
4261
4262 if (const Arg *A =
4263 Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) {
4264 CmdArgs.push_back(Elt: "-fdiagnostics-show-category");
4265 CmdArgs.push_back(Elt: A->getValue());
4266 }
4267
4268 Args.addOptInFlag(CmdArgs, options::OPT_fdiagnostics_show_hotness,
4269 options::OPT_fno_diagnostics_show_hotness);
4270
4271 if (const Arg *A =
4272 Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) {
4273 std::string Opt =
4274 std::string("-fdiagnostics-hotness-threshold=") + A->getValue();
4275 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Opt));
4276 }
4277
4278 if (const Arg *A =
4279 Args.getLastArg(options::OPT_fdiagnostics_misexpect_tolerance_EQ)) {
4280 std::string Opt =
4281 std::string("-fdiagnostics-misexpect-tolerance=") + A->getValue();
4282 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Opt));
4283 }
4284
4285 if (const Arg *A = Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) {
4286 CmdArgs.push_back(Elt: "-fdiagnostics-format");
4287 CmdArgs.push_back(Elt: A->getValue());
4288 if (StringRef(A->getValue()) == "sarif" ||
4289 StringRef(A->getValue()) == "SARIF")
4290 D.Diag(diag::warn_drv_sarif_format_unstable);
4291 }
4292
4293 if (const Arg *A = Args.getLastArg(
4294 options::OPT_fdiagnostics_show_note_include_stack,
4295 options::OPT_fno_diagnostics_show_note_include_stack)) {
4296 const Option &O = A->getOption();
4297 if (O.matches(options::OPT_fdiagnostics_show_note_include_stack))
4298 CmdArgs.push_back(Elt: "-fdiagnostics-show-note-include-stack");
4299 else
4300 CmdArgs.push_back(Elt: "-fno-diagnostics-show-note-include-stack");
4301 }
4302
4303 // Color diagnostics are parsed by the driver directly from argv and later
4304 // re-parsed to construct this job; claim any possible color diagnostic here
4305 // to avoid warn_drv_unused_argument and diagnose bad
4306 // OPT_fdiagnostics_color_EQ values.
4307 Args.getLastArg(options::OPT_fcolor_diagnostics,
4308 options::OPT_fno_color_diagnostics);
4309 if (const Arg *A = Args.getLastArg(options::OPT_fdiagnostics_color_EQ)) {
4310 StringRef Value(A->getValue());
4311 if (Value != "always" && Value != "never" && Value != "auto")
4312 D.Diag(diag::err_drv_invalid_argument_to_option)
4313 << Value << A->getOption().getName();
4314 }
4315
4316 if (D.getDiags().getDiagnosticOptions().ShowColors)
4317 CmdArgs.push_back(Elt: "-fcolor-diagnostics");
4318
4319 if (Args.hasArg(options::OPT_fansi_escape_codes))
4320 CmdArgs.push_back(Elt: "-fansi-escape-codes");
4321
4322 Args.addOptOutFlag(CmdArgs, options::OPT_fshow_source_location,
4323 options::OPT_fno_show_source_location);
4324
4325 Args.addOptOutFlag(CmdArgs, options::OPT_fdiagnostics_show_line_numbers,
4326 options::OPT_fno_diagnostics_show_line_numbers);
4327
4328 if (Args.hasArg(options::OPT_fdiagnostics_absolute_paths))
4329 CmdArgs.push_back(Elt: "-fdiagnostics-absolute-paths");
4330
4331 if (!Args.hasFlag(options::OPT_fshow_column, options::OPT_fno_show_column,
4332 ColumnDefault))
4333 CmdArgs.push_back(Elt: "-fno-show-column");
4334
4335 Args.addOptOutFlag(CmdArgs, options::OPT_fspell_checking,
4336 options::OPT_fno_spell_checking);
4337}
4338
4339DwarfFissionKind tools::getDebugFissionKind(const Driver &D,
4340 const ArgList &Args, Arg *&Arg) {
4341 Arg = Args.getLastArg(options::OPT_gsplit_dwarf, options::OPT_gsplit_dwarf_EQ,
4342 options::OPT_gno_split_dwarf);
4343 if (!Arg || Arg->getOption().matches(options::OPT_gno_split_dwarf))
4344 return DwarfFissionKind::None;
4345
4346 if (Arg->getOption().matches(options::OPT_gsplit_dwarf))
4347 return DwarfFissionKind::Split;
4348
4349 StringRef Value = Arg->getValue();
4350 if (Value == "split")
4351 return DwarfFissionKind::Split;
4352 if (Value == "single")
4353 return DwarfFissionKind::Single;
4354
4355 D.Diag(diag::err_drv_unsupported_option_argument)
4356 << Arg->getSpelling() << Arg->getValue();
4357 return DwarfFissionKind::None;
4358}
4359
4360static void renderDwarfFormat(const Driver &D, const llvm::Triple &T,
4361 const ArgList &Args, ArgStringList &CmdArgs,
4362 unsigned DwarfVersion) {
4363 auto *DwarfFormatArg =
4364 Args.getLastArg(options::OPT_gdwarf64, options::OPT_gdwarf32);
4365 if (!DwarfFormatArg)
4366 return;
4367
4368 if (DwarfFormatArg->getOption().matches(options::OPT_gdwarf64)) {
4369 if (DwarfVersion < 3)
4370 D.Diag(diag::err_drv_argument_only_allowed_with)
4371 << DwarfFormatArg->getAsString(Args) << "DWARFv3 or greater";
4372 else if (!T.isArch64Bit())
4373 D.Diag(diag::err_drv_argument_only_allowed_with)
4374 << DwarfFormatArg->getAsString(Args) << "64 bit architecture";
4375 else if (!T.isOSBinFormatELF())
4376 D.Diag(diag::err_drv_argument_only_allowed_with)
4377 << DwarfFormatArg->getAsString(Args) << "ELF platforms";
4378 }
4379
4380 DwarfFormatArg->render(Args, CmdArgs);
4381}
4382
4383static void
4384renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T,
4385 const ArgList &Args, bool IRInput, ArgStringList &CmdArgs,
4386 const InputInfo &Output,
4387 llvm::codegenoptions::DebugInfoKind &DebugInfoKind,
4388 DwarfFissionKind &DwarfFission) {
4389 if (Args.hasFlag(options::OPT_fdebug_info_for_profiling,
4390 options::OPT_fno_debug_info_for_profiling, false) &&
4391 checkDebugInfoOption(
4392 Args.getLastArg(options::OPT_fdebug_info_for_profiling), Args, D, TC))
4393 CmdArgs.push_back(Elt: "-fdebug-info-for-profiling");
4394
4395 // The 'g' groups options involve a somewhat intricate sequence of decisions
4396 // about what to pass from the driver to the frontend, but by the time they
4397 // reach cc1 they've been factored into three well-defined orthogonal choices:
4398 // * what level of debug info to generate
4399 // * what dwarf version to write
4400 // * what debugger tuning to use
4401 // This avoids having to monkey around further in cc1 other than to disable
4402 // codeview if not running in a Windows environment. Perhaps even that
4403 // decision should be made in the driver as well though.
4404 llvm::DebuggerKind DebuggerTuning = TC.getDefaultDebuggerTuning();
4405
4406 bool SplitDWARFInlining =
4407 Args.hasFlag(options::OPT_fsplit_dwarf_inlining,
4408 options::OPT_fno_split_dwarf_inlining, false);
4409
4410 // Normally -gsplit-dwarf is only useful with -gN. For IR input, Clang does
4411 // object file generation and no IR generation, -gN should not be needed. So
4412 // allow -gsplit-dwarf with either -gN or IR input.
4413 if (IRInput || Args.hasArg(options::OPT_g_Group)) {
4414 Arg *SplitDWARFArg;
4415 DwarfFission = getDebugFissionKind(D, Args, Arg&: SplitDWARFArg);
4416 if (DwarfFission != DwarfFissionKind::None &&
4417 !checkDebugInfoOption(A: SplitDWARFArg, Args, D, TC)) {
4418 DwarfFission = DwarfFissionKind::None;
4419 SplitDWARFInlining = false;
4420 }
4421 }
4422 if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) {
4423 DebugInfoKind = llvm::codegenoptions::DebugInfoConstructor;
4424
4425 // If the last option explicitly specified a debug-info level, use it.
4426 if (checkDebugInfoOption(A, Args, D, TC) &&
4427 A->getOption().matches(options::OPT_gN_Group)) {
4428 DebugInfoKind = debugLevelToInfoKind(A: *A);
4429 // For -g0 or -gline-tables-only, drop -gsplit-dwarf. This gets a bit more
4430 // complicated if you've disabled inline info in the skeleton CUs
4431 // (SplitDWARFInlining) - then there's value in composing split-dwarf and
4432 // line-tables-only, so let those compose naturally in that case.
4433 if (DebugInfoKind == llvm::codegenoptions::NoDebugInfo ||
4434 DebugInfoKind == llvm::codegenoptions::DebugDirectivesOnly ||
4435 (DebugInfoKind == llvm::codegenoptions::DebugLineTablesOnly &&
4436 SplitDWARFInlining))
4437 DwarfFission = DwarfFissionKind::None;
4438 }
4439 }
4440
4441 // If a debugger tuning argument appeared, remember it.
4442 bool HasDebuggerTuning = false;
4443 if (const Arg *A =
4444 Args.getLastArg(options::OPT_gTune_Group, options::OPT_ggdbN_Group)) {
4445 HasDebuggerTuning = true;
4446 if (checkDebugInfoOption(A, Args, D, TC)) {
4447 if (A->getOption().matches(options::OPT_glldb))
4448 DebuggerTuning = llvm::DebuggerKind::LLDB;
4449 else if (A->getOption().matches(options::OPT_gsce))
4450 DebuggerTuning = llvm::DebuggerKind::SCE;
4451 else if (A->getOption().matches(options::OPT_gdbx))
4452 DebuggerTuning = llvm::DebuggerKind::DBX;
4453 else
4454 DebuggerTuning = llvm::DebuggerKind::GDB;
4455 }
4456 }
4457
4458 // If a -gdwarf argument appeared, remember it.
4459 bool EmitDwarf = false;
4460 if (const Arg *A = getDwarfNArg(Args))
4461 EmitDwarf = checkDebugInfoOption(A, Args, D, TC);
4462
4463 bool EmitCodeView = false;
4464 if (const Arg *A = Args.getLastArg(options::OPT_gcodeview))
4465 EmitCodeView = checkDebugInfoOption(A, Args, D, TC);
4466
4467 // If the user asked for debug info but did not explicitly specify -gcodeview
4468 // or -gdwarf, ask the toolchain for the default format.
4469 if (!EmitCodeView && !EmitDwarf &&
4470 DebugInfoKind != llvm::codegenoptions::NoDebugInfo) {
4471 switch (TC.getDefaultDebugFormat()) {
4472 case llvm::codegenoptions::DIF_CodeView:
4473 EmitCodeView = true;
4474 break;
4475 case llvm::codegenoptions::DIF_DWARF:
4476 EmitDwarf = true;
4477 break;
4478 }
4479 }
4480
4481 unsigned RequestedDWARFVersion = 0; // DWARF version requested by the user
4482 unsigned EffectiveDWARFVersion = 0; // DWARF version TC can generate. It may
4483 // be lower than what the user wanted.
4484 if (EmitDwarf) {
4485 RequestedDWARFVersion = getDwarfVersion(TC, Args);
4486 // Clamp effective DWARF version to the max supported by the toolchain.
4487 EffectiveDWARFVersion =
4488 std::min(a: RequestedDWARFVersion, b: TC.getMaxDwarfVersion());
4489 } else {
4490 Args.ClaimAllArgs(options::OPT_fdebug_default_version);
4491 }
4492
4493 // -gline-directives-only supported only for the DWARF debug info.
4494 if (RequestedDWARFVersion == 0 &&
4495 DebugInfoKind == llvm::codegenoptions::DebugDirectivesOnly)
4496 DebugInfoKind = llvm::codegenoptions::NoDebugInfo;
4497
4498 // strict DWARF is set to false by default. But for DBX, we need it to be set
4499 // as true by default.
4500 if (const Arg *A = Args.getLastArg(options::OPT_gstrict_dwarf))
4501 (void)checkDebugInfoOption(A, Args, D, TC);
4502 if (Args.hasFlag(options::OPT_gstrict_dwarf, options::OPT_gno_strict_dwarf,
4503 DebuggerTuning == llvm::DebuggerKind::DBX))
4504 CmdArgs.push_back(Elt: "-gstrict-dwarf");
4505
4506 // And we handle flag -grecord-gcc-switches later with DWARFDebugFlags.
4507 Args.ClaimAllArgs(options::OPT_g_flags_Group);
4508
4509 // Column info is included by default for everything except SCE and
4510 // CodeView. Clang doesn't track end columns, just starting columns, which,
4511 // in theory, is fine for CodeView (and PDB). In practice, however, the
4512 // Microsoft debuggers don't handle missing end columns well, and the AIX
4513 // debugger DBX also doesn't handle the columns well, so it's better not to
4514 // include any column info.
4515 if (const Arg *A = Args.getLastArg(options::OPT_gcolumn_info))
4516 (void)checkDebugInfoOption(A, Args, D, TC);
4517 if (!Args.hasFlag(options::OPT_gcolumn_info, options::OPT_gno_column_info,
4518 !EmitCodeView &&
4519 (DebuggerTuning != llvm::DebuggerKind::SCE &&
4520 DebuggerTuning != llvm::DebuggerKind::DBX)))
4521 CmdArgs.push_back(Elt: "-gno-column-info");
4522
4523 // FIXME: Move backend command line options to the module.
4524 if (Args.hasFlag(options::OPT_gmodules, options::OPT_gno_modules, false)) {
4525 // If -gline-tables-only or -gline-directives-only is the last option it
4526 // wins.
4527 if (checkDebugInfoOption(Args.getLastArg(options::OPT_gmodules), Args, D,
4528 TC)) {
4529 if (DebugInfoKind != llvm::codegenoptions::DebugLineTablesOnly &&
4530 DebugInfoKind != llvm::codegenoptions::DebugDirectivesOnly) {
4531 DebugInfoKind = llvm::codegenoptions::DebugInfoConstructor;
4532 CmdArgs.push_back(Elt: "-dwarf-ext-refs");
4533 CmdArgs.push_back(Elt: "-fmodule-format=obj");
4534 }
4535 }
4536 }
4537
4538 if (T.isOSBinFormatELF() && SplitDWARFInlining)
4539 CmdArgs.push_back(Elt: "-fsplit-dwarf-inlining");
4540
4541 // After we've dealt with all combinations of things that could
4542 // make DebugInfoKind be other than None or DebugLineTablesOnly,
4543 // figure out if we need to "upgrade" it to standalone debug info.
4544 // We parse these two '-f' options whether or not they will be used,
4545 // to claim them even if you wrote "-fstandalone-debug -gline-tables-only"
4546 bool NeedFullDebug = Args.hasFlag(
4547 options::OPT_fstandalone_debug, options::OPT_fno_standalone_debug,
4548 DebuggerTuning == llvm::DebuggerKind::LLDB ||
4549 TC.GetDefaultStandaloneDebug());
4550 if (const Arg *A = Args.getLastArg(options::OPT_fstandalone_debug))
4551 (void)checkDebugInfoOption(A, Args, D, TC);
4552
4553 if (DebugInfoKind == llvm::codegenoptions::LimitedDebugInfo ||
4554 DebugInfoKind == llvm::codegenoptions::DebugInfoConstructor) {
4555 if (Args.hasFlag(options::OPT_fno_eliminate_unused_debug_types,
4556 options::OPT_feliminate_unused_debug_types, false))
4557 DebugInfoKind = llvm::codegenoptions::UnusedTypeInfo;
4558 else if (NeedFullDebug)
4559 DebugInfoKind = llvm::codegenoptions::FullDebugInfo;
4560 }
4561
4562 if (Args.hasFlag(options::OPT_gembed_source, options::OPT_gno_embed_source,
4563 false)) {
4564 // Source embedding is a vendor extension to DWARF v5. By now we have
4565 // checked if a DWARF version was stated explicitly, and have otherwise
4566 // fallen back to the target default, so if this is still not at least 5
4567 // we emit an error.
4568 const Arg *A = Args.getLastArg(options::OPT_gembed_source);
4569 if (RequestedDWARFVersion < 5)
4570 D.Diag(diag::err_drv_argument_only_allowed_with)
4571 << A->getAsString(Args) << "-gdwarf-5";
4572 else if (EffectiveDWARFVersion < 5)
4573 // The toolchain has reduced allowed dwarf version, so we can't enable
4574 // -gembed-source.
4575 D.Diag(diag::warn_drv_dwarf_version_limited_by_target)
4576 << A->getAsString(Args) << TC.getTripleString() << 5
4577 << EffectiveDWARFVersion;
4578 else if (checkDebugInfoOption(A, Args, D, TC))
4579 CmdArgs.push_back(Elt: "-gembed-source");
4580 }
4581
4582 if (EmitCodeView) {
4583 CmdArgs.push_back(Elt: "-gcodeview");
4584
4585 Args.addOptInFlag(CmdArgs, options::OPT_gcodeview_ghash,
4586 options::OPT_gno_codeview_ghash);
4587
4588 Args.addOptOutFlag(CmdArgs, options::OPT_gcodeview_command_line,
4589 options::OPT_gno_codeview_command_line);
4590 }
4591
4592 Args.addOptOutFlag(CmdArgs, options::OPT_ginline_line_tables,
4593 options::OPT_gno_inline_line_tables);
4594
4595 // When emitting remarks, we need at least debug lines in the output.
4596 if (willEmitRemarks(Args) &&
4597 DebugInfoKind <= llvm::codegenoptions::DebugDirectivesOnly)
4598 DebugInfoKind = llvm::codegenoptions::DebugLineTablesOnly;
4599
4600 // Adjust the debug info kind for the given toolchain.
4601 TC.adjustDebugInfoKind(DebugInfoKind, Args);
4602
4603 // On AIX, the debugger tuning option can be omitted if it is not explicitly
4604 // set.
4605 RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion: EffectiveDWARFVersion,
4606 DebuggerTuning: T.isOSAIX() && !HasDebuggerTuning
4607 ? llvm::DebuggerKind::Default
4608 : DebuggerTuning);
4609
4610 // -fdebug-macro turns on macro debug info generation.
4611 if (Args.hasFlag(options::OPT_fdebug_macro, options::OPT_fno_debug_macro,
4612 false))
4613 if (checkDebugInfoOption(Args.getLastArg(options::OPT_fdebug_macro), Args,
4614 D, TC))
4615 CmdArgs.push_back(Elt: "-debug-info-macro");
4616
4617 // -ggnu-pubnames turns on gnu style pubnames in the backend.
4618 const auto *PubnamesArg =
4619 Args.getLastArg(options::OPT_ggnu_pubnames, options::OPT_gno_gnu_pubnames,
4620 options::OPT_gpubnames, options::OPT_gno_pubnames);
4621 if (DwarfFission != DwarfFissionKind::None ||
4622 (PubnamesArg && checkDebugInfoOption(PubnamesArg, Args, D, TC))) {
4623 const bool OptionSet =
4624 (PubnamesArg &&
4625 (PubnamesArg->getOption().matches(options::OPT_gpubnames) ||
4626 PubnamesArg->getOption().matches(options::OPT_ggnu_pubnames)));
4627 if ((DebuggerTuning != llvm::DebuggerKind::LLDB || OptionSet) &&
4628 (!PubnamesArg ||
4629 (!PubnamesArg->getOption().matches(options::OPT_gno_gnu_pubnames) &&
4630 !PubnamesArg->getOption().matches(options::OPT_gno_pubnames))))
4631 CmdArgs.push_back(PubnamesArg && PubnamesArg->getOption().matches(
4632 options::OPT_gpubnames)
4633 ? "-gpubnames"
4634 : "-ggnu-pubnames");
4635 }
4636 const auto *SimpleTemplateNamesArg =
4637 Args.getLastArg(options::OPT_gsimple_template_names,
4638 options::OPT_gno_simple_template_names);
4639 bool ForwardTemplateParams = DebuggerTuning == llvm::DebuggerKind::SCE;
4640 if (SimpleTemplateNamesArg &&
4641 checkDebugInfoOption(SimpleTemplateNamesArg, Args, D, TC)) {
4642 const auto &Opt = SimpleTemplateNamesArg->getOption();
4643 if (Opt.matches(options::OPT_gsimple_template_names)) {
4644 ForwardTemplateParams = true;
4645 CmdArgs.push_back(Elt: "-gsimple-template-names=simple");
4646 }
4647 }
4648
4649 // Emit DW_TAG_template_alias for template aliases? True by default for SCE.
4650 bool UseDebugTemplateAlias =
4651 DebuggerTuning == llvm::DebuggerKind::SCE && RequestedDWARFVersion >= 4;
4652 if (const auto *DebugTemplateAlias = Args.getLastArg(
4653 options::OPT_gtemplate_alias, options::OPT_gno_template_alias)) {
4654 // DW_TAG_template_alias is only supported from DWARFv5 but if a user
4655 // asks for it we should let them have it (if the target supports it).
4656 if (checkDebugInfoOption(DebugTemplateAlias, Args, D, TC)) {
4657 const auto &Opt = DebugTemplateAlias->getOption();
4658 UseDebugTemplateAlias = Opt.matches(options::OPT_gtemplate_alias);
4659 }
4660 }
4661 if (UseDebugTemplateAlias)
4662 CmdArgs.push_back(Elt: "-gtemplate-alias");
4663
4664 if (const Arg *A = Args.getLastArg(options::OPT_gsrc_hash_EQ)) {
4665 StringRef v = A->getValue();
4666 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-gsrc-hash=" + v));
4667 }
4668
4669 Args.addOptInFlag(CmdArgs, options::OPT_fdebug_ranges_base_address,
4670 options::OPT_fno_debug_ranges_base_address);
4671
4672 // -gdwarf-aranges turns on the emission of the aranges section in the
4673 // backend.
4674 // Always enabled for SCE tuning.
4675 bool NeedAranges = DebuggerTuning == llvm::DebuggerKind::SCE;
4676 if (const Arg *A = Args.getLastArg(options::OPT_gdwarf_aranges))
4677 NeedAranges = checkDebugInfoOption(A, Args, D, TC) || NeedAranges;
4678 if (NeedAranges) {
4679 CmdArgs.push_back(Elt: "-mllvm");
4680 CmdArgs.push_back(Elt: "-generate-arange-section");
4681 }
4682
4683 Args.addOptInFlag(CmdArgs, options::OPT_fforce_dwarf_frame,
4684 options::OPT_fno_force_dwarf_frame);
4685
4686 if (Args.hasFlag(options::OPT_fdebug_types_section,
4687 options::OPT_fno_debug_types_section, false)) {
4688 if (!(T.isOSBinFormatELF() || T.isOSBinFormatWasm())) {
4689 D.Diag(diag::err_drv_unsupported_opt_for_target)
4690 << Args.getLastArg(options::OPT_fdebug_types_section)
4691 ->getAsString(Args)
4692 << T.getTriple();
4693 } else if (checkDebugInfoOption(
4694 Args.getLastArg(options::OPT_fdebug_types_section), Args, D,
4695 TC)) {
4696 CmdArgs.push_back(Elt: "-mllvm");
4697 CmdArgs.push_back(Elt: "-generate-type-units");
4698 }
4699 }
4700
4701 // To avoid join/split of directory+filename, the integrated assembler prefers
4702 // the directory form of .file on all DWARF versions. GNU as doesn't allow the
4703 // form before DWARF v5.
4704 if (!Args.hasFlag(options::OPT_fdwarf_directory_asm,
4705 options::OPT_fno_dwarf_directory_asm,
4706 TC.useIntegratedAs() || EffectiveDWARFVersion >= 5))
4707 CmdArgs.push_back(Elt: "-fno-dwarf-directory-asm");
4708
4709 // Decide how to render forward declarations of template instantiations.
4710 // SCE wants full descriptions, others just get them in the name.
4711 if (ForwardTemplateParams)
4712 CmdArgs.push_back(Elt: "-debug-forward-template-params");
4713
4714 // Do we need to explicitly import anonymous namespaces into the parent
4715 // scope?
4716 if (DebuggerTuning == llvm::DebuggerKind::SCE)
4717 CmdArgs.push_back(Elt: "-dwarf-explicit-import");
4718
4719 renderDwarfFormat(D, T, Args, CmdArgs, DwarfVersion: EffectiveDWARFVersion);
4720 RenderDebugInfoCompressionArgs(Args, CmdArgs, D, TC);
4721
4722 // This controls whether or not we perform JustMyCode instrumentation.
4723 if (Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false)) {
4724 if (TC.getTriple().isOSBinFormatELF() || D.IsCLMode()) {
4725 if (DebugInfoKind >= llvm::codegenoptions::DebugInfoConstructor)
4726 CmdArgs.push_back(Elt: "-fjmc");
4727 else if (D.IsCLMode())
4728 D.Diag(clang::diag::warn_drv_jmc_requires_debuginfo) << "/JMC"
4729 << "'/Zi', '/Z7'";
4730 else
4731 D.Diag(clang::diag::warn_drv_jmc_requires_debuginfo) << "-fjmc"
4732 << "-g";
4733 } else {
4734 D.Diag(clang::diag::warn_drv_fjmc_for_elf_only);
4735 }
4736 }
4737
4738 // Add in -fdebug-compilation-dir if necessary.
4739 const char *DebugCompilationDir =
4740 addDebugCompDirArg(Args, CmdArgs, VFS: D.getVFS());
4741
4742 addDebugPrefixMapArg(D, TC, Args, CmdArgs);
4743
4744 // Add the output path to the object file for CodeView debug infos.
4745 if (EmitCodeView && Output.isFilename())
4746 addDebugObjectName(Args, CmdArgs, DebugCompilationDir,
4747 OutputFileName: Output.getFilename());
4748}
4749
4750static void ProcessVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args,
4751 ArgStringList &CmdArgs) {
4752 unsigned RTOptionID = options::OPT__SLASH_MT;
4753
4754 if (Args.hasArg(options::OPT__SLASH_LDd))
4755 // The /LDd option implies /MTd. The dependent lib part can be overridden,
4756 // but defining _DEBUG is sticky.
4757 RTOptionID = options::OPT__SLASH_MTd;
4758
4759 if (Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group))
4760 RTOptionID = A->getOption().getID();
4761
4762 if (Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
4763 RTOptionID = llvm::StringSwitch<unsigned>(A->getValue())
4764 .Case("static", options::OPT__SLASH_MT)
4765 .Case("static_dbg", options::OPT__SLASH_MTd)
4766 .Case("dll", options::OPT__SLASH_MD)
4767 .Case("dll_dbg", options::OPT__SLASH_MDd)
4768 .Default(options::OPT__SLASH_MT);
4769 }
4770
4771 StringRef FlagForCRT;
4772 switch (RTOptionID) {
4773 case options::OPT__SLASH_MD:
4774 if (Args.hasArg(options::OPT__SLASH_LDd))
4775 CmdArgs.push_back(Elt: "-D_DEBUG");
4776 CmdArgs.push_back(Elt: "-D_MT");
4777 CmdArgs.push_back(Elt: "-D_DLL");
4778 FlagForCRT = "--dependent-lib=msvcrt";
4779 break;
4780 case options::OPT__SLASH_MDd:
4781 CmdArgs.push_back(Elt: "-D_DEBUG");
4782 CmdArgs.push_back(Elt: "-D_MT");
4783 CmdArgs.push_back(Elt: "-D_DLL");
4784 FlagForCRT = "--dependent-lib=msvcrtd";
4785 break;
4786 case options::OPT__SLASH_MT:
4787 if (Args.hasArg(options::OPT__SLASH_LDd))
4788 CmdArgs.push_back(Elt: "-D_DEBUG");
4789 CmdArgs.push_back(Elt: "-D_MT");
4790 CmdArgs.push_back(Elt: "-flto-visibility-public-std");
4791 FlagForCRT = "--dependent-lib=libcmt";
4792 break;
4793 case options::OPT__SLASH_MTd:
4794 CmdArgs.push_back(Elt: "-D_DEBUG");
4795 CmdArgs.push_back(Elt: "-D_MT");
4796 CmdArgs.push_back(Elt: "-flto-visibility-public-std");
4797 FlagForCRT = "--dependent-lib=libcmtd";
4798 break;
4799 default:
4800 llvm_unreachable("Unexpected option ID.");
4801 }
4802
4803 if (Args.hasArg(options::OPT_fms_omit_default_lib)) {
4804 CmdArgs.push_back(Elt: "-D_VC_NODEFAULTLIB");
4805 } else {
4806 CmdArgs.push_back(Elt: FlagForCRT.data());
4807
4808 // This provides POSIX compatibility (maps 'open' to '_open'), which most
4809 // users want. The /Za flag to cl.exe turns this off, but it's not
4810 // implemented in clang.
4811 CmdArgs.push_back(Elt: "--dependent-lib=oldnames");
4812 }
4813
4814 // All Arm64EC object files implicitly add softintrin.lib. This is necessary
4815 // even if the file doesn't actually refer to any of the routines because
4816 // the CRT itself has incomplete dependency markings.
4817 if (TC.getTriple().isWindowsArm64EC())
4818 CmdArgs.push_back(Elt: "--dependent-lib=softintrin");
4819}
4820
4821void Clang::ConstructJob(Compilation &C, const JobAction &JA,
4822 const InputInfo &Output, const InputInfoList &Inputs,
4823 const ArgList &Args, const char *LinkingOutput) const {
4824 const auto &TC = getToolChain();
4825 const llvm::Triple &RawTriple = TC.getTriple();
4826 const llvm::Triple &Triple = TC.getEffectiveTriple();
4827 const std::string &TripleStr = Triple.getTriple();
4828
4829 bool KernelOrKext =
4830 Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
4831 const Driver &D = TC.getDriver();
4832 ArgStringList CmdArgs;
4833
4834 assert(Inputs.size() >= 1 && "Must have at least one input.");
4835 // CUDA/HIP compilation may have multiple inputs (source file + results of
4836 // device-side compilations). OpenMP device jobs also take the host IR as a
4837 // second input. Module precompilation accepts a list of header files to
4838 // include as part of the module. API extraction accepts a list of header
4839 // files whose API information is emitted in the output. All other jobs are
4840 // expected to have exactly one input.
4841 bool IsCuda = JA.isOffloading(OKind: Action::OFK_Cuda);
4842 bool IsCudaDevice = JA.isDeviceOffloading(OKind: Action::OFK_Cuda);
4843 bool IsHIP = JA.isOffloading(OKind: Action::OFK_HIP);
4844 bool IsHIPDevice = JA.isDeviceOffloading(OKind: Action::OFK_HIP);
4845 bool IsOpenMPDevice = JA.isDeviceOffloading(OKind: Action::OFK_OpenMP);
4846 bool IsExtractAPI = isa<ExtractAPIJobAction>(Val: JA);
4847 bool IsDeviceOffloadAction = !(JA.isDeviceOffloading(OKind: Action::OFK_None) ||
4848 JA.isDeviceOffloading(OKind: Action::OFK_Host));
4849 bool IsHostOffloadingAction =
4850 JA.isHostOffloading(Action::OFK_OpenMP) ||
4851 (JA.isHostOffloading(C.getActiveOffloadKinds()) &&
4852 Args.hasFlag(options::OPT_offload_new_driver,
4853 options::OPT_no_offload_new_driver, false));
4854
4855 bool IsRDCMode =
4856 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false);
4857 bool IsUsingLTO = D.isUsingLTO(IsOffload: IsDeviceOffloadAction);
4858 auto LTOMode = D.getLTOMode(IsOffload: IsDeviceOffloadAction);
4859
4860 // Extract API doesn't have a main input file, so invent a fake one as a
4861 // placeholder.
4862 InputInfo ExtractAPIPlaceholderInput(Inputs[0].getType(), "extract-api",
4863 "extract-api");
4864
4865 const InputInfo &Input =
4866 IsExtractAPI ? ExtractAPIPlaceholderInput : Inputs[0];
4867
4868 InputInfoList ExtractAPIInputs;
4869 InputInfoList HostOffloadingInputs;
4870 const InputInfo *CudaDeviceInput = nullptr;
4871 const InputInfo *OpenMPDeviceInput = nullptr;
4872 for (const InputInfo &I : Inputs) {
4873 if (&I == &Input || I.getType() == types::TY_Nothing) {
4874 // This is the primary input or contains nothing.
4875 } else if (IsExtractAPI) {
4876 auto ExpectedInputType = ExtractAPIPlaceholderInput.getType();
4877 if (I.getType() != ExpectedInputType) {
4878 D.Diag(diag::err_drv_extract_api_wrong_kind)
4879 << I.getFilename() << types::getTypeName(I.getType())
4880 << types::getTypeName(ExpectedInputType);
4881 }
4882 ExtractAPIInputs.push_back(Elt: I);
4883 } else if (IsHostOffloadingAction) {
4884 HostOffloadingInputs.push_back(Elt: I);
4885 } else if ((IsCuda || IsHIP) && !CudaDeviceInput) {
4886 CudaDeviceInput = &I;
4887 } else if (IsOpenMPDevice && !OpenMPDeviceInput) {
4888 OpenMPDeviceInput = &I;
4889 } else {
4890 llvm_unreachable("unexpectedly given multiple inputs");
4891 }
4892 }
4893
4894 const llvm::Triple *AuxTriple =
4895 (IsCuda || IsHIP) ? TC.getAuxTriple() : nullptr;
4896 bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment();
4897 bool IsIAMCU = RawTriple.isOSIAMCU();
4898
4899 // Adjust IsWindowsXYZ for CUDA/HIP compilations. Even when compiling in
4900 // device mode (i.e., getToolchain().getTriple() is NVPTX/AMDGCN, not
4901 // Windows), we need to pass Windows-specific flags to cc1.
4902 if (IsCuda || IsHIP)
4903 IsWindowsMSVC |= AuxTriple && AuxTriple->isWindowsMSVCEnvironment();
4904
4905 // C++ is not supported for IAMCU.
4906 if (IsIAMCU && types::isCXX(Input.getType()))
4907 D.Diag(diag::err_drv_clang_unsupported) << "C++ for IAMCU";
4908
4909 // Invoke ourselves in -cc1 mode.
4910 //
4911 // FIXME: Implement custom jobs for internal actions.
4912 CmdArgs.push_back(Elt: "-cc1");
4913
4914 // Add the "effective" target triple.
4915 CmdArgs.push_back(Elt: "-triple");
4916 CmdArgs.push_back(Elt: Args.MakeArgString(Str: TripleStr));
4917
4918 if (const Arg *MJ = Args.getLastArg(options::OPT_MJ)) {
4919 DumpCompilationDatabase(C, Filename: MJ->getValue(), Target: TripleStr, Output, Input, Args);
4920 Args.ClaimAllArgs(options::OPT_MJ);
4921 } else if (const Arg *GenCDBFragment =
4922 Args.getLastArg(options::OPT_gen_cdb_fragment_path)) {
4923 DumpCompilationDatabaseFragmentToDir(Dir: GenCDBFragment->getValue(), C,
4924 Target: TripleStr, Output, Input, Args);
4925 Args.ClaimAllArgs(options::OPT_gen_cdb_fragment_path);
4926 }
4927
4928 if (IsCuda || IsHIP) {
4929 // We have to pass the triple of the host if compiling for a CUDA/HIP device
4930 // and vice-versa.
4931 std::string NormalizedTriple;
4932 if (JA.isDeviceOffloading(OKind: Action::OFK_Cuda) ||
4933 JA.isDeviceOffloading(OKind: Action::OFK_HIP))
4934 NormalizedTriple = C.getSingleOffloadToolChain<Action::OFK_Host>()
4935 ->getTriple()
4936 .normalize();
4937 else {
4938 // Host-side compilation.
4939 NormalizedTriple =
4940 (IsCuda ? C.getSingleOffloadToolChain<Action::OFK_Cuda>()
4941 : C.getSingleOffloadToolChain<Action::OFK_HIP>())
4942 ->getTriple()
4943 .normalize();
4944 if (IsCuda) {
4945 // We need to figure out which CUDA version we're compiling for, as that
4946 // determines how we load and launch GPU kernels.
4947 auto *CTC = static_cast<const toolchains::CudaToolChain *>(
4948 C.getSingleOffloadToolChain<Action::OFK_Cuda>());
4949 assert(CTC && "Expected valid CUDA Toolchain.");
4950 if (CTC && CTC->CudaInstallation.version() != CudaVersion::UNKNOWN)
4951 CmdArgs.push_back(Elt: Args.MakeArgString(
4952 Str: Twine("-target-sdk-version=") +
4953 CudaVersionToString(V: CTC->CudaInstallation.version())));
4954 // Unsized function arguments used for variadics were introduced in
4955 // CUDA-9.0. We still do not support generating code that actually uses
4956 // variadic arguments yet, but we do need to allow parsing them as
4957 // recent CUDA headers rely on that.
4958 // https://github.com/llvm/llvm-project/issues/58410
4959 if (CTC->CudaInstallation.version() >= CudaVersion::CUDA_90)
4960 CmdArgs.push_back(Elt: "-fcuda-allow-variadic-functions");
4961 }
4962 }
4963 CmdArgs.push_back(Elt: "-aux-triple");
4964 CmdArgs.push_back(Elt: Args.MakeArgString(Str: NormalizedTriple));
4965
4966 if (JA.isDeviceOffloading(OKind: Action::OFK_HIP) &&
4967 getToolChain().getTriple().isAMDGPU()) {
4968 // Device side compilation printf
4969 if (Args.getLastArg(options::OPT_mprintf_kind_EQ)) {
4970 CmdArgs.push_back(Args.MakeArgString(
4971 "-mprintf-kind=" +
4972 Args.getLastArgValue(options::OPT_mprintf_kind_EQ)));
4973 // Force compiler error on invalid conversion specifiers
4974 CmdArgs.push_back(
4975 Elt: Args.MakeArgString(Str: "-Werror=format-invalid-specifier"));
4976 }
4977 }
4978 }
4979
4980 // Unconditionally claim the printf option now to avoid unused diagnostic.
4981 if (const Arg *PF = Args.getLastArg(options::OPT_mprintf_kind_EQ))
4982 PF->claim();
4983
4984 if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false)) {
4985 CmdArgs.push_back(Elt: "-fsycl-is-device");
4986
4987 if (Arg *A = Args.getLastArg(options::OPT_sycl_std_EQ)) {
4988 A->render(Args, Output&: CmdArgs);
4989 } else {
4990 // Ensure the default version in SYCL mode is 2020.
4991 CmdArgs.push_back(Elt: "-sycl-std=2020");
4992 }
4993 }
4994
4995 if (IsOpenMPDevice) {
4996 // We have to pass the triple of the host if compiling for an OpenMP device.
4997 std::string NormalizedTriple =
4998 C.getSingleOffloadToolChain<Action::OFK_Host>()
4999 ->getTriple()
5000 .normalize();
5001 CmdArgs.push_back(Elt: "-aux-triple");
5002 CmdArgs.push_back(Elt: Args.MakeArgString(Str: NormalizedTriple));
5003 }
5004
5005 if (Triple.isOSWindows() && (Triple.getArch() == llvm::Triple::arm ||
5006 Triple.getArch() == llvm::Triple::thumb)) {
5007 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
5008 unsigned Version = 0;
5009 bool Failure =
5010 Triple.getArchName().substr(Start: Offset).consumeInteger(Radix: 10, Result&: Version);
5011 if (Failure || Version < 7)
5012 D.Diag(diag::err_target_unsupported_arch) << Triple.getArchName()
5013 << TripleStr;
5014 }
5015
5016 // Push all default warning arguments that are specific to
5017 // the given target. These come before user provided warning options
5018 // are provided.
5019 TC.addClangWarningOptions(CC1Args&: CmdArgs);
5020
5021 // FIXME: Subclass ToolChain for SPIR and move this to addClangWarningOptions.
5022 if (Triple.isSPIR() || Triple.isSPIRV())
5023 CmdArgs.push_back(Elt: "-Wspir-compat");
5024
5025 // Select the appropriate action.
5026 RewriteKind rewriteKind = RK_None;
5027
5028 bool UnifiedLTO = false;
5029 if (IsUsingLTO) {
5030 UnifiedLTO = Args.hasFlag(options::OPT_funified_lto,
5031 options::OPT_fno_unified_lto, Triple.isPS());
5032 if (UnifiedLTO)
5033 CmdArgs.push_back(Elt: "-funified-lto");
5034 }
5035
5036 // If CollectArgsForIntegratedAssembler() isn't called below, claim the args
5037 // it claims when not running an assembler. Otherwise, clang would emit
5038 // "argument unused" warnings for assembler flags when e.g. adding "-E" to
5039 // flags while debugging something. That'd be somewhat inconvenient, and it's
5040 // also inconsistent with most other flags -- we don't warn on
5041 // -ffunction-sections not being used in -E mode either for example, even
5042 // though it's not really used either.
5043 if (!isa<AssembleJobAction>(Val: JA)) {
5044 // The args claimed here should match the args used in
5045 // CollectArgsForIntegratedAssembler().
5046 if (TC.useIntegratedAs()) {
5047 Args.ClaimAllArgs(options::OPT_mrelax_all);
5048 Args.ClaimAllArgs(options::OPT_mno_relax_all);
5049 Args.ClaimAllArgs(options::OPT_mincremental_linker_compatible);
5050 Args.ClaimAllArgs(options::OPT_mno_incremental_linker_compatible);
5051 switch (C.getDefaultToolChain().getArch()) {
5052 case llvm::Triple::arm:
5053 case llvm::Triple::armeb:
5054 case llvm::Triple::thumb:
5055 case llvm::Triple::thumbeb:
5056 Args.ClaimAllArgs(options::OPT_mimplicit_it_EQ);
5057 break;
5058 default:
5059 break;
5060 }
5061 }
5062 Args.ClaimAllArgs(options::OPT_Wa_COMMA);
5063 Args.ClaimAllArgs(options::OPT_Xassembler);
5064 Args.ClaimAllArgs(options::OPT_femit_dwarf_unwind_EQ);
5065 }
5066
5067 if (isa<AnalyzeJobAction>(Val: JA)) {
5068 assert(JA.getType() == types::TY_Plist && "Invalid output type.");
5069 CmdArgs.push_back(Elt: "-analyze");
5070 } else if (isa<MigrateJobAction>(Val: JA)) {
5071 CmdArgs.push_back(Elt: "-migrate");
5072 } else if (isa<PreprocessJobAction>(Val: JA)) {
5073 if (Output.getType() == types::TY_Dependencies)
5074 CmdArgs.push_back(Elt: "-Eonly");
5075 else {
5076 CmdArgs.push_back(Elt: "-E");
5077 if (Args.hasArg(options::OPT_rewrite_objc) &&
5078 !Args.hasArg(options::OPT_g_Group))
5079 CmdArgs.push_back(Elt: "-P");
5080 else if (JA.getType() == types::TY_PP_CXXHeaderUnit)
5081 CmdArgs.push_back(Elt: "-fdirectives-only");
5082 }
5083 } else if (isa<AssembleJobAction>(Val: JA)) {
5084 CmdArgs.push_back(Elt: "-emit-obj");
5085
5086 CollectArgsForIntegratedAssembler(C, Args, CmdArgs, D);
5087
5088 // Also ignore explicit -force_cpusubtype_ALL option.
5089 (void)Args.hasArg(options::OPT_force__cpusubtype__ALL);
5090 } else if (isa<PrecompileJobAction>(Val: JA)) {
5091 if (JA.getType() == types::TY_Nothing)
5092 CmdArgs.push_back(Elt: "-fsyntax-only");
5093 else if (JA.getType() == types::TY_ModuleFile)
5094 CmdArgs.push_back(Elt: "-emit-module-interface");
5095 else if (JA.getType() == types::TY_HeaderUnit)
5096 CmdArgs.push_back(Elt: "-emit-header-unit");
5097 else
5098 CmdArgs.push_back(Elt: "-emit-pch");
5099 } else if (isa<VerifyPCHJobAction>(Val: JA)) {
5100 CmdArgs.push_back(Elt: "-verify-pch");
5101 } else if (isa<ExtractAPIJobAction>(Val: JA)) {
5102 assert(JA.getType() == types::TY_API_INFO &&
5103 "Extract API actions must generate a API information.");
5104 CmdArgs.push_back(Elt: "-extract-api");
5105
5106 if (Arg *PrettySGFArg = Args.getLastArg(options::OPT_emit_pretty_sgf))
5107 PrettySGFArg->render(Args, Output&: CmdArgs);
5108
5109 Arg *SymbolGraphDirArg = Args.getLastArg(options::OPT_symbol_graph_dir_EQ);
5110
5111 if (Arg *ProductNameArg = Args.getLastArg(options::OPT_product_name_EQ))
5112 ProductNameArg->render(Args, Output&: CmdArgs);
5113 if (Arg *ExtractAPIIgnoresFileArg =
5114 Args.getLastArg(options::OPT_extract_api_ignores_EQ))
5115 ExtractAPIIgnoresFileArg->render(Args, Output&: CmdArgs);
5116 if (Arg *EmitExtensionSymbolGraphs =
5117 Args.getLastArg(options::OPT_emit_extension_symbol_graphs)) {
5118 if (!SymbolGraphDirArg)
5119 D.Diag(diag::err_drv_missing_symbol_graph_dir);
5120
5121 EmitExtensionSymbolGraphs->render(Args, Output&: CmdArgs);
5122 }
5123 if (SymbolGraphDirArg)
5124 SymbolGraphDirArg->render(Args, Output&: CmdArgs);
5125 } else {
5126 assert((isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) &&
5127 "Invalid action for clang tool.");
5128 if (JA.getType() == types::TY_Nothing) {
5129 CmdArgs.push_back(Elt: "-fsyntax-only");
5130 } else if (JA.getType() == types::TY_LLVM_IR ||
5131 JA.getType() == types::TY_LTO_IR) {
5132 CmdArgs.push_back(Elt: "-emit-llvm");
5133 } else if (JA.getType() == types::TY_LLVM_BC ||
5134 JA.getType() == types::TY_LTO_BC) {
5135 // Emit textual llvm IR for AMDGPU offloading for -emit-llvm -S
5136 if (Triple.isAMDGCN() && IsOpenMPDevice && Args.hasArg(options::OPT_S) &&
5137 Args.hasArg(options::OPT_emit_llvm)) {
5138 CmdArgs.push_back(Elt: "-emit-llvm");
5139 } else {
5140 CmdArgs.push_back(Elt: "-emit-llvm-bc");
5141 }
5142 } else if (JA.getType() == types::TY_IFS ||
5143 JA.getType() == types::TY_IFS_CPP) {
5144 StringRef ArgStr =
5145 Args.hasArg(options::OPT_interface_stub_version_EQ)
5146 ? Args.getLastArgValue(options::OPT_interface_stub_version_EQ)
5147 : "ifs-v1";
5148 CmdArgs.push_back(Elt: "-emit-interface-stubs");
5149 CmdArgs.push_back(
5150 Elt: Args.MakeArgString(Str: Twine("-interface-stub-version=") + ArgStr.str()));
5151 } else if (JA.getType() == types::TY_PP_Asm) {
5152 CmdArgs.push_back(Elt: "-S");
5153 } else if (JA.getType() == types::TY_AST) {
5154 CmdArgs.push_back(Elt: "-emit-pch");
5155 } else if (JA.getType() == types::TY_ModuleFile) {
5156 CmdArgs.push_back(Elt: "-module-file-info");
5157 } else if (JA.getType() == types::TY_RewrittenObjC) {
5158 CmdArgs.push_back(Elt: "-rewrite-objc");
5159 rewriteKind = RK_NonFragile;
5160 } else if (JA.getType() == types::TY_RewrittenLegacyObjC) {
5161 CmdArgs.push_back(Elt: "-rewrite-objc");
5162 rewriteKind = RK_Fragile;
5163 } else {
5164 assert(JA.getType() == types::TY_PP_Asm && "Unexpected output type!");
5165 }
5166
5167 // Preserve use-list order by default when emitting bitcode, so that
5168 // loading the bitcode up in 'opt' or 'llc' and running passes gives the
5169 // same result as running passes here. For LTO, we don't need to preserve
5170 // the use-list order, since serialization to bitcode is part of the flow.
5171 if (JA.getType() == types::TY_LLVM_BC)
5172 CmdArgs.push_back(Elt: "-emit-llvm-uselists");
5173
5174 if (IsUsingLTO) {
5175 if (IsDeviceOffloadAction && !JA.isDeviceOffloading(Action::OFK_OpenMP) &&
5176 !Args.hasFlag(options::OPT_offload_new_driver,
5177 options::OPT_no_offload_new_driver, false) &&
5178 !Triple.isAMDGPU()) {
5179 D.Diag(diag::err_drv_unsupported_opt_for_target)
5180 << Args.getLastArg(options::OPT_foffload_lto,
5181 options::OPT_foffload_lto_EQ)
5182 ->getAsString(Args)
5183 << Triple.getTriple();
5184 } else if (Triple.isNVPTX() && !IsRDCMode &&
5185 JA.isDeviceOffloading(OKind: Action::OFK_Cuda)) {
5186 D.Diag(diag::err_drv_unsupported_opt_for_language_mode)
5187 << Args.getLastArg(options::OPT_foffload_lto,
5188 options::OPT_foffload_lto_EQ)
5189 ->getAsString(Args)
5190 << "-fno-gpu-rdc";
5191 } else {
5192 assert(LTOMode == LTOK_Full || LTOMode == LTOK_Thin);
5193 CmdArgs.push_back(Elt: Args.MakeArgString(
5194 Str: Twine("-flto=") + (LTOMode == LTOK_Thin ? "thin" : "full")));
5195 // PS4 uses the legacy LTO API, which does not support some of the
5196 // features enabled by -flto-unit.
5197 if (!RawTriple.isPS4() ||
5198 (D.getLTOMode() == LTOK_Full) || !UnifiedLTO)
5199 CmdArgs.push_back(Elt: "-flto-unit");
5200 }
5201 }
5202 }
5203
5204 Args.AddLastArg(CmdArgs, options::OPT_dumpdir);
5205
5206 if (const Arg *A = Args.getLastArg(options::OPT_fthinlto_index_EQ)) {
5207 if (!types::isLLVMIR(Input.getType()))
5208 D.Diag(diag::err_drv_arg_requires_bitcode_input) << A->getAsString(Args);
5209 Args.AddLastArg(CmdArgs, options::OPT_fthinlto_index_EQ);
5210 }
5211
5212 if (Triple.isPPC())
5213 Args.addOptInFlag(CmdArgs, options::OPT_mregnames,
5214 options::OPT_mno_regnames);
5215
5216 if (Args.getLastArg(options::OPT_fthin_link_bitcode_EQ))
5217 Args.AddLastArg(CmdArgs, options::OPT_fthin_link_bitcode_EQ);
5218
5219 if (Args.getLastArg(options::OPT_save_temps_EQ))
5220 Args.AddLastArg(CmdArgs, options::OPT_save_temps_EQ);
5221
5222 auto *MemProfArg = Args.getLastArg(options::OPT_fmemory_profile,
5223 options::OPT_fmemory_profile_EQ,
5224 options::OPT_fno_memory_profile);
5225 if (MemProfArg &&
5226 !MemProfArg->getOption().matches(options::OPT_fno_memory_profile))
5227 MemProfArg->render(Args, CmdArgs);
5228
5229 if (auto *MemProfUseArg =
5230 Args.getLastArg(options::OPT_fmemory_profile_use_EQ)) {
5231 if (MemProfArg)
5232 D.Diag(diag::err_drv_argument_not_allowed_with)
5233 << MemProfUseArg->getAsString(Args) << MemProfArg->getAsString(Args);
5234 if (auto *PGOInstrArg = Args.getLastArg(options::OPT_fprofile_generate,
5235 options::OPT_fprofile_generate_EQ))
5236 D.Diag(diag::err_drv_argument_not_allowed_with)
5237 << MemProfUseArg->getAsString(Args) << PGOInstrArg->getAsString(Args);
5238 MemProfUseArg->render(Args, CmdArgs);
5239 }
5240
5241 // Embed-bitcode option.
5242 // Only white-listed flags below are allowed to be embedded.
5243 if (C.getDriver().embedBitcodeInObject() && !IsUsingLTO &&
5244 (isa<BackendJobAction>(Val: JA) || isa<AssembleJobAction>(Val: JA))) {
5245 // Add flags implied by -fembed-bitcode.
5246 Args.AddLastArg(CmdArgs, options::OPT_fembed_bitcode_EQ);
5247 // Disable all llvm IR level optimizations.
5248 CmdArgs.push_back(Elt: "-disable-llvm-passes");
5249
5250 // Render target options.
5251 TC.addClangTargetOptions(DriverArgs: Args, CC1Args&: CmdArgs, DeviceOffloadKind: JA.getOffloadingDeviceKind());
5252
5253 // reject options that shouldn't be supported in bitcode
5254 // also reject kernel/kext
5255 static const constexpr unsigned kBitcodeOptionIgnorelist[] = {
5256 options::OPT_mkernel,
5257 options::OPT_fapple_kext,
5258 options::OPT_ffunction_sections,
5259 options::OPT_fno_function_sections,
5260 options::OPT_fdata_sections,
5261 options::OPT_fno_data_sections,
5262 options::OPT_fbasic_block_sections_EQ,
5263 options::OPT_funique_internal_linkage_names,
5264 options::OPT_fno_unique_internal_linkage_names,
5265 options::OPT_funique_section_names,
5266 options::OPT_fno_unique_section_names,
5267 options::OPT_funique_basic_block_section_names,
5268 options::OPT_fno_unique_basic_block_section_names,
5269 options::OPT_mrestrict_it,
5270 options::OPT_mno_restrict_it,
5271 options::OPT_mstackrealign,
5272 options::OPT_mno_stackrealign,
5273 options::OPT_mstack_alignment,
5274 options::OPT_mcmodel_EQ,
5275 options::OPT_mlong_calls,
5276 options::OPT_mno_long_calls,
5277 options::OPT_ggnu_pubnames,
5278 options::OPT_gdwarf_aranges,
5279 options::OPT_fdebug_types_section,
5280 options::OPT_fno_debug_types_section,
5281 options::OPT_fdwarf_directory_asm,
5282 options::OPT_fno_dwarf_directory_asm,
5283 options::OPT_mrelax_all,
5284 options::OPT_mno_relax_all,
5285 options::OPT_ftrap_function_EQ,
5286 options::OPT_ffixed_r9,
5287 options::OPT_mfix_cortex_a53_835769,
5288 options::OPT_mno_fix_cortex_a53_835769,
5289 options::OPT_ffixed_x18,
5290 options::OPT_mglobal_merge,
5291 options::OPT_mno_global_merge,
5292 options::OPT_mred_zone,
5293 options::OPT_mno_red_zone,
5294 options::OPT_Wa_COMMA,
5295 options::OPT_Xassembler,
5296 options::OPT_mllvm,
5297 };
5298 for (const auto &A : Args)
5299 if (llvm::is_contained(kBitcodeOptionIgnorelist, A->getOption().getID()))
5300 D.Diag(diag::err_drv_unsupported_embed_bitcode) << A->getSpelling();
5301
5302 // Render the CodeGen options that need to be passed.
5303 Args.addOptOutFlag(CmdArgs, options::OPT_foptimize_sibling_calls,
5304 options::OPT_fno_optimize_sibling_calls);
5305
5306 RenderFloatingPointOptions(TC, D, OFastEnabled: isOptimizationLevelFast(Args), Args,
5307 CmdArgs, JA);
5308
5309 // Render ABI arguments
5310 switch (TC.getArch()) {
5311 default: break;
5312 case llvm::Triple::arm:
5313 case llvm::Triple::armeb:
5314 case llvm::Triple::thumbeb:
5315 RenderARMABI(D, Triple, Args, CmdArgs);
5316 break;
5317 case llvm::Triple::aarch64:
5318 case llvm::Triple::aarch64_32:
5319 case llvm::Triple::aarch64_be:
5320 RenderAArch64ABI(Triple, Args, CmdArgs);
5321 break;
5322 }
5323
5324 // Optimization level for CodeGen.
5325 if (const Arg *A = Args.getLastArg(options::OPT_O_Group)) {
5326 if (A->getOption().matches(options::OPT_O4)) {
5327 CmdArgs.push_back(Elt: "-O3");
5328 D.Diag(diag::warn_O4_is_O3);
5329 } else {
5330 A->render(Args, Output&: CmdArgs);
5331 }
5332 }
5333
5334 // Input/Output file.
5335 if (Output.getType() == types::TY_Dependencies) {
5336 // Handled with other dependency code.
5337 } else if (Output.isFilename()) {
5338 CmdArgs.push_back(Elt: "-o");
5339 CmdArgs.push_back(Elt: Output.getFilename());
5340 } else {
5341 assert(Output.isNothing() && "Input output.");
5342 }
5343
5344 for (const auto &II : Inputs) {
5345 addDashXForInput(Args, Input: II, CmdArgs);
5346 if (II.isFilename())
5347 CmdArgs.push_back(Elt: II.getFilename());
5348 else
5349 II.getInputArg().renderAsInput(Args, Output&: CmdArgs);
5350 }
5351
5352 C.addCommand(C: std::make_unique<Command>(
5353 args: JA, args: *this, args: ResponseFileSupport::AtFileUTF8(), args: D.getClangProgramPath(),
5354 args&: CmdArgs, args: Inputs, args: Output, args: D.getPrependArg()));
5355 return;
5356 }
5357
5358 if (C.getDriver().embedBitcodeMarkerOnly() && !IsUsingLTO)
5359 CmdArgs.push_back(Elt: "-fembed-bitcode=marker");
5360
5361 // We normally speed up the clang process a bit by skipping destructors at
5362 // exit, but when we're generating diagnostics we can rely on some of the
5363 // cleanup.
5364 if (!C.isForDiagnostics())
5365 CmdArgs.push_back(Elt: "-disable-free");
5366 CmdArgs.push_back(Elt: "-clear-ast-before-backend");
5367
5368#ifdef NDEBUG
5369 const bool IsAssertBuild = false;
5370#else
5371 const bool IsAssertBuild = true;
5372#endif
5373
5374 // Disable the verification pass in asserts builds unless otherwise specified.
5375 if (Args.hasFlag(options::OPT_fno_verify_intermediate_code,
5376 options::OPT_fverify_intermediate_code, !IsAssertBuild)) {
5377 CmdArgs.push_back(Elt: "-disable-llvm-verifier");
5378 }
5379
5380 // Discard value names in assert builds unless otherwise specified.
5381 if (Args.hasFlag(options::OPT_fdiscard_value_names,
5382 options::OPT_fno_discard_value_names, !IsAssertBuild)) {
5383 if (Args.hasArg(options::OPT_fdiscard_value_names) &&
5384 llvm::any_of(Inputs, [](const clang::driver::InputInfo &II) {
5385 return types::isLLVMIR(II.getType());
5386 })) {
5387 D.Diag(diag::warn_ignoring_fdiscard_for_bitcode);
5388 }
5389 CmdArgs.push_back(Elt: "-discard-value-names");
5390 }
5391
5392 // Set the main file name, so that debug info works even with
5393 // -save-temps.
5394 CmdArgs.push_back(Elt: "-main-file-name");
5395 CmdArgs.push_back(Elt: getBaseInputName(Args, Input));
5396
5397 // Some flags which affect the language (via preprocessor
5398 // defines).
5399 if (Args.hasArg(options::OPT_static))
5400 CmdArgs.push_back(Elt: "-static-define");
5401
5402 if (Args.hasArg(options::OPT_municode))
5403 CmdArgs.push_back(Elt: "-DUNICODE");
5404
5405 if (isa<AnalyzeJobAction>(Val: JA))
5406 RenderAnalyzerOptions(Args, CmdArgs, Triple, Input);
5407
5408 if (isa<AnalyzeJobAction>(JA) ||
5409 (isa<PreprocessJobAction>(JA) && Args.hasArg(options::OPT__analyze)))
5410 CmdArgs.push_back(Elt: "-setup-static-analyzer");
5411
5412 // Enable compatilibily mode to avoid analyzer-config related errors.
5413 // Since we can't access frontend flags through hasArg, let's manually iterate
5414 // through them.
5415 bool FoundAnalyzerConfig = false;
5416 for (auto *Arg : Args.filtered(options::OPT_Xclang))
5417 if (StringRef(Arg->getValue()) == "-analyzer-config") {
5418 FoundAnalyzerConfig = true;
5419 break;
5420 }
5421 if (!FoundAnalyzerConfig)
5422 for (auto *Arg : Args.filtered(options::OPT_Xanalyzer))
5423 if (StringRef(Arg->getValue()) == "-analyzer-config") {
5424 FoundAnalyzerConfig = true;
5425 break;
5426 }
5427 if (FoundAnalyzerConfig)
5428 CmdArgs.push_back(Elt: "-analyzer-config-compatibility-mode=true");
5429
5430 CheckCodeGenerationOptions(D, Args);
5431
5432 unsigned FunctionAlignment = ParseFunctionAlignment(TC, Args);
5433 assert(FunctionAlignment <= 31 && "function alignment will be truncated!");
5434 if (FunctionAlignment) {
5435 CmdArgs.push_back(Elt: "-function-alignment");
5436 CmdArgs.push_back(Elt: Args.MakeArgString(Str: std::to_string(val: FunctionAlignment)));
5437 }
5438
5439 // We support -falign-loops=N where N is a power of 2. GCC supports more
5440 // forms.
5441 if (const Arg *A = Args.getLastArg(options::OPT_falign_loops_EQ)) {
5442 unsigned Value = 0;
5443 if (StringRef(A->getValue()).getAsInteger(10, Value) || Value > 65536)
5444 TC.getDriver().Diag(diag::err_drv_invalid_int_value)
5445 << A->getAsString(Args) << A->getValue();
5446 else if (Value & (Value - 1))
5447 TC.getDriver().Diag(diag::err_drv_alignment_not_power_of_two)
5448 << A->getAsString(Args) << A->getValue();
5449 // Treat =0 as unspecified (use the target preference).
5450 if (Value)
5451 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-falign-loops=" +
5452 Twine(std::min(a: Value, b: 65536u))));
5453 }
5454
5455 if (Triple.isOSzOS()) {
5456 // On z/OS some of the system header feature macros need to
5457 // be defined to enable most cross platform projects to build
5458 // successfully. Ths include the libc++ library. A
5459 // complicating factor is that users can define these
5460 // macros to the same or different values. We need to add
5461 // the definition for these macros to the compilation command
5462 // if the user hasn't already defined them.
5463
5464 auto findMacroDefinition = [&](const std::string &Macro) {
5465 auto MacroDefs = Args.getAllArgValues(options::OPT_D);
5466 return llvm::any_of(MacroDefs, [&](const std::string &M) {
5467 return M == Macro || M.find(Macro + '=') != std::string::npos;
5468 });
5469 };
5470
5471 // _UNIX03_WITHDRAWN is required for libcxx & porting.
5472 if (!findMacroDefinition("_UNIX03_WITHDRAWN"))
5473 CmdArgs.push_back(Elt: "-D_UNIX03_WITHDRAWN");
5474 // _OPEN_DEFAULT is required for XL compat
5475 if (!findMacroDefinition("_OPEN_DEFAULT"))
5476 CmdArgs.push_back(Elt: "-D_OPEN_DEFAULT");
5477 if (D.CCCIsCXX() || types::isCXX(Id: Input.getType())) {
5478 // _XOPEN_SOURCE=600 is required for libcxx.
5479 if (!findMacroDefinition("_XOPEN_SOURCE"))
5480 CmdArgs.push_back(Elt: "-D_XOPEN_SOURCE=600");
5481 }
5482 }
5483
5484 llvm::Reloc::Model RelocationModel;
5485 unsigned PICLevel;
5486 bool IsPIE;
5487 std::tie(args&: RelocationModel, args&: PICLevel, args&: IsPIE) = ParsePICArgs(ToolChain: TC, Args);
5488 Arg *LastPICDataRelArg =
5489 Args.getLastArg(options::OPT_mno_pic_data_is_text_relative,
5490 options::OPT_mpic_data_is_text_relative);
5491 bool NoPICDataIsTextRelative = false;
5492 if (LastPICDataRelArg) {
5493 if (LastPICDataRelArg->getOption().matches(
5494 options::OPT_mno_pic_data_is_text_relative)) {
5495 NoPICDataIsTextRelative = true;
5496 if (!PICLevel)
5497 D.Diag(diag::err_drv_argument_only_allowed_with)
5498 << "-mno-pic-data-is-text-relative"
5499 << "-fpic/-fpie";
5500 }
5501 if (!Triple.isSystemZ())
5502 D.Diag(diag::err_drv_unsupported_opt_for_target)
5503 << (NoPICDataIsTextRelative ? "-mno-pic-data-is-text-relative"
5504 : "-mpic-data-is-text-relative")
5505 << RawTriple.str();
5506 }
5507
5508 bool IsROPI = RelocationModel == llvm::Reloc::ROPI ||
5509 RelocationModel == llvm::Reloc::ROPI_RWPI;
5510 bool IsRWPI = RelocationModel == llvm::Reloc::RWPI ||
5511 RelocationModel == llvm::Reloc::ROPI_RWPI;
5512
5513 if (Args.hasArg(options::OPT_mcmse) &&
5514 !Args.hasArg(options::OPT_fallow_unsupported)) {
5515 if (IsROPI)
5516 D.Diag(diag::err_cmse_pi_are_incompatible) << IsROPI;
5517 if (IsRWPI)
5518 D.Diag(diag::err_cmse_pi_are_incompatible) << !IsRWPI;
5519 }
5520
5521 if (IsROPI && types::isCXX(Input.getType()) &&
5522 !Args.hasArg(options::OPT_fallow_unsupported))
5523 D.Diag(diag::err_drv_ropi_incompatible_with_cxx);
5524
5525 const char *RMName = RelocationModelName(Model: RelocationModel);
5526 if (RMName) {
5527 CmdArgs.push_back(Elt: "-mrelocation-model");
5528 CmdArgs.push_back(Elt: RMName);
5529 }
5530 if (PICLevel > 0) {
5531 CmdArgs.push_back(Elt: "-pic-level");
5532 CmdArgs.push_back(Elt: PICLevel == 1 ? "1" : "2");
5533 if (IsPIE)
5534 CmdArgs.push_back(Elt: "-pic-is-pie");
5535 if (NoPICDataIsTextRelative)
5536 CmdArgs.push_back(Elt: "-mcmodel=medium");
5537 }
5538
5539 if (RelocationModel == llvm::Reloc::ROPI ||
5540 RelocationModel == llvm::Reloc::ROPI_RWPI)
5541 CmdArgs.push_back(Elt: "-fropi");
5542 if (RelocationModel == llvm::Reloc::RWPI ||
5543 RelocationModel == llvm::Reloc::ROPI_RWPI)
5544 CmdArgs.push_back(Elt: "-frwpi");
5545
5546 if (Arg *A = Args.getLastArg(options::OPT_meabi)) {
5547 CmdArgs.push_back(Elt: "-meabi");
5548 CmdArgs.push_back(Elt: A->getValue());
5549 }
5550
5551 // -fsemantic-interposition is forwarded to CC1: set the
5552 // "SemanticInterposition" metadata to 1 (make some linkages interposable) and
5553 // make default visibility external linkage definitions dso_preemptable.
5554 //
5555 // -fno-semantic-interposition: if the target supports .Lfoo$local local
5556 // aliases (make default visibility external linkage definitions dso_local).
5557 // This is the CC1 default for ELF to match COFF/Mach-O.
5558 //
5559 // Otherwise use Clang's traditional behavior: like
5560 // -fno-semantic-interposition but local aliases are not used. So references
5561 // can be interposed if not optimized out.
5562 if (Triple.isOSBinFormatELF()) {
5563 Arg *A = Args.getLastArg(options::OPT_fsemantic_interposition,
5564 options::OPT_fno_semantic_interposition);
5565 if (RelocationModel != llvm::Reloc::Static && !IsPIE) {
5566 // The supported targets need to call AsmPrinter::getSymbolPreferLocal.
5567 bool SupportsLocalAlias =
5568 Triple.isAArch64() || Triple.isRISCV() || Triple.isX86();
5569 if (!A)
5570 CmdArgs.push_back(Elt: "-fhalf-no-semantic-interposition");
5571 else if (A->getOption().matches(options::OPT_fsemantic_interposition))
5572 A->render(Args, Output&: CmdArgs);
5573 else if (!SupportsLocalAlias)
5574 CmdArgs.push_back(Elt: "-fhalf-no-semantic-interposition");
5575 }
5576 }
5577
5578 {
5579 std::string Model;
5580 if (Arg *A = Args.getLastArg(options::OPT_mthread_model)) {
5581 if (!TC.isThreadModelSupported(A->getValue()))
5582 D.Diag(diag::err_drv_invalid_thread_model_for_target)
5583 << A->getValue() << A->getAsString(Args);
5584 Model = A->getValue();
5585 } else
5586 Model = TC.getThreadModel();
5587 if (Model != "posix") {
5588 CmdArgs.push_back(Elt: "-mthread-model");
5589 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Model));
5590 }
5591 }
5592
5593 if (Arg *A = Args.getLastArg(options::OPT_fveclib)) {
5594 StringRef Name = A->getValue();
5595 if (Name == "SVML") {
5596 if (Triple.getArch() != llvm::Triple::x86 &&
5597 Triple.getArch() != llvm::Triple::x86_64)
5598 D.Diag(diag::err_drv_unsupported_opt_for_target)
5599 << Name << Triple.getArchName();
5600 } else if (Name == "LIBMVEC-X86") {
5601 if (Triple.getArch() != llvm::Triple::x86 &&
5602 Triple.getArch() != llvm::Triple::x86_64)
5603 D.Diag(diag::err_drv_unsupported_opt_for_target)
5604 << Name << Triple.getArchName();
5605 } else if (Name == "SLEEF" || Name == "ArmPL") {
5606 if (Triple.getArch() != llvm::Triple::aarch64 &&
5607 Triple.getArch() != llvm::Triple::aarch64_be)
5608 D.Diag(diag::err_drv_unsupported_opt_for_target)
5609 << Name << Triple.getArchName();
5610 }
5611 A->render(Args, Output&: CmdArgs);
5612 }
5613
5614 if (Args.hasFlag(options::OPT_fmerge_all_constants,
5615 options::OPT_fno_merge_all_constants, false))
5616 CmdArgs.push_back(Elt: "-fmerge-all-constants");
5617
5618 Args.addOptOutFlag(CmdArgs, options::OPT_fdelete_null_pointer_checks,
5619 options::OPT_fno_delete_null_pointer_checks);
5620
5621 // LLVM Code Generator Options.
5622
5623 if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ_quadword_atomics)) {
5624 if (!Triple.isOSAIX() || Triple.isPPC32())
5625 D.Diag(diag::err_drv_unsupported_opt_for_target)
5626 << A->getSpelling() << RawTriple.str();
5627 CmdArgs.push_back(Elt: "-mabi=quadword-atomics");
5628 }
5629
5630 if (Arg *A = Args.getLastArg(options::OPT_mlong_double_128)) {
5631 // Emit the unsupported option error until the Clang's library integration
5632 // support for 128-bit long double is available for AIX.
5633 if (Triple.isOSAIX())
5634 D.Diag(diag::err_drv_unsupported_opt_for_target)
5635 << A->getSpelling() << RawTriple.str();
5636 }
5637
5638 if (Arg *A = Args.getLastArg(options::OPT_Wframe_larger_than_EQ)) {
5639 StringRef V = A->getValue(), V1 = V;
5640 unsigned Size;
5641 if (V1.consumeInteger(Radix: 10, Result&: Size) || !V1.empty())
5642 D.Diag(diag::err_drv_invalid_argument_to_option)
5643 << V << A->getOption().getName();
5644 else
5645 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-fwarn-stack-size=" + V));
5646 }
5647
5648 Args.addOptOutFlag(CmdArgs, options::OPT_fjump_tables,
5649 options::OPT_fno_jump_tables);
5650 Args.addOptInFlag(CmdArgs, options::OPT_fprofile_sample_accurate,
5651 options::OPT_fno_profile_sample_accurate);
5652 Args.addOptOutFlag(CmdArgs, options::OPT_fpreserve_as_comments,
5653 options::OPT_fno_preserve_as_comments);
5654
5655 if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
5656 CmdArgs.push_back(Elt: "-mregparm");
5657 CmdArgs.push_back(Elt: A->getValue());
5658 }
5659
5660 if (Arg *A = Args.getLastArg(options::OPT_maix_struct_return,
5661 options::OPT_msvr4_struct_return)) {
5662 if (!TC.getTriple().isPPC32()) {
5663 D.Diag(diag::err_drv_unsupported_opt_for_target)
5664 << A->getSpelling() << RawTriple.str();
5665 } else if (A->getOption().matches(options::OPT_maix_struct_return)) {
5666 CmdArgs.push_back(Elt: "-maix-struct-return");
5667 } else {
5668 assert(A->getOption().matches(options::OPT_msvr4_struct_return));
5669 CmdArgs.push_back(Elt: "-msvr4-struct-return");
5670 }
5671 }
5672
5673 if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,
5674 options::OPT_freg_struct_return)) {
5675 if (TC.getArch() != llvm::Triple::x86) {
5676 D.Diag(diag::err_drv_unsupported_opt_for_target)
5677 << A->getSpelling() << RawTriple.str();
5678 } else if (A->getOption().matches(options::OPT_fpcc_struct_return)) {
5679 CmdArgs.push_back(Elt: "-fpcc-struct-return");
5680 } else {
5681 assert(A->getOption().matches(options::OPT_freg_struct_return));
5682 CmdArgs.push_back(Elt: "-freg-struct-return");
5683 }
5684 }
5685
5686 if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false)) {
5687 if (Triple.getArch() == llvm::Triple::m68k)
5688 CmdArgs.push_back(Elt: "-fdefault-calling-conv=rtdcall");
5689 else
5690 CmdArgs.push_back(Elt: "-fdefault-calling-conv=stdcall");
5691 }
5692
5693 if (Args.hasArg(options::OPT_fenable_matrix)) {
5694 // enable-matrix is needed by both the LangOpts and by LLVM.
5695 CmdArgs.push_back(Elt: "-fenable-matrix");
5696 CmdArgs.push_back(Elt: "-mllvm");
5697 CmdArgs.push_back(Elt: "-enable-matrix");
5698 }
5699
5700 CodeGenOptions::FramePointerKind FPKeepKind =
5701 getFramePointerKind(Args, Triple: RawTriple);
5702 const char *FPKeepKindStr = nullptr;
5703 switch (FPKeepKind) {
5704 case CodeGenOptions::FramePointerKind::None:
5705 FPKeepKindStr = "-mframe-pointer=none";
5706 break;
5707 case CodeGenOptions::FramePointerKind::NonLeaf:
5708 FPKeepKindStr = "-mframe-pointer=non-leaf";
5709 break;
5710 case CodeGenOptions::FramePointerKind::All:
5711 FPKeepKindStr = "-mframe-pointer=all";
5712 break;
5713 }
5714 assert(FPKeepKindStr && "unknown FramePointerKind");
5715 CmdArgs.push_back(Elt: FPKeepKindStr);
5716
5717 Args.addOptOutFlag(CmdArgs, options::OPT_fzero_initialized_in_bss,
5718 options::OPT_fno_zero_initialized_in_bss);
5719
5720 bool OFastEnabled = isOptimizationLevelFast(Args);
5721 // If -Ofast is the optimization level, then -fstrict-aliasing should be
5722 // enabled. This alias option is being used to simplify the hasFlag logic.
5723 OptSpecifier StrictAliasingAliasOption =
5724 OFastEnabled ? options::OPT_Ofast : options::OPT_fstrict_aliasing;
5725 // We turn strict aliasing off by default if we're in CL mode, since MSVC
5726 // doesn't do any TBAA.
5727 bool TBAAOnByDefault = !D.IsCLMode();
5728 if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption,
5729 options::OPT_fno_strict_aliasing, TBAAOnByDefault))
5730 CmdArgs.push_back(Elt: "-relaxed-aliasing");
5731 if (!Args.hasFlag(options::OPT_fstruct_path_tbaa,
5732 options::OPT_fno_struct_path_tbaa, true))
5733 CmdArgs.push_back(Elt: "-no-struct-path-tbaa");
5734 Args.addOptInFlag(CmdArgs, options::OPT_fstrict_enums,
5735 options::OPT_fno_strict_enums);
5736 Args.addOptOutFlag(CmdArgs, options::OPT_fstrict_return,
5737 options::OPT_fno_strict_return);
5738 Args.addOptInFlag(CmdArgs, options::OPT_fallow_editor_placeholders,
5739 options::OPT_fno_allow_editor_placeholders);
5740 Args.addOptInFlag(CmdArgs, options::OPT_fstrict_vtable_pointers,
5741 options::OPT_fno_strict_vtable_pointers);
5742 Args.addOptInFlag(CmdArgs, options::OPT_fforce_emit_vtables,
5743 options::OPT_fno_force_emit_vtables);
5744 Args.addOptOutFlag(CmdArgs, options::OPT_foptimize_sibling_calls,
5745 options::OPT_fno_optimize_sibling_calls);
5746 Args.addOptOutFlag(CmdArgs, options::OPT_fescaping_block_tail_calls,
5747 options::OPT_fno_escaping_block_tail_calls);
5748
5749 Args.AddLastArg(CmdArgs, options::OPT_ffine_grained_bitfield_accesses,
5750 options::OPT_fno_fine_grained_bitfield_accesses);
5751
5752 Args.AddLastArg(CmdArgs, options::OPT_fexperimental_relative_cxx_abi_vtables,
5753 options::OPT_fno_experimental_relative_cxx_abi_vtables);
5754
5755 Args.AddLastArg(CmdArgs, options::OPT_fexperimental_omit_vtable_rtti,
5756 options::OPT_fno_experimental_omit_vtable_rtti);
5757
5758 // Handle segmented stacks.
5759 Args.addOptInFlag(CmdArgs, options::OPT_fsplit_stack,
5760 options::OPT_fno_split_stack);
5761
5762 // -fprotect-parens=0 is default.
5763 if (Args.hasFlag(options::OPT_fprotect_parens,
5764 options::OPT_fno_protect_parens, false))
5765 CmdArgs.push_back(Elt: "-fprotect-parens");
5766
5767 RenderFloatingPointOptions(TC, D, OFastEnabled, Args, CmdArgs, JA);
5768
5769 if (Arg *A = Args.getLastArg(options::OPT_fextend_args_EQ)) {
5770 const llvm::Triple::ArchType Arch = TC.getArch();
5771 if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) {
5772 StringRef V = A->getValue();
5773 if (V == "64")
5774 CmdArgs.push_back(Elt: "-fextend-arguments=64");
5775 else if (V != "32")
5776 D.Diag(diag::err_drv_invalid_argument_to_option)
5777 << A->getValue() << A->getOption().getName();
5778 } else
5779 D.Diag(diag::err_drv_unsupported_opt_for_target)
5780 << A->getOption().getName() << TripleStr;
5781 }
5782
5783 if (Arg *A = Args.getLastArg(options::OPT_mdouble_EQ)) {
5784 if (TC.getArch() == llvm::Triple::avr)
5785 A->render(Args, Output&: CmdArgs);
5786 else
5787 D.Diag(diag::err_drv_unsupported_opt_for_target)
5788 << A->getAsString(Args) << TripleStr;
5789 }
5790
5791 if (Arg *A = Args.getLastArg(options::OPT_LongDouble_Group)) {
5792 if (TC.getTriple().isX86())
5793 A->render(Args, Output&: CmdArgs);
5794 else if (TC.getTriple().isPPC() &&
5795 (A->getOption().getID() != options::OPT_mlong_double_80))
5796 A->render(Args, Output&: CmdArgs);
5797 else
5798 D.Diag(diag::err_drv_unsupported_opt_for_target)
5799 << A->getAsString(Args) << TripleStr;
5800 }
5801
5802 // Decide whether to use verbose asm. Verbose assembly is the default on
5803 // toolchains which have the integrated assembler on by default.
5804 bool IsIntegratedAssemblerDefault = TC.IsIntegratedAssemblerDefault();
5805 if (!Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
5806 IsIntegratedAssemblerDefault))
5807 CmdArgs.push_back(Elt: "-fno-verbose-asm");
5808
5809 // Parse 'none' or '$major.$minor'. Disallow -fbinutils-version=0 because we
5810 // use that to indicate the MC default in the backend.
5811 if (Arg *A = Args.getLastArg(options::OPT_fbinutils_version_EQ)) {
5812 StringRef V = A->getValue();
5813 unsigned Num;
5814 if (V == "none")
5815 A->render(Args, Output&: CmdArgs);
5816 else if (!V.consumeInteger(Radix: 10, Result&: Num) && Num > 0 &&
5817 (V.empty() || (V.consume_front(Prefix: ".") &&
5818 !V.consumeInteger(Radix: 10, Result&: Num) && V.empty())))
5819 A->render(Args, Output&: CmdArgs);
5820 else
5821 D.Diag(diag::err_drv_invalid_argument_to_option)
5822 << A->getValue() << A->getOption().getName();
5823 }
5824
5825 // If toolchain choose to use MCAsmParser for inline asm don't pass the
5826 // option to disable integrated-as explictly.
5827 if (!TC.useIntegratedAs() && !TC.parseInlineAsmUsingAsmParser())
5828 CmdArgs.push_back(Elt: "-no-integrated-as");
5829
5830 if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
5831 CmdArgs.push_back(Elt: "-mdebug-pass");
5832 CmdArgs.push_back(Elt: "Structure");
5833 }
5834 if (Args.hasArg(options::OPT_fdebug_pass_arguments)) {
5835 CmdArgs.push_back(Elt: "-mdebug-pass");
5836 CmdArgs.push_back(Elt: "Arguments");
5837 }
5838
5839 // Enable -mconstructor-aliases except on darwin, where we have to work around
5840 // a linker bug (see https://openradar.appspot.com/7198997), and CUDA device
5841 // code, where aliases aren't supported.
5842 if (!RawTriple.isOSDarwin() && !RawTriple.isNVPTX())
5843 CmdArgs.push_back(Elt: "-mconstructor-aliases");
5844
5845 // Darwin's kernel doesn't support guard variables; just die if we
5846 // try to use them.
5847 if (KernelOrKext && RawTriple.isOSDarwin())
5848 CmdArgs.push_back(Elt: "-fforbid-guard-variables");
5849
5850 if (Args.hasFlag(options::OPT_mms_bitfields, options::OPT_mno_ms_bitfields,
5851 Triple.isWindowsGNUEnvironment())) {
5852 CmdArgs.push_back(Elt: "-mms-bitfields");
5853 }
5854
5855 if (Triple.isWindowsGNUEnvironment()) {
5856 Args.addOptOutFlag(CmdArgs, options::OPT_fauto_import,
5857 options::OPT_fno_auto_import);
5858 }
5859
5860 if (Args.hasFlag(options::OPT_fms_volatile, options::OPT_fno_ms_volatile,
5861 Triple.isX86() && D.IsCLMode()))
5862 CmdArgs.push_back(Elt: "-fms-volatile");
5863
5864 // Non-PIC code defaults to -fdirect-access-external-data while PIC code
5865 // defaults to -fno-direct-access-external-data. Pass the option if different
5866 // from the default.
5867 if (Arg *A = Args.getLastArg(options::OPT_fdirect_access_external_data,
5868 options::OPT_fno_direct_access_external_data)) {
5869 if (A->getOption().matches(options::OPT_fdirect_access_external_data) !=
5870 (PICLevel == 0))
5871 A->render(Args, Output&: CmdArgs);
5872 } else if (PICLevel == 0 && Triple.isLoongArch()) {
5873 // Some targets default to -fno-direct-access-external-data even for
5874 // -fno-pic.
5875 CmdArgs.push_back(Elt: "-fno-direct-access-external-data");
5876 }
5877
5878 if (Args.hasFlag(options::OPT_fno_plt, options::OPT_fplt, false)) {
5879 CmdArgs.push_back(Elt: "-fno-plt");
5880 }
5881
5882 // -fhosted is default.
5883 // TODO: Audit uses of KernelOrKext and see where it'd be more appropriate to
5884 // use Freestanding.
5885 bool Freestanding =
5886 Args.hasFlag(options::OPT_ffreestanding, options::OPT_fhosted, false) ||
5887 KernelOrKext;
5888 if (Freestanding)
5889 CmdArgs.push_back(Elt: "-ffreestanding");
5890
5891 Args.AddLastArg(CmdArgs, options::OPT_fno_knr_functions);
5892
5893 // This is a coarse approximation of what llvm-gcc actually does, both
5894 // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
5895 // complicated ways.
5896 auto SanitizeArgs = TC.getSanitizerArgs(JobArgs: Args);
5897
5898 bool IsAsyncUnwindTablesDefault =
5899 TC.getDefaultUnwindTableLevel(Args) == ToolChain::UnwindTableLevel::Asynchronous;
5900 bool IsSyncUnwindTablesDefault =
5901 TC.getDefaultUnwindTableLevel(Args) == ToolChain::UnwindTableLevel::Synchronous;
5902
5903 bool AsyncUnwindTables = Args.hasFlag(
5904 options::OPT_fasynchronous_unwind_tables,
5905 options::OPT_fno_asynchronous_unwind_tables,
5906 (IsAsyncUnwindTablesDefault || SanitizeArgs.needsUnwindTables()) &&
5907 !Freestanding);
5908 bool UnwindTables =
5909 Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables,
5910 IsSyncUnwindTablesDefault && !Freestanding);
5911 if (AsyncUnwindTables)
5912 CmdArgs.push_back(Elt: "-funwind-tables=2");
5913 else if (UnwindTables)
5914 CmdArgs.push_back(Elt: "-funwind-tables=1");
5915
5916 // Prepare `-aux-target-cpu` and `-aux-target-feature` unless
5917 // `--gpu-use-aux-triple-only` is specified.
5918 if (!Args.getLastArg(options::OPT_gpu_use_aux_triple_only) &&
5919 (IsCudaDevice || IsHIPDevice)) {
5920 const ArgList &HostArgs =
5921 C.getArgsForToolChain(TC: nullptr, BoundArch: StringRef(), DeviceOffloadKind: Action::OFK_None);
5922 std::string HostCPU =
5923 getCPUName(D, Args: HostArgs, T: *TC.getAuxTriple(), /*FromAs*/ false);
5924 if (!HostCPU.empty()) {
5925 CmdArgs.push_back(Elt: "-aux-target-cpu");
5926 CmdArgs.push_back(Elt: Args.MakeArgString(Str: HostCPU));
5927 }
5928 getTargetFeatures(D, Triple: *TC.getAuxTriple(), Args: HostArgs, CmdArgs,
5929 /*ForAS*/ false, /*IsAux*/ true);
5930 }
5931
5932 TC.addClangTargetOptions(DriverArgs: Args, CC1Args&: CmdArgs, DeviceOffloadKind: JA.getOffloadingDeviceKind());
5933
5934 if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
5935 StringRef CM = A->getValue();
5936 bool Ok = false;
5937 if (Triple.isOSAIX() && CM == "medium")
5938 CM = "large";
5939 if (Triple.isAArch64(PointerWidth: 64)) {
5940 Ok = CM == "tiny" || CM == "small" || CM == "large";
5941 if (CM == "large" && !Triple.isOSBinFormatMachO() &&
5942 RelocationModel != llvm::Reloc::Static)
5943 D.Diag(diag::err_drv_argument_only_allowed_with)
5944 << A->getAsString(Args) << "-fno-pic";
5945 } else if (Triple.isLoongArch()) {
5946 if (CM == "extreme" &&
5947 Args.hasFlagNoClaim(options::OPT_fplt, options::OPT_fno_plt, false))
5948 D.Diag(diag::err_drv_argument_not_allowed_with)
5949 << A->getAsString(Args) << "-fplt";
5950 Ok = CM == "normal" || CM == "medium" || CM == "extreme";
5951 // Convert to LLVM recognizable names.
5952 if (Ok)
5953 CM = llvm::StringSwitch<StringRef>(CM)
5954 .Case(S: "normal", Value: "small")
5955 .Case(S: "extreme", Value: "large")
5956 .Default(Value: CM);
5957 } else if (Triple.isPPC64() || Triple.isOSAIX()) {
5958 Ok = CM == "small" || CM == "medium" || CM == "large";
5959 } else if (Triple.isRISCV()) {
5960 if (CM == "medlow")
5961 CM = "small";
5962 else if (CM == "medany")
5963 CM = "medium";
5964 Ok = CM == "small" || CM == "medium";
5965 } else if (Triple.getArch() == llvm::Triple::x86_64) {
5966 Ok = llvm::is_contained(Set: {"small", "kernel", "medium", "large", "tiny"},
5967 Element: CM);
5968 } else if (Triple.isNVPTX() || Triple.isAMDGPU() || Triple.isSPIRV()) {
5969 // NVPTX/AMDGPU/SPIRV does not care about the code model and will accept
5970 // whatever works for the host.
5971 Ok = true;
5972 } else if (Triple.isSPARC64()) {
5973 if (CM == "medlow")
5974 CM = "small";
5975 else if (CM == "medmid")
5976 CM = "medium";
5977 else if (CM == "medany")
5978 CM = "large";
5979 Ok = CM == "small" || CM == "medium" || CM == "large";
5980 }
5981 if (Ok) {
5982 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-mcmodel=" + CM));
5983 } else {
5984 D.Diag(diag::err_drv_unsupported_option_argument_for_target)
5985 << A->getSpelling() << CM << TripleStr;
5986 }
5987 }
5988
5989 if (Triple.getArch() == llvm::Triple::x86_64) {
5990 bool IsMediumCM = false;
5991 bool IsLargeCM = false;
5992 if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
5993 IsMediumCM = StringRef(A->getValue()) == "medium";
5994 IsLargeCM = StringRef(A->getValue()) == "large";
5995 }
5996 if (Arg *A = Args.getLastArg(options::OPT_mlarge_data_threshold_EQ)) {
5997 if (!IsMediumCM && !IsLargeCM) {
5998 D.Diag(diag::warn_drv_large_data_threshold_invalid_code_model)
5999 << A->getOption().getRenderName();
6000 } else {
6001 A->render(Args, Output&: CmdArgs);
6002 }
6003 } else if (IsMediumCM) {
6004 CmdArgs.push_back(Elt: "-mlarge-data-threshold=65536");
6005 } else if (IsLargeCM) {
6006 CmdArgs.push_back(Elt: "-mlarge-data-threshold=0");
6007 }
6008 }
6009
6010 if (Arg *A = Args.getLastArg(options::OPT_mtls_size_EQ)) {
6011 StringRef Value = A->getValue();
6012 unsigned TLSSize = 0;
6013 Value.getAsInteger(Radix: 10, Result&: TLSSize);
6014 if (!Triple.isAArch64() || !Triple.isOSBinFormatELF())
6015 D.Diag(diag::err_drv_unsupported_opt_for_target)
6016 << A->getOption().getName() << TripleStr;
6017 if (TLSSize != 12 && TLSSize != 24 && TLSSize != 32 && TLSSize != 48)
6018 D.Diag(diag::err_drv_invalid_int_value)
6019 << A->getOption().getName() << Value;
6020 Args.AddLastArg(CmdArgs, options::OPT_mtls_size_EQ);
6021 }
6022
6023 if (isTLSDESCEnabled(TC, Args))
6024 CmdArgs.push_back(Elt: "-enable-tlsdesc");
6025
6026 // Add the target cpu
6027 std::string CPU = getCPUName(D, Args, T: Triple, /*FromAs*/ false);
6028 if (!CPU.empty()) {
6029 CmdArgs.push_back(Elt: "-target-cpu");
6030 CmdArgs.push_back(Elt: Args.MakeArgString(Str: CPU));
6031 }
6032
6033 RenderTargetOptions(EffectiveTriple: Triple, Args, KernelOrKext, CmdArgs);
6034
6035 // Add clang-cl arguments.
6036 types::ID InputType = Input.getType();
6037 if (D.IsCLMode())
6038 AddClangCLArgs(Args, InputType, CmdArgs);
6039
6040 llvm::codegenoptions::DebugInfoKind DebugInfoKind =
6041 llvm::codegenoptions::NoDebugInfo;
6042 DwarfFissionKind DwarfFission = DwarfFissionKind::None;
6043 renderDebugOptions(TC, D, T: RawTriple, Args, IRInput: types::isLLVMIR(Id: InputType),
6044 CmdArgs, Output, DebugInfoKind, DwarfFission);
6045
6046 // Add the split debug info name to the command lines here so we
6047 // can propagate it to the backend.
6048 bool SplitDWARF = (DwarfFission != DwarfFissionKind::None) &&
6049 (TC.getTriple().isOSBinFormatELF() ||
6050 TC.getTriple().isOSBinFormatWasm() ||
6051 TC.getTriple().isOSBinFormatCOFF()) &&
6052 (isa<AssembleJobAction>(Val: JA) || isa<CompileJobAction>(Val: JA) ||
6053 isa<BackendJobAction>(Val: JA));
6054 if (SplitDWARF) {
6055 const char *SplitDWARFOut = SplitDebugName(JA, Args, Input, Output);
6056 CmdArgs.push_back(Elt: "-split-dwarf-file");
6057 CmdArgs.push_back(Elt: SplitDWARFOut);
6058 if (DwarfFission == DwarfFissionKind::Split) {
6059 CmdArgs.push_back(Elt: "-split-dwarf-output");
6060 CmdArgs.push_back(Elt: SplitDWARFOut);
6061 }
6062 }
6063
6064 // Pass the linker version in use.
6065 if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
6066 CmdArgs.push_back(Elt: "-target-linker-version");
6067 CmdArgs.push_back(Elt: A->getValue());
6068 }
6069
6070 // Explicitly error on some things we know we don't support and can't just
6071 // ignore.
6072 if (!Args.hasArg(options::OPT_fallow_unsupported)) {
6073 Arg *Unsupported;
6074 if (types::isCXX(Id: InputType) && RawTriple.isOSDarwin() &&
6075 TC.getArch() == llvm::Triple::x86) {
6076 if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext)) ||
6077 (Unsupported = Args.getLastArg(options::OPT_mkernel)))
6078 D.Diag(diag::err_drv_clang_unsupported_opt_cxx_darwin_i386)
6079 << Unsupported->getOption().getName();
6080 }
6081 // The faltivec option has been superseded by the maltivec option.
6082 if ((Unsupported = Args.getLastArg(options::OPT_faltivec)))
6083 D.Diag(diag::err_drv_clang_unsupported_opt_faltivec)
6084 << Unsupported->getOption().getName()
6085 << "please use -maltivec and include altivec.h explicitly";
6086 if ((Unsupported = Args.getLastArg(options::OPT_fno_altivec)))
6087 D.Diag(diag::err_drv_clang_unsupported_opt_faltivec)
6088 << Unsupported->getOption().getName() << "please use -mno-altivec";
6089 }
6090
6091 Args.AddAllArgs(CmdArgs, options::OPT_v);
6092
6093 if (Args.getLastArg(options::OPT_H)) {
6094 CmdArgs.push_back(Elt: "-H");
6095 CmdArgs.push_back(Elt: "-sys-header-deps");
6096 }
6097 Args.AddAllArgs(CmdArgs, options::OPT_fshow_skipped_includes);
6098
6099 if (D.CCPrintHeadersFormat && !D.CCGenDiagnostics) {
6100 CmdArgs.push_back(Elt: "-header-include-file");
6101 CmdArgs.push_back(Elt: !D.CCPrintHeadersFilename.empty()
6102 ? D.CCPrintHeadersFilename.c_str()
6103 : "-");
6104 CmdArgs.push_back(Elt: "-sys-header-deps");
6105 CmdArgs.push_back(Elt: Args.MakeArgString(
6106 Str: "-header-include-format=" +
6107 std::string(headerIncludeFormatKindToString(K: D.CCPrintHeadersFormat))));
6108 CmdArgs.push_back(
6109 Elt: Args.MakeArgString(Str: "-header-include-filtering=" +
6110 std::string(headerIncludeFilteringKindToString(
6111 K: D.CCPrintHeadersFiltering))));
6112 }
6113 Args.AddLastArg(CmdArgs, options::OPT_P);
6114 Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout);
6115
6116 if (D.CCLogDiagnostics && !D.CCGenDiagnostics) {
6117 CmdArgs.push_back(Elt: "-diagnostic-log-file");
6118 CmdArgs.push_back(Elt: !D.CCLogDiagnosticsFilename.empty()
6119 ? D.CCLogDiagnosticsFilename.c_str()
6120 : "-");
6121 }
6122
6123 // Give the gen diagnostics more chances to succeed, by avoiding intentional
6124 // crashes.
6125 if (D.CCGenDiagnostics)
6126 CmdArgs.push_back(Elt: "-disable-pragma-debug-crash");
6127
6128 // Allow backend to put its diagnostic files in the same place as frontend
6129 // crash diagnostics files.
6130 if (Args.hasArg(options::OPT_fcrash_diagnostics_dir)) {
6131 StringRef Dir = Args.getLastArgValue(options::OPT_fcrash_diagnostics_dir);
6132 CmdArgs.push_back(Elt: "-mllvm");
6133 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-crash-diagnostics-dir=" + Dir));
6134 }
6135
6136 bool UseSeparateSections = isUseSeparateSections(Triple);
6137
6138 if (Args.hasFlag(options::OPT_ffunction_sections,
6139 options::OPT_fno_function_sections, UseSeparateSections)) {
6140 CmdArgs.push_back(Elt: "-ffunction-sections");
6141 }
6142
6143 if (Arg *A = Args.getLastArg(options::OPT_fbasic_block_address_map,
6144 options::OPT_fno_basic_block_address_map)) {
6145 if ((Triple.isX86() || Triple.isAArch64()) && Triple.isOSBinFormatELF()) {
6146 if (A->getOption().matches(options::OPT_fbasic_block_address_map))
6147 A->render(Args, Output&: CmdArgs);
6148 } else {
6149 D.Diag(diag::err_drv_unsupported_opt_for_target)
6150 << A->getAsString(Args) << TripleStr;
6151 }
6152 }
6153
6154 if (Arg *A = Args.getLastArg(options::OPT_fbasic_block_sections_EQ)) {
6155 StringRef Val = A->getValue();
6156 if (Triple.isX86() && Triple.isOSBinFormatELF()) {
6157 if (Val != "all" && Val != "labels" && Val != "none" &&
6158 !Val.starts_with(Prefix: "list="))
6159 D.Diag(diag::err_drv_invalid_value)
6160 << A->getAsString(Args) << A->getValue();
6161 else
6162 A->render(Args, Output&: CmdArgs);
6163 } else if (Triple.isAArch64() && Triple.isOSBinFormatELF()) {
6164 // "all" is not supported on AArch64 since branch relaxation creates new
6165 // basic blocks for some cross-section branches.
6166 if (Val != "labels" && Val != "none" && !Val.starts_with(Prefix: "list="))
6167 D.Diag(diag::err_drv_invalid_value)
6168 << A->getAsString(Args) << A->getValue();
6169 else
6170 A->render(Args, Output&: CmdArgs);
6171 } else if (Triple.isNVPTX()) {
6172 // Do not pass the option to the GPU compilation. We still want it enabled
6173 // for the host-side compilation, so seeing it here is not an error.
6174 } else if (Val != "none") {
6175 // =none is allowed everywhere. It's useful for overriding the option
6176 // and is the same as not specifying the option.
6177 D.Diag(diag::err_drv_unsupported_opt_for_target)
6178 << A->getAsString(Args) << TripleStr;
6179 }
6180 }
6181
6182 bool HasDefaultDataSections = Triple.isOSBinFormatXCOFF();
6183 if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
6184 UseSeparateSections || HasDefaultDataSections)) {
6185 CmdArgs.push_back(Elt: "-fdata-sections");
6186 }
6187
6188 Args.addOptOutFlag(CmdArgs, options::OPT_funique_section_names,
6189 options::OPT_fno_unique_section_names);
6190 Args.addOptInFlag(CmdArgs, options::OPT_funique_internal_linkage_names,
6191 options::OPT_fno_unique_internal_linkage_names);
6192 Args.addOptInFlag(CmdArgs, options::OPT_funique_basic_block_section_names,
6193 options::OPT_fno_unique_basic_block_section_names);
6194 Args.addOptInFlag(CmdArgs, options::OPT_fconvergent_functions,
6195 options::OPT_fno_convergent_functions);
6196
6197 if (Arg *A = Args.getLastArg(options::OPT_fsplit_machine_functions,
6198 options::OPT_fno_split_machine_functions)) {
6199 if (!A->getOption().matches(options::OPT_fno_split_machine_functions)) {
6200 // This codegen pass is only available on x86 and AArch64 ELF targets.
6201 if ((Triple.isX86() || Triple.isAArch64()) && Triple.isOSBinFormatELF())
6202 A->render(Args, Output&: CmdArgs);
6203 else
6204 D.Diag(diag::err_drv_unsupported_opt_for_target)
6205 << A->getAsString(Args) << TripleStr;
6206 }
6207 }
6208
6209 Args.AddLastArg(CmdArgs, options::OPT_finstrument_functions,
6210 options::OPT_finstrument_functions_after_inlining,
6211 options::OPT_finstrument_function_entry_bare);
6212
6213 // NVPTX/AMDGCN doesn't support PGO or coverage. There's no runtime support
6214 // for sampling, overhead of call arc collection is way too high and there's
6215 // no way to collect the output.
6216 if (!Triple.isNVPTX() && !Triple.isAMDGCN())
6217 addPGOAndCoverageFlags(TC, C, JA, Output, Args, SanArgs&: SanitizeArgs, CmdArgs);
6218
6219 Args.AddLastArg(CmdArgs, options::OPT_fclang_abi_compat_EQ);
6220
6221 if (getLastProfileSampleUseArg(Args) &&
6222 Args.hasArg(options::OPT_fsample_profile_use_profi)) {
6223 CmdArgs.push_back(Elt: "-mllvm");
6224 CmdArgs.push_back(Elt: "-sample-profile-use-profi");
6225 }
6226
6227 // Add runtime flag for PS4/PS5 when PGO, coverage, or sanitizers are enabled.
6228 if (RawTriple.isPS() &&
6229 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
6230 PScpu::addProfileRTArgs(TC, Args, CmdArgs);
6231 PScpu::addSanitizerArgs(TC, Args, CmdArgs);
6232 }
6233
6234 // Pass options for controlling the default header search paths.
6235 if (Args.hasArg(options::OPT_nostdinc)) {
6236 CmdArgs.push_back(Elt: "-nostdsysteminc");
6237 CmdArgs.push_back(Elt: "-nobuiltininc");
6238 } else {
6239 if (Args.hasArg(options::OPT_nostdlibinc))
6240 CmdArgs.push_back(Elt: "-nostdsysteminc");
6241 Args.AddLastArg(CmdArgs, options::OPT_nostdincxx);
6242 Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
6243 }
6244
6245 // Pass the path to compiler resource files.
6246 CmdArgs.push_back(Elt: "-resource-dir");
6247 CmdArgs.push_back(Elt: D.ResourceDir.c_str());
6248
6249 Args.AddLastArg(CmdArgs, options::OPT_working_directory);
6250
6251 RenderARCMigrateToolOptions(D, Args, CmdArgs);
6252
6253 // Add preprocessing options like -I, -D, etc. if we are using the
6254 // preprocessor.
6255 //
6256 // FIXME: Support -fpreprocessed
6257 if (types::getPreprocessedType(Id: InputType) != types::TY_INVALID)
6258 AddPreprocessingOptions(C, JA, D, Args, CmdArgs, Output, Inputs);
6259
6260 // Don't warn about "clang -c -DPIC -fPIC test.i" because libtool.m4 assumes
6261 // that "The compiler can only warn and ignore the option if not recognized".
6262 // When building with ccache, it will pass -D options to clang even on
6263 // preprocessed inputs and configure concludes that -fPIC is not supported.
6264 Args.ClaimAllArgs(options::OPT_D);
6265
6266 // Manually translate -O4 to -O3; let clang reject others.
6267 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
6268 if (A->getOption().matches(options::OPT_O4)) {
6269 CmdArgs.push_back(Elt: "-O3");
6270 D.Diag(diag::warn_O4_is_O3);
6271 } else {
6272 A->render(Args, Output&: CmdArgs);
6273 }
6274 }
6275
6276 // Warn about ignored options to clang.
6277 for (const Arg *A :
6278 Args.filtered(options::OPT_clang_ignored_gcc_optimization_f_Group)) {
6279 D.Diag(diag::warn_ignored_gcc_optimization) << A->getAsString(Args);
6280 A->claim();
6281 }
6282
6283 for (const Arg *A :
6284 Args.filtered(options::OPT_clang_ignored_legacy_options_Group)) {
6285 D.Diag(diag::warn_ignored_clang_option) << A->getAsString(Args);
6286 A->claim();
6287 }
6288
6289 claimNoWarnArgs(Args);
6290
6291 Args.AddAllArgs(CmdArgs, options::OPT_R_Group);
6292
6293 for (const Arg *A :
6294 Args.filtered(options::OPT_W_Group, options::OPT__SLASH_wd)) {
6295 A->claim();
6296 if (A->getOption().getID() == options::OPT__SLASH_wd) {
6297 unsigned WarningNumber;
6298 if (StringRef(A->getValue()).getAsInteger(10, WarningNumber)) {
6299 D.Diag(diag::err_drv_invalid_int_value)
6300 << A->getAsString(Args) << A->getValue();
6301 continue;
6302 }
6303
6304 if (auto Group = diagGroupFromCLWarningID(WarningNumber)) {
6305 CmdArgs.push_back(Args.MakeArgString(
6306 "-Wno-" + DiagnosticIDs::getWarningOptionForGroup(*Group)));
6307 }
6308 continue;
6309 }
6310 A->render(Args, CmdArgs);
6311 }
6312
6313 Args.AddAllArgs(CmdArgs, options::OPT_Wsystem_headers_in_module_EQ);
6314
6315 if (Args.hasFlag(options::OPT_pedantic, options::OPT_no_pedantic, false))
6316 CmdArgs.push_back(Elt: "-pedantic");
6317 Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
6318 Args.AddLastArg(CmdArgs, options::OPT_w);
6319
6320 Args.addOptInFlag(CmdArgs, options::OPT_ffixed_point,
6321 options::OPT_fno_fixed_point);
6322
6323 if (Arg *A = Args.getLastArg(options::OPT_fcxx_abi_EQ))
6324 A->render(Args, Output&: CmdArgs);
6325
6326 Args.AddLastArg(CmdArgs, options::OPT_fexperimental_relative_cxx_abi_vtables,
6327 options::OPT_fno_experimental_relative_cxx_abi_vtables);
6328
6329 Args.AddLastArg(CmdArgs, options::OPT_fexperimental_omit_vtable_rtti,
6330 options::OPT_fno_experimental_omit_vtable_rtti);
6331
6332 if (Arg *A = Args.getLastArg(options::OPT_ffuchsia_api_level_EQ))
6333 A->render(Args, Output&: CmdArgs);
6334
6335 // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
6336 // (-ansi is equivalent to -std=c89 or -std=c++98).
6337 //
6338 // If a std is supplied, only add -trigraphs if it follows the
6339 // option.
6340 bool ImplyVCPPCVer = false;
6341 bool ImplyVCPPCXXVer = false;
6342 const Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi);
6343 if (Std) {
6344 if (Std->getOption().matches(options::OPT_ansi))
6345 if (types::isCXX(Id: InputType))
6346 CmdArgs.push_back(Elt: "-std=c++98");
6347 else
6348 CmdArgs.push_back(Elt: "-std=c89");
6349 else
6350 Std->render(Args, Output&: CmdArgs);
6351
6352 // If -f(no-)trigraphs appears after the language standard flag, honor it.
6353 if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi,
6354 options::OPT_ftrigraphs,
6355 options::OPT_fno_trigraphs))
6356 if (A != Std)
6357 A->render(Args, Output&: CmdArgs);
6358 } else {
6359 // Honor -std-default.
6360 //
6361 // FIXME: Clang doesn't correctly handle -std= when the input language
6362 // doesn't match. For the time being just ignore this for C++ inputs;
6363 // eventually we want to do all the standard defaulting here instead of
6364 // splitting it between the driver and clang -cc1.
6365 if (!types::isCXX(Id: InputType)) {
6366 if (!Args.hasArg(options::OPT__SLASH_std)) {
6367 Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ, "-std=",
6368 /*Joined=*/true);
6369 } else
6370 ImplyVCPPCVer = true;
6371 }
6372 else if (IsWindowsMSVC)
6373 ImplyVCPPCXXVer = true;
6374
6375 Args.AddLastArg(CmdArgs, options::OPT_ftrigraphs,
6376 options::OPT_fno_trigraphs);
6377 }
6378
6379 // GCC's behavior for -Wwrite-strings is a bit strange:
6380 // * In C, this "warning flag" changes the types of string literals from
6381 // 'char[N]' to 'const char[N]', and thus triggers an unrelated warning
6382 // for the discarded qualifier.
6383 // * In C++, this is just a normal warning flag.
6384 //
6385 // Implementing this warning correctly in C is hard, so we follow GCC's
6386 // behavior for now. FIXME: Directly diagnose uses of a string literal as
6387 // a non-const char* in C, rather than using this crude hack.
6388 if (!types::isCXX(Id: InputType)) {
6389 // FIXME: This should behave just like a warning flag, and thus should also
6390 // respect -Weverything, -Wno-everything, -Werror=write-strings, and so on.
6391 Arg *WriteStrings =
6392 Args.getLastArg(options::OPT_Wwrite_strings,
6393 options::OPT_Wno_write_strings, options::OPT_w);
6394 if (WriteStrings &&
6395 WriteStrings->getOption().matches(options::OPT_Wwrite_strings))
6396 CmdArgs.push_back(Elt: "-fconst-strings");
6397 }
6398
6399 // GCC provides a macro definition '__DEPRECATED' when -Wdeprecated is active
6400 // during C++ compilation, which it is by default. GCC keeps this define even
6401 // in the presence of '-w', match this behavior bug-for-bug.
6402 if (types::isCXX(InputType) &&
6403 Args.hasFlag(options::OPT_Wdeprecated, options::OPT_Wno_deprecated,
6404 true)) {
6405 CmdArgs.push_back(Elt: "-fdeprecated-macro");
6406 }
6407
6408 // Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'.
6409 if (Arg *Asm = Args.getLastArg(options::OPT_fasm, options::OPT_fno_asm)) {
6410 if (Asm->getOption().matches(options::OPT_fasm))
6411 CmdArgs.push_back(Elt: "-fgnu-keywords");
6412 else
6413 CmdArgs.push_back(Elt: "-fno-gnu-keywords");
6414 }
6415
6416 if (!ShouldEnableAutolink(Args, TC, JA))
6417 CmdArgs.push_back(Elt: "-fno-autolink");
6418
6419 Args.AddLastArg(CmdArgs, options::OPT_ftemplate_depth_EQ);
6420 Args.AddLastArg(CmdArgs, options::OPT_foperator_arrow_depth_EQ);
6421 Args.AddLastArg(CmdArgs, options::OPT_fconstexpr_depth_EQ);
6422 Args.AddLastArg(CmdArgs, options::OPT_fconstexpr_steps_EQ);
6423
6424 Args.AddLastArg(CmdArgs, options::OPT_fexperimental_library);
6425
6426 if (Args.hasArg(options::OPT_fexperimental_new_constant_interpreter))
6427 CmdArgs.push_back(Elt: "-fexperimental-new-constant-interpreter");
6428
6429 if (Arg *A = Args.getLastArg(options::OPT_fbracket_depth_EQ)) {
6430 CmdArgs.push_back(Elt: "-fbracket-depth");
6431 CmdArgs.push_back(Elt: A->getValue());
6432 }
6433
6434 if (Arg *A = Args.getLastArg(options::OPT_Wlarge_by_value_copy_EQ,
6435 options::OPT_Wlarge_by_value_copy_def)) {
6436 if (A->getNumValues()) {
6437 StringRef bytes = A->getValue();
6438 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-Wlarge-by-value-copy=" + bytes));
6439 } else
6440 CmdArgs.push_back(Elt: "-Wlarge-by-value-copy=64"); // default value
6441 }
6442
6443 if (Args.hasArg(options::OPT_relocatable_pch))
6444 CmdArgs.push_back(Elt: "-relocatable-pch");
6445
6446 if (const Arg *A = Args.getLastArg(options::OPT_fcf_runtime_abi_EQ)) {
6447 static const char *kCFABIs[] = {
6448 "standalone", "objc", "swift", "swift-5.0", "swift-4.2", "swift-4.1",
6449 };
6450
6451 if (!llvm::is_contained(Range&: kCFABIs, Element: StringRef(A->getValue())))
6452 D.Diag(diag::err_drv_invalid_cf_runtime_abi) << A->getValue();
6453 else
6454 A->render(Args, Output&: CmdArgs);
6455 }
6456
6457 if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
6458 CmdArgs.push_back(Elt: "-fconstant-string-class");
6459 CmdArgs.push_back(Elt: A->getValue());
6460 }
6461
6462 if (Arg *A = Args.getLastArg(options::OPT_ftabstop_EQ)) {
6463 CmdArgs.push_back(Elt: "-ftabstop");
6464 CmdArgs.push_back(Elt: A->getValue());
6465 }
6466
6467 Args.addOptInFlag(CmdArgs, options::OPT_fstack_size_section,
6468 options::OPT_fno_stack_size_section);
6469
6470 if (Args.hasArg(options::OPT_fstack_usage)) {
6471 CmdArgs.push_back(Elt: "-stack-usage-file");
6472
6473 if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
6474 SmallString<128> OutputFilename(OutputOpt->getValue());
6475 llvm::sys::path::replace_extension(path&: OutputFilename, extension: "su");
6476 CmdArgs.push_back(Elt: Args.MakeArgString(Str: OutputFilename));
6477 } else
6478 CmdArgs.push_back(
6479 Elt: Args.MakeArgString(Str: Twine(getBaseInputStem(Args, Inputs)) + ".su"));
6480 }
6481
6482 CmdArgs.push_back(Elt: "-ferror-limit");
6483 if (Arg *A = Args.getLastArg(options::OPT_ferror_limit_EQ))
6484 CmdArgs.push_back(Elt: A->getValue());
6485 else
6486 CmdArgs.push_back(Elt: "19");
6487
6488 Args.AddLastArg(CmdArgs, options::OPT_fconstexpr_backtrace_limit_EQ);
6489 Args.AddLastArg(CmdArgs, options::OPT_fmacro_backtrace_limit_EQ);
6490 Args.AddLastArg(CmdArgs, options::OPT_ftemplate_backtrace_limit_EQ);
6491 Args.AddLastArg(CmdArgs, options::OPT_fspell_checking_limit_EQ);
6492 Args.AddLastArg(CmdArgs, options::OPT_fcaret_diagnostics_max_lines_EQ);
6493
6494 // Pass -fmessage-length=.
6495 unsigned MessageLength = 0;
6496 if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
6497 StringRef V(A->getValue());
6498 if (V.getAsInteger(0, MessageLength))
6499 D.Diag(diag::err_drv_invalid_argument_to_option)
6500 << V << A->getOption().getName();
6501 } else {
6502 // If -fmessage-length=N was not specified, determine whether this is a
6503 // terminal and, if so, implicitly define -fmessage-length appropriately.
6504 MessageLength = llvm::sys::Process::StandardErrColumns();
6505 }
6506 if (MessageLength != 0)
6507 CmdArgs.push_back(
6508 Elt: Args.MakeArgString(Str: "-fmessage-length=" + Twine(MessageLength)));
6509
6510 if (Arg *A = Args.getLastArg(options::OPT_frandomize_layout_seed_EQ))
6511 CmdArgs.push_back(
6512 Elt: Args.MakeArgString(Str: "-frandomize-layout-seed=" + Twine(A->getValue(N: 0))));
6513
6514 if (Arg *A = Args.getLastArg(options::OPT_frandomize_layout_seed_file_EQ))
6515 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-frandomize-layout-seed-file=" +
6516 Twine(A->getValue(N: 0))));
6517
6518 // -fvisibility= and -fvisibility-ms-compat are of a piece.
6519 if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ,
6520 options::OPT_fvisibility_ms_compat)) {
6521 if (A->getOption().matches(options::OPT_fvisibility_EQ)) {
6522 A->render(Args, Output&: CmdArgs);
6523 } else {
6524 assert(A->getOption().matches(options::OPT_fvisibility_ms_compat));
6525 CmdArgs.push_back(Elt: "-fvisibility=hidden");
6526 CmdArgs.push_back(Elt: "-ftype-visibility=default");
6527 }
6528 } else if (IsOpenMPDevice) {
6529 // When compiling for the OpenMP device we want protected visibility by
6530 // default. This prevents the device from accidentally preempting code on
6531 // the host, makes the system more robust, and improves performance.
6532 CmdArgs.push_back(Elt: "-fvisibility=protected");
6533 }
6534
6535 // PS4/PS5 process these options in addClangTargetOptions.
6536 if (!RawTriple.isPS()) {
6537 if (const Arg *A =
6538 Args.getLastArg(options::OPT_fvisibility_from_dllstorageclass,
6539 options::OPT_fno_visibility_from_dllstorageclass)) {
6540 if (A->getOption().matches(
6541 options::OPT_fvisibility_from_dllstorageclass)) {
6542 CmdArgs.push_back(Elt: "-fvisibility-from-dllstorageclass");
6543 Args.AddLastArg(CmdArgs, options::OPT_fvisibility_dllexport_EQ);
6544 Args.AddLastArg(CmdArgs, options::OPT_fvisibility_nodllstorageclass_EQ);
6545 Args.AddLastArg(CmdArgs, options::OPT_fvisibility_externs_dllimport_EQ);
6546 Args.AddLastArg(CmdArgs,
6547 options::OPT_fvisibility_externs_nodllstorageclass_EQ);
6548 }
6549 }
6550 }
6551
6552 if (Args.hasFlag(options::OPT_fvisibility_inlines_hidden,
6553 options::OPT_fno_visibility_inlines_hidden, false))
6554 CmdArgs.push_back(Elt: "-fvisibility-inlines-hidden");
6555
6556 Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden_static_local_var,
6557 options::OPT_fno_visibility_inlines_hidden_static_local_var);
6558
6559 // -fvisibility-global-new-delete-hidden is a deprecated spelling of
6560 // -fvisibility-global-new-delete=force-hidden.
6561 if (const Arg *A =
6562 Args.getLastArg(options::OPT_fvisibility_global_new_delete_hidden)) {
6563 D.Diag(diag::warn_drv_deprecated_arg)
6564 << A->getAsString(Args)
6565 << "-fvisibility-global-new-delete=force-hidden";
6566 }
6567
6568 if (const Arg *A =
6569 Args.getLastArg(options::OPT_fvisibility_global_new_delete_EQ,
6570 options::OPT_fvisibility_global_new_delete_hidden)) {
6571 if (A->getOption().matches(options::OPT_fvisibility_global_new_delete_EQ)) {
6572 A->render(Args, Output&: CmdArgs);
6573 } else {
6574 assert(A->getOption().matches(
6575 options::OPT_fvisibility_global_new_delete_hidden));
6576 CmdArgs.push_back(Elt: "-fvisibility-global-new-delete=force-hidden");
6577 }
6578 }
6579
6580 Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
6581
6582 if (Args.hasFlag(options::OPT_fnew_infallible,
6583 options::OPT_fno_new_infallible, false))
6584 CmdArgs.push_back(Elt: "-fnew-infallible");
6585
6586 if (Args.hasFlag(options::OPT_fno_operator_names,
6587 options::OPT_foperator_names, false))
6588 CmdArgs.push_back(Elt: "-fno-operator-names");
6589
6590 // Forward -f (flag) options which we can pass directly.
6591 Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
6592 Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
6593 Args.AddLastArg(CmdArgs, options::OPT_fdigraphs, options::OPT_fno_digraphs);
6594 Args.AddLastArg(CmdArgs, options::OPT_fzero_call_used_regs_EQ);
6595
6596 if (Args.hasFlag(options::OPT_femulated_tls, options::OPT_fno_emulated_tls,
6597 Triple.hasDefaultEmulatedTLS()))
6598 CmdArgs.push_back(Elt: "-femulated-tls");
6599
6600 Args.addOptInFlag(CmdArgs, options::OPT_fcheck_new,
6601 options::OPT_fno_check_new);
6602
6603 if (Arg *A = Args.getLastArg(options::OPT_fzero_call_used_regs_EQ)) {
6604 // FIXME: There's no reason for this to be restricted to X86. The backend
6605 // code needs to be changed to include the appropriate function calls
6606 // automatically.
6607 if (!Triple.isX86() && !Triple.isAArch64())
6608 D.Diag(diag::err_drv_unsupported_opt_for_target)
6609 << A->getAsString(Args) << TripleStr;
6610 }
6611
6612 // AltiVec-like language extensions aren't relevant for assembling.
6613 if (!isa<PreprocessJobAction>(JA) || Output.getType() != types::TY_PP_Asm)
6614 Args.AddLastArg(CmdArgs, options::OPT_fzvector);
6615
6616 Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
6617 Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
6618
6619 // Forward flags for OpenMP. We don't do this if the current action is an
6620 // device offloading action other than OpenMP.
6621 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
6622 options::OPT_fno_openmp, false) &&
6623 (JA.isDeviceOffloading(Action::OFK_None) ||
6624 JA.isDeviceOffloading(Action::OFK_OpenMP))) {
6625 switch (D.getOpenMPRuntime(Args)) {
6626 case Driver::OMPRT_OMP:
6627 case Driver::OMPRT_IOMP5:
6628 // Clang can generate useful OpenMP code for these two runtime libraries.
6629 CmdArgs.push_back(Elt: "-fopenmp");
6630
6631 // If no option regarding the use of TLS in OpenMP codegeneration is
6632 // given, decide a default based on the target. Otherwise rely on the
6633 // options and pass the right information to the frontend.
6634 if (!Args.hasFlag(options::OPT_fopenmp_use_tls,
6635 options::OPT_fnoopenmp_use_tls, /*Default=*/true))
6636 CmdArgs.push_back(Elt: "-fnoopenmp-use-tls");
6637 Args.AddLastArg(CmdArgs, options::OPT_fopenmp_simd,
6638 options::OPT_fno_openmp_simd);
6639 Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_enable_irbuilder);
6640 Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ);
6641 if (!Args.hasFlag(options::OPT_fopenmp_extensions,
6642 options::OPT_fno_openmp_extensions, /*Default=*/true))
6643 CmdArgs.push_back(Elt: "-fno-openmp-extensions");
6644 Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_cuda_number_of_sm_EQ);
6645 Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_cuda_blocks_per_sm_EQ);
6646 Args.AddAllArgs(CmdArgs,
6647 options::OPT_fopenmp_cuda_teams_reduction_recs_num_EQ);
6648 if (Args.hasFlag(options::OPT_fopenmp_optimistic_collapse,
6649 options::OPT_fno_openmp_optimistic_collapse,
6650 /*Default=*/false))
6651 CmdArgs.push_back(Elt: "-fopenmp-optimistic-collapse");
6652
6653 // When in OpenMP offloading mode with NVPTX target, forward
6654 // cuda-mode flag
6655 if (Args.hasFlag(options::OPT_fopenmp_cuda_mode,
6656 options::OPT_fno_openmp_cuda_mode, /*Default=*/false))
6657 CmdArgs.push_back(Elt: "-fopenmp-cuda-mode");
6658
6659 // When in OpenMP offloading mode, enable debugging on the device.
6660 Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_target_debug_EQ);
6661 if (Args.hasFlag(options::OPT_fopenmp_target_debug,
6662 options::OPT_fno_openmp_target_debug, /*Default=*/false))
6663 CmdArgs.push_back(Elt: "-fopenmp-target-debug");
6664
6665 // When in OpenMP offloading mode, forward assumptions information about
6666 // thread and team counts in the device.
6667 if (Args.hasFlag(options::OPT_fopenmp_assume_teams_oversubscription,
6668 options::OPT_fno_openmp_assume_teams_oversubscription,
6669 /*Default=*/false))
6670 CmdArgs.push_back(Elt: "-fopenmp-assume-teams-oversubscription");
6671 if (Args.hasFlag(options::OPT_fopenmp_assume_threads_oversubscription,
6672 options::OPT_fno_openmp_assume_threads_oversubscription,
6673 /*Default=*/false))
6674 CmdArgs.push_back(Elt: "-fopenmp-assume-threads-oversubscription");
6675 if (Args.hasArg(options::OPT_fopenmp_assume_no_thread_state))
6676 CmdArgs.push_back(Elt: "-fopenmp-assume-no-thread-state");
6677 if (Args.hasArg(options::OPT_fopenmp_assume_no_nested_parallelism))
6678 CmdArgs.push_back(Elt: "-fopenmp-assume-no-nested-parallelism");
6679 if (Args.hasArg(options::OPT_fopenmp_offload_mandatory))
6680 CmdArgs.push_back(Elt: "-fopenmp-offload-mandatory");
6681 if (Args.hasArg(options::OPT_fopenmp_force_usm))
6682 CmdArgs.push_back(Elt: "-fopenmp-force-usm");
6683 break;
6684 default:
6685 // By default, if Clang doesn't know how to generate useful OpenMP code
6686 // for a specific runtime library, we just don't pass the '-fopenmp' flag
6687 // down to the actual compilation.
6688 // FIXME: It would be better to have a mode which *only* omits IR
6689 // generation based on the OpenMP support so that we get consistent
6690 // semantic analysis, etc.
6691 break;
6692 }
6693 } else {
6694 Args.AddLastArg(CmdArgs, options::OPT_fopenmp_simd,
6695 options::OPT_fno_openmp_simd);
6696 Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ);
6697 Args.addOptOutFlag(CmdArgs, options::OPT_fopenmp_extensions,
6698 options::OPT_fno_openmp_extensions);
6699 }
6700
6701 // Forward the new driver to change offloading code generation.
6702 if (Args.hasFlag(options::OPT_offload_new_driver,
6703 options::OPT_no_offload_new_driver, false))
6704 CmdArgs.push_back(Elt: "--offload-new-driver");
6705
6706 SanitizeArgs.addArgs(TC, Args, CmdArgs, InputType);
6707
6708 const XRayArgs &XRay = TC.getXRayArgs();
6709 XRay.addArgs(TC, Args, CmdArgs, InputType);
6710
6711 for (const auto &Filename :
6712 Args.getAllArgValues(options::OPT_fprofile_list_EQ)) {
6713 if (D.getVFS().exists(Filename))
6714 CmdArgs.push_back(Args.MakeArgString("-fprofile-list=" + Filename));
6715 else
6716 D.Diag(clang::diag::err_drv_no_such_file) << Filename;
6717 }
6718
6719 if (Arg *A = Args.getLastArg(options::OPT_fpatchable_function_entry_EQ)) {
6720 StringRef S0 = A->getValue(), S = S0;
6721 unsigned Size, Offset = 0;
6722 if (!Triple.isAArch64() && !Triple.isLoongArch() && !Triple.isRISCV() &&
6723 !Triple.isX86())
6724 D.Diag(diag::err_drv_unsupported_opt_for_target)
6725 << A->getAsString(Args) << TripleStr;
6726 else if (S.consumeInteger(Radix: 10, Result&: Size) ||
6727 (!S.empty() && (!S.consume_front(Prefix: ",") ||
6728 S.consumeInteger(Radix: 10, Result&: Offset) || !S.empty())))
6729 D.Diag(diag::err_drv_invalid_argument_to_option)
6730 << S0 << A->getOption().getName();
6731 else if (Size < Offset)
6732 D.Diag(diag::err_drv_unsupported_fpatchable_function_entry_argument);
6733 else {
6734 CmdArgs.push_back(Elt: Args.MakeArgString(Str: A->getSpelling() + Twine(Size)));
6735 CmdArgs.push_back(Elt: Args.MakeArgString(
6736 Str: "-fpatchable-function-entry-offset=" + Twine(Offset)));
6737 }
6738 }
6739
6740 Args.AddLastArg(CmdArgs, options::OPT_fms_hotpatch);
6741
6742 if (TC.SupportsProfiling()) {
6743 Args.AddLastArg(CmdArgs, options::OPT_pg);
6744
6745 llvm::Triple::ArchType Arch = TC.getArch();
6746 if (Arg *A = Args.getLastArg(options::OPT_mfentry)) {
6747 if (Arch == llvm::Triple::systemz || TC.getTriple().isX86())
6748 A->render(Args, Output&: CmdArgs);
6749 else
6750 D.Diag(diag::err_drv_unsupported_opt_for_target)
6751 << A->getAsString(Args) << TripleStr;
6752 }
6753 if (Arg *A = Args.getLastArg(options::OPT_mnop_mcount)) {
6754 if (Arch == llvm::Triple::systemz)
6755 A->render(Args, Output&: CmdArgs);
6756 else
6757 D.Diag(diag::err_drv_unsupported_opt_for_target)
6758 << A->getAsString(Args) << TripleStr;
6759 }
6760 if (Arg *A = Args.getLastArg(options::OPT_mrecord_mcount)) {
6761 if (Arch == llvm::Triple::systemz)
6762 A->render(Args, Output&: CmdArgs);
6763 else
6764 D.Diag(diag::err_drv_unsupported_opt_for_target)
6765 << A->getAsString(Args) << TripleStr;
6766 }
6767 }
6768
6769 if (Arg *A = Args.getLastArgNoClaim(options::OPT_pg)) {
6770 if (TC.getTriple().isOSzOS()) {
6771 D.Diag(diag::err_drv_unsupported_opt_for_target)
6772 << A->getAsString(Args) << TripleStr;
6773 }
6774 }
6775 if (Arg *A = Args.getLastArgNoClaim(options::OPT_p)) {
6776 if (!(TC.getTriple().isOSAIX() || TC.getTriple().isOSOpenBSD())) {
6777 D.Diag(diag::err_drv_unsupported_opt_for_target)
6778 << A->getAsString(Args) << TripleStr;
6779 }
6780 }
6781 if (Arg *A = Args.getLastArgNoClaim(options::OPT_p, options::OPT_pg)) {
6782 if (A->getOption().matches(options::OPT_p)) {
6783 A->claim();
6784 if (TC.getTriple().isOSAIX() && !Args.hasArgNoClaim(options::OPT_pg))
6785 CmdArgs.push_back(Elt: "-pg");
6786 }
6787 }
6788
6789 // Reject AIX-specific link options on other targets.
6790 if (!TC.getTriple().isOSAIX()) {
6791 for (const Arg *A : Args.filtered(options::OPT_b, options::OPT_K,
6792 options::OPT_mxcoff_build_id_EQ)) {
6793 D.Diag(diag::err_drv_unsupported_opt_for_target)
6794 << A->getSpelling() << TripleStr;
6795 }
6796 }
6797
6798 if (Args.getLastArg(options::OPT_fapple_kext) ||
6799 (Args.hasArg(options::OPT_mkernel) && types::isCXX(InputType)))
6800 CmdArgs.push_back(Elt: "-fapple-kext");
6801
6802 Args.AddLastArg(CmdArgs, options::OPT_altivec_src_compat);
6803 Args.AddLastArg(CmdArgs, options::OPT_flax_vector_conversions_EQ);
6804 Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
6805 Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
6806 Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
6807 Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
6808 Args.AddLastArg(CmdArgs, options::OPT_ftime_report_EQ);
6809 Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
6810 Args.AddLastArg(CmdArgs, options::OPT_malign_double);
6811 Args.AddLastArg(CmdArgs, options::OPT_fno_temp_file);
6812
6813 if (const char *Name = C.getTimeTraceFile(JA: &JA)) {
6814 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-ftime-trace=" + Twine(Name)));
6815 Args.AddLastArg(CmdArgs, options::OPT_ftime_trace_granularity_EQ);
6816 }
6817
6818 if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) {
6819 CmdArgs.push_back(Elt: "-ftrapv-handler");
6820 CmdArgs.push_back(Elt: A->getValue());
6821 }
6822
6823 Args.AddLastArg(CmdArgs, options::OPT_ftrap_function_EQ);
6824
6825 // -fno-strict-overflow implies -fwrapv if it isn't disabled, but
6826 // -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
6827 if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
6828 if (A->getOption().matches(options::OPT_fwrapv))
6829 CmdArgs.push_back(Elt: "-fwrapv");
6830 } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
6831 options::OPT_fno_strict_overflow)) {
6832 if (A->getOption().matches(options::OPT_fno_strict_overflow))
6833 CmdArgs.push_back(Elt: "-fwrapv");
6834 }
6835
6836 Args.AddLastArg(CmdArgs, options::OPT_ffinite_loops,
6837 options::OPT_fno_finite_loops);
6838
6839 Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
6840 Args.AddLastArg(CmdArgs, options::OPT_funroll_loops,
6841 options::OPT_fno_unroll_loops);
6842
6843 Args.AddLastArg(CmdArgs, options::OPT_fstrict_flex_arrays_EQ);
6844
6845 Args.AddLastArg(CmdArgs, options::OPT_pthread);
6846
6847 Args.addOptInFlag(CmdArgs, options::OPT_mspeculative_load_hardening,
6848 options::OPT_mno_speculative_load_hardening);
6849
6850 RenderSSPOptions(D, TC, Args, CmdArgs, KernelOrKext);
6851 RenderSCPOptions(TC, Args, CmdArgs);
6852 RenderTrivialAutoVarInitOptions(D, TC, Args, CmdArgs);
6853
6854 Args.AddLastArg(CmdArgs, options::OPT_fswift_async_fp_EQ);
6855
6856 Args.addOptInFlag(CmdArgs, options::OPT_mstackrealign,
6857 options::OPT_mno_stackrealign);
6858
6859 if (Args.hasArg(options::OPT_mstack_alignment)) {
6860 StringRef alignment = Args.getLastArgValue(options::OPT_mstack_alignment);
6861 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-mstack-alignment=" + alignment));
6862 }
6863
6864 if (Args.hasArg(options::OPT_mstack_probe_size)) {
6865 StringRef Size = Args.getLastArgValue(options::OPT_mstack_probe_size);
6866
6867 if (!Size.empty())
6868 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-mstack-probe-size=" + Size));
6869 else
6870 CmdArgs.push_back(Elt: "-mstack-probe-size=0");
6871 }
6872
6873 Args.addOptOutFlag(CmdArgs, options::OPT_mstack_arg_probe,
6874 options::OPT_mno_stack_arg_probe);
6875
6876 if (Arg *A = Args.getLastArg(options::OPT_mrestrict_it,
6877 options::OPT_mno_restrict_it)) {
6878 if (A->getOption().matches(options::OPT_mrestrict_it)) {
6879 CmdArgs.push_back(Elt: "-mllvm");
6880 CmdArgs.push_back(Elt: "-arm-restrict-it");
6881 } else {
6882 CmdArgs.push_back(Elt: "-mllvm");
6883 CmdArgs.push_back(Elt: "-arm-default-it");
6884 }
6885 }
6886
6887 // Forward -cl options to -cc1
6888 RenderOpenCLOptions(Args, CmdArgs, InputType);
6889
6890 // Forward hlsl options to -cc1
6891 RenderHLSLOptions(Args, CmdArgs, InputType);
6892
6893 // Forward OpenACC options to -cc1
6894 RenderOpenACCOptions(D, Args, CmdArgs, InputType);
6895
6896 if (IsHIP) {
6897 if (Args.hasFlag(options::OPT_fhip_new_launch_api,
6898 options::OPT_fno_hip_new_launch_api, true))
6899 CmdArgs.push_back(Elt: "-fhip-new-launch-api");
6900 Args.addOptInFlag(CmdArgs, options::OPT_fgpu_allow_device_init,
6901 options::OPT_fno_gpu_allow_device_init);
6902 Args.AddLastArg(CmdArgs, options::OPT_hipstdpar);
6903 Args.AddLastArg(CmdArgs, options::OPT_hipstdpar_interpose_alloc);
6904 Args.addOptInFlag(CmdArgs, options::OPT_fhip_kernel_arg_name,
6905 options::OPT_fno_hip_kernel_arg_name);
6906 }
6907
6908 if (IsCuda || IsHIP) {
6909 if (IsRDCMode)
6910 CmdArgs.push_back(Elt: "-fgpu-rdc");
6911 Args.addOptInFlag(CmdArgs, options::OPT_fgpu_defer_diag,
6912 options::OPT_fno_gpu_defer_diag);
6913 if (Args.hasFlag(options::OPT_fgpu_exclude_wrong_side_overloads,
6914 options::OPT_fno_gpu_exclude_wrong_side_overloads,
6915 false)) {
6916 CmdArgs.push_back(Elt: "-fgpu-exclude-wrong-side-overloads");
6917 CmdArgs.push_back(Elt: "-fgpu-defer-diag");
6918 }
6919 }
6920
6921 // Forward -nogpulib to -cc1.
6922 if (Args.hasArg(options::OPT_nogpulib))
6923 CmdArgs.push_back(Elt: "-nogpulib");
6924
6925 if (Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) {
6926 CmdArgs.push_back(
6927 Elt: Args.MakeArgString(Str: Twine("-fcf-protection=") + A->getValue()));
6928 }
6929
6930 if (Arg *A = Args.getLastArg(options::OPT_mfunction_return_EQ))
6931 CmdArgs.push_back(
6932 Elt: Args.MakeArgString(Str: Twine("-mfunction-return=") + A->getValue()));
6933
6934 Args.AddLastArg(CmdArgs, options::OPT_mindirect_branch_cs_prefix);
6935
6936 // Forward -f options with positive and negative forms; we translate these by
6937 // hand. Do not propagate PGO options to the GPU-side compilations as the
6938 // profile info is for the host-side compilation only.
6939 if (!(IsCudaDevice || IsHIPDevice)) {
6940 if (Arg *A = getLastProfileSampleUseArg(Args)) {
6941 auto *PGOArg = Args.getLastArg(
6942 options::OPT_fprofile_generate, options::OPT_fprofile_generate_EQ,
6943 options::OPT_fcs_profile_generate,
6944 options::OPT_fcs_profile_generate_EQ, options::OPT_fprofile_use,
6945 options::OPT_fprofile_use_EQ);
6946 if (PGOArg)
6947 D.Diag(diag::err_drv_argument_not_allowed_with)
6948 << "SampleUse with PGO options";
6949
6950 StringRef fname = A->getValue();
6951 if (!llvm::sys::fs::exists(Path: fname))
6952 D.Diag(diag::err_drv_no_such_file) << fname;
6953 else
6954 A->render(Args, Output&: CmdArgs);
6955 }
6956 Args.AddLastArg(CmdArgs, options::OPT_fprofile_remapping_file_EQ);
6957
6958 if (Args.hasFlag(options::OPT_fpseudo_probe_for_profiling,
6959 options::OPT_fno_pseudo_probe_for_profiling, false)) {
6960 CmdArgs.push_back(Elt: "-fpseudo-probe-for-profiling");
6961 // Enforce -funique-internal-linkage-names if it's not explicitly turned
6962 // off.
6963 if (Args.hasFlag(options::OPT_funique_internal_linkage_names,
6964 options::OPT_fno_unique_internal_linkage_names, true))
6965 CmdArgs.push_back(Elt: "-funique-internal-linkage-names");
6966 }
6967 }
6968 RenderBuiltinOptions(TC, T: RawTriple, Args, CmdArgs);
6969
6970 Args.addOptOutFlag(CmdArgs, options::OPT_fassume_sane_operator_new,
6971 options::OPT_fno_assume_sane_operator_new);
6972
6973 if (Args.hasFlag(options::OPT_fapinotes, options::OPT_fno_apinotes, false))
6974 CmdArgs.push_back(Elt: "-fapinotes");
6975 if (Args.hasFlag(options::OPT_fapinotes_modules,
6976 options::OPT_fno_apinotes_modules, false))
6977 CmdArgs.push_back(Elt: "-fapinotes-modules");
6978 Args.AddLastArg(CmdArgs, options::OPT_fapinotes_swift_version);
6979
6980 // -fblocks=0 is default.
6981 if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
6982 TC.IsBlocksDefault()) ||
6983 (Args.hasArg(options::OPT_fgnu_runtime) &&
6984 Args.hasArg(options::OPT_fobjc_nonfragile_abi) &&
6985 !Args.hasArg(options::OPT_fno_blocks))) {
6986 CmdArgs.push_back(Elt: "-fblocks");
6987
6988 if (!Args.hasArg(options::OPT_fgnu_runtime) && !TC.hasBlocksRuntime())
6989 CmdArgs.push_back(Elt: "-fblocks-runtime-optional");
6990 }
6991
6992 // -fencode-extended-block-signature=1 is default.
6993 if (TC.IsEncodeExtendedBlockSignatureDefault())
6994 CmdArgs.push_back(Elt: "-fencode-extended-block-signature");
6995
6996 if (Args.hasFlag(options::OPT_fcoro_aligned_allocation,
6997 options::OPT_fno_coro_aligned_allocation, false) &&
6998 types::isCXX(InputType))
6999 CmdArgs.push_back(Elt: "-fcoro-aligned-allocation");
7000
7001 Args.AddLastArg(CmdArgs, options::OPT_fdouble_square_bracket_attributes,
7002 options::OPT_fno_double_square_bracket_attributes);
7003
7004 Args.addOptOutFlag(CmdArgs, options::OPT_faccess_control,
7005 options::OPT_fno_access_control);
7006 Args.addOptOutFlag(CmdArgs, options::OPT_felide_constructors,
7007 options::OPT_fno_elide_constructors);
7008
7009 ToolChain::RTTIMode RTTIMode = TC.getRTTIMode();
7010
7011 if (KernelOrKext || (types::isCXX(Id: InputType) &&
7012 (RTTIMode == ToolChain::RM_Disabled)))
7013 CmdArgs.push_back(Elt: "-fno-rtti");
7014
7015 // -fshort-enums=0 is default for all architectures except Hexagon and z/OS.
7016 if (Args.hasFlag(options::OPT_fshort_enums, options::OPT_fno_short_enums,
7017 TC.getArch() == llvm::Triple::hexagon || Triple.isOSzOS()))
7018 CmdArgs.push_back(Elt: "-fshort-enums");
7019
7020 RenderCharacterOptions(Args, T: AuxTriple ? *AuxTriple : RawTriple, CmdArgs);
7021
7022 // -fuse-cxa-atexit is default.
7023 if (!Args.hasFlag(
7024 options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit,
7025 !RawTriple.isOSAIX() && !RawTriple.isOSWindows() &&
7026 ((RawTriple.getVendor() != llvm::Triple::MipsTechnologies) ||
7027 RawTriple.hasEnvironment())) ||
7028 KernelOrKext)
7029 CmdArgs.push_back(Elt: "-fno-use-cxa-atexit");
7030
7031 if (Args.hasFlag(options::OPT_fregister_global_dtors_with_atexit,
7032 options::OPT_fno_register_global_dtors_with_atexit,
7033 RawTriple.isOSDarwin() && !KernelOrKext))
7034 CmdArgs.push_back(Elt: "-fregister-global-dtors-with-atexit");
7035
7036 Args.addOptInFlag(CmdArgs, options::OPT_fuse_line_directives,
7037 options::OPT_fno_use_line_directives);
7038
7039 // -fno-minimize-whitespace is default.
7040 if (Args.hasFlag(options::OPT_fminimize_whitespace,
7041 options::OPT_fno_minimize_whitespace, false)) {
7042 types::ID InputType = Inputs[0].getType();
7043 if (!isDerivedFromC(InputType))
7044 D.Diag(diag::err_drv_opt_unsupported_input_type)
7045 << "-fminimize-whitespace" << types::getTypeName(InputType);
7046 CmdArgs.push_back(Elt: "-fminimize-whitespace");
7047 }
7048
7049 // -fno-keep-system-includes is default.
7050 if (Args.hasFlag(options::OPT_fkeep_system_includes,
7051 options::OPT_fno_keep_system_includes, false)) {
7052 types::ID InputType = Inputs[0].getType();
7053 if (!isDerivedFromC(InputType))
7054 D.Diag(diag::err_drv_opt_unsupported_input_type)
7055 << "-fkeep-system-includes" << types::getTypeName(InputType);
7056 CmdArgs.push_back(Elt: "-fkeep-system-includes");
7057 }
7058
7059 // -fms-extensions=0 is default.
7060 if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
7061 IsWindowsMSVC))
7062 CmdArgs.push_back(Elt: "-fms-extensions");
7063
7064 // -fms-compatibility=0 is default.
7065 bool IsMSVCCompat = Args.hasFlag(
7066 options::OPT_fms_compatibility, options::OPT_fno_ms_compatibility,
7067 (IsWindowsMSVC && Args.hasFlag(options::OPT_fms_extensions,
7068 options::OPT_fno_ms_extensions, true)));
7069 if (IsMSVCCompat)
7070 CmdArgs.push_back(Elt: "-fms-compatibility");
7071
7072 if (Triple.isWindowsMSVCEnvironment() && !D.IsCLMode() &&
7073 Args.hasArg(options::OPT_fms_runtime_lib_EQ))
7074 ProcessVSRuntimeLibrary(TC: getToolChain(), Args, CmdArgs);
7075
7076 // Handle -fgcc-version, if present.
7077 VersionTuple GNUCVer;
7078 if (Arg *A = Args.getLastArg(options::OPT_fgnuc_version_EQ)) {
7079 // Check that the version has 1 to 3 components and the minor and patch
7080 // versions fit in two decimal digits.
7081 StringRef Val = A->getValue();
7082 Val = Val.empty() ? "0" : Val; // Treat "" as 0 or disable.
7083 bool Invalid = GNUCVer.tryParse(string: Val);
7084 unsigned Minor = GNUCVer.getMinor().value_or(u: 0);
7085 unsigned Patch = GNUCVer.getSubminor().value_or(u: 0);
7086 if (Invalid || GNUCVer.getBuild() || Minor >= 100 || Patch >= 100) {
7087 D.Diag(diag::err_drv_invalid_value)
7088 << A->getAsString(Args) << A->getValue();
7089 }
7090 } else if (!IsMSVCCompat) {
7091 // Imitate GCC 4.2.1 by default if -fms-compatibility is not in effect.
7092 GNUCVer = VersionTuple(4, 2, 1);
7093 }
7094 if (!GNUCVer.empty()) {
7095 CmdArgs.push_back(
7096 Elt: Args.MakeArgString(Str: "-fgnuc-version=" + GNUCVer.getAsString()));
7097 }
7098
7099 VersionTuple MSVT = TC.computeMSVCVersion(D: &D, Args);
7100 if (!MSVT.empty())
7101 CmdArgs.push_back(
7102 Elt: Args.MakeArgString(Str: "-fms-compatibility-version=" + MSVT.getAsString()));
7103
7104 bool IsMSVC2015Compatible = MSVT.getMajor() >= 19;
7105 if (ImplyVCPPCVer) {
7106 StringRef LanguageStandard;
7107 if (const Arg *StdArg = Args.getLastArg(options::OPT__SLASH_std)) {
7108 Std = StdArg;
7109 LanguageStandard = llvm::StringSwitch<StringRef>(StdArg->getValue())
7110 .Case(S: "c11", Value: "-std=c11")
7111 .Case(S: "c17", Value: "-std=c17")
7112 .Default(Value: "");
7113 if (LanguageStandard.empty())
7114 D.Diag(clang::diag::warn_drv_unused_argument)
7115 << StdArg->getAsString(Args);
7116 }
7117 CmdArgs.push_back(Elt: LanguageStandard.data());
7118 }
7119 if (ImplyVCPPCXXVer) {
7120 StringRef LanguageStandard;
7121 if (const Arg *StdArg = Args.getLastArg(options::OPT__SLASH_std)) {
7122 Std = StdArg;
7123 LanguageStandard = llvm::StringSwitch<StringRef>(StdArg->getValue())
7124 .Case(S: "c++14", Value: "-std=c++14")
7125 .Case(S: "c++17", Value: "-std=c++17")
7126 .Case(S: "c++20", Value: "-std=c++20")
7127 // TODO add c++23 and c++26 when MSVC supports it.
7128 .Case(S: "c++latest", Value: "-std=c++26")
7129 .Default(Value: "");
7130 if (LanguageStandard.empty())
7131 D.Diag(clang::diag::warn_drv_unused_argument)
7132 << StdArg->getAsString(Args);
7133 }
7134
7135 if (LanguageStandard.empty()) {
7136 if (IsMSVC2015Compatible)
7137 LanguageStandard = "-std=c++14";
7138 else
7139 LanguageStandard = "-std=c++11";
7140 }
7141
7142 CmdArgs.push_back(Elt: LanguageStandard.data());
7143 }
7144
7145 Args.addOptInFlag(CmdArgs, options::OPT_fborland_extensions,
7146 options::OPT_fno_borland_extensions);
7147
7148 // -fno-declspec is default, except for PS4/PS5.
7149 if (Args.hasFlag(options::OPT_fdeclspec, options::OPT_fno_declspec,
7150 RawTriple.isPS()))
7151 CmdArgs.push_back(Elt: "-fdeclspec");
7152 else if (Args.hasArg(options::OPT_fno_declspec))
7153 CmdArgs.push_back(Elt: "-fno-declspec"); // Explicitly disabling __declspec.
7154
7155 // -fthreadsafe-static is default, except for MSVC compatibility versions less
7156 // than 19.
7157 if (!Args.hasFlag(options::OPT_fthreadsafe_statics,
7158 options::OPT_fno_threadsafe_statics,
7159 !types::isOpenCL(InputType) &&
7160 (!IsWindowsMSVC || IsMSVC2015Compatible)))
7161 CmdArgs.push_back(Elt: "-fno-threadsafe-statics");
7162
7163 // Add -fno-assumptions, if it was specified.
7164 if (!Args.hasFlag(options::OPT_fassumptions, options::OPT_fno_assumptions,
7165 true))
7166 CmdArgs.push_back(Elt: "-fno-assumptions");
7167
7168 // -fgnu-keywords default varies depending on language; only pass if
7169 // specified.
7170 Args.AddLastArg(CmdArgs, options::OPT_fgnu_keywords,
7171 options::OPT_fno_gnu_keywords);
7172
7173 Args.addOptInFlag(CmdArgs, options::OPT_fgnu89_inline,
7174 options::OPT_fno_gnu89_inline);
7175
7176 const Arg *InlineArg = Args.getLastArg(options::OPT_finline_functions,
7177 options::OPT_finline_hint_functions,
7178 options::OPT_fno_inline_functions);
7179 if (Arg *A = Args.getLastArg(options::OPT_finline, options::OPT_fno_inline)) {
7180 if (A->getOption().matches(options::OPT_fno_inline))
7181 A->render(Args, Output&: CmdArgs);
7182 } else if (InlineArg) {
7183 InlineArg->render(Args, Output&: CmdArgs);
7184 }
7185
7186 Args.AddLastArg(CmdArgs, options::OPT_finline_max_stacksize_EQ);
7187
7188 // FIXME: Find a better way to determine whether we are in C++20.
7189 bool HaveCxx20 =
7190 Std &&
7191 (Std->containsValue(Value: "c++2a") || Std->containsValue(Value: "gnu++2a") ||
7192 Std->containsValue(Value: "c++20") || Std->containsValue(Value: "gnu++20") ||
7193 Std->containsValue(Value: "c++2b") || Std->containsValue(Value: "gnu++2b") ||
7194 Std->containsValue(Value: "c++23") || Std->containsValue(Value: "gnu++23") ||
7195 Std->containsValue(Value: "c++2c") || Std->containsValue(Value: "gnu++2c") ||
7196 Std->containsValue(Value: "c++26") || Std->containsValue(Value: "gnu++26") ||
7197 Std->containsValue(Value: "c++latest") || Std->containsValue(Value: "gnu++latest"));
7198 bool HaveModules =
7199 RenderModulesOptions(C, D, Args, Input, Output, HaveStd20: HaveCxx20, CmdArgs);
7200
7201 // -fdelayed-template-parsing is default when targeting MSVC.
7202 // Many old Windows SDK versions require this to parse.
7203 //
7204 // According to
7205 // https://learn.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=msvc-170,
7206 // MSVC actually defaults to -fno-delayed-template-parsing (/Zc:twoPhase-
7207 // with MSVC CLI) if using C++20. So we match the behavior with MSVC here to
7208 // not enable -fdelayed-template-parsing by default after C++20.
7209 //
7210 // FIXME: Given -fdelayed-template-parsing is a source of bugs, we should be
7211 // able to disable this by default at some point.
7212 if (Args.hasFlag(options::OPT_fdelayed_template_parsing,
7213 options::OPT_fno_delayed_template_parsing,
7214 IsWindowsMSVC && !HaveCxx20)) {
7215 if (HaveCxx20)
7216 D.Diag(clang::diag::warn_drv_delayed_template_parsing_after_cxx20);
7217
7218 CmdArgs.push_back(Elt: "-fdelayed-template-parsing");
7219 }
7220
7221 if (Args.hasFlag(options::OPT_fpch_validate_input_files_content,
7222 options::OPT_fno_pch_validate_input_files_content, false))
7223 CmdArgs.push_back(Elt: "-fvalidate-ast-input-files-content");
7224 if (Args.hasFlag(options::OPT_fpch_instantiate_templates,
7225 options::OPT_fno_pch_instantiate_templates, false))
7226 CmdArgs.push_back(Elt: "-fpch-instantiate-templates");
7227 if (Args.hasFlag(options::OPT_fpch_codegen, options::OPT_fno_pch_codegen,
7228 false))
7229 CmdArgs.push_back(Elt: "-fmodules-codegen");
7230 if (Args.hasFlag(options::OPT_fpch_debuginfo, options::OPT_fno_pch_debuginfo,
7231 false))
7232 CmdArgs.push_back(Elt: "-fmodules-debuginfo");
7233
7234 ObjCRuntime Runtime = AddObjCRuntimeArgs(args: Args, inputs: Inputs, cmdArgs&: CmdArgs, rewrite: rewriteKind);
7235 RenderObjCOptions(TC, D, T: RawTriple, Args, Runtime, InferCovariantReturns: rewriteKind != RK_None,
7236 Input, CmdArgs);
7237
7238 if (types::isObjC(Input.getType()) &&
7239 Args.hasFlag(options::OPT_fobjc_encode_cxx_class_template_spec,
7240 options::OPT_fno_objc_encode_cxx_class_template_spec,
7241 !Runtime.isNeXTFamily()))
7242 CmdArgs.push_back(Elt: "-fobjc-encode-cxx-class-template-spec");
7243
7244 if (Args.hasFlag(options::OPT_fapplication_extension,
7245 options::OPT_fno_application_extension, false))
7246 CmdArgs.push_back(Elt: "-fapplication-extension");
7247
7248 // Handle GCC-style exception args.
7249 bool EH = false;
7250 if (!C.getDriver().IsCLMode())
7251 EH = addExceptionArgs(Args, InputType, TC, KernelOrKext, objcRuntime: Runtime, CmdArgs);
7252
7253 // Handle exception personalities
7254 Arg *A = Args.getLastArg(
7255 options::OPT_fsjlj_exceptions, options::OPT_fseh_exceptions,
7256 options::OPT_fdwarf_exceptions, options::OPT_fwasm_exceptions);
7257 if (A) {
7258 const Option &Opt = A->getOption();
7259 if (Opt.matches(options::OPT_fsjlj_exceptions))
7260 CmdArgs.push_back(Elt: "-exception-model=sjlj");
7261 if (Opt.matches(options::OPT_fseh_exceptions))
7262 CmdArgs.push_back(Elt: "-exception-model=seh");
7263 if (Opt.matches(options::OPT_fdwarf_exceptions))
7264 CmdArgs.push_back(Elt: "-exception-model=dwarf");
7265 if (Opt.matches(options::OPT_fwasm_exceptions))
7266 CmdArgs.push_back(Elt: "-exception-model=wasm");
7267 } else {
7268 switch (TC.GetExceptionModel(Args)) {
7269 default:
7270 break;
7271 case llvm::ExceptionHandling::DwarfCFI:
7272 CmdArgs.push_back(Elt: "-exception-model=dwarf");
7273 break;
7274 case llvm::ExceptionHandling::SjLj:
7275 CmdArgs.push_back(Elt: "-exception-model=sjlj");
7276 break;
7277 case llvm::ExceptionHandling::WinEH:
7278 CmdArgs.push_back(Elt: "-exception-model=seh");
7279 break;
7280 }
7281 }
7282
7283 // C++ "sane" operator new.
7284 Args.addOptOutFlag(CmdArgs, options::OPT_fassume_sane_operator_new,
7285 options::OPT_fno_assume_sane_operator_new);
7286
7287 // -fassume-unique-vtables is on by default.
7288 Args.addOptOutFlag(CmdArgs, options::OPT_fassume_unique_vtables,
7289 options::OPT_fno_assume_unique_vtables);
7290
7291 // -frelaxed-template-template-args is off by default, as it is a severe
7292 // breaking change until a corresponding change to template partial ordering
7293 // is provided.
7294 Args.addOptInFlag(CmdArgs, options::OPT_frelaxed_template_template_args,
7295 options::OPT_fno_relaxed_template_template_args);
7296
7297 // -fsized-deallocation is off by default, as it is an ABI-breaking change for
7298 // most platforms.
7299 Args.addOptInFlag(CmdArgs, options::OPT_fsized_deallocation,
7300 options::OPT_fno_sized_deallocation);
7301
7302 // -faligned-allocation is on by default in C++17 onwards and otherwise off
7303 // by default.
7304 if (Arg *A = Args.getLastArg(options::OPT_faligned_allocation,
7305 options::OPT_fno_aligned_allocation,
7306 options::OPT_faligned_new_EQ)) {
7307 if (A->getOption().matches(options::OPT_fno_aligned_allocation))
7308 CmdArgs.push_back(Elt: "-fno-aligned-allocation");
7309 else
7310 CmdArgs.push_back(Elt: "-faligned-allocation");
7311 }
7312
7313 // The default new alignment can be specified using a dedicated option or via
7314 // a GCC-compatible option that also turns on aligned allocation.
7315 if (Arg *A = Args.getLastArg(options::OPT_fnew_alignment_EQ,
7316 options::OPT_faligned_new_EQ))
7317 CmdArgs.push_back(
7318 Elt: Args.MakeArgString(Str: Twine("-fnew-alignment=") + A->getValue()));
7319
7320 // -fconstant-cfstrings is default, and may be subject to argument translation
7321 // on Darwin.
7322 if (!Args.hasFlag(options::OPT_fconstant_cfstrings,
7323 options::OPT_fno_constant_cfstrings, true) ||
7324 !Args.hasFlag(options::OPT_mconstant_cfstrings,
7325 options::OPT_mno_constant_cfstrings, true))
7326 CmdArgs.push_back(Elt: "-fno-constant-cfstrings");
7327
7328 Args.addOptInFlag(CmdArgs, options::OPT_fpascal_strings,
7329 options::OPT_fno_pascal_strings);
7330
7331 // Honor -fpack-struct= and -fpack-struct, if given. Note that
7332 // -fno-pack-struct doesn't apply to -fpack-struct=.
7333 if (Arg *A = Args.getLastArg(options::OPT_fpack_struct_EQ)) {
7334 std::string PackStructStr = "-fpack-struct=";
7335 PackStructStr += A->getValue();
7336 CmdArgs.push_back(Elt: Args.MakeArgString(Str: PackStructStr));
7337 } else if (Args.hasFlag(options::OPT_fpack_struct,
7338 options::OPT_fno_pack_struct, false)) {
7339 CmdArgs.push_back(Elt: "-fpack-struct=1");
7340 }
7341
7342 // Handle -fmax-type-align=N and -fno-type-align
7343 bool SkipMaxTypeAlign = Args.hasArg(options::OPT_fno_max_type_align);
7344 if (Arg *A = Args.getLastArg(options::OPT_fmax_type_align_EQ)) {
7345 if (!SkipMaxTypeAlign) {
7346 std::string MaxTypeAlignStr = "-fmax-type-align=";
7347 MaxTypeAlignStr += A->getValue();
7348 CmdArgs.push_back(Elt: Args.MakeArgString(Str: MaxTypeAlignStr));
7349 }
7350 } else if (RawTriple.isOSDarwin()) {
7351 if (!SkipMaxTypeAlign) {
7352 std::string MaxTypeAlignStr = "-fmax-type-align=16";
7353 CmdArgs.push_back(Elt: Args.MakeArgString(Str: MaxTypeAlignStr));
7354 }
7355 }
7356
7357 if (!Args.hasFlag(options::OPT_Qy, options::OPT_Qn, true))
7358 CmdArgs.push_back(Elt: "-Qn");
7359
7360 // -fno-common is the default, set -fcommon only when that flag is set.
7361 Args.addOptInFlag(CmdArgs, options::OPT_fcommon, options::OPT_fno_common);
7362
7363 // -fsigned-bitfields is default, and clang doesn't yet support
7364 // -funsigned-bitfields.
7365 if (!Args.hasFlag(options::OPT_fsigned_bitfields,
7366 options::OPT_funsigned_bitfields, true))
7367 D.Diag(diag::warn_drv_clang_unsupported)
7368 << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args);
7369
7370 // -fsigned-bitfields is default, and clang doesn't support -fno-for-scope.
7371 if (!Args.hasFlag(options::OPT_ffor_scope, options::OPT_fno_for_scope, true))
7372 D.Diag(diag::err_drv_clang_unsupported)
7373 << Args.getLastArg(options::OPT_fno_for_scope)->getAsString(Args);
7374
7375 // -finput_charset=UTF-8 is default. Reject others
7376 if (Arg *inputCharset = Args.getLastArg(options::OPT_finput_charset_EQ)) {
7377 StringRef value = inputCharset->getValue();
7378 if (!value.equals_insensitive("utf-8"))
7379 D.Diag(diag::err_drv_invalid_value) << inputCharset->getAsString(Args)
7380 << value;
7381 }
7382
7383 // -fexec_charset=UTF-8 is default. Reject others
7384 if (Arg *execCharset = Args.getLastArg(options::OPT_fexec_charset_EQ)) {
7385 StringRef value = execCharset->getValue();
7386 if (!value.equals_insensitive("utf-8"))
7387 D.Diag(diag::err_drv_invalid_value) << execCharset->getAsString(Args)
7388 << value;
7389 }
7390
7391 RenderDiagnosticsOptions(D, Args, CmdArgs);
7392
7393 Args.addOptInFlag(CmdArgs, options::OPT_fasm_blocks,
7394 options::OPT_fno_asm_blocks);
7395
7396 Args.addOptOutFlag(CmdArgs, options::OPT_fgnu_inline_asm,
7397 options::OPT_fno_gnu_inline_asm);
7398
7399 // Enable vectorization per default according to the optimization level
7400 // selected. For optimization levels that want vectorization we use the alias
7401 // option to simplify the hasFlag logic.
7402 bool EnableVec = shouldEnableVectorizerAtOLevel(Args, isSlpVec: false);
7403 OptSpecifier VectorizeAliasOption =
7404 EnableVec ? options::OPT_O_Group : options::OPT_fvectorize;
7405 if (Args.hasFlag(options::OPT_fvectorize, VectorizeAliasOption,
7406 options::OPT_fno_vectorize, EnableVec))
7407 CmdArgs.push_back(Elt: "-vectorize-loops");
7408
7409 // -fslp-vectorize is enabled based on the optimization level selected.
7410 bool EnableSLPVec = shouldEnableVectorizerAtOLevel(Args, isSlpVec: true);
7411 OptSpecifier SLPVectAliasOption =
7412 EnableSLPVec ? options::OPT_O_Group : options::OPT_fslp_vectorize;
7413 if (Args.hasFlag(options::OPT_fslp_vectorize, SLPVectAliasOption,
7414 options::OPT_fno_slp_vectorize, EnableSLPVec))
7415 CmdArgs.push_back(Elt: "-vectorize-slp");
7416
7417 ParseMPreferVectorWidth(D, Args, CmdArgs);
7418
7419 Args.AddLastArg(CmdArgs, options::OPT_fshow_overloads_EQ);
7420 Args.AddLastArg(CmdArgs,
7421 options::OPT_fsanitize_undefined_strip_path_components_EQ);
7422
7423 // -fdollars-in-identifiers default varies depending on platform and
7424 // language; only pass if specified.
7425 if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
7426 options::OPT_fno_dollars_in_identifiers)) {
7427 if (A->getOption().matches(options::OPT_fdollars_in_identifiers))
7428 CmdArgs.push_back(Elt: "-fdollars-in-identifiers");
7429 else
7430 CmdArgs.push_back(Elt: "-fno-dollars-in-identifiers");
7431 }
7432
7433 Args.addOptInFlag(CmdArgs, options::OPT_fapple_pragma_pack,
7434 options::OPT_fno_apple_pragma_pack);
7435
7436 // Remarks can be enabled with any of the `-f.*optimization-record.*` flags.
7437 if (willEmitRemarks(Args) && checkRemarksOptions(D, Args, Triple))
7438 renderRemarksOptions(Args, CmdArgs, Triple, Input, Output, JA);
7439
7440 bool RewriteImports = Args.hasFlag(options::OPT_frewrite_imports,
7441 options::OPT_fno_rewrite_imports, false);
7442 if (RewriteImports)
7443 CmdArgs.push_back(Elt: "-frewrite-imports");
7444
7445 Args.addOptInFlag(CmdArgs, options::OPT_fdirectives_only,
7446 options::OPT_fno_directives_only);
7447
7448 // Enable rewrite includes if the user's asked for it or if we're generating
7449 // diagnostics.
7450 // TODO: Once -module-dependency-dir works with -frewrite-includes it'd be
7451 // nice to enable this when doing a crashdump for modules as well.
7452 if (Args.hasFlag(options::OPT_frewrite_includes,
7453 options::OPT_fno_rewrite_includes, false) ||
7454 (C.isForDiagnostics() && !HaveModules))
7455 CmdArgs.push_back(Elt: "-frewrite-includes");
7456
7457 // Only allow -traditional or -traditional-cpp outside in preprocessing modes.
7458 if (Arg *A = Args.getLastArg(options::OPT_traditional,
7459 options::OPT_traditional_cpp)) {
7460 if (isa<PreprocessJobAction>(Val: JA))
7461 CmdArgs.push_back(Elt: "-traditional-cpp");
7462 else
7463 D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
7464 }
7465
7466 Args.AddLastArg(CmdArgs, options::OPT_dM);
7467 Args.AddLastArg(CmdArgs, options::OPT_dD);
7468 Args.AddLastArg(CmdArgs, options::OPT_dI);
7469
7470 Args.AddLastArg(CmdArgs, options::OPT_fmax_tokens_EQ);
7471
7472 // Handle serialized diagnostics.
7473 if (Arg *A = Args.getLastArg(options::OPT__serialize_diags)) {
7474 CmdArgs.push_back(Elt: "-serialize-diagnostic-file");
7475 CmdArgs.push_back(Elt: Args.MakeArgString(Str: A->getValue()));
7476 }
7477
7478 if (Args.hasArg(options::OPT_fretain_comments_from_system_headers))
7479 CmdArgs.push_back(Elt: "-fretain-comments-from-system-headers");
7480
7481 // Forward -fcomment-block-commands to -cc1.
7482 Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands);
7483 // Forward -fparse-all-comments to -cc1.
7484 Args.AddAllArgs(CmdArgs, options::OPT_fparse_all_comments);
7485
7486 // Turn -fplugin=name.so into -load name.so
7487 for (const Arg *A : Args.filtered(options::OPT_fplugin_EQ)) {
7488 CmdArgs.push_back("-load");
7489 CmdArgs.push_back(A->getValue());
7490 A->claim();
7491 }
7492
7493 // Turn -fplugin-arg-pluginname-key=value into
7494 // -plugin-arg-pluginname key=value
7495 // GCC has an actual plugin_argument struct with key/value pairs that it
7496 // passes to its plugins, but we don't, so just pass it on as-is.
7497 //
7498 // The syntax for -fplugin-arg- is ambiguous if both plugin name and
7499 // argument key are allowed to contain dashes. GCC therefore only
7500 // allows dashes in the key. We do the same.
7501 for (const Arg *A : Args.filtered(options::OPT_fplugin_arg)) {
7502 auto ArgValue = StringRef(A->getValue());
7503 auto FirstDashIndex = ArgValue.find('-');
7504 StringRef PluginName = ArgValue.substr(0, FirstDashIndex);
7505 StringRef Arg = ArgValue.substr(FirstDashIndex + 1);
7506
7507 A->claim();
7508 if (FirstDashIndex == StringRef::npos || Arg.empty()) {
7509 if (PluginName.empty()) {
7510 D.Diag(diag::warn_drv_missing_plugin_name) << A->getAsString(Args);
7511 } else {
7512 D.Diag(diag::warn_drv_missing_plugin_arg)
7513 << PluginName << A->getAsString(Args);
7514 }
7515 continue;
7516 }
7517
7518 CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-arg-") + PluginName));
7519 CmdArgs.push_back(Args.MakeArgString(Arg));
7520 }
7521
7522 // Forward -fpass-plugin=name.so to -cc1.
7523 for (const Arg *A : Args.filtered(options::OPT_fpass_plugin_EQ)) {
7524 CmdArgs.push_back(
7525 Args.MakeArgString(Twine("-fpass-plugin=") + A->getValue()));
7526 A->claim();
7527 }
7528
7529 // Forward --vfsoverlay to -cc1.
7530 for (const Arg *A : Args.filtered(options::OPT_vfsoverlay)) {
7531 CmdArgs.push_back("--vfsoverlay");
7532 CmdArgs.push_back(A->getValue());
7533 A->claim();
7534 }
7535
7536 Args.addOptInFlag(CmdArgs, options::OPT_fsafe_buffer_usage_suggestions,
7537 options::OPT_fno_safe_buffer_usage_suggestions);
7538
7539 // Setup statistics file output.
7540 SmallString<128> StatsFile = getStatsFileName(Args, Output, Input, D);
7541 if (!StatsFile.empty()) {
7542 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Twine("-stats-file=") + StatsFile));
7543 if (D.CCPrintInternalStats)
7544 CmdArgs.push_back(Elt: "-stats-file-append");
7545 }
7546
7547 // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
7548 // parser.
7549 for (auto Arg : Args.filtered(options::OPT_Xclang)) {
7550 Arg->claim();
7551 // -finclude-default-header flag is for preprocessor,
7552 // do not pass it to other cc1 commands when save-temps is enabled
7553 if (C.getDriver().isSaveTempsEnabled() &&
7554 !isa<PreprocessJobAction>(JA)) {
7555 if (StringRef(Arg->getValue()) == "-finclude-default-header")
7556 continue;
7557 }
7558 CmdArgs.push_back(Arg->getValue());
7559 }
7560 for (const Arg *A : Args.filtered(options::OPT_mllvm)) {
7561 A->claim();
7562
7563 // We translate this by hand to the -cc1 argument, since nightly test uses
7564 // it and developers have been trained to spell it with -mllvm. Both
7565 // spellings are now deprecated and should be removed.
7566 if (StringRef(A->getValue(0)) == "-disable-llvm-optzns") {
7567 CmdArgs.push_back("-disable-llvm-optzns");
7568 } else {
7569 A->render(Args, CmdArgs);
7570 }
7571 }
7572
7573 // With -save-temps, we want to save the unoptimized bitcode output from the
7574 // CompileJobAction, use -disable-llvm-passes to get pristine IR generated
7575 // by the frontend.
7576 // When -fembed-bitcode is enabled, optimized bitcode is emitted because it
7577 // has slightly different breakdown between stages.
7578 // FIXME: -fembed-bitcode -save-temps will save optimized bitcode instead of
7579 // pristine IR generated by the frontend. Ideally, a new compile action should
7580 // be added so both IR can be captured.
7581 if ((C.getDriver().isSaveTempsEnabled() ||
7582 JA.isHostOffloading(OKind: Action::OFK_OpenMP)) &&
7583 !(C.getDriver().embedBitcodeInObject() && !IsUsingLTO) &&
7584 isa<CompileJobAction>(Val: JA))
7585 CmdArgs.push_back(Elt: "-disable-llvm-passes");
7586
7587 Args.AddAllArgs(CmdArgs, options::OPT_undef);
7588
7589 const char *Exec = D.getClangProgramPath();
7590
7591 // Optionally embed the -cc1 level arguments into the debug info or a
7592 // section, for build analysis.
7593 // Also record command line arguments into the debug info if
7594 // -grecord-gcc-switches options is set on.
7595 // By default, -gno-record-gcc-switches is set on and no recording.
7596 auto GRecordSwitches =
7597 Args.hasFlag(options::OPT_grecord_command_line,
7598 options::OPT_gno_record_command_line, false);
7599 auto FRecordSwitches =
7600 Args.hasFlag(options::OPT_frecord_command_line,
7601 options::OPT_fno_record_command_line, false);
7602 if (FRecordSwitches && !Triple.isOSBinFormatELF() &&
7603 !Triple.isOSBinFormatXCOFF() && !Triple.isOSBinFormatMachO())
7604 D.Diag(diag::err_drv_unsupported_opt_for_target)
7605 << Args.getLastArg(options::OPT_frecord_command_line)->getAsString(Args)
7606 << TripleStr;
7607 if (TC.UseDwarfDebugFlags() || GRecordSwitches || FRecordSwitches) {
7608 ArgStringList OriginalArgs;
7609 for (const auto &Arg : Args)
7610 Arg->render(Args, Output&: OriginalArgs);
7611
7612 SmallString<256> Flags;
7613 EscapeSpacesAndBackslashes(Arg: Exec, Res&: Flags);
7614 for (const char *OriginalArg : OriginalArgs) {
7615 SmallString<128> EscapedArg;
7616 EscapeSpacesAndBackslashes(Arg: OriginalArg, Res&: EscapedArg);
7617 Flags += " ";
7618 Flags += EscapedArg;
7619 }
7620 auto FlagsArgString = Args.MakeArgString(Str: Flags);
7621 if (TC.UseDwarfDebugFlags() || GRecordSwitches) {
7622 CmdArgs.push_back(Elt: "-dwarf-debug-flags");
7623 CmdArgs.push_back(Elt: FlagsArgString);
7624 }
7625 if (FRecordSwitches) {
7626 CmdArgs.push_back(Elt: "-record-command-line");
7627 CmdArgs.push_back(Elt: FlagsArgString);
7628 }
7629 }
7630
7631 // Host-side offloading compilation receives all device-side outputs. Include
7632 // them in the host compilation depending on the target. If the host inputs
7633 // are not empty we use the new-driver scheme, otherwise use the old scheme.
7634 if ((IsCuda || IsHIP) && CudaDeviceInput) {
7635 CmdArgs.push_back(Elt: "-fcuda-include-gpubinary");
7636 CmdArgs.push_back(Elt: CudaDeviceInput->getFilename());
7637 } else if (!HostOffloadingInputs.empty()) {
7638 if ((IsCuda || IsHIP) && !IsRDCMode) {
7639 assert(HostOffloadingInputs.size() == 1 && "Only one input expected");
7640 CmdArgs.push_back(Elt: "-fcuda-include-gpubinary");
7641 CmdArgs.push_back(Elt: HostOffloadingInputs.front().getFilename());
7642 } else {
7643 for (const InputInfo Input : HostOffloadingInputs)
7644 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-fembed-offload-object=" +
7645 TC.getInputFilename(Input)));
7646 }
7647 }
7648
7649 if (IsCuda) {
7650 if (Args.hasFlag(options::OPT_fcuda_short_ptr,
7651 options::OPT_fno_cuda_short_ptr, false))
7652 CmdArgs.push_back(Elt: "-fcuda-short-ptr");
7653 }
7654
7655 if (IsCuda || IsHIP) {
7656 // Determine the original source input.
7657 const Action *SourceAction = &JA;
7658 while (SourceAction->getKind() != Action::InputClass) {
7659 assert(!SourceAction->getInputs().empty() && "unexpected root action!");
7660 SourceAction = SourceAction->getInputs()[0];
7661 }
7662 auto CUID = cast<InputAction>(Val: SourceAction)->getId();
7663 if (!CUID.empty())
7664 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Twine("-cuid=") + Twine(CUID)));
7665
7666 // -ffast-math turns on -fgpu-approx-transcendentals implicitly, but will
7667 // be overriden by -fno-gpu-approx-transcendentals.
7668 bool UseApproxTranscendentals = Args.hasFlag(
7669 options::OPT_ffast_math, options::OPT_fno_fast_math, false);
7670 if (Args.hasFlag(options::OPT_fgpu_approx_transcendentals,
7671 options::OPT_fno_gpu_approx_transcendentals,
7672 UseApproxTranscendentals))
7673 CmdArgs.push_back(Elt: "-fgpu-approx-transcendentals");
7674 } else {
7675 Args.claimAllArgs(options::OPT_fgpu_approx_transcendentals,
7676 options::OPT_fno_gpu_approx_transcendentals);
7677 }
7678
7679 if (IsHIP) {
7680 CmdArgs.push_back(Elt: "-fcuda-allow-variadic-functions");
7681 Args.AddLastArg(CmdArgs, options::OPT_fgpu_default_stream_EQ);
7682 }
7683
7684 Args.AddLastArg(CmdArgs, options::OPT_foffload_uniform_block,
7685 options::OPT_fno_offload_uniform_block);
7686
7687 Args.AddLastArg(CmdArgs, options::OPT_foffload_implicit_host_device_templates,
7688 options::OPT_fno_offload_implicit_host_device_templates);
7689
7690 if (IsCudaDevice || IsHIPDevice) {
7691 StringRef InlineThresh =
7692 Args.getLastArgValue(options::OPT_fgpu_inline_threshold_EQ);
7693 if (!InlineThresh.empty()) {
7694 std::string ArgStr =
7695 std::string("-inline-threshold=") + InlineThresh.str();
7696 CmdArgs.append(IL: {"-mllvm", Args.MakeArgStringRef(Str: ArgStr)});
7697 }
7698 }
7699
7700 if (IsHIPDevice)
7701 Args.addOptOutFlag(CmdArgs,
7702 options::OPT_fhip_fp32_correctly_rounded_divide_sqrt,
7703 options::OPT_fno_hip_fp32_correctly_rounded_divide_sqrt);
7704
7705 // OpenMP offloading device jobs take the argument -fopenmp-host-ir-file-path
7706 // to specify the result of the compile phase on the host, so the meaningful
7707 // device declarations can be identified. Also, -fopenmp-is-target-device is
7708 // passed along to tell the frontend that it is generating code for a device,
7709 // so that only the relevant declarations are emitted.
7710 if (IsOpenMPDevice) {
7711 CmdArgs.push_back(Elt: "-fopenmp-is-target-device");
7712 if (OpenMPDeviceInput) {
7713 CmdArgs.push_back(Elt: "-fopenmp-host-ir-file-path");
7714 CmdArgs.push_back(Elt: Args.MakeArgString(Str: OpenMPDeviceInput->getFilename()));
7715 }
7716 }
7717
7718 if (Triple.isAMDGPU()) {
7719 handleAMDGPUCodeObjectVersionOptions(D, Args, CmdArgs);
7720
7721 Args.addOptInFlag(CmdArgs, options::OPT_munsafe_fp_atomics,
7722 options::OPT_mno_unsafe_fp_atomics);
7723 Args.addOptOutFlag(CmdArgs, options::OPT_mamdgpu_ieee,
7724 options::OPT_mno_amdgpu_ieee);
7725 }
7726
7727 // For all the host OpenMP offloading compile jobs we need to pass the targets
7728 // information using -fopenmp-targets= option.
7729 if (JA.isHostOffloading(OKind: Action::OFK_OpenMP)) {
7730 SmallString<128> Targets("-fopenmp-targets=");
7731
7732 SmallVector<std::string, 4> Triples;
7733 auto TCRange = C.getOffloadToolChains<Action::OFK_OpenMP>();
7734 std::transform(first: TCRange.first, last: TCRange.second, result: std::back_inserter(x&: Triples),
7735 unary_op: [](auto TC) { return TC.second->getTripleString(); });
7736 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Targets + llvm::join(R&: Triples, Separator: ",")));
7737 }
7738
7739 bool VirtualFunctionElimination =
7740 Args.hasFlag(options::OPT_fvirtual_function_elimination,
7741 options::OPT_fno_virtual_function_elimination, false);
7742 if (VirtualFunctionElimination) {
7743 // VFE requires full LTO (currently, this might be relaxed to allow ThinLTO
7744 // in the future).
7745 if (LTOMode != LTOK_Full)
7746 D.Diag(diag::err_drv_argument_only_allowed_with)
7747 << "-fvirtual-function-elimination"
7748 << "-flto=full";
7749
7750 CmdArgs.push_back(Elt: "-fvirtual-function-elimination");
7751 }
7752
7753 // VFE requires whole-program-vtables, and enables it by default.
7754 bool WholeProgramVTables = Args.hasFlag(
7755 options::OPT_fwhole_program_vtables,
7756 options::OPT_fno_whole_program_vtables, VirtualFunctionElimination);
7757 if (VirtualFunctionElimination && !WholeProgramVTables) {
7758 D.Diag(diag::err_drv_argument_not_allowed_with)
7759 << "-fno-whole-program-vtables"
7760 << "-fvirtual-function-elimination";
7761 }
7762
7763 if (WholeProgramVTables) {
7764 // PS4 uses the legacy LTO API, which does not support this feature in
7765 // ThinLTO mode.
7766 bool IsPS4 = getToolChain().getTriple().isPS4();
7767
7768 // Check if we passed LTO options but they were suppressed because this is a
7769 // device offloading action, or we passed device offload LTO options which
7770 // were suppressed because this is not the device offload action.
7771 // Check if we are using PS4 in regular LTO mode.
7772 // Otherwise, issue an error.
7773 if ((!IsUsingLTO && !D.isUsingLTO(!IsDeviceOffloadAction)) ||
7774 (IsPS4 && !UnifiedLTO && (D.getLTOMode() != LTOK_Full)))
7775 D.Diag(diag::err_drv_argument_only_allowed_with)
7776 << "-fwhole-program-vtables"
7777 << ((IsPS4 && !UnifiedLTO) ? "-flto=full" : "-flto");
7778
7779 // Propagate -fwhole-program-vtables if this is an LTO compile.
7780 if (IsUsingLTO)
7781 CmdArgs.push_back(Elt: "-fwhole-program-vtables");
7782 }
7783
7784 bool DefaultsSplitLTOUnit =
7785 ((WholeProgramVTables || SanitizeArgs.needsLTO()) &&
7786 (LTOMode == LTOK_Full || TC.canSplitThinLTOUnit())) ||
7787 (!Triple.isPS4() && UnifiedLTO);
7788 bool SplitLTOUnit =
7789 Args.hasFlag(options::OPT_fsplit_lto_unit,
7790 options::OPT_fno_split_lto_unit, DefaultsSplitLTOUnit);
7791 if (SanitizeArgs.needsLTO() && !SplitLTOUnit)
7792 D.Diag(diag::err_drv_argument_not_allowed_with) << "-fno-split-lto-unit"
7793 << "-fsanitize=cfi";
7794 if (SplitLTOUnit)
7795 CmdArgs.push_back(Elt: "-fsplit-lto-unit");
7796
7797 if (Arg *A = Args.getLastArg(options::OPT_ffat_lto_objects,
7798 options::OPT_fno_fat_lto_objects)) {
7799 if (IsUsingLTO && A->getOption().matches(options::OPT_ffat_lto_objects)) {
7800 assert(LTOMode == LTOK_Full || LTOMode == LTOK_Thin);
7801 if (!Triple.isOSBinFormatELF()) {
7802 D.Diag(diag::err_drv_unsupported_opt_for_target)
7803 << A->getAsString(Args) << TC.getTripleString();
7804 }
7805 CmdArgs.push_back(Elt: Args.MakeArgString(
7806 Str: Twine("-flto=") + (LTOMode == LTOK_Thin ? "thin" : "full")));
7807 CmdArgs.push_back(Elt: "-flto-unit");
7808 CmdArgs.push_back(Elt: "-ffat-lto-objects");
7809 A->render(Args, Output&: CmdArgs);
7810 }
7811 }
7812
7813 if (Arg *A = Args.getLastArg(options::OPT_fglobal_isel,
7814 options::OPT_fno_global_isel)) {
7815 CmdArgs.push_back(Elt: "-mllvm");
7816 if (A->getOption().matches(options::OPT_fglobal_isel)) {
7817 CmdArgs.push_back(Elt: "-global-isel=1");
7818
7819 // GISel is on by default on AArch64 -O0, so don't bother adding
7820 // the fallback remarks for it. Other combinations will add a warning of
7821 // some kind.
7822 bool IsArchSupported = Triple.getArch() == llvm::Triple::aarch64;
7823 bool IsOptLevelSupported = false;
7824
7825 Arg *A = Args.getLastArg(options::OPT_O_Group);
7826 if (Triple.getArch() == llvm::Triple::aarch64) {
7827 if (!A || A->getOption().matches(options::OPT_O0))
7828 IsOptLevelSupported = true;
7829 }
7830 if (!IsArchSupported || !IsOptLevelSupported) {
7831 CmdArgs.push_back(Elt: "-mllvm");
7832 CmdArgs.push_back(Elt: "-global-isel-abort=2");
7833
7834 if (!IsArchSupported)
7835 D.Diag(diag::warn_drv_global_isel_incomplete) << Triple.getArchName();
7836 else
7837 D.Diag(diag::warn_drv_global_isel_incomplete_opt);
7838 }
7839 } else {
7840 CmdArgs.push_back(Elt: "-global-isel=0");
7841 }
7842 }
7843
7844 if (Args.hasArg(options::OPT_forder_file_instrumentation)) {
7845 CmdArgs.push_back(Elt: "-forder-file-instrumentation");
7846 // Enable order file instrumentation when ThinLTO is not on. When ThinLTO is
7847 // on, we need to pass these flags as linker flags and that will be handled
7848 // outside of the compiler.
7849 if (!IsUsingLTO) {
7850 CmdArgs.push_back(Elt: "-mllvm");
7851 CmdArgs.push_back(Elt: "-enable-order-file-instrumentation");
7852 }
7853 }
7854
7855 if (Arg *A = Args.getLastArg(options::OPT_fforce_enable_int128,
7856 options::OPT_fno_force_enable_int128)) {
7857 if (A->getOption().matches(options::OPT_fforce_enable_int128))
7858 CmdArgs.push_back(Elt: "-fforce-enable-int128");
7859 }
7860
7861 Args.addOptInFlag(CmdArgs, options::OPT_fkeep_static_consts,
7862 options::OPT_fno_keep_static_consts);
7863 Args.addOptInFlag(CmdArgs, options::OPT_fkeep_persistent_storage_variables,
7864 options::OPT_fno_keep_persistent_storage_variables);
7865 Args.addOptInFlag(CmdArgs, options::OPT_fcomplete_member_pointers,
7866 options::OPT_fno_complete_member_pointers);
7867 Args.addOptOutFlag(CmdArgs, options::OPT_fcxx_static_destructors,
7868 options::OPT_fno_cxx_static_destructors);
7869
7870 addMachineOutlinerArgs(D, Args, CmdArgs, Triple, /*IsLTO=*/false);
7871
7872 addOutlineAtomicsArgs(D, TC: getToolChain(), Args, CmdArgs, Triple);
7873
7874 if (Triple.isAArch64() &&
7875 (Args.hasArg(options::OPT_mno_fmv) ||
7876 (Triple.isAndroid() && Triple.isAndroidVersionLT(23)) ||
7877 getToolChain().GetRuntimeLibType(Args) != ToolChain::RLT_CompilerRT)) {
7878 // Disable Function Multiversioning on AArch64 target.
7879 CmdArgs.push_back(Elt: "-target-feature");
7880 CmdArgs.push_back(Elt: "-fmv");
7881 }
7882
7883 if (Args.hasFlag(options::OPT_faddrsig, options::OPT_fno_addrsig,
7884 (TC.getTriple().isOSBinFormatELF() ||
7885 TC.getTriple().isOSBinFormatCOFF()) &&
7886 !TC.getTriple().isPS4() && !TC.getTriple().isVE() &&
7887 !TC.getTriple().isOSNetBSD() &&
7888 !Distro(D.getVFS(), TC.getTriple()).IsGentoo() &&
7889 !TC.getTriple().isAndroid() && TC.useIntegratedAs()))
7890 CmdArgs.push_back(Elt: "-faddrsig");
7891
7892 if ((Triple.isOSBinFormatELF() || Triple.isOSBinFormatMachO()) &&
7893 (EH || UnwindTables || AsyncUnwindTables ||
7894 DebugInfoKind != llvm::codegenoptions::NoDebugInfo))
7895 CmdArgs.push_back(Elt: "-D__GCC_HAVE_DWARF2_CFI_ASM=1");
7896
7897 if (Arg *A = Args.getLastArg(options::OPT_fsymbol_partition_EQ)) {
7898 std::string Str = A->getAsString(Args);
7899 if (!TC.getTriple().isOSBinFormatELF())
7900 D.Diag(diag::err_drv_unsupported_opt_for_target)
7901 << Str << TC.getTripleString();
7902 CmdArgs.push_back(Elt: Args.MakeArgString(Str));
7903 }
7904
7905 // Add the "-o out -x type src.c" flags last. This is done primarily to make
7906 // the -cc1 command easier to edit when reproducing compiler crashes.
7907 if (Output.getType() == types::TY_Dependencies) {
7908 // Handled with other dependency code.
7909 } else if (Output.isFilename()) {
7910 if (Output.getType() == clang::driver::types::TY_IFS_CPP ||
7911 Output.getType() == clang::driver::types::TY_IFS) {
7912 SmallString<128> OutputFilename(Output.getFilename());
7913 llvm::sys::path::replace_extension(path&: OutputFilename, extension: "ifs");
7914 CmdArgs.push_back(Elt: "-o");
7915 CmdArgs.push_back(Elt: Args.MakeArgString(Str: OutputFilename));
7916 } else {
7917 CmdArgs.push_back(Elt: "-o");
7918 CmdArgs.push_back(Elt: Output.getFilename());
7919 }
7920 } else {
7921 assert(Output.isNothing() && "Invalid output.");
7922 }
7923
7924 addDashXForInput(Args, Input, CmdArgs);
7925
7926 ArrayRef<InputInfo> FrontendInputs = Input;
7927 if (IsExtractAPI)
7928 FrontendInputs = ExtractAPIInputs;
7929 else if (Input.isNothing())
7930 FrontendInputs = {};
7931
7932 for (const InputInfo &Input : FrontendInputs) {
7933 if (Input.isFilename())
7934 CmdArgs.push_back(Elt: Input.getFilename());
7935 else
7936 Input.getInputArg().renderAsInput(Args, Output&: CmdArgs);
7937 }
7938
7939 if (D.CC1Main && !D.CCGenDiagnostics) {
7940 // Invoke the CC1 directly in this process
7941 C.addCommand(C: std::make_unique<CC1Command>(
7942 args: JA, args: *this, args: ResponseFileSupport::AtFileUTF8(), args&: Exec, args&: CmdArgs, args: Inputs,
7943 args: Output, args: D.getPrependArg()));
7944 } else {
7945 C.addCommand(C: std::make_unique<Command>(
7946 args: JA, args: *this, args: ResponseFileSupport::AtFileUTF8(), args&: Exec, args&: CmdArgs, args: Inputs,
7947 args: Output, args: D.getPrependArg()));
7948 }
7949
7950 // Make the compile command echo its inputs for /showFilenames.
7951 if (Output.getType() == types::TY_Object &&
7952 Args.hasFlag(options::OPT__SLASH_showFilenames,
7953 options::OPT__SLASH_showFilenames_, false)) {
7954 C.getJobs().getJobs().back()->PrintInputFilenames = true;
7955 }
7956
7957 if (Arg *A = Args.getLastArg(options::OPT_pg))
7958 if (FPKeepKind == CodeGenOptions::FramePointerKind::None &&
7959 !Args.hasArg(options::OPT_mfentry))
7960 D.Diag(diag::err_drv_argument_not_allowed_with) << "-fomit-frame-pointer"
7961 << A->getAsString(Args);
7962
7963 // Claim some arguments which clang supports automatically.
7964
7965 // -fpch-preprocess is used with gcc to add a special marker in the output to
7966 // include the PCH file.
7967 Args.ClaimAllArgs(options::OPT_fpch_preprocess);
7968
7969 // Claim some arguments which clang doesn't support, but we don't
7970 // care to warn the user about.
7971 Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group);
7972 Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group);
7973
7974 // Disable warnings for clang -E -emit-llvm foo.c
7975 Args.ClaimAllArgs(options::OPT_emit_llvm);
7976}
7977
7978Clang::Clang(const ToolChain &TC, bool HasIntegratedBackend)
7979 // CAUTION! The first constructor argument ("clang") is not arbitrary,
7980 // as it is for other tools. Some operations on a Tool actually test
7981 // whether that tool is Clang based on the Tool's Name as a string.
7982 : Tool("clang", "clang frontend", TC), HasBackend(HasIntegratedBackend) {}
7983
7984Clang::~Clang() {}
7985
7986/// Add options related to the Objective-C runtime/ABI.
7987///
7988/// Returns true if the runtime is non-fragile.
7989ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
7990 const InputInfoList &inputs,
7991 ArgStringList &cmdArgs,
7992 RewriteKind rewriteKind) const {
7993 // Look for the controlling runtime option.
7994 Arg *runtimeArg =
7995 args.getLastArg(options::OPT_fnext_runtime, options::OPT_fgnu_runtime,
7996 options::OPT_fobjc_runtime_EQ);
7997
7998 // Just forward -fobjc-runtime= to the frontend. This supercedes
7999 // options about fragility.
8000 if (runtimeArg &&
8001 runtimeArg->getOption().matches(options::OPT_fobjc_runtime_EQ)) {
8002 ObjCRuntime runtime;
8003 StringRef value = runtimeArg->getValue();
8004 if (runtime.tryParse(input: value)) {
8005 getToolChain().getDriver().Diag(diag::err_drv_unknown_objc_runtime)
8006 << value;
8007 }
8008 if ((runtime.getKind() == ObjCRuntime::GNUstep) &&
8009 (runtime.getVersion() >= VersionTuple(2, 0)))
8010 if (!getToolChain().getTriple().isOSBinFormatELF() &&
8011 !getToolChain().getTriple().isOSBinFormatCOFF()) {
8012 getToolChain().getDriver().Diag(
8013 diag::err_drv_gnustep_objc_runtime_incompatible_binary)
8014 << runtime.getVersion().getMajor();
8015 }
8016
8017 runtimeArg->render(Args: args, Output&: cmdArgs);
8018 return runtime;
8019 }
8020
8021 // Otherwise, we'll need the ABI "version". Version numbers are
8022 // slightly confusing for historical reasons:
8023 // 1 - Traditional "fragile" ABI
8024 // 2 - Non-fragile ABI, version 1
8025 // 3 - Non-fragile ABI, version 2
8026 unsigned objcABIVersion = 1;
8027 // If -fobjc-abi-version= is present, use that to set the version.
8028 if (Arg *abiArg = args.getLastArg(options::OPT_fobjc_abi_version_EQ)) {
8029 StringRef value = abiArg->getValue();
8030 if (value == "1")
8031 objcABIVersion = 1;
8032 else if (value == "2")
8033 objcABIVersion = 2;
8034 else if (value == "3")
8035 objcABIVersion = 3;
8036 else
8037 getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) << value;
8038 } else {
8039 // Otherwise, determine if we are using the non-fragile ABI.
8040 bool nonFragileABIIsDefault =
8041 (rewriteKind == RK_NonFragile ||
8042 (rewriteKind == RK_None &&
8043 getToolChain().IsObjCNonFragileABIDefault()));
8044 if (args.hasFlag(options::OPT_fobjc_nonfragile_abi,
8045 options::OPT_fno_objc_nonfragile_abi,
8046 nonFragileABIIsDefault)) {
8047// Determine the non-fragile ABI version to use.
8048#ifdef DISABLE_DEFAULT_NONFRAGILEABI_TWO
8049 unsigned nonFragileABIVersion = 1;
8050#else
8051 unsigned nonFragileABIVersion = 2;
8052#endif
8053
8054 if (Arg *abiArg =
8055 args.getLastArg(options::OPT_fobjc_nonfragile_abi_version_EQ)) {
8056 StringRef value = abiArg->getValue();
8057 if (value == "1")
8058 nonFragileABIVersion = 1;
8059 else if (value == "2")
8060 nonFragileABIVersion = 2;
8061 else
8062 getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
8063 << value;
8064 }
8065
8066 objcABIVersion = 1 + nonFragileABIVersion;
8067 } else {
8068 objcABIVersion = 1;
8069 }
8070 }
8071
8072 // We don't actually care about the ABI version other than whether
8073 // it's non-fragile.
8074 bool isNonFragile = objcABIVersion != 1;
8075
8076 // If we have no runtime argument, ask the toolchain for its default runtime.
8077 // However, the rewriter only really supports the Mac runtime, so assume that.
8078 ObjCRuntime runtime;
8079 if (!runtimeArg) {
8080 switch (rewriteKind) {
8081 case RK_None:
8082 runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
8083 break;
8084 case RK_Fragile:
8085 runtime = ObjCRuntime(ObjCRuntime::FragileMacOSX, VersionTuple());
8086 break;
8087 case RK_NonFragile:
8088 runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
8089 break;
8090 }
8091
8092 // -fnext-runtime
8093 } else if (runtimeArg->getOption().matches(options::OPT_fnext_runtime)) {
8094 // On Darwin, make this use the default behavior for the toolchain.
8095 if (getToolChain().getTriple().isOSDarwin()) {
8096 runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
8097
8098 // Otherwise, build for a generic macosx port.
8099 } else {
8100 runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
8101 }
8102
8103 // -fgnu-runtime
8104 } else {
8105 assert(runtimeArg->getOption().matches(options::OPT_fgnu_runtime));
8106 // Legacy behaviour is to target the gnustep runtime if we are in
8107 // non-fragile mode or the GCC runtime in fragile mode.
8108 if (isNonFragile)
8109 runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(2, 0));
8110 else
8111 runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple());
8112 }
8113
8114 if (llvm::any_of(Range: inputs, P: [](const InputInfo &input) {
8115 return types::isObjC(Id: input.getType());
8116 }))
8117 cmdArgs.push_back(
8118 Elt: args.MakeArgString(Str: "-fobjc-runtime=" + runtime.getAsString()));
8119 return runtime;
8120}
8121
8122static bool maybeConsumeDash(const std::string &EH, size_t &I) {
8123 bool HaveDash = (I + 1 < EH.size() && EH[I + 1] == '-');
8124 I += HaveDash;
8125 return !HaveDash;
8126}
8127
8128namespace {
8129struct EHFlags {
8130 bool Synch = false;
8131 bool Asynch = false;
8132 bool NoUnwindC = false;
8133};
8134} // end anonymous namespace
8135
8136/// /EH controls whether to run destructor cleanups when exceptions are
8137/// thrown. There are three modifiers:
8138/// - s: Cleanup after "synchronous" exceptions, aka C++ exceptions.
8139/// - a: Cleanup after "asynchronous" exceptions, aka structured exceptions.
8140/// The 'a' modifier is unimplemented and fundamentally hard in LLVM IR.
8141/// - c: Assume that extern "C" functions are implicitly nounwind.
8142/// The default is /EHs-c-, meaning cleanups are disabled.
8143static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args,
8144 bool isWindowsMSVC) {
8145 EHFlags EH;
8146
8147 std::vector<std::string> EHArgs =
8148 Args.getAllArgValues(options::OPT__SLASH_EH);
8149 for (auto EHVal : EHArgs) {
8150 for (size_t I = 0, E = EHVal.size(); I != E; ++I) {
8151 switch (EHVal[I]) {
8152 case 'a':
8153 EH.Asynch = maybeConsumeDash(EH: EHVal, I);
8154 if (EH.Asynch) {
8155 // Async exceptions are Windows MSVC only.
8156 if (!isWindowsMSVC) {
8157 EH.Asynch = false;
8158 D.Diag(clang::diag::warn_drv_unused_argument) << "/EHa" << EHVal;
8159 continue;
8160 }
8161 EH.Synch = false;
8162 }
8163 continue;
8164 case 'c':
8165 EH.NoUnwindC = maybeConsumeDash(EH: EHVal, I);
8166 continue;
8167 case 's':
8168 EH.Synch = maybeConsumeDash(EH: EHVal, I);
8169 if (EH.Synch)
8170 EH.Asynch = false;
8171 continue;
8172 default:
8173 break;
8174 }
8175 D.Diag(clang::diag::err_drv_invalid_value) << "/EH" << EHVal;
8176 break;
8177 }
8178 }
8179 // The /GX, /GX- flags are only processed if there are not /EH flags.
8180 // The default is that /GX is not specified.
8181 if (EHArgs.empty() &&
8182 Args.hasFlag(options::OPT__SLASH_GX, options::OPT__SLASH_GX_,
8183 /*Default=*/false)) {
8184 EH.Synch = true;
8185 EH.NoUnwindC = true;
8186 }
8187
8188 if (Args.hasArg(options::OPT__SLASH_kernel)) {
8189 EH.Synch = false;
8190 EH.NoUnwindC = false;
8191 EH.Asynch = false;
8192 }
8193
8194 return EH;
8195}
8196
8197void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
8198 ArgStringList &CmdArgs) const {
8199 bool isNVPTX = getToolChain().getTriple().isNVPTX();
8200
8201 ProcessVSRuntimeLibrary(TC: getToolChain(), Args, CmdArgs);
8202
8203 if (Arg *ShowIncludes =
8204 Args.getLastArg(options::OPT__SLASH_showIncludes,
8205 options::OPT__SLASH_showIncludes_user)) {
8206 CmdArgs.push_back(Elt: "--show-includes");
8207 if (ShowIncludes->getOption().matches(options::OPT__SLASH_showIncludes))
8208 CmdArgs.push_back(Elt: "-sys-header-deps");
8209 }
8210
8211 // This controls whether or not we emit RTTI data for polymorphic types.
8212 if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
8213 /*Default=*/false))
8214 CmdArgs.push_back(Elt: "-fno-rtti-data");
8215
8216 // This controls whether or not we emit stack-protector instrumentation.
8217 // In MSVC, Buffer Security Check (/GS) is on by default.
8218 if (!isNVPTX && Args.hasFlag(options::OPT__SLASH_GS, options::OPT__SLASH_GS_,
8219 /*Default=*/true)) {
8220 CmdArgs.push_back(Elt: "-stack-protector");
8221 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Twine(LangOptions::SSPStrong)));
8222 }
8223
8224 const Driver &D = getToolChain().getDriver();
8225
8226 bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment();
8227 EHFlags EH = parseClangCLEHFlags(D, Args, isWindowsMSVC: IsWindowsMSVC);
8228 if (!isNVPTX && (EH.Synch || EH.Asynch)) {
8229 if (types::isCXX(Id: InputType))
8230 CmdArgs.push_back(Elt: "-fcxx-exceptions");
8231 CmdArgs.push_back(Elt: "-fexceptions");
8232 if (EH.Asynch)
8233 CmdArgs.push_back(Elt: "-fasync-exceptions");
8234 }
8235 if (types::isCXX(Id: InputType) && EH.Synch && EH.NoUnwindC)
8236 CmdArgs.push_back(Elt: "-fexternc-nounwind");
8237
8238 // /EP should expand to -E -P.
8239 if (Args.hasArg(options::OPT__SLASH_EP)) {
8240 CmdArgs.push_back(Elt: "-E");
8241 CmdArgs.push_back(Elt: "-P");
8242 }
8243
8244 if (Args.hasFlag(options::OPT__SLASH_Zc_dllexportInlines_,
8245 options::OPT__SLASH_Zc_dllexportInlines,
8246 false)) {
8247 CmdArgs.push_back(Elt: "-fno-dllexport-inlines");
8248 }
8249
8250 if (Args.hasFlag(options::OPT__SLASH_Zc_wchar_t_,
8251 options::OPT__SLASH_Zc_wchar_t, false)) {
8252 CmdArgs.push_back(Elt: "-fno-wchar");
8253 }
8254
8255 if (Args.hasArg(options::OPT__SLASH_kernel)) {
8256 llvm::Triple::ArchType Arch = getToolChain().getArch();
8257 std::vector<std::string> Values =
8258 Args.getAllArgValues(options::OPT__SLASH_arch);
8259 if (!Values.empty()) {
8260 llvm::SmallSet<std::string, 4> SupportedArches;
8261 if (Arch == llvm::Triple::x86)
8262 SupportedArches.insert(V: "IA32");
8263
8264 for (auto &V : Values)
8265 if (!SupportedArches.contains(V))
8266 D.Diag(diag::err_drv_argument_not_allowed_with)
8267 << std::string("/arch:").append(V) << "/kernel";
8268 }
8269
8270 CmdArgs.push_back(Elt: "-fno-rtti");
8271 if (Args.hasFlag(options::OPT__SLASH_GR, options::OPT__SLASH_GR_, false))
8272 D.Diag(diag::err_drv_argument_not_allowed_with) << "/GR"
8273 << "/kernel";
8274 }
8275
8276 Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg);
8277 Arg *BestCaseArg = Args.getLastArg(options::OPT__SLASH_vmb);
8278 if (MostGeneralArg && BestCaseArg)
8279 D.Diag(clang::diag::err_drv_argument_not_allowed_with)
8280 << MostGeneralArg->getAsString(Args) << BestCaseArg->getAsString(Args);
8281
8282 if (MostGeneralArg) {
8283 Arg *SingleArg = Args.getLastArg(options::OPT__SLASH_vms);
8284 Arg *MultipleArg = Args.getLastArg(options::OPT__SLASH_vmm);
8285 Arg *VirtualArg = Args.getLastArg(options::OPT__SLASH_vmv);
8286
8287 Arg *FirstConflict = SingleArg ? SingleArg : MultipleArg;
8288 Arg *SecondConflict = VirtualArg ? VirtualArg : MultipleArg;
8289 if (FirstConflict && SecondConflict && FirstConflict != SecondConflict)
8290 D.Diag(clang::diag::err_drv_argument_not_allowed_with)
8291 << FirstConflict->getAsString(Args)
8292 << SecondConflict->getAsString(Args);
8293
8294 if (SingleArg)
8295 CmdArgs.push_back(Elt: "-fms-memptr-rep=single");
8296 else if (MultipleArg)
8297 CmdArgs.push_back(Elt: "-fms-memptr-rep=multiple");
8298 else
8299 CmdArgs.push_back(Elt: "-fms-memptr-rep=virtual");
8300 }
8301
8302 if (Args.hasArg(options::OPT_regcall4))
8303 CmdArgs.push_back(Elt: "-regcall4");
8304
8305 // Parse the default calling convention options.
8306 if (Arg *CCArg =
8307 Args.getLastArg(options::OPT__SLASH_Gd, options::OPT__SLASH_Gr,
8308 options::OPT__SLASH_Gz, options::OPT__SLASH_Gv,
8309 options::OPT__SLASH_Gregcall)) {
8310 unsigned DCCOptId = CCArg->getOption().getID();
8311 const char *DCCFlag = nullptr;
8312 bool ArchSupported = !isNVPTX;
8313 llvm::Triple::ArchType Arch = getToolChain().getArch();
8314 switch (DCCOptId) {
8315 case options::OPT__SLASH_Gd:
8316 DCCFlag = "-fdefault-calling-conv=cdecl";
8317 break;
8318 case options::OPT__SLASH_Gr:
8319 ArchSupported = Arch == llvm::Triple::x86;
8320 DCCFlag = "-fdefault-calling-conv=fastcall";
8321 break;
8322 case options::OPT__SLASH_Gz:
8323 ArchSupported = Arch == llvm::Triple::x86;
8324 DCCFlag = "-fdefault-calling-conv=stdcall";
8325 break;
8326 case options::OPT__SLASH_Gv:
8327 ArchSupported = Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64;
8328 DCCFlag = "-fdefault-calling-conv=vectorcall";
8329 break;
8330 case options::OPT__SLASH_Gregcall:
8331 ArchSupported = Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64;
8332 DCCFlag = "-fdefault-calling-conv=regcall";
8333 break;
8334 }
8335
8336 // MSVC doesn't warn if /Gr or /Gz is used on x64, so we don't either.
8337 if (ArchSupported && DCCFlag)
8338 CmdArgs.push_back(Elt: DCCFlag);
8339 }
8340
8341 if (Args.hasArg(options::OPT__SLASH_Gregcall4))
8342 CmdArgs.push_back(Elt: "-regcall4");
8343
8344 Args.AddLastArg(CmdArgs, options::OPT_vtordisp_mode_EQ);
8345
8346 if (!Args.hasArg(options::OPT_fdiagnostics_format_EQ)) {
8347 CmdArgs.push_back(Elt: "-fdiagnostics-format");
8348 CmdArgs.push_back(Elt: "msvc");
8349 }
8350
8351 if (Args.hasArg(options::OPT__SLASH_kernel))
8352 CmdArgs.push_back(Elt: "-fms-kernel");
8353
8354 for (const Arg *A : Args.filtered(options::OPT__SLASH_guard)) {
8355 StringRef GuardArgs = A->getValue();
8356 // The only valid options are "cf", "cf,nochecks", "cf-", "ehcont" and
8357 // "ehcont-".
8358 if (GuardArgs.equals_insensitive("cf")) {
8359 // Emit CFG instrumentation and the table of address-taken functions.
8360 CmdArgs.push_back("-cfguard");
8361 } else if (GuardArgs.equals_insensitive("cf,nochecks")) {
8362 // Emit only the table of address-taken functions.
8363 CmdArgs.push_back("-cfguard-no-checks");
8364 } else if (GuardArgs.equals_insensitive("ehcont")) {
8365 // Emit EH continuation table.
8366 CmdArgs.push_back("-ehcontguard");
8367 } else if (GuardArgs.equals_insensitive("cf-") ||
8368 GuardArgs.equals_insensitive("ehcont-")) {
8369 // Do nothing, but we might want to emit a security warning in future.
8370 } else {
8371 D.Diag(diag::err_drv_invalid_value) << A->getSpelling() << GuardArgs;
8372 }
8373 A->claim();
8374 }
8375}
8376
8377const char *Clang::getBaseInputName(const ArgList &Args,
8378 const InputInfo &Input) {
8379 return Args.MakeArgString(Str: llvm::sys::path::filename(path: Input.getBaseInput()));
8380}
8381
8382const char *Clang::getBaseInputStem(const ArgList &Args,
8383 const InputInfoList &Inputs) {
8384 const char *Str = getBaseInputName(Args, Input: Inputs[0]);
8385
8386 if (const char *End = strrchr(s: Str, c: '.'))
8387 return Args.MakeArgString(Str: std::string(Str, End));
8388
8389 return Str;
8390}
8391
8392const char *Clang::getDependencyFileName(const ArgList &Args,
8393 const InputInfoList &Inputs) {
8394 // FIXME: Think about this more.
8395
8396 if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
8397 SmallString<128> OutputFilename(OutputOpt->getValue());
8398 llvm::sys::path::replace_extension(path&: OutputFilename, extension: llvm::Twine('d'));
8399 return Args.MakeArgString(Str: OutputFilename);
8400 }
8401
8402 return Args.MakeArgString(Str: Twine(getBaseInputStem(Args, Inputs)) + ".d");
8403}
8404
8405// Begin ClangAs
8406
8407void ClangAs::AddMIPSTargetArgs(const ArgList &Args,
8408 ArgStringList &CmdArgs) const {
8409 StringRef CPUName;
8410 StringRef ABIName;
8411 const llvm::Triple &Triple = getToolChain().getTriple();
8412 mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
8413
8414 CmdArgs.push_back(Elt: "-target-abi");
8415 CmdArgs.push_back(Elt: ABIName.data());
8416}
8417
8418void ClangAs::AddX86TargetArgs(const ArgList &Args,
8419 ArgStringList &CmdArgs) const {
8420 addX86AlignBranchArgs(D: getToolChain().getDriver(), Args, CmdArgs,
8421 /*IsLTO=*/false);
8422
8423 if (Arg *A = Args.getLastArg(options::OPT_masm_EQ)) {
8424 StringRef Value = A->getValue();
8425 if (Value == "intel" || Value == "att") {
8426 CmdArgs.push_back(Elt: "-mllvm");
8427 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-x86-asm-syntax=" + Value));
8428 } else {
8429 getToolChain().getDriver().Diag(diag::err_drv_unsupported_option_argument)
8430 << A->getSpelling() << Value;
8431 }
8432 }
8433}
8434
8435void ClangAs::AddLoongArchTargetArgs(const ArgList &Args,
8436 ArgStringList &CmdArgs) const {
8437 CmdArgs.push_back(Elt: "-target-abi");
8438 CmdArgs.push_back(Elt: loongarch::getLoongArchABI(D: getToolChain().getDriver(), Args,
8439 Triple: getToolChain().getTriple())
8440 .data());
8441}
8442
8443void ClangAs::AddRISCVTargetArgs(const ArgList &Args,
8444 ArgStringList &CmdArgs) const {
8445 const llvm::Triple &Triple = getToolChain().getTriple();
8446 StringRef ABIName = riscv::getRISCVABI(Args, Triple);
8447
8448 CmdArgs.push_back(Elt: "-target-abi");
8449 CmdArgs.push_back(Elt: ABIName.data());
8450
8451 if (Args.hasFlag(options::OPT_mdefault_build_attributes,
8452 options::OPT_mno_default_build_attributes, true)) {
8453 CmdArgs.push_back(Elt: "-mllvm");
8454 CmdArgs.push_back(Elt: "-riscv-add-build-attributes");
8455 }
8456}
8457
8458void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
8459 const InputInfo &Output, const InputInfoList &Inputs,
8460 const ArgList &Args,
8461 const char *LinkingOutput) const {
8462 ArgStringList CmdArgs;
8463
8464 assert(Inputs.size() == 1 && "Unexpected number of inputs.");
8465 const InputInfo &Input = Inputs[0];
8466
8467 const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
8468 const std::string &TripleStr = Triple.getTriple();
8469 const auto &D = getToolChain().getDriver();
8470
8471 // Don't warn about "clang -w -c foo.s"
8472 Args.ClaimAllArgs(options::OPT_w);
8473 // and "clang -emit-llvm -c foo.s"
8474 Args.ClaimAllArgs(options::OPT_emit_llvm);
8475
8476 claimNoWarnArgs(Args);
8477
8478 // Invoke ourselves in -cc1as mode.
8479 //
8480 // FIXME: Implement custom jobs for internal actions.
8481 CmdArgs.push_back(Elt: "-cc1as");
8482
8483 // Add the "effective" target triple.
8484 CmdArgs.push_back(Elt: "-triple");
8485 CmdArgs.push_back(Elt: Args.MakeArgString(Str: TripleStr));
8486
8487 getToolChain().addClangCC1ASTargetOptions(Args, CC1ASArgs&: CmdArgs);
8488
8489 // Set the output mode, we currently only expect to be used as a real
8490 // assembler.
8491 CmdArgs.push_back(Elt: "-filetype");
8492 CmdArgs.push_back(Elt: "obj");
8493
8494 // Set the main file name, so that debug info works even with
8495 // -save-temps or preprocessed assembly.
8496 CmdArgs.push_back(Elt: "-main-file-name");
8497 CmdArgs.push_back(Elt: Clang::getBaseInputName(Args, Input));
8498
8499 // Add the target cpu
8500 std::string CPU = getCPUName(D, Args, T: Triple, /*FromAs*/ true);
8501 if (!CPU.empty()) {
8502 CmdArgs.push_back(Elt: "-target-cpu");
8503 CmdArgs.push_back(Elt: Args.MakeArgString(Str: CPU));
8504 }
8505
8506 // Add the target features
8507 getTargetFeatures(D, Triple, Args, CmdArgs, ForAS: true);
8508
8509 // Ignore explicit -force_cpusubtype_ALL option.
8510 (void)Args.hasArg(options::OPT_force__cpusubtype__ALL);
8511
8512 // Pass along any -I options so we get proper .include search paths.
8513 Args.AddAllArgs(CmdArgs, options::OPT_I_Group);
8514
8515 // Determine the original source input.
8516 auto FindSource = [](const Action *S) -> const Action * {
8517 while (S->getKind() != Action::InputClass) {
8518 assert(!S->getInputs().empty() && "unexpected root action!");
8519 S = S->getInputs()[0];
8520 }
8521 return S;
8522 };
8523 const Action *SourceAction = FindSource(&JA);
8524
8525 // Forward -g and handle debug info related flags, assuming we are dealing
8526 // with an actual assembly file.
8527 bool WantDebug = false;
8528 Args.ClaimAllArgs(options::OPT_g_Group);
8529 if (Arg *A = Args.getLastArg(options::OPT_g_Group))
8530 WantDebug = !A->getOption().matches(options::OPT_g0) &&
8531 !A->getOption().matches(options::OPT_ggdb0);
8532
8533 llvm::codegenoptions::DebugInfoKind DebugInfoKind =
8534 llvm::codegenoptions::NoDebugInfo;
8535
8536 // Add the -fdebug-compilation-dir flag if needed.
8537 const char *DebugCompilationDir =
8538 addDebugCompDirArg(Args, CmdArgs, VFS: C.getDriver().getVFS());
8539
8540 if (SourceAction->getType() == types::TY_Asm ||
8541 SourceAction->getType() == types::TY_PP_Asm) {
8542 // You might think that it would be ok to set DebugInfoKind outside of
8543 // the guard for source type, however there is a test which asserts
8544 // that some assembler invocation receives no -debug-info-kind,
8545 // and it's not clear whether that test is just overly restrictive.
8546 DebugInfoKind = (WantDebug ? llvm::codegenoptions::DebugInfoConstructor
8547 : llvm::codegenoptions::NoDebugInfo);
8548
8549 addDebugPrefixMapArg(D: getToolChain().getDriver(), TC: getToolChain(), Args,
8550 CmdArgs);
8551
8552 // Set the AT_producer to the clang version when using the integrated
8553 // assembler on assembly source files.
8554 CmdArgs.push_back(Elt: "-dwarf-debug-producer");
8555 CmdArgs.push_back(Elt: Args.MakeArgString(Str: getClangFullVersion()));
8556
8557 // And pass along -I options
8558 Args.AddAllArgs(CmdArgs, options::OPT_I);
8559 }
8560 const unsigned DwarfVersion = getDwarfVersion(TC: getToolChain(), Args);
8561 RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion,
8562 DebuggerTuning: llvm::DebuggerKind::Default);
8563 renderDwarfFormat(D, T: Triple, Args, CmdArgs, DwarfVersion);
8564 RenderDebugInfoCompressionArgs(Args, CmdArgs, D, TC: getToolChain());
8565
8566 // Handle -fPIC et al -- the relocation-model affects the assembler
8567 // for some targets.
8568 llvm::Reloc::Model RelocationModel;
8569 unsigned PICLevel;
8570 bool IsPIE;
8571 std::tie(args&: RelocationModel, args&: PICLevel, args&: IsPIE) =
8572 ParsePICArgs(ToolChain: getToolChain(), Args);
8573
8574 const char *RMName = RelocationModelName(Model: RelocationModel);
8575 if (RMName) {
8576 CmdArgs.push_back(Elt: "-mrelocation-model");
8577 CmdArgs.push_back(Elt: RMName);
8578 }
8579
8580 // Optionally embed the -cc1as level arguments into the debug info, for build
8581 // analysis.
8582 if (getToolChain().UseDwarfDebugFlags()) {
8583 ArgStringList OriginalArgs;
8584 for (const auto &Arg : Args)
8585 Arg->render(Args, Output&: OriginalArgs);
8586
8587 SmallString<256> Flags;
8588 const char *Exec = getToolChain().getDriver().getClangProgramPath();
8589 EscapeSpacesAndBackslashes(Arg: Exec, Res&: Flags);
8590 for (const char *OriginalArg : OriginalArgs) {
8591 SmallString<128> EscapedArg;
8592 EscapeSpacesAndBackslashes(Arg: OriginalArg, Res&: EscapedArg);
8593 Flags += " ";
8594 Flags += EscapedArg;
8595 }
8596 CmdArgs.push_back(Elt: "-dwarf-debug-flags");
8597 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Flags));
8598 }
8599
8600 // FIXME: Add -static support, once we have it.
8601
8602 // Add target specific flags.
8603 switch (getToolChain().getArch()) {
8604 default:
8605 break;
8606
8607 case llvm::Triple::mips:
8608 case llvm::Triple::mipsel:
8609 case llvm::Triple::mips64:
8610 case llvm::Triple::mips64el:
8611 AddMIPSTargetArgs(Args, CmdArgs);
8612 break;
8613
8614 case llvm::Triple::x86:
8615 case llvm::Triple::x86_64:
8616 AddX86TargetArgs(Args, CmdArgs);
8617 break;
8618
8619 case llvm::Triple::arm:
8620 case llvm::Triple::armeb:
8621 case llvm::Triple::thumb:
8622 case llvm::Triple::thumbeb:
8623 // This isn't in AddARMTargetArgs because we want to do this for assembly
8624 // only, not C/C++.
8625 if (Args.hasFlag(options::OPT_mdefault_build_attributes,
8626 options::OPT_mno_default_build_attributes, true)) {
8627 CmdArgs.push_back(Elt: "-mllvm");
8628 CmdArgs.push_back(Elt: "-arm-add-build-attributes");
8629 }
8630 break;
8631
8632 case llvm::Triple::aarch64:
8633 case llvm::Triple::aarch64_32:
8634 case llvm::Triple::aarch64_be:
8635 if (Args.hasArg(options::OPT_mmark_bti_property)) {
8636 CmdArgs.push_back(Elt: "-mllvm");
8637 CmdArgs.push_back(Elt: "-aarch64-mark-bti-property");
8638 }
8639 break;
8640
8641 case llvm::Triple::loongarch32:
8642 case llvm::Triple::loongarch64:
8643 AddLoongArchTargetArgs(Args, CmdArgs);
8644 break;
8645
8646 case llvm::Triple::riscv32:
8647 case llvm::Triple::riscv64:
8648 AddRISCVTargetArgs(Args, CmdArgs);
8649 break;
8650
8651 case llvm::Triple::hexagon:
8652 if (Args.hasFlag(options::OPT_mdefault_build_attributes,
8653 options::OPT_mno_default_build_attributes, true)) {
8654 CmdArgs.push_back(Elt: "-mllvm");
8655 CmdArgs.push_back(Elt: "-hexagon-add-build-attributes");
8656 }
8657 break;
8658 }
8659
8660 // Consume all the warning flags. Usually this would be handled more
8661 // gracefully by -cc1 (warning about unknown warning flags, etc) but -cc1as
8662 // doesn't handle that so rather than warning about unused flags that are
8663 // actually used, we'll lie by omission instead.
8664 // FIXME: Stop lying and consume only the appropriate driver flags
8665 Args.ClaimAllArgs(options::OPT_W_Group);
8666
8667 CollectArgsForIntegratedAssembler(C, Args, CmdArgs,
8668 D: getToolChain().getDriver());
8669
8670 Args.AddAllArgs(CmdArgs, options::OPT_mllvm);
8671
8672 if (DebugInfoKind > llvm::codegenoptions::NoDebugInfo && Output.isFilename())
8673 addDebugObjectName(Args, CmdArgs, DebugCompilationDir,
8674 OutputFileName: Output.getFilename());
8675
8676 // Fixup any previous commands that use -object-file-name because when we
8677 // generated them, the final .obj name wasn't yet known.
8678 for (Command &J : C.getJobs()) {
8679 if (SourceAction != FindSource(&J.getSource()))
8680 continue;
8681 auto &JArgs = J.getArguments();
8682 for (unsigned I = 0; I < JArgs.size(); ++I) {
8683 if (StringRef(JArgs[I]).starts_with(Prefix: "-object-file-name=") &&
8684 Output.isFilename()) {
8685 ArgStringList NewArgs(JArgs.begin(), JArgs.begin() + I);
8686 addDebugObjectName(Args, CmdArgs&: NewArgs, DebugCompilationDir,
8687 OutputFileName: Output.getFilename());
8688 NewArgs.append(in_start: JArgs.begin() + I + 1, in_end: JArgs.end());
8689 J.replaceArguments(List: NewArgs);
8690 break;
8691 }
8692 }
8693 }
8694
8695 assert(Output.isFilename() && "Unexpected lipo output.");
8696 CmdArgs.push_back(Elt: "-o");
8697 CmdArgs.push_back(Elt: Output.getFilename());
8698
8699 const llvm::Triple &T = getToolChain().getTriple();
8700 Arg *A;
8701 if (getDebugFissionKind(D, Args, Arg&: A) == DwarfFissionKind::Split &&
8702 T.isOSBinFormatELF()) {
8703 CmdArgs.push_back(Elt: "-split-dwarf-output");
8704 CmdArgs.push_back(Elt: SplitDebugName(JA, Args, Input, Output));
8705 }
8706
8707 if (Triple.isAMDGPU())
8708 handleAMDGPUCodeObjectVersionOptions(D, Args, CmdArgs, /*IsCC1As=*/true);
8709
8710 assert(Input.isFilename() && "Invalid input.");
8711 CmdArgs.push_back(Elt: Input.getFilename());
8712
8713 const char *Exec = getToolChain().getDriver().getClangProgramPath();
8714 if (D.CC1Main && !D.CCGenDiagnostics) {
8715 // Invoke cc1as directly in this process.
8716 C.addCommand(C: std::make_unique<CC1Command>(
8717 args: JA, args: *this, args: ResponseFileSupport::AtFileUTF8(), args&: Exec, args&: CmdArgs, args: Inputs,
8718 args: Output, args: D.getPrependArg()));
8719 } else {
8720 C.addCommand(C: std::make_unique<Command>(
8721 args: JA, args: *this, args: ResponseFileSupport::AtFileUTF8(), args&: Exec, args&: CmdArgs, args: Inputs,
8722 args: Output, args: D.getPrependArg()));
8723 }
8724}
8725
8726// Begin OffloadBundler
8727void OffloadBundler::ConstructJob(Compilation &C, const JobAction &JA,
8728 const InputInfo &Output,
8729 const InputInfoList &Inputs,
8730 const llvm::opt::ArgList &TCArgs,
8731 const char *LinkingOutput) const {
8732 // The version with only one output is expected to refer to a bundling job.
8733 assert(isa<OffloadBundlingJobAction>(JA) && "Expecting bundling job!");
8734
8735 // The bundling command looks like this:
8736 // clang-offload-bundler -type=bc
8737 // -targets=host-triple,openmp-triple1,openmp-triple2
8738 // -output=output_file
8739 // -input=unbundle_file_host
8740 // -input=unbundle_file_tgt1
8741 // -input=unbundle_file_tgt2
8742
8743 ArgStringList CmdArgs;
8744
8745 // Get the type.
8746 CmdArgs.push_back(Elt: TCArgs.MakeArgString(
8747 Str: Twine("-type=") + types::getTypeTempSuffix(Id: Output.getType())));
8748
8749 assert(JA.getInputs().size() == Inputs.size() &&
8750 "Not have inputs for all dependence actions??");
8751
8752 // Get the targets.
8753 SmallString<128> Triples;
8754 Triples += "-targets=";
8755 for (unsigned I = 0; I < Inputs.size(); ++I) {
8756 if (I)
8757 Triples += ',';
8758
8759 // Find ToolChain for this input.
8760 Action::OffloadKind CurKind = Action::OFK_Host;
8761 const ToolChain *CurTC = &getToolChain();
8762 const Action *CurDep = JA.getInputs()[I];
8763
8764 if (const auto *OA = dyn_cast<OffloadAction>(Val: CurDep)) {
8765 CurTC = nullptr;
8766 OA->doOnEachDependence(Work: [&](Action *A, const ToolChain *TC, const char *) {
8767 assert(CurTC == nullptr && "Expected one dependence!");
8768 CurKind = A->getOffloadingDeviceKind();
8769 CurTC = TC;
8770 });
8771 }
8772 Triples += Action::GetOffloadKindName(Kind: CurKind);
8773 Triples += '-';
8774 Triples += CurTC->getTriple().normalize();
8775 if ((CurKind == Action::OFK_HIP || CurKind == Action::OFK_Cuda) &&
8776 !StringRef(CurDep->getOffloadingArch()).empty()) {
8777 Triples += '-';
8778 Triples += CurDep->getOffloadingArch();
8779 }
8780
8781 // TODO: Replace parsing of -march flag. Can be done by storing GPUArch
8782 // with each toolchain.
8783 StringRef GPUArchName;
8784 if (CurKind == Action::OFK_OpenMP) {
8785 // Extract GPUArch from -march argument in TC argument list.
8786 for (unsigned ArgIndex = 0; ArgIndex < TCArgs.size(); ArgIndex++) {
8787 auto ArchStr = StringRef(TCArgs.getArgString(Index: ArgIndex));
8788 auto Arch = ArchStr.starts_with_insensitive(Prefix: "-march=");
8789 if (Arch) {
8790 GPUArchName = ArchStr.substr(Start: 7);
8791 Triples += "-";
8792 break;
8793 }
8794 }
8795 Triples += GPUArchName.str();
8796 }
8797 }
8798 CmdArgs.push_back(Elt: TCArgs.MakeArgString(Str: Triples));
8799
8800 // Get bundled file command.
8801 CmdArgs.push_back(
8802 Elt: TCArgs.MakeArgString(Str: Twine("-output=") + Output.getFilename()));
8803
8804 // Get unbundled files command.
8805 for (unsigned I = 0; I < Inputs.size(); ++I) {
8806 SmallString<128> UB;
8807 UB += "-input=";
8808
8809 // Find ToolChain for this input.
8810 const ToolChain *CurTC = &getToolChain();
8811 if (const auto *OA = dyn_cast<OffloadAction>(Val: JA.getInputs()[I])) {
8812 CurTC = nullptr;
8813 OA->doOnEachDependence(Work: [&](Action *, const ToolChain *TC, const char *) {
8814 assert(CurTC == nullptr && "Expected one dependence!");
8815 CurTC = TC;
8816 });
8817 UB += C.addTempFile(
8818 Name: C.getArgs().MakeArgString(Str: CurTC->getInputFilename(Input: Inputs[I])));
8819 } else {
8820 UB += CurTC->getInputFilename(Input: Inputs[I]);
8821 }
8822 CmdArgs.push_back(Elt: TCArgs.MakeArgString(Str: UB));
8823 }
8824 addOffloadCompressArgs(TCArgs, CmdArgs);
8825 // All the inputs are encoded as commands.
8826 C.addCommand(C: std::make_unique<Command>(
8827 args: JA, args: *this, args: ResponseFileSupport::None(),
8828 args: TCArgs.MakeArgString(Str: getToolChain().GetProgramPath(Name: getShortName())),
8829 args&: CmdArgs, args: std::nullopt, args: Output));
8830}
8831
8832void OffloadBundler::ConstructJobMultipleOutputs(
8833 Compilation &C, const JobAction &JA, const InputInfoList &Outputs,
8834 const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs,
8835 const char *LinkingOutput) const {
8836 // The version with multiple outputs is expected to refer to a unbundling job.
8837 auto &UA = cast<OffloadUnbundlingJobAction>(Val: JA);
8838
8839 // The unbundling command looks like this:
8840 // clang-offload-bundler -type=bc
8841 // -targets=host-triple,openmp-triple1,openmp-triple2
8842 // -input=input_file
8843 // -output=unbundle_file_host
8844 // -output=unbundle_file_tgt1
8845 // -output=unbundle_file_tgt2
8846 // -unbundle
8847
8848 ArgStringList CmdArgs;
8849
8850 assert(Inputs.size() == 1 && "Expecting to unbundle a single file!");
8851 InputInfo Input = Inputs.front();
8852
8853 // Get the type.
8854 CmdArgs.push_back(Elt: TCArgs.MakeArgString(
8855 Str: Twine("-type=") + types::getTypeTempSuffix(Id: Input.getType())));
8856
8857 // Get the targets.
8858 SmallString<128> Triples;
8859 Triples += "-targets=";
8860 auto DepInfo = UA.getDependentActionsInfo();
8861 for (unsigned I = 0; I < DepInfo.size(); ++I) {
8862 if (I)
8863 Triples += ',';
8864
8865 auto &Dep = DepInfo[I];
8866 Triples += Action::GetOffloadKindName(Kind: Dep.DependentOffloadKind);
8867 Triples += '-';
8868 Triples += Dep.DependentToolChain->getTriple().normalize();
8869 if ((Dep.DependentOffloadKind == Action::OFK_HIP ||
8870 Dep.DependentOffloadKind == Action::OFK_Cuda) &&
8871 !Dep.DependentBoundArch.empty()) {
8872 Triples += '-';
8873 Triples += Dep.DependentBoundArch;
8874 }
8875 // TODO: Replace parsing of -march flag. Can be done by storing GPUArch
8876 // with each toolchain.
8877 StringRef GPUArchName;
8878 if (Dep.DependentOffloadKind == Action::OFK_OpenMP) {
8879 // Extract GPUArch from -march argument in TC argument list.
8880 for (unsigned ArgIndex = 0; ArgIndex < TCArgs.size(); ArgIndex++) {
8881 StringRef ArchStr = StringRef(TCArgs.getArgString(Index: ArgIndex));
8882 auto Arch = ArchStr.starts_with_insensitive(Prefix: "-march=");
8883 if (Arch) {
8884 GPUArchName = ArchStr.substr(Start: 7);
8885 Triples += "-";
8886 break;
8887 }
8888 }
8889 Triples += GPUArchName.str();
8890 }
8891 }
8892
8893 CmdArgs.push_back(Elt: TCArgs.MakeArgString(Str: Triples));
8894
8895 // Get bundled file command.
8896 CmdArgs.push_back(
8897 Elt: TCArgs.MakeArgString(Str: Twine("-input=") + Input.getFilename()));
8898
8899 // Get unbundled files command.
8900 for (unsigned I = 0; I < Outputs.size(); ++I) {
8901 SmallString<128> UB;
8902 UB += "-output=";
8903 UB += DepInfo[I].DependentToolChain->getInputFilename(Input: Outputs[I]);
8904 CmdArgs.push_back(Elt: TCArgs.MakeArgString(Str: UB));
8905 }
8906 CmdArgs.push_back(Elt: "-unbundle");
8907 CmdArgs.push_back(Elt: "-allow-missing-bundles");
8908 if (TCArgs.hasArg(options::OPT_v))
8909 CmdArgs.push_back(Elt: "-verbose");
8910
8911 // All the inputs are encoded as commands.
8912 C.addCommand(C: std::make_unique<Command>(
8913 args: JA, args: *this, args: ResponseFileSupport::None(),
8914 args: TCArgs.MakeArgString(Str: getToolChain().GetProgramPath(Name: getShortName())),
8915 args&: CmdArgs, args: std::nullopt, args: Outputs));
8916}
8917
8918void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA,
8919 const InputInfo &Output,
8920 const InputInfoList &Inputs,
8921 const llvm::opt::ArgList &Args,
8922 const char *LinkingOutput) const {
8923 ArgStringList CmdArgs;
8924
8925 // Add the output file name.
8926 assert(Output.isFilename() && "Invalid output.");
8927 CmdArgs.push_back(Elt: "-o");
8928 CmdArgs.push_back(Elt: Output.getFilename());
8929
8930 // Create the inputs to bundle the needed metadata.
8931 for (const InputInfo &Input : Inputs) {
8932 const Action *OffloadAction = Input.getAction();
8933 const ToolChain *TC = OffloadAction->getOffloadingToolChain();
8934 const ArgList &TCArgs =
8935 C.getArgsForToolChain(TC, BoundArch: OffloadAction->getOffloadingArch(),
8936 DeviceOffloadKind: OffloadAction->getOffloadingDeviceKind());
8937 StringRef File = C.getArgs().MakeArgString(Str: TC->getInputFilename(Input));
8938 StringRef Arch = OffloadAction->getOffloadingArch()
8939 ? OffloadAction->getOffloadingArch()
8940 : TCArgs.getLastArgValue(options::OPT_march_EQ);
8941 StringRef Kind =
8942 Action::GetOffloadKindName(Kind: OffloadAction->getOffloadingDeviceKind());
8943
8944 ArgStringList Features;
8945 SmallVector<StringRef> FeatureArgs;
8946 getTargetFeatures(D: TC->getDriver(), Triple: TC->getTriple(), Args: TCArgs, CmdArgs&: Features,
8947 ForAS: false);
8948 llvm::copy_if(Range&: Features, Out: std::back_inserter(x&: FeatureArgs),
8949 P: [](StringRef Arg) { return !Arg.starts_with(Prefix: "-target"); });
8950
8951 if (TC->getTriple().isAMDGPU()) {
8952 for (StringRef Feature : llvm::split(Str: Arch.split(Separator: ':').second, Separator: ':')) {
8953 FeatureArgs.emplace_back(
8954 Args: Args.MakeArgString(Str: Feature.take_back() + Feature.drop_back()));
8955 }
8956 }
8957
8958 // TODO: We need to pass in the full target-id and handle it properly in the
8959 // linker wrapper.
8960 SmallVector<std::string> Parts{
8961 "file=" + File.str(),
8962 "triple=" + TC->getTripleString(),
8963 "arch=" + Arch.str(),
8964 "kind=" + Kind.str(),
8965 };
8966
8967 if (TC->getDriver().isUsingLTO(/* IsOffload */ true) ||
8968 TC->getTriple().isAMDGPU())
8969 for (StringRef Feature : FeatureArgs)
8970 Parts.emplace_back(Args: "feature=" + Feature.str());
8971
8972 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "--image=" + llvm::join(R&: Parts, Separator: ",")));
8973 }
8974
8975 C.addCommand(C: std::make_unique<Command>(
8976 args: JA, args: *this, args: ResponseFileSupport::None(),
8977 args: Args.MakeArgString(Str: getToolChain().GetProgramPath(Name: getShortName())),
8978 args&: CmdArgs, args: Inputs, args: Output));
8979}
8980
8981void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
8982 const InputInfo &Output,
8983 const InputInfoList &Inputs,
8984 const ArgList &Args,
8985 const char *LinkingOutput) const {
8986 const Driver &D = getToolChain().getDriver();
8987 const llvm::Triple TheTriple = getToolChain().getTriple();
8988 ArgStringList CmdArgs;
8989
8990 // Pass the CUDA path to the linker wrapper tool.
8991 for (Action::OffloadKind Kind : {Action::OFK_Cuda, Action::OFK_OpenMP}) {
8992 auto TCRange = C.getOffloadToolChains(Kind);
8993 for (auto &I : llvm::make_range(x: TCRange.first, y: TCRange.second)) {
8994 const ToolChain *TC = I.second;
8995 if (TC->getTriple().isNVPTX()) {
8996 CudaInstallationDetector CudaInstallation(D, TheTriple, Args);
8997 if (CudaInstallation.isValid())
8998 CmdArgs.push_back(Elt: Args.MakeArgString(
8999 Str: "--cuda-path=" + CudaInstallation.getInstallPath()));
9000 break;
9001 }
9002 }
9003 }
9004
9005 // Pass in the optimization level to use for LTO.
9006 if (const Arg *A = Args.getLastArg(options::OPT_O_Group)) {
9007 StringRef OOpt;
9008 if (A->getOption().matches(options::OPT_O4) ||
9009 A->getOption().matches(options::OPT_Ofast))
9010 OOpt = "3";
9011 else if (A->getOption().matches(options::OPT_O)) {
9012 OOpt = A->getValue();
9013 if (OOpt == "g")
9014 OOpt = "1";
9015 else if (OOpt == "s" || OOpt == "z")
9016 OOpt = "2";
9017 } else if (A->getOption().matches(options::OPT_O0))
9018 OOpt = "0";
9019 if (!OOpt.empty())
9020 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Twine("--opt-level=O") + OOpt));
9021 }
9022
9023 CmdArgs.push_back(
9024 Elt: Args.MakeArgString(Str: "--host-triple=" + TheTriple.getTriple()));
9025 if (Args.hasArg(options::OPT_v))
9026 CmdArgs.push_back(Elt: "--wrapper-verbose");
9027
9028 if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) {
9029 if (!A->getOption().matches(options::OPT_g0))
9030 CmdArgs.push_back(Elt: "--device-debug");
9031 }
9032
9033 // code-object-version=X needs to be passed to clang-linker-wrapper to ensure
9034 // that it is used by lld.
9035 if (const Arg *A = Args.getLastArg(options::OPT_mcode_object_version_EQ)) {
9036 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-mllvm"));
9037 CmdArgs.push_back(Elt: Args.MakeArgString(
9038 Str: Twine("--amdhsa-code-object-version=") + A->getValue()));
9039 }
9040
9041 for (const auto &A : Args.getAllArgValues(options::OPT_Xcuda_ptxas))
9042 CmdArgs.push_back(Args.MakeArgString("--ptxas-arg=" + A));
9043
9044 // Forward remarks passes to the LLVM backend in the wrapper.
9045 if (const Arg *A = Args.getLastArg(options::OPT_Rpass_EQ))
9046 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Twine("--offload-opt=-pass-remarks=") +
9047 A->getValue()));
9048 if (const Arg *A = Args.getLastArg(options::OPT_Rpass_missed_EQ))
9049 CmdArgs.push_back(Elt: Args.MakeArgString(
9050 Str: Twine("--offload-opt=-pass-remarks-missed=") + A->getValue()));
9051 if (const Arg *A = Args.getLastArg(options::OPT_Rpass_analysis_EQ))
9052 CmdArgs.push_back(Elt: Args.MakeArgString(
9053 Str: Twine("--offload-opt=-pass-remarks-analysis=") + A->getValue()));
9054 if (Args.getLastArg(options::OPT_save_temps_EQ))
9055 CmdArgs.push_back(Elt: "--save-temps");
9056
9057 // Construct the link job so we can wrap around it.
9058 Linker->ConstructJob(C, JA, Output, Inputs, TCArgs: Args, LinkingOutput);
9059 const auto &LinkCommand = C.getJobs().getJobs().back();
9060
9061 // Forward -Xoffload-linker<-triple> arguments to the device link job.
9062 for (Arg *A : Args.filtered(options::OPT_Xoffload_linker)) {
9063 StringRef Val = A->getValue(0);
9064 if (Val.empty())
9065 CmdArgs.push_back(
9066 Args.MakeArgString(Twine("--device-linker=") + A->getValue(1)));
9067 else
9068 CmdArgs.push_back(Args.MakeArgString(
9069 "--device-linker=" +
9070 ToolChain::getOpenMPTriple(Val.drop_front()).getTriple() + "=" +
9071 A->getValue(1)));
9072 }
9073 Args.ClaimAllArgs(options::OPT_Xoffload_linker);
9074
9075 // Embed bitcode instead of an object in JIT mode.
9076 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
9077 options::OPT_fno_openmp_target_jit, false))
9078 CmdArgs.push_back(Elt: "--embed-bitcode");
9079
9080 // Forward `-mllvm` arguments to the LLVM invocations if present.
9081 for (Arg *A : Args.filtered(options::OPT_mllvm)) {
9082 CmdArgs.push_back("-mllvm");
9083 CmdArgs.push_back(A->getValue());
9084 A->claim();
9085 }
9086
9087 // Add the linker arguments to be forwarded by the wrapper.
9088 CmdArgs.push_back(Elt: Args.MakeArgString(Str: Twine("--linker-path=") +
9089 LinkCommand->getExecutable()));
9090 for (const char *LinkArg : LinkCommand->getArguments())
9091 CmdArgs.push_back(Elt: LinkArg);
9092
9093 addOffloadCompressArgs(TCArgs: Args, CmdArgs);
9094
9095 const char *Exec =
9096 Args.MakeArgString(Str: getToolChain().GetProgramPath(Name: "clang-linker-wrapper"));
9097
9098 // Replace the executable and arguments of the link job with the
9099 // wrapper.
9100 LinkCommand->replaceExecutable(Exe: Exec);
9101 LinkCommand->replaceArguments(List: CmdArgs);
9102}
9103

source code of clang/lib/Driver/ToolChains/Clang.cpp