1 //===-- Clang.cpp - Clang+LLVM ToolChain Implementations --------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
11 #include "Arch/AArch64.h"
13 #include "Arch/CSKY.h"
14 #include "Arch/LoongArch.h"
15 #include "Arch/M68k.h"
16 #include "Arch/Mips.h"
18 #include "Arch/RISCV.h"
19 #include "Arch/Sparc.h"
20 #include "Arch/SystemZ.h"
23 #include "CommonArgs.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/Frontend/Debug/Options.h"
49 #include "llvm/Object/ObjectFile.h"
50 #include "llvm/Option/ArgList.h"
51 #include "llvm/Support/CodeGen.h"
52 #include "llvm/Support/Compiler.h"
53 #include "llvm/Support/Compression.h"
54 #include "llvm/Support/Error.h"
55 #include "llvm/Support/FileSystem.h"
56 #include "llvm/Support/Path.h"
57 #include "llvm/Support/Process.h"
58 #include "llvm/Support/YAMLParser.h"
59 #include "llvm/TargetParser/AArch64TargetParser.h"
60 #include "llvm/TargetParser/ARMTargetParserCommon.h"
61 #include "llvm/TargetParser/Host.h"
62 #include "llvm/TargetParser/LoongArchTargetParser.h"
63 #include "llvm/TargetParser/RISCVISAInfo.h"
64 #include "llvm/TargetParser/RISCVTargetParser.h"
67 using namespace clang::driver
;
68 using namespace clang::driver::tools
;
69 using namespace clang
;
70 using namespace llvm::opt
;
72 static void CheckPreprocessingOptions(const Driver
&D
, const ArgList
&Args
) {
73 if (Arg
*A
= Args
.getLastArg(clang::driver::options::OPT_C
, options::OPT_CC
,
74 options::OPT_fminimize_whitespace
,
75 options::OPT_fno_minimize_whitespace
,
76 options::OPT_fkeep_system_includes
,
77 options::OPT_fno_keep_system_includes
)) {
78 if (!Args
.hasArg(options::OPT_E
) && !Args
.hasArg(options::OPT__SLASH_P
) &&
79 !Args
.hasArg(options::OPT__SLASH_EP
) && !D
.CCCIsCPP()) {
80 D
.Diag(clang::diag::err_drv_argument_only_allowed_with
)
81 << A
->getBaseArg().getAsString(Args
)
82 << (D
.IsCLMode() ? "/E, /P or /EP" : "-E");
87 static void CheckCodeGenerationOptions(const Driver
&D
, const ArgList
&Args
) {
88 // In gcc, only ARM checks this, but it seems reasonable to check universally.
89 if (Args
.hasArg(options::OPT_static
))
91 Args
.getLastArg(options::OPT_dynamic
, options::OPT_mdynamic_no_pic
))
92 D
.Diag(diag::err_drv_argument_not_allowed_with
) << A
->getAsString(Args
)
96 // Add backslashes to escape spaces and other backslashes.
97 // This is used for the space-separated argument list specified with
98 // the -dwarf-debug-flags option.
99 static void EscapeSpacesAndBackslashes(const char *Arg
,
100 SmallVectorImpl
<char> &Res
) {
101 for (; *Arg
; ++Arg
) {
114 /// Apply \a Work on the current tool chain \a RegularToolChain and any other
115 /// offloading tool chain that is associated with the current action \a JA.
117 forAllAssociatedToolChains(Compilation
&C
, const JobAction
&JA
,
118 const ToolChain
&RegularToolChain
,
119 llvm::function_ref
<void(const ToolChain
&)> Work
) {
120 // Apply Work on the current/regular tool chain.
121 Work(RegularToolChain
);
123 // Apply Work on all the offloading tool chains associated with the current
125 if (JA
.isHostOffloading(Action::OFK_Cuda
))
126 Work(*C
.getSingleOffloadToolChain
<Action::OFK_Cuda
>());
127 else if (JA
.isDeviceOffloading(Action::OFK_Cuda
))
128 Work(*C
.getSingleOffloadToolChain
<Action::OFK_Host
>());
129 else if (JA
.isHostOffloading(Action::OFK_HIP
))
130 Work(*C
.getSingleOffloadToolChain
<Action::OFK_HIP
>());
131 else if (JA
.isDeviceOffloading(Action::OFK_HIP
))
132 Work(*C
.getSingleOffloadToolChain
<Action::OFK_Host
>());
134 if (JA
.isHostOffloading(Action::OFK_OpenMP
)) {
135 auto TCs
= C
.getOffloadToolChains
<Action::OFK_OpenMP
>();
136 for (auto II
= TCs
.first
, IE
= TCs
.second
; II
!= IE
; ++II
)
138 } else if (JA
.isDeviceOffloading(Action::OFK_OpenMP
))
139 Work(*C
.getSingleOffloadToolChain
<Action::OFK_Host
>());
142 // TODO: Add support for other offloading programming models here.
146 /// This is a helper function for validating the optional refinement step
147 /// parameter in reciprocal argument strings. Return false if there is an error
148 /// parsing the refinement step. Otherwise, return true and set the Position
149 /// of the refinement step in the input string.
150 static bool getRefinementStep(StringRef In
, const Driver
&D
,
151 const Arg
&A
, size_t &Position
) {
152 const char RefinementStepToken
= ':';
153 Position
= In
.find(RefinementStepToken
);
154 if (Position
!= StringRef::npos
) {
155 StringRef Option
= A
.getOption().getName();
156 StringRef RefStep
= In
.substr(Position
+ 1);
157 // Allow exactly one numeric character for the additional refinement
158 // step parameter. This is reasonable for all currently-supported
159 // operations and architectures because we would expect that a larger value
160 // of refinement steps would cause the estimate "optimization" to
161 // under-perform the native operation. Also, if the estimate does not
162 // converge quickly, it probably will not ever converge, so further
163 // refinement steps will not produce a better answer.
164 if (RefStep
.size() != 1) {
165 D
.Diag(diag::err_drv_invalid_value
) << Option
<< RefStep
;
168 char RefStepChar
= RefStep
[0];
169 if (RefStepChar
< '0' || RefStepChar
> '9') {
170 D
.Diag(diag::err_drv_invalid_value
) << Option
<< RefStep
;
177 /// The -mrecip flag requires processing of many optional parameters.
178 static void ParseMRecip(const Driver
&D
, const ArgList
&Args
,
179 ArgStringList
&OutStrings
) {
180 StringRef DisabledPrefixIn
= "!";
181 StringRef DisabledPrefixOut
= "!";
182 StringRef EnabledPrefixOut
= "";
183 StringRef Out
= "-mrecip=";
185 Arg
*A
= Args
.getLastArg(options::OPT_mrecip
, options::OPT_mrecip_EQ
);
189 unsigned NumOptions
= A
->getNumValues();
190 if (NumOptions
== 0) {
191 // No option is the same as "all".
192 OutStrings
.push_back(Args
.MakeArgString(Out
+ "all"));
196 // Pass through "all", "none", or "default" with an optional refinement step.
197 if (NumOptions
== 1) {
198 StringRef Val
= A
->getValue(0);
200 if (!getRefinementStep(Val
, D
, *A
, RefStepLoc
))
202 StringRef ValBase
= Val
.slice(0, RefStepLoc
);
203 if (ValBase
== "all" || ValBase
== "none" || ValBase
== "default") {
204 OutStrings
.push_back(Args
.MakeArgString(Out
+ Val
));
209 // Each reciprocal type may be enabled or disabled individually.
210 // Check each input value for validity, concatenate them all back together,
213 llvm::StringMap
<bool> OptionStrings
;
214 OptionStrings
.insert(std::make_pair("divd", false));
215 OptionStrings
.insert(std::make_pair("divf", false));
216 OptionStrings
.insert(std::make_pair("divh", false));
217 OptionStrings
.insert(std::make_pair("vec-divd", false));
218 OptionStrings
.insert(std::make_pair("vec-divf", false));
219 OptionStrings
.insert(std::make_pair("vec-divh", false));
220 OptionStrings
.insert(std::make_pair("sqrtd", false));
221 OptionStrings
.insert(std::make_pair("sqrtf", false));
222 OptionStrings
.insert(std::make_pair("sqrth", false));
223 OptionStrings
.insert(std::make_pair("vec-sqrtd", false));
224 OptionStrings
.insert(std::make_pair("vec-sqrtf", false));
225 OptionStrings
.insert(std::make_pair("vec-sqrth", false));
227 for (unsigned i
= 0; i
!= NumOptions
; ++i
) {
228 StringRef Val
= A
->getValue(i
);
230 bool IsDisabled
= Val
.starts_with(DisabledPrefixIn
);
231 // Ignore the disablement token for string matching.
236 if (!getRefinementStep(Val
, D
, *A
, RefStep
))
239 StringRef ValBase
= Val
.slice(0, RefStep
);
240 llvm::StringMap
<bool>::iterator OptionIter
= OptionStrings
.find(ValBase
);
241 if (OptionIter
== OptionStrings
.end()) {
242 // Try again specifying float suffix.
243 OptionIter
= OptionStrings
.find(ValBase
.str() + 'f');
244 if (OptionIter
== OptionStrings
.end()) {
245 // The input name did not match any known option string.
246 D
.Diag(diag::err_drv_unknown_argument
) << Val
;
249 // The option was specified without a half or float or double suffix.
250 // Make sure that the double or half entry was not already specified.
251 // The float entry will be checked below.
252 if (OptionStrings
[ValBase
.str() + 'd'] ||
253 OptionStrings
[ValBase
.str() + 'h']) {
254 D
.Diag(diag::err_drv_invalid_value
) << A
->getOption().getName() << Val
;
259 if (OptionIter
->second
== true) {
260 // Duplicate option specified.
261 D
.Diag(diag::err_drv_invalid_value
) << A
->getOption().getName() << Val
;
265 // Mark the matched option as found. Do not allow duplicate specifiers.
266 OptionIter
->second
= true;
268 // If the precision was not specified, also mark the double and half entry
270 if (ValBase
.back() != 'f' && ValBase
.back() != 'd' && ValBase
.back() != 'h') {
271 OptionStrings
[ValBase
.str() + 'd'] = true;
272 OptionStrings
[ValBase
.str() + 'h'] = true;
275 // Build the output string.
276 StringRef Prefix
= IsDisabled
? DisabledPrefixOut
: EnabledPrefixOut
;
277 Out
= Args
.MakeArgString(Out
+ Prefix
+ Val
);
278 if (i
!= NumOptions
- 1)
279 Out
= Args
.MakeArgString(Out
+ ",");
282 OutStrings
.push_back(Args
.MakeArgString(Out
));
285 /// The -mprefer-vector-width option accepts either a positive integer
286 /// or the string "none".
287 static void ParseMPreferVectorWidth(const Driver
&D
, const ArgList
&Args
,
288 ArgStringList
&CmdArgs
) {
289 Arg
*A
= Args
.getLastArg(options::OPT_mprefer_vector_width_EQ
);
293 StringRef Value
= A
->getValue();
294 if (Value
== "none") {
295 CmdArgs
.push_back("-mprefer-vector-width=none");
298 if (Value
.getAsInteger(10, Width
)) {
299 D
.Diag(diag::err_drv_invalid_value
) << A
->getOption().getName() << Value
;
302 CmdArgs
.push_back(Args
.MakeArgString("-mprefer-vector-width=" + Value
));
307 shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime
&runtime
,
308 const llvm::Triple
&Triple
) {
309 // We use the zero-cost exception tables for Objective-C if the non-fragile
310 // ABI is enabled or when compiling for x86_64 and ARM on Snow Leopard and
312 if (runtime
.isNonFragile())
315 if (!Triple
.isMacOSX())
318 return (!Triple
.isMacOSXVersionLT(10, 5) &&
319 (Triple
.getArch() == llvm::Triple::x86_64
||
320 Triple
.getArch() == llvm::Triple::arm
));
323 /// Adds exception related arguments to the driver command arguments. There's a
324 /// main flag, -fexceptions and also language specific flags to enable/disable
325 /// C++ and Objective-C exceptions. This makes it possible to for example
326 /// disable C++ exceptions but enable Objective-C exceptions.
327 static bool addExceptionArgs(const ArgList
&Args
, types::ID InputType
,
328 const ToolChain
&TC
, bool KernelOrKext
,
329 const ObjCRuntime
&objcRuntime
,
330 ArgStringList
&CmdArgs
) {
331 const llvm::Triple
&Triple
= TC
.getTriple();
334 // -mkernel and -fapple-kext imply no exceptions, so claim exception related
335 // arguments now to avoid warnings about unused arguments.
336 Args
.ClaimAllArgs(options::OPT_fexceptions
);
337 Args
.ClaimAllArgs(options::OPT_fno_exceptions
);
338 Args
.ClaimAllArgs(options::OPT_fobjc_exceptions
);
339 Args
.ClaimAllArgs(options::OPT_fno_objc_exceptions
);
340 Args
.ClaimAllArgs(options::OPT_fcxx_exceptions
);
341 Args
.ClaimAllArgs(options::OPT_fno_cxx_exceptions
);
342 Args
.ClaimAllArgs(options::OPT_fasync_exceptions
);
343 Args
.ClaimAllArgs(options::OPT_fno_async_exceptions
);
347 // See if the user explicitly enabled exceptions.
348 bool EH
= Args
.hasFlag(options::OPT_fexceptions
, options::OPT_fno_exceptions
,
351 // Async exceptions are Windows MSVC only.
352 if (Triple
.isWindowsMSVCEnvironment()) {
353 bool EHa
= Args
.hasFlag(options::OPT_fasync_exceptions
,
354 options::OPT_fno_async_exceptions
, false);
356 CmdArgs
.push_back("-fasync-exceptions");
361 // Obj-C exceptions are enabled by default, regardless of -fexceptions. This
362 // is not necessarily sensible, but follows GCC.
363 if (types::isObjC(InputType
) &&
364 Args
.hasFlag(options::OPT_fobjc_exceptions
,
365 options::OPT_fno_objc_exceptions
, true)) {
366 CmdArgs
.push_back("-fobjc-exceptions");
368 EH
|= shouldUseExceptionTablesForObjCExceptions(objcRuntime
, Triple
);
371 if (types::isCXX(InputType
)) {
372 // Disable C++ EH by default on XCore and PS4/PS5.
373 bool CXXExceptionsEnabled
= Triple
.getArch() != llvm::Triple::xcore
&&
374 !Triple
.isPS() && !Triple
.isDriverKit();
375 Arg
*ExceptionArg
= Args
.getLastArg(
376 options::OPT_fcxx_exceptions
, options::OPT_fno_cxx_exceptions
,
377 options::OPT_fexceptions
, options::OPT_fno_exceptions
);
379 CXXExceptionsEnabled
=
380 ExceptionArg
->getOption().matches(options::OPT_fcxx_exceptions
) ||
381 ExceptionArg
->getOption().matches(options::OPT_fexceptions
);
383 if (CXXExceptionsEnabled
) {
384 CmdArgs
.push_back("-fcxx-exceptions");
390 // OPT_fignore_exceptions means exception could still be thrown,
391 // but no clean up or catch would happen in current module.
392 // So we do not set EH to false.
393 Args
.AddLastArg(CmdArgs
, options::OPT_fignore_exceptions
);
395 Args
.addOptInFlag(CmdArgs
, options::OPT_fassume_nothrow_exception_dtor
,
396 options::OPT_fno_assume_nothrow_exception_dtor
);
399 CmdArgs
.push_back("-fexceptions");
403 static bool ShouldEnableAutolink(const ArgList
&Args
, const ToolChain
&TC
,
404 const JobAction
&JA
) {
406 if (TC
.getTriple().isOSDarwin()) {
407 // The native darwin assembler doesn't support the linker_option directives,
408 // so we disable them if we think the .s file will be passed to it.
409 Default
= TC
.useIntegratedAs();
411 // The linker_option directives are intended for host compilation.
412 if (JA
.isDeviceOffloading(Action::OFK_Cuda
) ||
413 JA
.isDeviceOffloading(Action::OFK_HIP
))
415 return Args
.hasFlag(options::OPT_fautolink
, options::OPT_fno_autolink
,
419 /// Add a CC1 option to specify the debug compilation directory.
420 static const char *addDebugCompDirArg(const ArgList
&Args
,
421 ArgStringList
&CmdArgs
,
422 const llvm::vfs::FileSystem
&VFS
) {
423 if (Arg
*A
= Args
.getLastArg(options::OPT_ffile_compilation_dir_EQ
,
424 options::OPT_fdebug_compilation_dir_EQ
)) {
425 if (A
->getOption().matches(options::OPT_ffile_compilation_dir_EQ
))
426 CmdArgs
.push_back(Args
.MakeArgString(Twine("-fdebug-compilation-dir=") +
429 A
->render(Args
, CmdArgs
);
430 } else if (llvm::ErrorOr
<std::string
> CWD
=
431 VFS
.getCurrentWorkingDirectory()) {
432 CmdArgs
.push_back(Args
.MakeArgString("-fdebug-compilation-dir=" + *CWD
));
434 StringRef
Path(CmdArgs
.back());
435 return Path
.substr(Path
.find('=') + 1).data();
438 static void addDebugObjectName(const ArgList
&Args
, ArgStringList
&CmdArgs
,
439 const char *DebugCompilationDir
,
440 const char *OutputFileName
) {
441 // No need to generate a value for -object-file-name if it was provided.
442 for (auto *Arg
: Args
.filtered(options::OPT_Xclang
))
443 if (StringRef(Arg
->getValue()).starts_with("-object-file-name"))
446 if (Args
.hasArg(options::OPT_object_file_name_EQ
))
449 SmallString
<128> ObjFileNameForDebug(OutputFileName
);
450 if (ObjFileNameForDebug
!= "-" &&
451 !llvm::sys::path::is_absolute(ObjFileNameForDebug
) &&
452 (!DebugCompilationDir
||
453 llvm::sys::path::is_absolute(DebugCompilationDir
))) {
454 // Make the path absolute in the debug infos like MSVC does.
455 llvm::sys::fs::make_absolute(ObjFileNameForDebug
);
457 // If the object file name is a relative path, then always use Windows
458 // backslash style as -object-file-name is used for embedding object file path
459 // in codeview and it can only be generated when targeting on Windows.
460 // Otherwise, just use native absolute path.
461 llvm::sys::path::Style Style
=
462 llvm::sys::path::is_absolute(ObjFileNameForDebug
)
463 ? llvm::sys::path::Style::native
464 : llvm::sys::path::Style::windows_backslash
;
465 llvm::sys::path::remove_dots(ObjFileNameForDebug
, /*remove_dot_dot=*/true,
468 Args
.MakeArgString(Twine("-object-file-name=") + ObjFileNameForDebug
));
471 /// Add a CC1 and CC1AS option to specify the debug file path prefix map.
472 static void addDebugPrefixMapArg(const Driver
&D
, const ToolChain
&TC
,
473 const ArgList
&Args
, ArgStringList
&CmdArgs
) {
474 auto AddOneArg
= [&](StringRef Map
, StringRef Name
) {
475 if (!Map
.contains('='))
476 D
.Diag(diag::err_drv_invalid_argument_to_option
) << Map
<< Name
;
478 CmdArgs
.push_back(Args
.MakeArgString("-fdebug-prefix-map=" + Map
));
481 for (const Arg
*A
: Args
.filtered(options::OPT_ffile_prefix_map_EQ
,
482 options::OPT_fdebug_prefix_map_EQ
)) {
483 AddOneArg(A
->getValue(), A
->getOption().getName());
486 std::string GlobalRemapEntry
= TC
.GetGlobalDebugPathRemapping();
487 if (GlobalRemapEntry
.empty())
489 AddOneArg(GlobalRemapEntry
, "environment");
492 /// Add a CC1 and CC1AS option to specify the macro file path prefix map.
493 static void addMacroPrefixMapArg(const Driver
&D
, const ArgList
&Args
,
494 ArgStringList
&CmdArgs
) {
495 for (const Arg
*A
: Args
.filtered(options::OPT_ffile_prefix_map_EQ
,
496 options::OPT_fmacro_prefix_map_EQ
)) {
497 StringRef Map
= A
->getValue();
498 if (!Map
.contains('='))
499 D
.Diag(diag::err_drv_invalid_argument_to_option
)
500 << Map
<< A
->getOption().getName();
502 CmdArgs
.push_back(Args
.MakeArgString("-fmacro-prefix-map=" + Map
));
507 /// Add a CC1 and CC1AS option to specify the coverage file path prefix map.
508 static void addCoveragePrefixMapArg(const Driver
&D
, const ArgList
&Args
,
509 ArgStringList
&CmdArgs
) {
510 for (const Arg
*A
: Args
.filtered(options::OPT_ffile_prefix_map_EQ
,
511 options::OPT_fcoverage_prefix_map_EQ
)) {
512 StringRef Map
= A
->getValue();
513 if (!Map
.contains('='))
514 D
.Diag(diag::err_drv_invalid_argument_to_option
)
515 << Map
<< A
->getOption().getName();
517 CmdArgs
.push_back(Args
.MakeArgString("-fcoverage-prefix-map=" + Map
));
522 /// Vectorize at all optimization levels greater than 1 except for -Oz.
523 /// For -Oz the loop vectorizer is disabled, while the slp vectorizer is
525 static bool shouldEnableVectorizerAtOLevel(const ArgList
&Args
, bool isSlpVec
) {
526 if (Arg
*A
= Args
.getLastArg(options::OPT_O_Group
)) {
527 if (A
->getOption().matches(options::OPT_O4
) ||
528 A
->getOption().matches(options::OPT_Ofast
))
531 if (A
->getOption().matches(options::OPT_O0
))
534 assert(A
->getOption().matches(options::OPT_O
) && "Must have a -O flag");
537 StringRef
S(A
->getValue());
541 // Don't vectorize -Oz, unless it's the slp vectorizer.
545 unsigned OptLevel
= 0;
546 if (S
.getAsInteger(10, OptLevel
))
555 /// Add -x lang to \p CmdArgs for \p Input.
556 static void addDashXForInput(const ArgList
&Args
, const InputInfo
&Input
,
557 ArgStringList
&CmdArgs
) {
558 // When using -verify-pch, we don't want to provide the type
559 // 'precompiled-header' if it was inferred from the file extension
560 if (Args
.hasArg(options::OPT_verify_pch
) && Input
.getType() == types::TY_PCH
)
563 CmdArgs
.push_back("-x");
564 if (Args
.hasArg(options::OPT_rewrite_objc
))
565 CmdArgs
.push_back(types::getTypeName(types::TY_PP_ObjCXX
));
567 // Map the driver type to the frontend type. This is mostly an identity
568 // mapping, except that the distinction between module interface units
569 // and other source files does not exist at the frontend layer.
570 const char *ClangType
;
571 switch (Input
.getType()) {
572 case types::TY_CXXModule
:
575 case types::TY_PP_CXXModule
:
576 ClangType
= "c++-cpp-output";
579 ClangType
= types::getTypeName(Input
.getType());
582 CmdArgs
.push_back(ClangType
);
586 static void addPGOAndCoverageFlags(const ToolChain
&TC
, Compilation
&C
,
587 const JobAction
&JA
, const InputInfo
&Output
,
588 const ArgList
&Args
, SanitizerArgs
&SanArgs
,
589 ArgStringList
&CmdArgs
) {
590 const Driver
&D
= TC
.getDriver();
591 auto *PGOGenerateArg
= Args
.getLastArg(options::OPT_fprofile_generate
,
592 options::OPT_fprofile_generate_EQ
,
593 options::OPT_fno_profile_generate
);
594 if (PGOGenerateArg
&&
595 PGOGenerateArg
->getOption().matches(options::OPT_fno_profile_generate
))
596 PGOGenerateArg
= nullptr;
598 auto *CSPGOGenerateArg
= getLastCSProfileGenerateArg(Args
);
600 auto *ProfileGenerateArg
= Args
.getLastArg(
601 options::OPT_fprofile_instr_generate
,
602 options::OPT_fprofile_instr_generate_EQ
,
603 options::OPT_fno_profile_instr_generate
);
604 if (ProfileGenerateArg
&&
605 ProfileGenerateArg
->getOption().matches(
606 options::OPT_fno_profile_instr_generate
))
607 ProfileGenerateArg
= nullptr;
609 if (PGOGenerateArg
&& ProfileGenerateArg
)
610 D
.Diag(diag::err_drv_argument_not_allowed_with
)
611 << PGOGenerateArg
->getSpelling() << ProfileGenerateArg
->getSpelling();
613 auto *ProfileUseArg
= getLastProfileUseArg(Args
);
615 if (PGOGenerateArg
&& ProfileUseArg
)
616 D
.Diag(diag::err_drv_argument_not_allowed_with
)
617 << ProfileUseArg
->getSpelling() << PGOGenerateArg
->getSpelling();
619 if (ProfileGenerateArg
&& ProfileUseArg
)
620 D
.Diag(diag::err_drv_argument_not_allowed_with
)
621 << ProfileGenerateArg
->getSpelling() << ProfileUseArg
->getSpelling();
623 if (CSPGOGenerateArg
&& PGOGenerateArg
) {
624 D
.Diag(diag::err_drv_argument_not_allowed_with
)
625 << CSPGOGenerateArg
->getSpelling() << PGOGenerateArg
->getSpelling();
626 PGOGenerateArg
= nullptr;
629 if (TC
.getTriple().isOSAIX()) {
630 if (Arg
*ProfileSampleUseArg
= getLastProfileSampleUseArg(Args
))
631 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
632 << ProfileSampleUseArg
->getSpelling() << TC
.getTriple().str();
635 if (ProfileGenerateArg
) {
636 if (ProfileGenerateArg
->getOption().matches(
637 options::OPT_fprofile_instr_generate_EQ
))
638 CmdArgs
.push_back(Args
.MakeArgString(Twine("-fprofile-instrument-path=") +
639 ProfileGenerateArg
->getValue()));
640 // The default is to use Clang Instrumentation.
641 CmdArgs
.push_back("-fprofile-instrument=clang");
642 if (TC
.getTriple().isWindowsMSVCEnvironment() &&
643 Args
.hasFlag(options::OPT_frtlib_defaultlib
,
644 options::OPT_fno_rtlib_defaultlib
, true)) {
645 // Add dependent lib for clang_rt.profile
646 CmdArgs
.push_back(Args
.MakeArgString(
647 "--dependent-lib=" + TC
.getCompilerRTBasename(Args
, "profile")));
651 Arg
*PGOGenArg
= nullptr;
652 if (PGOGenerateArg
) {
653 assert(!CSPGOGenerateArg
);
654 PGOGenArg
= PGOGenerateArg
;
655 CmdArgs
.push_back("-fprofile-instrument=llvm");
657 if (CSPGOGenerateArg
) {
658 assert(!PGOGenerateArg
);
659 PGOGenArg
= CSPGOGenerateArg
;
660 CmdArgs
.push_back("-fprofile-instrument=csllvm");
663 if (TC
.getTriple().isWindowsMSVCEnvironment() &&
664 Args
.hasFlag(options::OPT_frtlib_defaultlib
,
665 options::OPT_fno_rtlib_defaultlib
, true)) {
666 // Add dependent lib for clang_rt.profile
667 CmdArgs
.push_back(Args
.MakeArgString(
668 "--dependent-lib=" + TC
.getCompilerRTBasename(Args
, "profile")));
670 if (PGOGenArg
->getOption().matches(
671 PGOGenerateArg
? options::OPT_fprofile_generate_EQ
672 : options::OPT_fcs_profile_generate_EQ
)) {
673 SmallString
<128> Path(PGOGenArg
->getValue());
674 llvm::sys::path::append(Path
, "default_%m.profraw");
676 Args
.MakeArgString(Twine("-fprofile-instrument-path=") + Path
));
681 if (ProfileUseArg
->getOption().matches(options::OPT_fprofile_instr_use_EQ
))
682 CmdArgs
.push_back(Args
.MakeArgString(
683 Twine("-fprofile-instrument-use-path=") + ProfileUseArg
->getValue()));
684 else if ((ProfileUseArg
->getOption().matches(
685 options::OPT_fprofile_use_EQ
) ||
686 ProfileUseArg
->getOption().matches(
687 options::OPT_fprofile_instr_use
))) {
688 SmallString
<128> Path(
689 ProfileUseArg
->getNumValues() == 0 ? "" : ProfileUseArg
->getValue());
690 if (Path
.empty() || llvm::sys::fs::is_directory(Path
))
691 llvm::sys::path::append(Path
, "default.profdata");
693 Args
.MakeArgString(Twine("-fprofile-instrument-use-path=") + Path
));
697 bool EmitCovNotes
= Args
.hasFlag(options::OPT_ftest_coverage
,
698 options::OPT_fno_test_coverage
, false) ||
699 Args
.hasArg(options::OPT_coverage
);
700 bool EmitCovData
= TC
.needsGCovInstrumentation(Args
);
702 if (Args
.hasFlag(options::OPT_fcoverage_mapping
,
703 options::OPT_fno_coverage_mapping
, false)) {
704 if (!ProfileGenerateArg
)
705 D
.Diag(clang::diag::err_drv_argument_only_allowed_with
)
706 << "-fcoverage-mapping"
707 << "-fprofile-instr-generate";
709 CmdArgs
.push_back("-fcoverage-mapping");
712 if (Args
.hasFlag(options::OPT_fmcdc_coverage
, options::OPT_fno_mcdc_coverage
,
714 if (!Args
.hasFlag(options::OPT_fcoverage_mapping
,
715 options::OPT_fno_coverage_mapping
, false))
716 D
.Diag(clang::diag::err_drv_argument_only_allowed_with
)
718 << "-fcoverage-mapping";
720 CmdArgs
.push_back("-fcoverage-mcdc");
723 if (Arg
*A
= Args
.getLastArg(options::OPT_ffile_compilation_dir_EQ
,
724 options::OPT_fcoverage_compilation_dir_EQ
)) {
725 if (A
->getOption().matches(options::OPT_ffile_compilation_dir_EQ
))
726 CmdArgs
.push_back(Args
.MakeArgString(
727 Twine("-fcoverage-compilation-dir=") + A
->getValue()));
729 A
->render(Args
, CmdArgs
);
730 } else if (llvm::ErrorOr
<std::string
> CWD
=
731 D
.getVFS().getCurrentWorkingDirectory()) {
732 CmdArgs
.push_back(Args
.MakeArgString("-fcoverage-compilation-dir=" + *CWD
));
735 if (Args
.hasArg(options::OPT_fprofile_exclude_files_EQ
)) {
736 auto *Arg
= Args
.getLastArg(options::OPT_fprofile_exclude_files_EQ
);
737 if (!Args
.hasArg(options::OPT_coverage
))
738 D
.Diag(clang::diag::err_drv_argument_only_allowed_with
)
739 << "-fprofile-exclude-files="
742 StringRef v
= Arg
->getValue();
744 Args
.MakeArgString(Twine("-fprofile-exclude-files=" + v
)));
747 if (Args
.hasArg(options::OPT_fprofile_filter_files_EQ
)) {
748 auto *Arg
= Args
.getLastArg(options::OPT_fprofile_filter_files_EQ
);
749 if (!Args
.hasArg(options::OPT_coverage
))
750 D
.Diag(clang::diag::err_drv_argument_only_allowed_with
)
751 << "-fprofile-filter-files="
754 StringRef v
= Arg
->getValue();
755 CmdArgs
.push_back(Args
.MakeArgString(Twine("-fprofile-filter-files=" + v
)));
758 if (const auto *A
= Args
.getLastArg(options::OPT_fprofile_update_EQ
)) {
759 StringRef Val
= A
->getValue();
760 if (Val
== "atomic" || Val
== "prefer-atomic")
761 CmdArgs
.push_back("-fprofile-update=atomic");
762 else if (Val
!= "single")
763 D
.Diag(diag::err_drv_unsupported_option_argument
)
764 << A
->getSpelling() << Val
;
767 int FunctionGroups
= 1;
768 int SelectedFunctionGroup
= 0;
769 if (const auto *A
= Args
.getLastArg(options::OPT_fprofile_function_groups
)) {
770 StringRef Val
= A
->getValue();
771 if (Val
.getAsInteger(0, FunctionGroups
) || FunctionGroups
< 1)
772 D
.Diag(diag::err_drv_invalid_int_value
) << A
->getAsString(Args
) << Val
;
775 Args
.getLastArg(options::OPT_fprofile_selected_function_group
)) {
776 StringRef Val
= A
->getValue();
777 if (Val
.getAsInteger(0, SelectedFunctionGroup
) ||
778 SelectedFunctionGroup
< 0 || SelectedFunctionGroup
>= FunctionGroups
)
779 D
.Diag(diag::err_drv_invalid_int_value
) << A
->getAsString(Args
) << Val
;
781 if (FunctionGroups
!= 1)
782 CmdArgs
.push_back(Args
.MakeArgString("-fprofile-function-groups=" +
783 Twine(FunctionGroups
)));
784 if (SelectedFunctionGroup
!= 0)
785 CmdArgs
.push_back(Args
.MakeArgString("-fprofile-selected-function-group=" +
786 Twine(SelectedFunctionGroup
)));
788 // Leave -fprofile-dir= an unused argument unless .gcda emission is
789 // enabled. To be polite, with '-fprofile-arcs -fno-profile-arcs' consider
790 // the flag used. There is no -fno-profile-dir, so the user has no
791 // targeted way to suppress the warning.
792 Arg
*FProfileDir
= nullptr;
793 if (Args
.hasArg(options::OPT_fprofile_arcs
) ||
794 Args
.hasArg(options::OPT_coverage
))
795 FProfileDir
= Args
.getLastArg(options::OPT_fprofile_dir
);
797 // TODO: Don't claim -c/-S to warn about -fsyntax-only -c/-S, -E -c/-S,
798 // like we warn about -fsyntax-only -E.
799 (void)(Args
.hasArg(options::OPT_c
) || Args
.hasArg(options::OPT_S
));
801 // Put the .gcno and .gcda files (if needed) next to the primary output file,
802 // or fall back to a file in the current directory for `clang -c --coverage
803 // d/a.c` in the absence of -o.
804 if (EmitCovNotes
|| EmitCovData
) {
805 SmallString
<128> CoverageFilename
;
806 if (Arg
*DumpDir
= Args
.getLastArgNoClaim(options::OPT_dumpdir
)) {
807 // Form ${dumpdir}${basename}.gcno. Note that dumpdir may not end with a
809 CoverageFilename
= DumpDir
->getValue();
810 CoverageFilename
+= llvm::sys::path::filename(Output
.getBaseInput());
811 } else if (Arg
*FinalOutput
=
812 C
.getArgs().getLastArg(options::OPT__SLASH_Fo
)) {
813 CoverageFilename
= FinalOutput
->getValue();
814 } else if (Arg
*FinalOutput
= C
.getArgs().getLastArg(options::OPT_o
)) {
815 CoverageFilename
= FinalOutput
->getValue();
817 CoverageFilename
= llvm::sys::path::filename(Output
.getBaseInput());
819 if (llvm::sys::path::is_relative(CoverageFilename
))
820 (void)D
.getVFS().makeAbsolute(CoverageFilename
);
821 llvm::sys::path::replace_extension(CoverageFilename
, "gcno");
824 Args
.MakeArgString("-coverage-notes-file=" + CoverageFilename
));
829 SmallString
<128> Gcno
= std::move(CoverageFilename
);
830 CoverageFilename
= FProfileDir
->getValue();
831 llvm::sys::path::append(CoverageFilename
, Gcno
);
833 llvm::sys::path::replace_extension(CoverageFilename
, "gcda");
835 Args
.MakeArgString("-coverage-data-file=" + CoverageFilename
));
841 RenderDebugEnablingArgs(const ArgList
&Args
, ArgStringList
&CmdArgs
,
842 llvm::codegenoptions::DebugInfoKind DebugInfoKind
,
843 unsigned DwarfVersion
,
844 llvm::DebuggerKind DebuggerTuning
) {
845 addDebugInfoKind(CmdArgs
, DebugInfoKind
);
846 if (DwarfVersion
> 0)
848 Args
.MakeArgString("-dwarf-version=" + Twine(DwarfVersion
)));
849 switch (DebuggerTuning
) {
850 case llvm::DebuggerKind::GDB
:
851 CmdArgs
.push_back("-debugger-tuning=gdb");
853 case llvm::DebuggerKind::LLDB
:
854 CmdArgs
.push_back("-debugger-tuning=lldb");
856 case llvm::DebuggerKind::SCE
:
857 CmdArgs
.push_back("-debugger-tuning=sce");
859 case llvm::DebuggerKind::DBX
:
860 CmdArgs
.push_back("-debugger-tuning=dbx");
867 static bool checkDebugInfoOption(const Arg
*A
, const ArgList
&Args
,
868 const Driver
&D
, const ToolChain
&TC
) {
869 assert(A
&& "Expected non-nullptr argument.");
870 if (TC
.supportsDebugInfoOption(A
))
872 D
.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target
)
873 << A
->getAsString(Args
) << TC
.getTripleString();
877 static void RenderDebugInfoCompressionArgs(const ArgList
&Args
,
878 ArgStringList
&CmdArgs
,
880 const ToolChain
&TC
) {
881 const Arg
*A
= Args
.getLastArg(options::OPT_gz_EQ
);
884 if (checkDebugInfoOption(A
, Args
, D
, TC
)) {
885 StringRef Value
= A
->getValue();
886 if (Value
== "none") {
887 CmdArgs
.push_back("--compress-debug-sections=none");
888 } else if (Value
== "zlib") {
889 if (llvm::compression::zlib::isAvailable()) {
891 Args
.MakeArgString("--compress-debug-sections=" + Twine(Value
)));
893 D
.Diag(diag::warn_debug_compression_unavailable
) << "zlib";
895 } else if (Value
== "zstd") {
896 if (llvm::compression::zstd::isAvailable()) {
898 Args
.MakeArgString("--compress-debug-sections=" + Twine(Value
)));
900 D
.Diag(diag::warn_debug_compression_unavailable
) << "zstd";
903 D
.Diag(diag::err_drv_unsupported_option_argument
)
904 << A
->getSpelling() << Value
;
909 static void handleAMDGPUCodeObjectVersionOptions(const Driver
&D
,
911 ArgStringList
&CmdArgs
,
912 bool IsCC1As
= false) {
913 // If no version was requested by the user, use the default value from the
914 // back end. This is consistent with the value returned from
915 // getAMDGPUCodeObjectVersion. This lets clang emit IR for amdgpu without
916 // requiring the corresponding llvm to have the AMDGPU target enabled,
917 // provided the user (e.g. front end tests) can use the default.
918 if (haveAMDGPUCodeObjectVersionArgument(D
, Args
)) {
919 unsigned CodeObjVer
= getAMDGPUCodeObjectVersion(D
, Args
);
920 CmdArgs
.insert(CmdArgs
.begin() + 1,
921 Args
.MakeArgString(Twine("--amdhsa-code-object-version=") +
923 CmdArgs
.insert(CmdArgs
.begin() + 1, "-mllvm");
924 // -cc1as does not accept -mcode-object-version option.
926 CmdArgs
.insert(CmdArgs
.begin() + 1,
927 Args
.MakeArgString(Twine("-mcode-object-version=") +
932 static bool maybeHasClangPchSignature(const Driver
&D
, StringRef Path
) {
933 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>> MemBuf
=
934 D
.getVFS().getBufferForFile(Path
);
937 llvm::file_magic Magic
= llvm::identify_magic((*MemBuf
)->getBuffer());
938 if (Magic
== llvm::file_magic::unknown
)
940 // Return true for both raw Clang AST files and object files which may
941 // contain a __clangast section.
942 if (Magic
== llvm::file_magic::clang_ast
)
944 Expected
<std::unique_ptr
<llvm::object::ObjectFile
>> Obj
=
945 llvm::object::ObjectFile::createObjectFile(**MemBuf
, Magic
);
946 return !Obj
.takeError();
949 static bool gchProbe(const Driver
&D
, StringRef Path
) {
950 llvm::ErrorOr
<llvm::vfs::Status
> Status
= D
.getVFS().status(Path
);
954 if (Status
->isDirectory()) {
956 for (llvm::vfs::directory_iterator DI
= D
.getVFS().dir_begin(Path
, EC
), DE
;
957 !EC
&& DI
!= DE
; DI
= DI
.increment(EC
)) {
958 if (maybeHasClangPchSignature(D
, DI
->path()))
961 D
.Diag(diag::warn_drv_pch_ignoring_gch_dir
) << Path
;
965 if (maybeHasClangPchSignature(D
, Path
))
967 D
.Diag(diag::warn_drv_pch_ignoring_gch_file
) << Path
;
971 void Clang::AddPreprocessingOptions(Compilation
&C
, const JobAction
&JA
,
972 const Driver
&D
, const ArgList
&Args
,
973 ArgStringList
&CmdArgs
,
974 const InputInfo
&Output
,
975 const InputInfoList
&Inputs
) const {
976 const bool IsIAMCU
= getToolChain().getTriple().isOSIAMCU();
978 CheckPreprocessingOptions(D
, Args
);
980 Args
.AddLastArg(CmdArgs
, options::OPT_C
);
981 Args
.AddLastArg(CmdArgs
, options::OPT_CC
);
983 // Handle dependency file generation.
984 Arg
*ArgM
= Args
.getLastArg(options::OPT_MM
);
986 ArgM
= Args
.getLastArg(options::OPT_M
);
987 Arg
*ArgMD
= Args
.getLastArg(options::OPT_MMD
);
989 ArgMD
= Args
.getLastArg(options::OPT_MD
);
991 // -M and -MM imply -w.
993 CmdArgs
.push_back("-w");
998 // Determine the output location.
1000 if (Arg
*MF
= Args
.getLastArg(options::OPT_MF
)) {
1001 DepFile
= MF
->getValue();
1002 C
.addFailureResultFile(DepFile
, &JA
);
1003 } else if (Output
.getType() == types::TY_Dependencies
) {
1004 DepFile
= Output
.getFilename();
1005 } else if (!ArgMD
) {
1008 DepFile
= getDependencyFileName(Args
, Inputs
);
1009 C
.addFailureResultFile(DepFile
, &JA
);
1011 CmdArgs
.push_back("-dependency-file");
1012 CmdArgs
.push_back(DepFile
);
1014 bool HasTarget
= false;
1015 for (const Arg
*A
: Args
.filtered(options::OPT_MT
, options::OPT_MQ
)) {
1018 if (A
->getOption().matches(options::OPT_MT
)) {
1019 A
->render(Args
, CmdArgs
);
1021 CmdArgs
.push_back("-MT");
1022 SmallString
<128> Quoted
;
1023 quoteMakeTarget(A
->getValue(), Quoted
);
1024 CmdArgs
.push_back(Args
.MakeArgString(Quoted
));
1028 // Add a default target if one wasn't specified.
1030 const char *DepTarget
;
1032 // If user provided -o, that is the dependency target, except
1033 // when we are only generating a dependency file.
1034 Arg
*OutputOpt
= Args
.getLastArg(options::OPT_o
, options::OPT__SLASH_Fo
);
1035 if (OutputOpt
&& Output
.getType() != types::TY_Dependencies
) {
1036 DepTarget
= OutputOpt
->getValue();
1038 // Otherwise derive from the base input.
1040 // FIXME: This should use the computed output file location.
1041 SmallString
<128> P(Inputs
[0].getBaseInput());
1042 llvm::sys::path::replace_extension(P
, "o");
1043 DepTarget
= Args
.MakeArgString(llvm::sys::path::filename(P
));
1046 CmdArgs
.push_back("-MT");
1047 SmallString
<128> Quoted
;
1048 quoteMakeTarget(DepTarget
, Quoted
);
1049 CmdArgs
.push_back(Args
.MakeArgString(Quoted
));
1052 if (ArgM
->getOption().matches(options::OPT_M
) ||
1053 ArgM
->getOption().matches(options::OPT_MD
))
1054 CmdArgs
.push_back("-sys-header-deps");
1055 if ((isa
<PrecompileJobAction
>(JA
) &&
1056 !Args
.hasArg(options::OPT_fno_module_file_deps
)) ||
1057 Args
.hasArg(options::OPT_fmodule_file_deps
))
1058 CmdArgs
.push_back("-module-file-deps");
1061 if (Args
.hasArg(options::OPT_MG
)) {
1062 if (!ArgM
|| ArgM
->getOption().matches(options::OPT_MD
) ||
1063 ArgM
->getOption().matches(options::OPT_MMD
))
1064 D
.Diag(diag::err_drv_mg_requires_m_or_mm
);
1065 CmdArgs
.push_back("-MG");
1068 Args
.AddLastArg(CmdArgs
, options::OPT_MP
);
1069 Args
.AddLastArg(CmdArgs
, options::OPT_MV
);
1071 // Add offload include arguments specific for CUDA/HIP. This must happen
1072 // before we -I or -include anything else, because we must pick up the
1073 // CUDA/HIP headers from the particular CUDA/ROCm installation, rather than
1074 // from e.g. /usr/local/include.
1075 if (JA
.isOffloading(Action::OFK_Cuda
))
1076 getToolChain().AddCudaIncludeArgs(Args
, CmdArgs
);
1077 if (JA
.isOffloading(Action::OFK_HIP
))
1078 getToolChain().AddHIPIncludeArgs(Args
, CmdArgs
);
1080 // If we are offloading to a target via OpenMP we need to include the
1081 // openmp_wrappers folder which contains alternative system headers.
1082 if (JA
.isDeviceOffloading(Action::OFK_OpenMP
) &&
1083 !Args
.hasArg(options::OPT_nostdinc
) &&
1084 !Args
.hasArg(options::OPT_nogpuinc
) &&
1085 (getToolChain().getTriple().isNVPTX() ||
1086 getToolChain().getTriple().isAMDGCN())) {
1087 if (!Args
.hasArg(options::OPT_nobuiltininc
)) {
1088 // Add openmp_wrappers/* to our system include path. This lets us wrap
1089 // standard library headers.
1090 SmallString
<128> P(D
.ResourceDir
);
1091 llvm::sys::path::append(P
, "include");
1092 llvm::sys::path::append(P
, "openmp_wrappers");
1093 CmdArgs
.push_back("-internal-isystem");
1094 CmdArgs
.push_back(Args
.MakeArgString(P
));
1097 CmdArgs
.push_back("-include");
1098 CmdArgs
.push_back("__clang_openmp_device_functions.h");
1101 // Add -i* options, and automatically translate to
1102 // -include-pch/-include-pth for transparent PCH support. It's
1103 // wonky, but we include looking for .gch so we can support seamless
1104 // replacement into a build system already set up to be generating
1107 if (getToolChain().getDriver().IsCLMode()) {
1108 const Arg
*YcArg
= Args
.getLastArg(options::OPT__SLASH_Yc
);
1109 const Arg
*YuArg
= Args
.getLastArg(options::OPT__SLASH_Yu
);
1110 if (YcArg
&& JA
.getKind() >= Action::PrecompileJobClass
&&
1111 JA
.getKind() <= Action::AssembleJobClass
) {
1112 CmdArgs
.push_back(Args
.MakeArgString("-building-pch-with-obj"));
1113 // -fpch-instantiate-templates is the default when creating
1114 // precomp using /Yc
1115 if (Args
.hasFlag(options::OPT_fpch_instantiate_templates
,
1116 options::OPT_fno_pch_instantiate_templates
, true))
1117 CmdArgs
.push_back(Args
.MakeArgString("-fpch-instantiate-templates"));
1119 if (YcArg
|| YuArg
) {
1120 StringRef ThroughHeader
= YcArg
? YcArg
->getValue() : YuArg
->getValue();
1121 if (!isa
<PrecompileJobAction
>(JA
)) {
1122 CmdArgs
.push_back("-include-pch");
1123 CmdArgs
.push_back(Args
.MakeArgString(D
.GetClPchPath(
1124 C
, !ThroughHeader
.empty()
1126 : llvm::sys::path::filename(Inputs
[0].getBaseInput()))));
1129 if (ThroughHeader
.empty()) {
1130 CmdArgs
.push_back(Args
.MakeArgString(
1131 Twine("-pch-through-hdrstop-") + (YcArg
? "create" : "use")));
1134 Args
.MakeArgString(Twine("-pch-through-header=") + ThroughHeader
));
1139 bool RenderedImplicitInclude
= false;
1140 for (const Arg
*A
: Args
.filtered(options::OPT_clang_i_Group
)) {
1141 if (A
->getOption().matches(options::OPT_include
) &&
1142 D
.getProbePrecompiled()) {
1143 // Handling of gcc-style gch precompiled headers.
1144 bool IsFirstImplicitInclude
= !RenderedImplicitInclude
;
1145 RenderedImplicitInclude
= true;
1147 bool FoundPCH
= false;
1148 SmallString
<128> P(A
->getValue());
1149 // We want the files to have a name like foo.h.pch. Add a dummy extension
1150 // so that replace_extension does the right thing.
1152 llvm::sys::path::replace_extension(P
, "pch");
1153 if (D
.getVFS().exists(P
))
1157 // For GCC compat, probe for a file or directory ending in .gch instead.
1158 llvm::sys::path::replace_extension(P
, "gch");
1159 FoundPCH
= gchProbe(D
, P
.str());
1163 if (IsFirstImplicitInclude
) {
1165 CmdArgs
.push_back("-include-pch");
1166 CmdArgs
.push_back(Args
.MakeArgString(P
));
1169 // Ignore the PCH if not first on command line and emit warning.
1170 D
.Diag(diag::warn_drv_pch_not_first_include
) << P
1171 << A
->getAsString(Args
);
1174 } else if (A
->getOption().matches(options::OPT_isystem_after
)) {
1175 // Handling of paths which must come late. These entries are handled by
1176 // the toolchain itself after the resource dir is inserted in the right
1178 // Do not claim the argument so that the use of the argument does not
1179 // silently go unnoticed on toolchains which do not honour the option.
1181 } else if (A
->getOption().matches(options::OPT_stdlibxx_isystem
)) {
1182 // Translated to -internal-isystem by the driver, no need to pass to cc1.
1184 } else if (A
->getOption().matches(options::OPT_ibuiltininc
)) {
1185 // This is used only by the driver. No need to pass to cc1.
1189 // Not translated, render as usual.
1191 A
->render(Args
, CmdArgs
);
1194 Args
.addAllArgs(CmdArgs
,
1195 {options::OPT_D
, options::OPT_U
, options::OPT_I_Group
,
1196 options::OPT_F
, options::OPT_index_header_map
,
1197 options::OPT_embed_dir_EQ
});
1199 // Add -Wp, and -Xpreprocessor if using the preprocessor.
1201 // FIXME: There is a very unfortunate problem here, some troubled
1202 // souls abuse -Wp, to pass preprocessor options in gcc syntax. To
1203 // really support that we would have to parse and then translate
1204 // those options. :(
1205 Args
.AddAllArgValues(CmdArgs
, options::OPT_Wp_COMMA
,
1206 options::OPT_Xpreprocessor
);
1208 // -I- is a deprecated GCC feature, reject it.
1209 if (Arg
*A
= Args
.getLastArg(options::OPT_I_
))
1210 D
.Diag(diag::err_drv_I_dash_not_supported
) << A
->getAsString(Args
);
1212 // If we have a --sysroot, and don't have an explicit -isysroot flag, add an
1213 // -isysroot to the CC1 invocation.
1214 StringRef sysroot
= C
.getSysRoot();
1215 if (sysroot
!= "") {
1216 if (!Args
.hasArg(options::OPT_isysroot
)) {
1217 CmdArgs
.push_back("-isysroot");
1218 CmdArgs
.push_back(C
.getArgs().MakeArgString(sysroot
));
1222 // Parse additional include paths from environment variables.
1223 // FIXME: We should probably sink the logic for handling these from the
1224 // frontend into the driver. It will allow deleting 4 otherwise unused flags.
1225 // CPATH - included following the user specified includes (but prior to
1226 // builtin and standard includes).
1227 addDirectoryList(Args
, CmdArgs
, "-I", "CPATH");
1228 // C_INCLUDE_PATH - system includes enabled when compiling C.
1229 addDirectoryList(Args
, CmdArgs
, "-c-isystem", "C_INCLUDE_PATH");
1230 // CPLUS_INCLUDE_PATH - system includes enabled when compiling C++.
1231 addDirectoryList(Args
, CmdArgs
, "-cxx-isystem", "CPLUS_INCLUDE_PATH");
1232 // OBJC_INCLUDE_PATH - system includes enabled when compiling ObjC.
1233 addDirectoryList(Args
, CmdArgs
, "-objc-isystem", "OBJC_INCLUDE_PATH");
1234 // OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++.
1235 addDirectoryList(Args
, CmdArgs
, "-objcxx-isystem", "OBJCPLUS_INCLUDE_PATH");
1237 // While adding the include arguments, we also attempt to retrieve the
1238 // arguments of related offloading toolchains or arguments that are specific
1239 // of an offloading programming model.
1241 // Add C++ include arguments, if needed.
1242 if (types::isCXX(Inputs
[0].getType())) {
1243 bool HasStdlibxxIsystem
= Args
.hasArg(options::OPT_stdlibxx_isystem
);
1244 forAllAssociatedToolChains(
1245 C
, JA
, getToolChain(),
1246 [&Args
, &CmdArgs
, HasStdlibxxIsystem
](const ToolChain
&TC
) {
1247 HasStdlibxxIsystem
? TC
.AddClangCXXStdlibIsystemArgs(Args
, CmdArgs
)
1248 : TC
.AddClangCXXStdlibIncludeArgs(Args
, CmdArgs
);
1252 // If we are compiling for a GPU target we want to override the system headers
1253 // with ones created by the 'libc' project if present.
1254 // TODO: This should be moved to `AddClangSystemIncludeArgs` by passing the
1255 // OffloadKind as an argument.
1256 if (!Args
.hasArg(options::OPT_nostdinc
) &&
1257 !Args
.hasArg(options::OPT_nogpuinc
) &&
1258 !Args
.hasArg(options::OPT_nobuiltininc
)) {
1259 // Without an offloading language we will include these headers directly.
1260 // Offloading languages will instead only use the declarations stored in
1261 // the resource directory at clang/lib/Headers/llvm_libc_wrappers.
1262 if ((getToolChain().getTriple().isNVPTX() ||
1263 getToolChain().getTriple().isAMDGCN()) &&
1264 C
.getActiveOffloadKinds() == Action::OFK_None
) {
1265 SmallString
<128> P(llvm::sys::path::parent_path(D
.Dir
));
1266 llvm::sys::path::append(P
, "include");
1267 llvm::sys::path::append(P
, getToolChain().getTripleString());
1268 CmdArgs
.push_back("-internal-isystem");
1269 CmdArgs
.push_back(Args
.MakeArgString(P
));
1270 } else if (C
.getActiveOffloadKinds() == Action::OFK_OpenMP
) {
1271 // TODO: CUDA / HIP include their own headers for some common functions
1272 // implemented here. We'll need to clean those up so they do not conflict.
1273 SmallString
<128> P(D
.ResourceDir
);
1274 llvm::sys::path::append(P
, "include");
1275 llvm::sys::path::append(P
, "llvm_libc_wrappers");
1276 CmdArgs
.push_back("-internal-isystem");
1277 CmdArgs
.push_back(Args
.MakeArgString(P
));
1281 // Add system include arguments for all targets but IAMCU.
1283 forAllAssociatedToolChains(C
, JA
, getToolChain(),
1284 [&Args
, &CmdArgs
](const ToolChain
&TC
) {
1285 TC
.AddClangSystemIncludeArgs(Args
, CmdArgs
);
1288 // For IAMCU add special include arguments.
1289 getToolChain().AddIAMCUIncludeArgs(Args
, CmdArgs
);
1292 addMacroPrefixMapArg(D
, Args
, CmdArgs
);
1293 addCoveragePrefixMapArg(D
, Args
, CmdArgs
);
1295 Args
.AddLastArg(CmdArgs
, options::OPT_ffile_reproducible
,
1296 options::OPT_fno_file_reproducible
);
1298 if (const char *Epoch
= std::getenv("SOURCE_DATE_EPOCH")) {
1299 CmdArgs
.push_back("-source-date-epoch");
1300 CmdArgs
.push_back(Args
.MakeArgString(Epoch
));
1303 Args
.addOptInFlag(CmdArgs
, options::OPT_fdefine_target_os_macros
,
1304 options::OPT_fno_define_target_os_macros
);
1307 // FIXME: Move to target hook.
1308 static bool isSignedCharDefault(const llvm::Triple
&Triple
) {
1309 switch (Triple
.getArch()) {
1313 case llvm::Triple::aarch64
:
1314 case llvm::Triple::aarch64_32
:
1315 case llvm::Triple::aarch64_be
:
1316 case llvm::Triple::arm
:
1317 case llvm::Triple::armeb
:
1318 case llvm::Triple::thumb
:
1319 case llvm::Triple::thumbeb
:
1320 if (Triple
.isOSDarwin() || Triple
.isOSWindows())
1324 case llvm::Triple::ppc
:
1325 case llvm::Triple::ppc64
:
1326 if (Triple
.isOSDarwin())
1330 case llvm::Triple::hexagon
:
1331 case llvm::Triple::ppcle
:
1332 case llvm::Triple::ppc64le
:
1333 case llvm::Triple::riscv32
:
1334 case llvm::Triple::riscv64
:
1335 case llvm::Triple::systemz
:
1336 case llvm::Triple::xcore
:
1341 static bool hasMultipleInvocations(const llvm::Triple
&Triple
,
1342 const ArgList
&Args
) {
1343 // Supported only on Darwin where we invoke the compiler multiple times
1344 // followed by an invocation to lipo.
1345 if (!Triple
.isOSDarwin())
1347 // If more than one "-arch <arch>" is specified, we're targeting multiple
1348 // architectures resulting in a fat binary.
1349 return Args
.getAllArgValues(options::OPT_arch
).size() > 1;
1352 static bool checkRemarksOptions(const Driver
&D
, const ArgList
&Args
,
1353 const llvm::Triple
&Triple
) {
1354 // When enabling remarks, we need to error if:
1355 // * The remark file is specified but we're targeting multiple architectures,
1356 // which means more than one remark file is being generated.
1357 bool hasMultipleInvocations
= ::hasMultipleInvocations(Triple
, Args
);
1358 bool hasExplicitOutputFile
=
1359 Args
.getLastArg(options::OPT_foptimization_record_file_EQ
);
1360 if (hasMultipleInvocations
&& hasExplicitOutputFile
) {
1361 D
.Diag(diag::err_drv_invalid_output_with_multiple_archs
)
1362 << "-foptimization-record-file";
1368 static void renderRemarksOptions(const ArgList
&Args
, ArgStringList
&CmdArgs
,
1369 const llvm::Triple
&Triple
,
1370 const InputInfo
&Input
,
1371 const InputInfo
&Output
, const JobAction
&JA
) {
1372 StringRef Format
= "yaml";
1373 if (const Arg
*A
= Args
.getLastArg(options::OPT_fsave_optimization_record_EQ
))
1374 Format
= A
->getValue();
1376 CmdArgs
.push_back("-opt-record-file");
1378 const Arg
*A
= Args
.getLastArg(options::OPT_foptimization_record_file_EQ
);
1380 CmdArgs
.push_back(A
->getValue());
1382 bool hasMultipleArchs
=
1383 Triple
.isOSDarwin() && // Only supported on Darwin platforms.
1384 Args
.getAllArgValues(options::OPT_arch
).size() > 1;
1388 if (Args
.hasArg(options::OPT_c
) || Args
.hasArg(options::OPT_S
)) {
1389 if (Arg
*FinalOutput
= Args
.getLastArg(options::OPT_o
))
1390 F
= FinalOutput
->getValue();
1392 if (Format
!= "yaml" && // For YAML, keep the original behavior.
1393 Triple
.isOSDarwin() && // Enable this only on darwin, since it's the only platform supporting .dSYM bundles.
1394 Output
.isFilename())
1395 F
= Output
.getFilename();
1399 // Use the input filename.
1400 F
= llvm::sys::path::stem(Input
.getBaseInput());
1402 // If we're compiling for an offload architecture (i.e. a CUDA device),
1403 // we need to make the file name for the device compilation different
1404 // from the host compilation.
1405 if (!JA
.isDeviceOffloading(Action::OFK_None
) &&
1406 !JA
.isDeviceOffloading(Action::OFK_Host
)) {
1407 llvm::sys::path::replace_extension(F
, "");
1408 F
+= Action::GetOffloadingFileNamePrefix(JA
.getOffloadingDeviceKind(),
1409 Triple
.normalize());
1411 F
+= JA
.getOffloadingArch();
1415 // If we're having more than one "-arch", we should name the files
1416 // differently so that every cc1 invocation writes to a different file.
1417 // We're doing that by appending "-<arch>" with "<arch>" being the arch
1418 // name from the triple.
1419 if (hasMultipleArchs
) {
1420 // First, remember the extension.
1421 SmallString
<64> OldExtension
= llvm::sys::path::extension(F
);
1423 llvm::sys::path::replace_extension(F
, "");
1424 // attach -<arch> to it.
1426 F
+= Triple
.getArchName();
1427 // put back the extension.
1428 llvm::sys::path::replace_extension(F
, OldExtension
);
1431 SmallString
<32> Extension
;
1432 Extension
+= "opt.";
1433 Extension
+= Format
;
1435 llvm::sys::path::replace_extension(F
, Extension
);
1436 CmdArgs
.push_back(Args
.MakeArgString(F
));
1440 Args
.getLastArg(options::OPT_foptimization_record_passes_EQ
)) {
1441 CmdArgs
.push_back("-opt-record-passes");
1442 CmdArgs
.push_back(A
->getValue());
1445 if (!Format
.empty()) {
1446 CmdArgs
.push_back("-opt-record-format");
1447 CmdArgs
.push_back(Format
.data());
1451 void AddAAPCSVolatileBitfieldArgs(const ArgList
&Args
, ArgStringList
&CmdArgs
) {
1452 if (!Args
.hasFlag(options::OPT_faapcs_bitfield_width
,
1453 options::OPT_fno_aapcs_bitfield_width
, true))
1454 CmdArgs
.push_back("-fno-aapcs-bitfield-width");
1456 if (Args
.getLastArg(options::OPT_ForceAAPCSBitfieldLoad
))
1457 CmdArgs
.push_back("-faapcs-bitfield-load");
1461 void RenderARMABI(const Driver
&D
, const llvm::Triple
&Triple
,
1462 const ArgList
&Args
, ArgStringList
&CmdArgs
) {
1463 // Select the ABI to use.
1464 // FIXME: Support -meabi.
1465 // FIXME: Parts of this are duplicated in the backend, unify this somehow.
1466 const char *ABIName
= nullptr;
1467 if (Arg
*A
= Args
.getLastArg(options::OPT_mabi_EQ
)) {
1468 ABIName
= A
->getValue();
1470 std::string CPU
= getCPUName(D
, Args
, Triple
, /*FromAs*/ false);
1471 ABIName
= llvm::ARM::computeDefaultTargetABI(Triple
, CPU
).data();
1474 CmdArgs
.push_back("-target-abi");
1475 CmdArgs
.push_back(ABIName
);
1478 void AddUnalignedAccessWarning(ArgStringList
&CmdArgs
) {
1479 auto StrictAlignIter
=
1480 llvm::find_if(llvm::reverse(CmdArgs
), [](StringRef Arg
) {
1481 return Arg
== "+strict-align" || Arg
== "-strict-align";
1483 if (StrictAlignIter
!= CmdArgs
.rend() &&
1484 StringRef(*StrictAlignIter
) == "+strict-align")
1485 CmdArgs
.push_back("-Wunaligned-access");
1489 // Each combination of options here forms a signing schema, and in most cases
1490 // each signing schema is its own incompatible ABI. The default values of the
1491 // options represent the default signing schema.
1492 static void handlePAuthABI(const ArgList
&DriverArgs
, ArgStringList
&CC1Args
) {
1493 if (!DriverArgs
.hasArg(options::OPT_fptrauth_intrinsics
,
1494 options::OPT_fno_ptrauth_intrinsics
))
1495 CC1Args
.push_back("-fptrauth-intrinsics");
1497 if (!DriverArgs
.hasArg(options::OPT_fptrauth_calls
,
1498 options::OPT_fno_ptrauth_calls
))
1499 CC1Args
.push_back("-fptrauth-calls");
1501 if (!DriverArgs
.hasArg(options::OPT_fptrauth_returns
,
1502 options::OPT_fno_ptrauth_returns
))
1503 CC1Args
.push_back("-fptrauth-returns");
1505 if (!DriverArgs
.hasArg(options::OPT_fptrauth_auth_traps
,
1506 options::OPT_fno_ptrauth_auth_traps
))
1507 CC1Args
.push_back("-fptrauth-auth-traps");
1509 if (!DriverArgs
.hasArg(
1510 options::OPT_fptrauth_vtable_pointer_address_discrimination
,
1511 options::OPT_fno_ptrauth_vtable_pointer_address_discrimination
))
1512 CC1Args
.push_back("-fptrauth-vtable-pointer-address-discrimination");
1514 if (!DriverArgs
.hasArg(
1515 options::OPT_fptrauth_vtable_pointer_type_discrimination
,
1516 options::OPT_fno_ptrauth_vtable_pointer_type_discrimination
))
1517 CC1Args
.push_back("-fptrauth-vtable-pointer-type-discrimination");
1519 if (!DriverArgs
.hasArg(options::OPT_fptrauth_indirect_gotos
,
1520 options::OPT_fno_ptrauth_indirect_gotos
))
1521 CC1Args
.push_back("-fptrauth-indirect-gotos");
1523 if (!DriverArgs
.hasArg(options::OPT_fptrauth_init_fini
,
1524 options::OPT_fno_ptrauth_init_fini
))
1525 CC1Args
.push_back("-fptrauth-init-fini");
1528 static void CollectARMPACBTIOptions(const ToolChain
&TC
, const ArgList
&Args
,
1529 ArgStringList
&CmdArgs
, bool isAArch64
) {
1530 const Arg
*A
= isAArch64
1531 ? Args
.getLastArg(options::OPT_msign_return_address_EQ
,
1532 options::OPT_mbranch_protection_EQ
)
1533 : Args
.getLastArg(options::OPT_mbranch_protection_EQ
);
1537 const Driver
&D
= TC
.getDriver();
1538 const llvm::Triple
&Triple
= TC
.getEffectiveTriple();
1539 if (!(isAArch64
|| (Triple
.isArmT32() && Triple
.isArmMClass())))
1540 D
.Diag(diag::warn_incompatible_branch_protection_option
)
1541 << Triple
.getArchName();
1543 StringRef Scope
, Key
;
1544 bool IndirectBranches
, BranchProtectionPAuthLR
, GuardedControlStack
;
1546 if (A
->getOption().matches(options::OPT_msign_return_address_EQ
)) {
1547 Scope
= A
->getValue();
1548 if (Scope
!= "none" && Scope
!= "non-leaf" && Scope
!= "all")
1549 D
.Diag(diag::err_drv_unsupported_option_argument
)
1550 << A
->getSpelling() << Scope
;
1552 IndirectBranches
= false;
1553 BranchProtectionPAuthLR
= false;
1554 GuardedControlStack
= false;
1557 llvm::ARM::ParsedBranchProtection PBP
;
1558 bool EnablePAuthLR
= false;
1560 // To know if we need to enable PAuth-LR As part of the standard branch
1561 // protection option, it needs to be determined if the feature has been
1562 // activated in the `march` argument. This information is stored within the
1563 // CmdArgs variable and can be found using a search.
1565 auto isPAuthLR
= [](const char *member
) {
1566 llvm::AArch64::ExtensionInfo pauthlr_extension
=
1567 llvm::AArch64::getExtensionByID(llvm::AArch64::AEK_PAUTHLR
);
1568 return pauthlr_extension
.PosTargetFeature
== member
;
1571 if (std::any_of(CmdArgs
.begin(), CmdArgs
.end(), isPAuthLR
))
1572 EnablePAuthLR
= true;
1574 if (!llvm::ARM::parseBranchProtection(A
->getValue(), PBP
, DiagMsg
,
1576 D
.Diag(diag::err_drv_unsupported_option_argument
)
1577 << A
->getSpelling() << DiagMsg
;
1578 if (!isAArch64
&& PBP
.Key
== "b_key")
1579 D
.Diag(diag::warn_unsupported_branch_protection
)
1580 << "b-key" << A
->getAsString(Args
);
1583 BranchProtectionPAuthLR
= PBP
.BranchProtectionPAuthLR
;
1584 IndirectBranches
= PBP
.BranchTargetEnforcement
;
1585 GuardedControlStack
= PBP
.GuardedControlStack
;
1589 Args
.MakeArgString(Twine("-msign-return-address=") + Scope
));
1590 if (Scope
!= "none") {
1591 if (Triple
.getEnvironment() == llvm::Triple::PAuthTest
)
1592 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
1593 << A
->getAsString(Args
) << Triple
.getTriple();
1595 Args
.MakeArgString(Twine("-msign-return-address-key=") + Key
));
1597 if (BranchProtectionPAuthLR
) {
1598 if (Triple
.getEnvironment() == llvm::Triple::PAuthTest
)
1599 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
1600 << A
->getAsString(Args
) << Triple
.getTriple();
1602 Args
.MakeArgString(Twine("-mbranch-protection-pauth-lr")));
1604 if (IndirectBranches
)
1605 CmdArgs
.push_back("-mbranch-target-enforce");
1606 // GCS is currently untested with PAuthABI, but enabling this could be allowed
1607 // in future after testing with a suitable system.
1608 if (GuardedControlStack
) {
1609 if (Triple
.getEnvironment() == llvm::Triple::PAuthTest
)
1610 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
1611 << A
->getAsString(Args
) << Triple
.getTriple();
1612 CmdArgs
.push_back("-mguarded-control-stack");
1616 void Clang::AddARMTargetArgs(const llvm::Triple
&Triple
, const ArgList
&Args
,
1617 ArgStringList
&CmdArgs
, bool KernelOrKext
) const {
1618 RenderARMABI(getToolChain().getDriver(), Triple
, Args
, CmdArgs
);
1620 // Determine floating point ABI from the options & target defaults.
1621 arm::FloatABI ABI
= arm::getARMFloatABI(getToolChain(), Args
);
1622 if (ABI
== arm::FloatABI::Soft
) {
1623 // Floating point operations and argument passing are soft.
1624 // FIXME: This changes CPP defines, we need -target-soft-float.
1625 CmdArgs
.push_back("-msoft-float");
1626 CmdArgs
.push_back("-mfloat-abi");
1627 CmdArgs
.push_back("soft");
1628 } else if (ABI
== arm::FloatABI::SoftFP
) {
1629 // Floating point operations are hard, but argument passing is soft.
1630 CmdArgs
.push_back("-mfloat-abi");
1631 CmdArgs
.push_back("soft");
1633 // Floating point operations and argument passing are hard.
1634 assert(ABI
== arm::FloatABI::Hard
&& "Invalid float abi!");
1635 CmdArgs
.push_back("-mfloat-abi");
1636 CmdArgs
.push_back("hard");
1639 // Forward the -mglobal-merge option for explicit control over the pass.
1640 if (Arg
*A
= Args
.getLastArg(options::OPT_mglobal_merge
,
1641 options::OPT_mno_global_merge
)) {
1642 CmdArgs
.push_back("-mllvm");
1643 if (A
->getOption().matches(options::OPT_mno_global_merge
))
1644 CmdArgs
.push_back("-arm-global-merge=false");
1646 CmdArgs
.push_back("-arm-global-merge=true");
1649 if (!Args
.hasFlag(options::OPT_mimplicit_float
,
1650 options::OPT_mno_implicit_float
, true))
1651 CmdArgs
.push_back("-no-implicit-float");
1653 if (Args
.getLastArg(options::OPT_mcmse
))
1654 CmdArgs
.push_back("-mcmse");
1656 AddAAPCSVolatileBitfieldArgs(Args
, CmdArgs
);
1658 // Enable/disable return address signing and indirect branch targets.
1659 CollectARMPACBTIOptions(getToolChain(), Args
, CmdArgs
, false /*isAArch64*/);
1661 AddUnalignedAccessWarning(CmdArgs
);
1664 void Clang::RenderTargetOptions(const llvm::Triple
&EffectiveTriple
,
1665 const ArgList
&Args
, bool KernelOrKext
,
1666 ArgStringList
&CmdArgs
) const {
1667 const ToolChain
&TC
= getToolChain();
1669 // Add the target features
1670 getTargetFeatures(TC
.getDriver(), EffectiveTriple
, Args
, CmdArgs
, false);
1672 // Add target specific flags.
1673 switch (TC
.getArch()) {
1677 case llvm::Triple::arm
:
1678 case llvm::Triple::armeb
:
1679 case llvm::Triple::thumb
:
1680 case llvm::Triple::thumbeb
:
1681 // Use the effective triple, which takes into account the deployment target.
1682 AddARMTargetArgs(EffectiveTriple
, Args
, CmdArgs
, KernelOrKext
);
1685 case llvm::Triple::aarch64
:
1686 case llvm::Triple::aarch64_32
:
1687 case llvm::Triple::aarch64_be
:
1688 AddAArch64TargetArgs(Args
, CmdArgs
);
1691 case llvm::Triple::loongarch32
:
1692 case llvm::Triple::loongarch64
:
1693 AddLoongArchTargetArgs(Args
, CmdArgs
);
1696 case llvm::Triple::mips
:
1697 case llvm::Triple::mipsel
:
1698 case llvm::Triple::mips64
:
1699 case llvm::Triple::mips64el
:
1700 AddMIPSTargetArgs(Args
, CmdArgs
);
1703 case llvm::Triple::ppc
:
1704 case llvm::Triple::ppcle
:
1705 case llvm::Triple::ppc64
:
1706 case llvm::Triple::ppc64le
:
1707 AddPPCTargetArgs(Args
, CmdArgs
);
1710 case llvm::Triple::riscv32
:
1711 case llvm::Triple::riscv64
:
1712 AddRISCVTargetArgs(Args
, CmdArgs
);
1715 case llvm::Triple::sparc
:
1716 case llvm::Triple::sparcel
:
1717 case llvm::Triple::sparcv9
:
1718 AddSparcTargetArgs(Args
, CmdArgs
);
1721 case llvm::Triple::systemz
:
1722 AddSystemZTargetArgs(Args
, CmdArgs
);
1725 case llvm::Triple::x86
:
1726 case llvm::Triple::x86_64
:
1727 AddX86TargetArgs(Args
, CmdArgs
);
1730 case llvm::Triple::lanai
:
1731 AddLanaiTargetArgs(Args
, CmdArgs
);
1734 case llvm::Triple::hexagon
:
1735 AddHexagonTargetArgs(Args
, CmdArgs
);
1738 case llvm::Triple::wasm32
:
1739 case llvm::Triple::wasm64
:
1740 AddWebAssemblyTargetArgs(Args
, CmdArgs
);
1743 case llvm::Triple::ve
:
1744 AddVETargetArgs(Args
, CmdArgs
);
1750 void RenderAArch64ABI(const llvm::Triple
&Triple
, const ArgList
&Args
,
1751 ArgStringList
&CmdArgs
) {
1752 const char *ABIName
= nullptr;
1753 if (Arg
*A
= Args
.getLastArg(options::OPT_mabi_EQ
))
1754 ABIName
= A
->getValue();
1755 else if (Triple
.isOSDarwin())
1756 ABIName
= "darwinpcs";
1757 else if (Triple
.getEnvironment() == llvm::Triple::PAuthTest
)
1758 ABIName
= "pauthtest";
1762 CmdArgs
.push_back("-target-abi");
1763 CmdArgs
.push_back(ABIName
);
1767 void Clang::AddAArch64TargetArgs(const ArgList
&Args
,
1768 ArgStringList
&CmdArgs
) const {
1769 const llvm::Triple
&Triple
= getToolChain().getEffectiveTriple();
1771 if (!Args
.hasFlag(options::OPT_mred_zone
, options::OPT_mno_red_zone
, true) ||
1772 Args
.hasArg(options::OPT_mkernel
) ||
1773 Args
.hasArg(options::OPT_fapple_kext
))
1774 CmdArgs
.push_back("-disable-red-zone");
1776 if (!Args
.hasFlag(options::OPT_mimplicit_float
,
1777 options::OPT_mno_implicit_float
, true))
1778 CmdArgs
.push_back("-no-implicit-float");
1780 RenderAArch64ABI(Triple
, Args
, CmdArgs
);
1782 // Forward the -mglobal-merge option for explicit control over the pass.
1783 if (Arg
*A
= Args
.getLastArg(options::OPT_mglobal_merge
,
1784 options::OPT_mno_global_merge
)) {
1785 CmdArgs
.push_back("-mllvm");
1786 if (A
->getOption().matches(options::OPT_mno_global_merge
))
1787 CmdArgs
.push_back("-aarch64-enable-global-merge=false");
1789 CmdArgs
.push_back("-aarch64-enable-global-merge=true");
1792 // Enable/disable return address signing and indirect branch targets.
1793 CollectARMPACBTIOptions(getToolChain(), Args
, CmdArgs
, true /*isAArch64*/);
1795 if (Triple
.getEnvironment() == llvm::Triple::PAuthTest
)
1796 handlePAuthABI(Args
, CmdArgs
);
1798 // Handle -msve_vector_bits=<bits>
1799 if (Arg
*A
= Args
.getLastArg(options::OPT_msve_vector_bits_EQ
)) {
1800 StringRef Val
= A
->getValue();
1801 const Driver
&D
= getToolChain().getDriver();
1802 if (Val
== "128" || Val
== "256" || Val
== "512" || Val
== "1024" ||
1803 Val
== "2048" || Val
== "128+" || Val
== "256+" || Val
== "512+" ||
1804 Val
== "1024+" || Val
== "2048+") {
1806 if (!Val
.consume_back("+")) {
1807 bool Invalid
= Val
.getAsInteger(10, Bits
); (void)Invalid
;
1808 assert(!Invalid
&& "Failed to parse value");
1810 Args
.MakeArgString("-mvscale-max=" + llvm::Twine(Bits
/ 128)));
1813 bool Invalid
= Val
.getAsInteger(10, Bits
); (void)Invalid
;
1814 assert(!Invalid
&& "Failed to parse value");
1816 Args
.MakeArgString("-mvscale-min=" + llvm::Twine(Bits
/ 128)));
1817 // Silently drop requests for vector-length agnostic code as it's implied.
1818 } else if (Val
!= "scalable")
1819 // Handle the unsupported values passed to msve-vector-bits.
1820 D
.Diag(diag::err_drv_unsupported_option_argument
)
1821 << A
->getSpelling() << Val
;
1824 AddAAPCSVolatileBitfieldArgs(Args
, CmdArgs
);
1826 if (const Arg
*A
= Args
.getLastArg(clang::driver::options::OPT_mtune_EQ
)) {
1827 CmdArgs
.push_back("-tune-cpu");
1828 if (strcmp(A
->getValue(), "native") == 0)
1829 CmdArgs
.push_back(Args
.MakeArgString(llvm::sys::getHostCPUName()));
1831 CmdArgs
.push_back(A
->getValue());
1834 AddUnalignedAccessWarning(CmdArgs
);
1836 Args
.addOptInFlag(CmdArgs
, options::OPT_fptrauth_intrinsics
,
1837 options::OPT_fno_ptrauth_intrinsics
);
1838 Args
.addOptInFlag(CmdArgs
, options::OPT_fptrauth_calls
,
1839 options::OPT_fno_ptrauth_calls
);
1840 Args
.addOptInFlag(CmdArgs
, options::OPT_fptrauth_returns
,
1841 options::OPT_fno_ptrauth_returns
);
1842 Args
.addOptInFlag(CmdArgs
, options::OPT_fptrauth_auth_traps
,
1843 options::OPT_fno_ptrauth_auth_traps
);
1845 CmdArgs
, options::OPT_fptrauth_vtable_pointer_address_discrimination
,
1846 options::OPT_fno_ptrauth_vtable_pointer_address_discrimination
);
1848 CmdArgs
, options::OPT_fptrauth_vtable_pointer_type_discrimination
,
1849 options::OPT_fno_ptrauth_vtable_pointer_type_discrimination
);
1851 CmdArgs
, options::OPT_fptrauth_type_info_vtable_pointer_discrimination
,
1852 options::OPT_fno_ptrauth_type_info_vtable_pointer_discrimination
);
1853 Args
.addOptInFlag(CmdArgs
, options::OPT_fptrauth_init_fini
,
1854 options::OPT_fno_ptrauth_init_fini
);
1856 CmdArgs
, options::OPT_fptrauth_function_pointer_type_discrimination
,
1857 options::OPT_fno_ptrauth_function_pointer_type_discrimination
);
1859 Args
.addOptInFlag(CmdArgs
, options::OPT_fptrauth_indirect_gotos
,
1860 options::OPT_fno_ptrauth_indirect_gotos
);
1863 void Clang::AddLoongArchTargetArgs(const ArgList
&Args
,
1864 ArgStringList
&CmdArgs
) const {
1865 const llvm::Triple
&Triple
= getToolChain().getTriple();
1867 CmdArgs
.push_back("-target-abi");
1869 loongarch::getLoongArchABI(getToolChain().getDriver(), Args
, Triple
)
1873 if (const Arg
*A
= Args
.getLastArg(options::OPT_mtune_EQ
)) {
1874 std::string TuneCPU
= A
->getValue();
1875 TuneCPU
= loongarch::postProcessTargetCPUString(TuneCPU
, Triple
);
1876 CmdArgs
.push_back("-tune-cpu");
1877 CmdArgs
.push_back(Args
.MakeArgString(TuneCPU
));
1881 void Clang::AddMIPSTargetArgs(const ArgList
&Args
,
1882 ArgStringList
&CmdArgs
) const {
1883 const Driver
&D
= getToolChain().getDriver();
1886 const llvm::Triple
&Triple
= getToolChain().getTriple();
1887 mips::getMipsCPUAndABI(Args
, Triple
, CPUName
, ABIName
);
1889 CmdArgs
.push_back("-target-abi");
1890 CmdArgs
.push_back(ABIName
.data());
1892 mips::FloatABI ABI
= mips::getMipsFloatABI(D
, Args
, Triple
);
1893 if (ABI
== mips::FloatABI::Soft
) {
1894 // Floating point operations and argument passing are soft.
1895 CmdArgs
.push_back("-msoft-float");
1896 CmdArgs
.push_back("-mfloat-abi");
1897 CmdArgs
.push_back("soft");
1899 // Floating point operations and argument passing are hard.
1900 assert(ABI
== mips::FloatABI::Hard
&& "Invalid float abi!");
1901 CmdArgs
.push_back("-mfloat-abi");
1902 CmdArgs
.push_back("hard");
1905 if (Arg
*A
= Args
.getLastArg(options::OPT_mldc1_sdc1
,
1906 options::OPT_mno_ldc1_sdc1
)) {
1907 if (A
->getOption().matches(options::OPT_mno_ldc1_sdc1
)) {
1908 CmdArgs
.push_back("-mllvm");
1909 CmdArgs
.push_back("-mno-ldc1-sdc1");
1913 if (Arg
*A
= Args
.getLastArg(options::OPT_mcheck_zero_division
,
1914 options::OPT_mno_check_zero_division
)) {
1915 if (A
->getOption().matches(options::OPT_mno_check_zero_division
)) {
1916 CmdArgs
.push_back("-mllvm");
1917 CmdArgs
.push_back("-mno-check-zero-division");
1921 if (Args
.getLastArg(options::OPT_mfix4300
)) {
1922 CmdArgs
.push_back("-mllvm");
1923 CmdArgs
.push_back("-mfix4300");
1926 if (Arg
*A
= Args
.getLastArg(options::OPT_G
)) {
1927 StringRef v
= A
->getValue();
1928 CmdArgs
.push_back("-mllvm");
1929 CmdArgs
.push_back(Args
.MakeArgString("-mips-ssection-threshold=" + v
));
1933 Arg
*GPOpt
= Args
.getLastArg(options::OPT_mgpopt
, options::OPT_mno_gpopt
);
1935 Args
.getLastArg(options::OPT_mabicalls
, options::OPT_mno_abicalls
);
1937 // -mabicalls is the default for many MIPS environments, even with -fno-pic.
1938 // -mgpopt is the default for static, -fno-pic environments but these two
1939 // options conflict. We want to be certain that -mno-abicalls -mgpopt is
1940 // the only case where -mllvm -mgpopt is passed.
1941 // NOTE: We need a warning here or in the backend to warn when -mgpopt is
1942 // passed explicitly when compiling something with -mabicalls
1943 // (implictly) in affect. Currently the warning is in the backend.
1945 // When the ABI in use is N64, we also need to determine the PIC mode that
1946 // is in use, as -fno-pic for N64 implies -mno-abicalls.
1948 ABICalls
&& ABICalls
->getOption().matches(options::OPT_mno_abicalls
);
1950 llvm::Reloc::Model RelocationModel
;
1953 std::tie(RelocationModel
, PICLevel
, IsPIE
) =
1954 ParsePICArgs(getToolChain(), Args
);
1956 NoABICalls
= NoABICalls
||
1957 (RelocationModel
== llvm::Reloc::Static
&& ABIName
== "n64");
1959 bool WantGPOpt
= GPOpt
&& GPOpt
->getOption().matches(options::OPT_mgpopt
);
1960 // We quietly ignore -mno-gpopt as the backend defaults to -mno-gpopt.
1961 if (NoABICalls
&& (!GPOpt
|| WantGPOpt
)) {
1962 CmdArgs
.push_back("-mllvm");
1963 CmdArgs
.push_back("-mgpopt");
1965 Arg
*LocalSData
= Args
.getLastArg(options::OPT_mlocal_sdata
,
1966 options::OPT_mno_local_sdata
);
1967 Arg
*ExternSData
= Args
.getLastArg(options::OPT_mextern_sdata
,
1968 options::OPT_mno_extern_sdata
);
1969 Arg
*EmbeddedData
= Args
.getLastArg(options::OPT_membedded_data
,
1970 options::OPT_mno_embedded_data
);
1972 CmdArgs
.push_back("-mllvm");
1973 if (LocalSData
->getOption().matches(options::OPT_mlocal_sdata
)) {
1974 CmdArgs
.push_back("-mlocal-sdata=1");
1976 CmdArgs
.push_back("-mlocal-sdata=0");
1978 LocalSData
->claim();
1982 CmdArgs
.push_back("-mllvm");
1983 if (ExternSData
->getOption().matches(options::OPT_mextern_sdata
)) {
1984 CmdArgs
.push_back("-mextern-sdata=1");
1986 CmdArgs
.push_back("-mextern-sdata=0");
1988 ExternSData
->claim();
1992 CmdArgs
.push_back("-mllvm");
1993 if (EmbeddedData
->getOption().matches(options::OPT_membedded_data
)) {
1994 CmdArgs
.push_back("-membedded-data=1");
1996 CmdArgs
.push_back("-membedded-data=0");
1998 EmbeddedData
->claim();
2001 } else if ((!ABICalls
|| (!NoABICalls
&& ABICalls
)) && WantGPOpt
)
2002 D
.Diag(diag::warn_drv_unsupported_gpopt
) << (ABICalls
? 0 : 1);
2007 if (Arg
*A
= Args
.getLastArg(options::OPT_mcompact_branches_EQ
)) {
2008 StringRef Val
= StringRef(A
->getValue());
2009 if (mips::hasCompactBranches(CPUName
)) {
2010 if (Val
== "never" || Val
== "always" || Val
== "optimal") {
2011 CmdArgs
.push_back("-mllvm");
2012 CmdArgs
.push_back(Args
.MakeArgString("-mips-compact-branches=" + Val
));
2014 D
.Diag(diag::err_drv_unsupported_option_argument
)
2015 << A
->getSpelling() << Val
;
2017 D
.Diag(diag::warn_target_unsupported_compact_branches
) << CPUName
;
2020 if (Arg
*A
= Args
.getLastArg(options::OPT_mrelax_pic_calls
,
2021 options::OPT_mno_relax_pic_calls
)) {
2022 if (A
->getOption().matches(options::OPT_mno_relax_pic_calls
)) {
2023 CmdArgs
.push_back("-mllvm");
2024 CmdArgs
.push_back("-mips-jalr-reloc=0");
2029 void Clang::AddPPCTargetArgs(const ArgList
&Args
,
2030 ArgStringList
&CmdArgs
) const {
2031 const Driver
&D
= getToolChain().getDriver();
2032 const llvm::Triple
&T
= getToolChain().getTriple();
2033 if (Args
.getLastArg(options::OPT_mtune_EQ
)) {
2034 CmdArgs
.push_back("-tune-cpu");
2035 std::string CPU
= ppc::getPPCTuneCPU(Args
, T
);
2036 CmdArgs
.push_back(Args
.MakeArgString(CPU
));
2039 // Select the ABI to use.
2040 const char *ABIName
= nullptr;
2041 if (T
.isOSBinFormatELF()) {
2042 switch (getToolChain().getArch()) {
2043 case llvm::Triple::ppc64
: {
2044 if (T
.isPPC64ELFv2ABI())
2050 case llvm::Triple::ppc64le
:
2058 bool IEEELongDouble
= getToolChain().defaultToIEEELongDouble();
2059 bool VecExtabi
= false;
2060 for (const Arg
*A
: Args
.filtered(options::OPT_mabi_EQ
)) {
2061 StringRef V
= A
->getValue();
2062 if (V
== "ieeelongdouble") {
2063 IEEELongDouble
= true;
2065 } else if (V
== "ibmlongdouble") {
2066 IEEELongDouble
= false;
2068 } else if (V
== "vec-default") {
2071 } else if (V
== "vec-extabi") {
2074 } else if (V
== "elfv1") {
2077 } else if (V
== "elfv2") {
2080 } else if (V
!= "altivec")
2081 // The ppc64 linux abis are all "altivec" abis by default. Accept and ignore
2082 // the option if given as we don't have backend support for any targets
2083 // that don't use the altivec abi.
2084 ABIName
= A
->getValue();
2087 CmdArgs
.push_back("-mabi=ieeelongdouble");
2090 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
2091 << "-mabi=vec-extabi" << T
.str();
2092 CmdArgs
.push_back("-mabi=vec-extabi");
2095 ppc::FloatABI FloatABI
= ppc::getPPCFloatABI(D
, Args
);
2096 if (FloatABI
== ppc::FloatABI::Soft
) {
2097 // Floating point operations and argument passing are soft.
2098 CmdArgs
.push_back("-msoft-float");
2099 CmdArgs
.push_back("-mfloat-abi");
2100 CmdArgs
.push_back("soft");
2102 // Floating point operations and argument passing are hard.
2103 assert(FloatABI
== ppc::FloatABI::Hard
&& "Invalid float abi!");
2104 CmdArgs
.push_back("-mfloat-abi");
2105 CmdArgs
.push_back("hard");
2109 CmdArgs
.push_back("-target-abi");
2110 CmdArgs
.push_back(ABIName
);
2114 static void SetRISCVSmallDataLimit(const ToolChain
&TC
, const ArgList
&Args
,
2115 ArgStringList
&CmdArgs
) {
2116 const Driver
&D
= TC
.getDriver();
2117 const llvm::Triple
&Triple
= TC
.getTriple();
2118 // Default small data limitation is eight.
2119 const char *SmallDataLimit
= "8";
2120 // Get small data limitation.
2121 if (Args
.getLastArg(options::OPT_shared
, options::OPT_fpic
,
2122 options::OPT_fPIC
)) {
2123 // Not support linker relaxation for PIC.
2124 SmallDataLimit
= "0";
2125 if (Args
.hasArg(options::OPT_G
)) {
2126 D
.Diag(diag::warn_drv_unsupported_sdata
);
2128 } else if (Args
.getLastArgValue(options::OPT_mcmodel_EQ
)
2129 .equals_insensitive("large") &&
2130 (Triple
.getArch() == llvm::Triple::riscv64
)) {
2131 // Not support linker relaxation for RV64 with large code model.
2132 SmallDataLimit
= "0";
2133 if (Args
.hasArg(options::OPT_G
)) {
2134 D
.Diag(diag::warn_drv_unsupported_sdata
);
2136 } else if (Triple
.isAndroid()) {
2137 // GP relaxation is not supported on Android.
2138 SmallDataLimit
= "0";
2139 if (Args
.hasArg(options::OPT_G
)) {
2140 D
.Diag(diag::warn_drv_unsupported_sdata
);
2142 } else if (Arg
*A
= Args
.getLastArg(options::OPT_G
)) {
2143 SmallDataLimit
= A
->getValue();
2145 // Forward the -msmall-data-limit= option.
2146 CmdArgs
.push_back("-msmall-data-limit");
2147 CmdArgs
.push_back(SmallDataLimit
);
2150 void Clang::AddRISCVTargetArgs(const ArgList
&Args
,
2151 ArgStringList
&CmdArgs
) const {
2152 const llvm::Triple
&Triple
= getToolChain().getTriple();
2153 StringRef ABIName
= riscv::getRISCVABI(Args
, Triple
);
2155 CmdArgs
.push_back("-target-abi");
2156 CmdArgs
.push_back(ABIName
.data());
2158 SetRISCVSmallDataLimit(getToolChain(), Args
, CmdArgs
);
2160 if (!Args
.hasFlag(options::OPT_mimplicit_float
,
2161 options::OPT_mno_implicit_float
, true))
2162 CmdArgs
.push_back("-no-implicit-float");
2164 if (const Arg
*A
= Args
.getLastArg(options::OPT_mtune_EQ
)) {
2165 CmdArgs
.push_back("-tune-cpu");
2166 if (strcmp(A
->getValue(), "native") == 0)
2167 CmdArgs
.push_back(Args
.MakeArgString(llvm::sys::getHostCPUName()));
2169 CmdArgs
.push_back(A
->getValue());
2172 // Handle -mrvv-vector-bits=<bits>
2173 if (Arg
*A
= Args
.getLastArg(options::OPT_mrvv_vector_bits_EQ
)) {
2174 StringRef Val
= A
->getValue();
2175 const Driver
&D
= getToolChain().getDriver();
2177 // Get minimum VLen from march.
2178 unsigned MinVLen
= 0;
2179 std::string Arch
= riscv::getRISCVArch(Args
, Triple
);
2180 auto ISAInfo
= llvm::RISCVISAInfo::parseArchString(
2181 Arch
, /*EnableExperimentalExtensions*/ true);
2182 // Ignore parsing error.
2183 if (!errorToBool(ISAInfo
.takeError()))
2184 MinVLen
= (*ISAInfo
)->getMinVLen();
2186 // If the value is "zvl", use MinVLen from march. Otherwise, try to parse
2187 // as integer as long as we have a MinVLen.
2189 if (Val
== "zvl" && MinVLen
>= llvm::RISCV::RVVBitsPerBlock
) {
2191 } else if (!Val
.getAsInteger(10, Bits
)) {
2192 // Only accept power of 2 values beteen RVVBitsPerBlock and 65536 that
2193 // at least MinVLen.
2194 if (Bits
< MinVLen
|| Bits
< llvm::RISCV::RVVBitsPerBlock
||
2195 Bits
> 65536 || !llvm::isPowerOf2_32(Bits
))
2199 // If we got a valid value try to use it.
2201 unsigned VScaleMin
= Bits
/ llvm::RISCV::RVVBitsPerBlock
;
2203 Args
.MakeArgString("-mvscale-max=" + llvm::Twine(VScaleMin
)));
2205 Args
.MakeArgString("-mvscale-min=" + llvm::Twine(VScaleMin
)));
2206 } else if (Val
!= "scalable") {
2207 // Handle the unsupported values passed to mrvv-vector-bits.
2208 D
.Diag(diag::err_drv_unsupported_option_argument
)
2209 << A
->getSpelling() << Val
;
2214 void Clang::AddSparcTargetArgs(const ArgList
&Args
,
2215 ArgStringList
&CmdArgs
) const {
2216 sparc::FloatABI FloatABI
=
2217 sparc::getSparcFloatABI(getToolChain().getDriver(), Args
);
2219 if (FloatABI
== sparc::FloatABI::Soft
) {
2220 // Floating point operations and argument passing are soft.
2221 CmdArgs
.push_back("-msoft-float");
2222 CmdArgs
.push_back("-mfloat-abi");
2223 CmdArgs
.push_back("soft");
2225 // Floating point operations and argument passing are hard.
2226 assert(FloatABI
== sparc::FloatABI::Hard
&& "Invalid float abi!");
2227 CmdArgs
.push_back("-mfloat-abi");
2228 CmdArgs
.push_back("hard");
2231 if (const Arg
*A
= Args
.getLastArg(clang::driver::options::OPT_mtune_EQ
)) {
2232 StringRef Name
= A
->getValue();
2233 std::string TuneCPU
;
2234 if (Name
== "native")
2235 TuneCPU
= std::string(llvm::sys::getHostCPUName());
2237 TuneCPU
= std::string(Name
);
2239 CmdArgs
.push_back("-tune-cpu");
2240 CmdArgs
.push_back(Args
.MakeArgString(TuneCPU
));
2244 void Clang::AddSystemZTargetArgs(const ArgList
&Args
,
2245 ArgStringList
&CmdArgs
) const {
2246 if (const Arg
*A
= Args
.getLastArg(options::OPT_mtune_EQ
)) {
2247 CmdArgs
.push_back("-tune-cpu");
2248 if (strcmp(A
->getValue(), "native") == 0)
2249 CmdArgs
.push_back(Args
.MakeArgString(llvm::sys::getHostCPUName()));
2251 CmdArgs
.push_back(A
->getValue());
2255 Args
.hasFlag(options::OPT_mbackchain
, options::OPT_mno_backchain
, false);
2256 bool HasPackedStack
= Args
.hasFlag(options::OPT_mpacked_stack
,
2257 options::OPT_mno_packed_stack
, false);
2258 systemz::FloatABI FloatABI
=
2259 systemz::getSystemZFloatABI(getToolChain().getDriver(), Args
);
2260 bool HasSoftFloat
= (FloatABI
== systemz::FloatABI::Soft
);
2261 if (HasBackchain
&& HasPackedStack
&& !HasSoftFloat
) {
2262 const Driver
&D
= getToolChain().getDriver();
2263 D
.Diag(diag::err_drv_unsupported_opt
)
2264 << "-mpacked-stack -mbackchain -mhard-float";
2267 CmdArgs
.push_back("-mbackchain");
2269 CmdArgs
.push_back("-mpacked-stack");
2271 // Floating point operations and argument passing are soft.
2272 CmdArgs
.push_back("-msoft-float");
2273 CmdArgs
.push_back("-mfloat-abi");
2274 CmdArgs
.push_back("soft");
2278 void Clang::AddX86TargetArgs(const ArgList
&Args
,
2279 ArgStringList
&CmdArgs
) const {
2280 const Driver
&D
= getToolChain().getDriver();
2281 addX86AlignBranchArgs(D
, Args
, CmdArgs
, /*IsLTO=*/false);
2283 if (!Args
.hasFlag(options::OPT_mred_zone
, options::OPT_mno_red_zone
, true) ||
2284 Args
.hasArg(options::OPT_mkernel
) ||
2285 Args
.hasArg(options::OPT_fapple_kext
))
2286 CmdArgs
.push_back("-disable-red-zone");
2288 if (!Args
.hasFlag(options::OPT_mtls_direct_seg_refs
,
2289 options::OPT_mno_tls_direct_seg_refs
, true))
2290 CmdArgs
.push_back("-mno-tls-direct-seg-refs");
2292 // Default to avoid implicit floating-point for kernel/kext code, but allow
2293 // that to be overridden with -mno-soft-float.
2294 bool NoImplicitFloat
= (Args
.hasArg(options::OPT_mkernel
) ||
2295 Args
.hasArg(options::OPT_fapple_kext
));
2296 if (Arg
*A
= Args
.getLastArg(
2297 options::OPT_msoft_float
, options::OPT_mno_soft_float
,
2298 options::OPT_mimplicit_float
, options::OPT_mno_implicit_float
)) {
2299 const Option
&O
= A
->getOption();
2300 NoImplicitFloat
= (O
.matches(options::OPT_mno_implicit_float
) ||
2301 O
.matches(options::OPT_msoft_float
));
2303 if (NoImplicitFloat
)
2304 CmdArgs
.push_back("-no-implicit-float");
2306 if (Arg
*A
= Args
.getLastArg(options::OPT_masm_EQ
)) {
2307 StringRef Value
= A
->getValue();
2308 if (Value
== "intel" || Value
== "att") {
2309 CmdArgs
.push_back("-mllvm");
2310 CmdArgs
.push_back(Args
.MakeArgString("-x86-asm-syntax=" + Value
));
2311 CmdArgs
.push_back(Args
.MakeArgString("-inline-asm=" + Value
));
2313 D
.Diag(diag::err_drv_unsupported_option_argument
)
2314 << A
->getSpelling() << Value
;
2316 } else if (D
.IsCLMode()) {
2317 CmdArgs
.push_back("-mllvm");
2318 CmdArgs
.push_back("-x86-asm-syntax=intel");
2321 if (Arg
*A
= Args
.getLastArg(options::OPT_mskip_rax_setup
,
2322 options::OPT_mno_skip_rax_setup
))
2323 if (A
->getOption().matches(options::OPT_mskip_rax_setup
))
2324 CmdArgs
.push_back(Args
.MakeArgString("-mskip-rax-setup"));
2326 // Set flags to support MCU ABI.
2327 if (Args
.hasFlag(options::OPT_miamcu
, options::OPT_mno_iamcu
, false)) {
2328 CmdArgs
.push_back("-mfloat-abi");
2329 CmdArgs
.push_back("soft");
2330 CmdArgs
.push_back("-mstack-alignment=4");
2335 // Default to "generic" unless -march is present or targetting the PS4/PS5.
2336 std::string TuneCPU
;
2337 if (!Args
.hasArg(clang::driver::options::OPT_march_EQ
) &&
2338 !getToolChain().getTriple().isPS())
2339 TuneCPU
= "generic";
2341 // Override based on -mtune.
2342 if (const Arg
*A
= Args
.getLastArg(clang::driver::options::OPT_mtune_EQ
)) {
2343 StringRef Name
= A
->getValue();
2345 if (Name
== "native") {
2346 Name
= llvm::sys::getHostCPUName();
2348 TuneCPU
= std::string(Name
);
2350 TuneCPU
= std::string(Name
);
2353 if (!TuneCPU
.empty()) {
2354 CmdArgs
.push_back("-tune-cpu");
2355 CmdArgs
.push_back(Args
.MakeArgString(TuneCPU
));
2359 void Clang::AddHexagonTargetArgs(const ArgList
&Args
,
2360 ArgStringList
&CmdArgs
) const {
2361 CmdArgs
.push_back("-mqdsp6-compat");
2362 CmdArgs
.push_back("-Wreturn-type");
2364 if (auto G
= toolchains::HexagonToolChain::getSmallDataThreshold(Args
)) {
2365 CmdArgs
.push_back("-mllvm");
2367 Args
.MakeArgString("-hexagon-small-data-threshold=" + Twine(*G
)));
2370 if (!Args
.hasArg(options::OPT_fno_short_enums
))
2371 CmdArgs
.push_back("-fshort-enums");
2372 if (Args
.getLastArg(options::OPT_mieee_rnd_near
)) {
2373 CmdArgs
.push_back("-mllvm");
2374 CmdArgs
.push_back("-enable-hexagon-ieee-rnd-near");
2376 CmdArgs
.push_back("-mllvm");
2377 CmdArgs
.push_back("-machine-sink-split=0");
2380 void Clang::AddLanaiTargetArgs(const ArgList
&Args
,
2381 ArgStringList
&CmdArgs
) const {
2382 if (Arg
*A
= Args
.getLastArg(options::OPT_mcpu_EQ
)) {
2383 StringRef CPUName
= A
->getValue();
2385 CmdArgs
.push_back("-target-cpu");
2386 CmdArgs
.push_back(Args
.MakeArgString(CPUName
));
2388 if (Arg
*A
= Args
.getLastArg(options::OPT_mregparm_EQ
)) {
2389 StringRef Value
= A
->getValue();
2390 // Only support mregparm=4 to support old usage. Report error for all other
2393 if (Value
.getAsInteger(10, Mregparm
)) {
2394 if (Mregparm
!= 4) {
2395 getToolChain().getDriver().Diag(
2396 diag::err_drv_unsupported_option_argument
)
2397 << A
->getSpelling() << Value
;
2403 void Clang::AddWebAssemblyTargetArgs(const ArgList
&Args
,
2404 ArgStringList
&CmdArgs
) const {
2405 // Default to "hidden" visibility.
2406 if (!Args
.hasArg(options::OPT_fvisibility_EQ
,
2407 options::OPT_fvisibility_ms_compat
))
2408 CmdArgs
.push_back("-fvisibility=hidden");
2411 void Clang::AddVETargetArgs(const ArgList
&Args
, ArgStringList
&CmdArgs
) const {
2412 // Floating point operations and argument passing are hard.
2413 CmdArgs
.push_back("-mfloat-abi");
2414 CmdArgs
.push_back("hard");
2417 void Clang::DumpCompilationDatabase(Compilation
&C
, StringRef Filename
,
2418 StringRef Target
, const InputInfo
&Output
,
2419 const InputInfo
&Input
, const ArgList
&Args
) const {
2420 // If this is a dry run, do not create the compilation database file.
2421 if (C
.getArgs().hasArg(options::OPT__HASH_HASH_HASH
))
2424 using llvm::yaml::escape
;
2425 const Driver
&D
= getToolChain().getDriver();
2427 if (!CompilationDatabase
) {
2429 auto File
= std::make_unique
<llvm::raw_fd_ostream
>(
2431 llvm::sys::fs::OF_TextWithCRLF
| llvm::sys::fs::OF_Append
);
2433 D
.Diag(clang::diag::err_drv_compilationdatabase
) << Filename
2437 CompilationDatabase
= std::move(File
);
2439 auto &CDB
= *CompilationDatabase
;
2440 auto CWD
= D
.getVFS().getCurrentWorkingDirectory();
2443 CDB
<< "{ \"directory\": \"" << escape(*CWD
) << "\"";
2444 CDB
<< ", \"file\": \"" << escape(Input
.getFilename()) << "\"";
2445 if (Output
.isFilename())
2446 CDB
<< ", \"output\": \"" << escape(Output
.getFilename()) << "\"";
2447 CDB
<< ", \"arguments\": [\"" << escape(D
.ClangExecutable
) << "\"";
2448 SmallString
<128> Buf
;
2450 Buf
+= types::getTypeName(Input
.getType());
2451 CDB
<< ", \"" << escape(Buf
) << "\"";
2452 if (!D
.SysRoot
.empty() && !Args
.hasArg(options::OPT__sysroot_EQ
)) {
2455 CDB
<< ", \"" << escape(Buf
) << "\"";
2457 CDB
<< ", \"" << escape(Input
.getFilename()) << "\"";
2458 if (Output
.isFilename())
2459 CDB
<< ", \"-o\", \"" << escape(Output
.getFilename()) << "\"";
2460 for (auto &A
: Args
) {
2461 auto &O
= A
->getOption();
2462 // Skip language selection, which is positional.
2463 if (O
.getID() == options::OPT_x
)
2465 // Skip writing dependency output and the compilation database itself.
2466 if (O
.getGroup().isValid() && O
.getGroup().getID() == options::OPT_M_Group
)
2468 if (O
.getID() == options::OPT_gen_cdb_fragment_path
)
2471 if (O
.getKind() == Option::InputClass
)
2474 if (O
.getID() == options::OPT_o
)
2476 // All other arguments are quoted and appended.
2478 A
->render(Args
, ASL
);
2480 CDB
<< ", \"" << escape(it
) << "\"";
2484 CDB
<< ", \"" << escape(Buf
) << "\"]},\n";
2487 void Clang::DumpCompilationDatabaseFragmentToDir(
2488 StringRef Dir
, Compilation
&C
, StringRef Target
, const InputInfo
&Output
,
2489 const InputInfo
&Input
, const llvm::opt::ArgList
&Args
) const {
2490 // If this is a dry run, do not create the compilation database file.
2491 if (C
.getArgs().hasArg(options::OPT__HASH_HASH_HASH
))
2494 if (CompilationDatabase
)
2495 DumpCompilationDatabase(C
, "", Target
, Output
, Input
, Args
);
2497 SmallString
<256> Path
= Dir
;
2498 const auto &Driver
= C
.getDriver();
2499 Driver
.getVFS().makeAbsolute(Path
);
2500 auto Err
= llvm::sys::fs::create_directory(Path
, /*IgnoreExisting=*/true);
2502 Driver
.Diag(diag::err_drv_compilationdatabase
) << Dir
<< Err
.message();
2506 llvm::sys::path::append(
2508 Twine(llvm::sys::path::filename(Input
.getFilename())) + ".%%%%.json");
2510 SmallString
<256> TempPath
;
2511 Err
= llvm::sys::fs::createUniqueFile(Path
, FD
, TempPath
,
2512 llvm::sys::fs::OF_Text
);
2514 Driver
.Diag(diag::err_drv_compilationdatabase
) << Path
<< Err
.message();
2517 CompilationDatabase
=
2518 std::make_unique
<llvm::raw_fd_ostream
>(FD
, /*shouldClose=*/true);
2519 DumpCompilationDatabase(C
, "", Target
, Output
, Input
, Args
);
2522 static bool CheckARMImplicitITArg(StringRef Value
) {
2523 return Value
== "always" || Value
== "never" || Value
== "arm" ||
2527 static void AddARMImplicitITArgs(const ArgList
&Args
, ArgStringList
&CmdArgs
,
2529 CmdArgs
.push_back("-mllvm");
2530 CmdArgs
.push_back(Args
.MakeArgString("-arm-implicit-it=" + Value
));
2533 static void CollectArgsForIntegratedAssembler(Compilation
&C
,
2534 const ArgList
&Args
,
2535 ArgStringList
&CmdArgs
,
2537 // Default to -mno-relax-all.
2539 // Note: RISC-V requires an indirect jump for offsets larger than 1MiB. This
2540 // cannot be done by assembler branch relaxation as it needs a free temporary
2541 // register. Because of this, branch relaxation is handled by a MachineIR pass
2542 // before the assembler. Forcing assembler branch relaxation for -O0 makes the
2543 // MachineIR branch relaxation inaccurate and it will miss cases where an
2544 // indirect branch is necessary.
2545 Args
.addOptInFlag(CmdArgs
, options::OPT_mrelax_all
,
2546 options::OPT_mno_relax_all
);
2548 // Only default to -mincremental-linker-compatible if we think we are
2549 // targeting the MSVC linker.
2550 bool DefaultIncrementalLinkerCompatible
=
2551 C
.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
2552 if (Args
.hasFlag(options::OPT_mincremental_linker_compatible
,
2553 options::OPT_mno_incremental_linker_compatible
,
2554 DefaultIncrementalLinkerCompatible
))
2555 CmdArgs
.push_back("-mincremental-linker-compatible");
2557 Args
.AddLastArg(CmdArgs
, options::OPT_femit_dwarf_unwind_EQ
);
2559 Args
.addOptInFlag(CmdArgs
, options::OPT_femit_compact_unwind_non_canonical
,
2560 options::OPT_fno_emit_compact_unwind_non_canonical
);
2562 // If you add more args here, also add them to the block below that
2563 // starts with "// If CollectArgsForIntegratedAssembler() isn't called below".
2565 // When passing -I arguments to the assembler we sometimes need to
2566 // unconditionally take the next argument. For example, when parsing
2567 // '-Wa,-I -Wa,foo' we need to accept the -Wa,foo arg after seeing the
2568 // -Wa,-I arg and when parsing '-Wa,-I,foo' we need to accept the 'foo'
2569 // arg after parsing the '-I' arg.
2570 bool TakeNextArg
= false;
2572 const llvm::Triple
&Triple
= C
.getDefaultToolChain().getTriple();
2573 bool Crel
= false, ExperimentalCrel
= false;
2574 bool UseRelaxRelocations
= C
.getDefaultToolChain().useRelaxRelocations();
2575 bool UseNoExecStack
= false;
2576 const char *MipsTargetFeature
= nullptr;
2577 StringRef ImplicitIt
;
2579 Args
.filtered(options::OPT_Wa_COMMA
, options::OPT_Xassembler
,
2580 options::OPT_mimplicit_it_EQ
)) {
2583 if (A
->getOption().getID() == options::OPT_mimplicit_it_EQ
) {
2584 switch (C
.getDefaultToolChain().getArch()) {
2585 case llvm::Triple::arm
:
2586 case llvm::Triple::armeb
:
2587 case llvm::Triple::thumb
:
2588 case llvm::Triple::thumbeb
:
2589 // Only store the value; the last value set takes effect.
2590 ImplicitIt
= A
->getValue();
2591 if (!CheckARMImplicitITArg(ImplicitIt
))
2592 D
.Diag(diag::err_drv_unsupported_option_argument
)
2593 << A
->getSpelling() << ImplicitIt
;
2600 for (StringRef Value
: A
->getValues()) {
2602 CmdArgs
.push_back(Value
.data());
2603 TakeNextArg
= false;
2607 if (C
.getDefaultToolChain().getTriple().isOSBinFormatCOFF() &&
2608 Value
== "-mbig-obj")
2609 continue; // LLVM handles bigobj automatically
2611 switch (C
.getDefaultToolChain().getArch()) {
2614 case llvm::Triple::x86
:
2615 case llvm::Triple::x86_64
:
2616 if (Value
== "-msse2avx") {
2617 CmdArgs
.push_back("-msse2avx");
2621 case llvm::Triple::wasm32
:
2622 case llvm::Triple::wasm64
:
2623 if (Value
== "--no-type-check") {
2624 CmdArgs
.push_back("-mno-type-check");
2628 case llvm::Triple::thumb
:
2629 case llvm::Triple::thumbeb
:
2630 case llvm::Triple::arm
:
2631 case llvm::Triple::armeb
:
2632 if (Value
.starts_with("-mimplicit-it=")) {
2633 // Only store the value; the last value set takes effect.
2634 ImplicitIt
= Value
.split("=").second
;
2635 if (CheckARMImplicitITArg(ImplicitIt
))
2638 if (Value
== "-mthumb")
2639 // -mthumb has already been processed in ComputeLLVMTriple()
2640 // recognize but skip over here.
2643 case llvm::Triple::mips
:
2644 case llvm::Triple::mipsel
:
2645 case llvm::Triple::mips64
:
2646 case llvm::Triple::mips64el
:
2647 if (Value
== "--trap") {
2648 CmdArgs
.push_back("-target-feature");
2649 CmdArgs
.push_back("+use-tcc-in-div");
2652 if (Value
== "--break") {
2653 CmdArgs
.push_back("-target-feature");
2654 CmdArgs
.push_back("-use-tcc-in-div");
2657 if (Value
.starts_with("-msoft-float")) {
2658 CmdArgs
.push_back("-target-feature");
2659 CmdArgs
.push_back("+soft-float");
2662 if (Value
.starts_with("-mhard-float")) {
2663 CmdArgs
.push_back("-target-feature");
2664 CmdArgs
.push_back("-soft-float");
2668 MipsTargetFeature
= llvm::StringSwitch
<const char *>(Value
)
2669 .Case("-mips1", "+mips1")
2670 .Case("-mips2", "+mips2")
2671 .Case("-mips3", "+mips3")
2672 .Case("-mips4", "+mips4")
2673 .Case("-mips5", "+mips5")
2674 .Case("-mips32", "+mips32")
2675 .Case("-mips32r2", "+mips32r2")
2676 .Case("-mips32r3", "+mips32r3")
2677 .Case("-mips32r5", "+mips32r5")
2678 .Case("-mips32r6", "+mips32r6")
2679 .Case("-mips64", "+mips64")
2680 .Case("-mips64r2", "+mips64r2")
2681 .Case("-mips64r3", "+mips64r3")
2682 .Case("-mips64r5", "+mips64r5")
2683 .Case("-mips64r6", "+mips64r6")
2685 if (MipsTargetFeature
)
2689 if (Value
== "-force_cpusubtype_ALL") {
2690 // Do nothing, this is the default and we don't support anything else.
2691 } else if (Value
== "-L") {
2692 CmdArgs
.push_back("-msave-temp-labels");
2693 } else if (Value
== "--fatal-warnings") {
2694 CmdArgs
.push_back("-massembler-fatal-warnings");
2695 } else if (Value
== "--no-warn" || Value
== "-W") {
2696 CmdArgs
.push_back("-massembler-no-warn");
2697 } else if (Value
== "--noexecstack") {
2698 UseNoExecStack
= true;
2699 } else if (Value
.starts_with("-compress-debug-sections") ||
2700 Value
.starts_with("--compress-debug-sections") ||
2701 Value
== "-nocompress-debug-sections" ||
2702 Value
== "--nocompress-debug-sections") {
2703 CmdArgs
.push_back(Value
.data());
2704 } else if (Value
== "--crel") {
2706 } else if (Value
== "--no-crel") {
2708 } else if (Value
== "--allow-experimental-crel") {
2709 ExperimentalCrel
= true;
2710 } else if (Value
== "-mrelax-relocations=yes" ||
2711 Value
== "--mrelax-relocations=yes") {
2712 UseRelaxRelocations
= true;
2713 } else if (Value
== "-mrelax-relocations=no" ||
2714 Value
== "--mrelax-relocations=no") {
2715 UseRelaxRelocations
= false;
2716 } else if (Value
.starts_with("-I")) {
2717 CmdArgs
.push_back(Value
.data());
2718 // We need to consume the next argument if the current arg is a plain
2719 // -I. The next arg will be the include directory.
2722 } else if (Value
.starts_with("-gdwarf-")) {
2723 // "-gdwarf-N" options are not cc1as options.
2724 unsigned DwarfVersion
= DwarfVersionNum(Value
);
2725 if (DwarfVersion
== 0) { // Send it onward, and let cc1as complain.
2726 CmdArgs
.push_back(Value
.data());
2728 RenderDebugEnablingArgs(Args
, CmdArgs
,
2729 llvm::codegenoptions::DebugInfoConstructor
,
2730 DwarfVersion
, llvm::DebuggerKind::Default
);
2732 } else if (Value
.starts_with("-mcpu") || Value
.starts_with("-mfpu") ||
2733 Value
.starts_with("-mhwdiv") || Value
.starts_with("-march")) {
2734 // Do nothing, we'll validate it later.
2735 } else if (Value
== "-defsym" || Value
== "--defsym") {
2736 if (A
->getNumValues() != 2) {
2737 D
.Diag(diag::err_drv_defsym_invalid_format
) << Value
;
2740 const char *S
= A
->getValue(1);
2741 auto Pair
= StringRef(S
).split('=');
2742 auto Sym
= Pair
.first
;
2743 auto SVal
= Pair
.second
;
2745 if (Sym
.empty() || SVal
.empty()) {
2746 D
.Diag(diag::err_drv_defsym_invalid_format
) << S
;
2750 if (SVal
.getAsInteger(0, IVal
)) {
2751 D
.Diag(diag::err_drv_defsym_invalid_symval
) << SVal
;
2754 CmdArgs
.push_back("--defsym");
2756 } else if (Value
== "-fdebug-compilation-dir") {
2757 CmdArgs
.push_back("-fdebug-compilation-dir");
2759 } else if (Value
.consume_front("-fdebug-compilation-dir=")) {
2760 // The flag is a -Wa / -Xassembler argument and Options doesn't
2761 // parse the argument, so this isn't automatically aliased to
2762 // -fdebug-compilation-dir (without '=') here.
2763 CmdArgs
.push_back("-fdebug-compilation-dir");
2764 CmdArgs
.push_back(Value
.data());
2765 } else if (Value
== "--version") {
2766 D
.PrintVersion(C
, llvm::outs());
2768 D
.Diag(diag::err_drv_unsupported_option_argument
)
2769 << A
->getSpelling() << Value
;
2773 if (ImplicitIt
.size())
2774 AddARMImplicitITArgs(Args
, CmdArgs
, ImplicitIt
);
2776 if (!ExperimentalCrel
)
2777 D
.Diag(diag::err_drv_experimental_crel
);
2778 if (Triple
.isOSBinFormatELF() && !Triple
.isMIPS()) {
2779 CmdArgs
.push_back("--crel");
2781 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
2782 << "-Wa,--crel" << D
.getTargetTriple();
2785 if (!UseRelaxRelocations
)
2786 CmdArgs
.push_back("-mrelax-relocations=no");
2788 CmdArgs
.push_back("-mnoexecstack");
2789 if (MipsTargetFeature
!= nullptr) {
2790 CmdArgs
.push_back("-target-feature");
2791 CmdArgs
.push_back(MipsTargetFeature
);
2794 // forward -fembed-bitcode to assmebler
2795 if (C
.getDriver().embedBitcodeEnabled() ||
2796 C
.getDriver().embedBitcodeMarkerOnly())
2797 Args
.AddLastArg(CmdArgs
, options::OPT_fembed_bitcode_EQ
);
2799 if (const char *AsSecureLogFile
= getenv("AS_SECURE_LOG_FILE")) {
2800 CmdArgs
.push_back("-as-secure-log-file");
2801 CmdArgs
.push_back(Args
.MakeArgString(AsSecureLogFile
));
2805 static std::string
ComplexRangeKindToStr(LangOptions::ComplexRangeKind Range
) {
2807 case LangOptions::ComplexRangeKind::CX_Full
:
2810 case LangOptions::ComplexRangeKind::CX_Basic
:
2813 case LangOptions::ComplexRangeKind::CX_Improved
:
2816 case LangOptions::ComplexRangeKind::CX_Promoted
:
2824 static std::string
ComplexArithmeticStr(LangOptions::ComplexRangeKind Range
) {
2825 return (Range
== LangOptions::ComplexRangeKind::CX_None
)
2827 : "-fcomplex-arithmetic=" + ComplexRangeKindToStr(Range
);
2830 static void EmitComplexRangeDiag(const Driver
&D
, std::string str1
,
2832 if ((str1
.compare(str2
) != 0) && !str2
.empty() && !str1
.empty()) {
2833 D
.Diag(clang::diag::warn_drv_overriding_option
) << str1
<< str2
;
2838 RenderComplexRangeOption(LangOptions::ComplexRangeKind Range
) {
2839 std::string ComplexRangeStr
= ComplexRangeKindToStr(Range
);
2840 if (!ComplexRangeStr
.empty())
2841 return "-complex-range=" + ComplexRangeStr
;
2842 return ComplexRangeStr
;
2845 static void RenderFloatingPointOptions(const ToolChain
&TC
, const Driver
&D
,
2846 bool OFastEnabled
, const ArgList
&Args
,
2847 ArgStringList
&CmdArgs
,
2848 const JobAction
&JA
) {
2849 // Handle various floating point optimization flags, mapping them to the
2850 // appropriate LLVM code generation flags. This is complicated by several
2851 // "umbrella" flags, so we do this by stepping through the flags incrementally
2852 // adjusting what we think is enabled/disabled, then at the end setting the
2853 // LLVM flags based on the final state.
2854 bool HonorINFs
= true;
2855 bool HonorNaNs
= true;
2856 bool ApproxFunc
= false;
2857 // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes.
2858 bool MathErrno
= TC
.IsMathErrnoDefault();
2859 bool AssociativeMath
= false;
2860 bool ReciprocalMath
= false;
2861 bool SignedZeros
= true;
2862 bool TrappingMath
= false; // Implemented via -ffp-exception-behavior
2863 bool TrappingMathPresent
= false; // Is trapping-math in args, and not
2864 // overriden by ffp-exception-behavior?
2865 bool RoundingFPMath
= false;
2866 // -ffp-model values: strict, fast, precise
2867 StringRef FPModel
= "";
2868 // -ffp-exception-behavior options: strict, maytrap, ignore
2869 StringRef FPExceptionBehavior
= "";
2870 // -ffp-eval-method options: double, extended, source
2871 StringRef FPEvalMethod
= "";
2872 llvm::DenormalMode DenormalFPMath
=
2873 TC
.getDefaultDenormalModeForType(Args
, JA
);
2874 llvm::DenormalMode DenormalFP32Math
=
2875 TC
.getDefaultDenormalModeForType(Args
, JA
, &llvm::APFloat::IEEEsingle());
2877 // CUDA and HIP don't rely on the frontend to pass an ffp-contract option.
2878 // If one wasn't given by the user, don't pass it here.
2879 StringRef FPContract
;
2880 StringRef LastSeenFfpContractOption
;
2881 bool SeenUnsafeMathModeOption
= false;
2882 if (!JA
.isDeviceOffloading(Action::OFK_Cuda
) &&
2883 !JA
.isOffloading(Action::OFK_HIP
))
2885 bool StrictFPModel
= false;
2886 StringRef Float16ExcessPrecision
= "";
2887 StringRef BFloat16ExcessPrecision
= "";
2888 LangOptions::ComplexRangeKind Range
= LangOptions::ComplexRangeKind::CX_None
;
2889 std::string ComplexRangeStr
= "";
2890 std::string GccRangeComplexOption
= "";
2892 // Lambda to set fast-math options. This is also used by -ffp-model=fast
2893 auto applyFastMath
= [&]() {
2897 AssociativeMath
= true;
2898 ReciprocalMath
= true;
2900 SignedZeros
= false;
2901 TrappingMath
= false;
2902 RoundingFPMath
= false;
2903 FPExceptionBehavior
= "";
2904 // If fast-math is set then set the fp-contract mode to fast.
2905 FPContract
= "fast";
2906 // ffast-math enables basic range rules for complex multiplication and
2908 // Warn if user expects to perform full implementation of complex
2909 // multiplication or division in the presence of nan or ninf flags.
2910 if (Range
== LangOptions::ComplexRangeKind::CX_Full
||
2911 Range
== LangOptions::ComplexRangeKind::CX_Improved
||
2912 Range
== LangOptions::ComplexRangeKind::CX_Promoted
)
2913 EmitComplexRangeDiag(
2914 D
, ComplexArithmeticStr(Range
),
2915 !GccRangeComplexOption
.empty()
2916 ? GccRangeComplexOption
2917 : ComplexArithmeticStr(LangOptions::ComplexRangeKind::CX_Basic
));
2918 Range
= LangOptions::ComplexRangeKind::CX_Basic
;
2919 SeenUnsafeMathModeOption
= true;
2922 if (const Arg
*A
= Args
.getLastArg(options::OPT_flimited_precision_EQ
)) {
2923 CmdArgs
.push_back("-mlimit-float-precision");
2924 CmdArgs
.push_back(A
->getValue());
2927 for (const Arg
*A
: Args
) {
2928 switch (A
->getOption().getID()) {
2929 // If this isn't an FP option skip the claim below
2932 case options::OPT_fcx_limited_range
:
2933 if (GccRangeComplexOption
.empty()) {
2934 if (Range
!= LangOptions::ComplexRangeKind::CX_Basic
)
2935 EmitComplexRangeDiag(D
, RenderComplexRangeOption(Range
),
2936 "-fcx-limited-range");
2938 if (GccRangeComplexOption
!= "-fno-cx-limited-range")
2939 EmitComplexRangeDiag(D
, GccRangeComplexOption
, "-fcx-limited-range");
2941 GccRangeComplexOption
= "-fcx-limited-range";
2942 Range
= LangOptions::ComplexRangeKind::CX_Basic
;
2944 case options::OPT_fno_cx_limited_range
:
2945 if (GccRangeComplexOption
.empty()) {
2946 EmitComplexRangeDiag(D
, RenderComplexRangeOption(Range
),
2947 "-fno-cx-limited-range");
2949 if (GccRangeComplexOption
.compare("-fcx-limited-range") != 0 &&
2950 GccRangeComplexOption
.compare("-fno-cx-fortran-rules") != 0)
2951 EmitComplexRangeDiag(D
, GccRangeComplexOption
,
2952 "-fno-cx-limited-range");
2954 GccRangeComplexOption
= "-fno-cx-limited-range";
2955 Range
= LangOptions::ComplexRangeKind::CX_Full
;
2957 case options::OPT_fcx_fortran_rules
:
2958 if (GccRangeComplexOption
.empty())
2959 EmitComplexRangeDiag(D
, RenderComplexRangeOption(Range
),
2960 "-fcx-fortran-rules");
2962 EmitComplexRangeDiag(D
, GccRangeComplexOption
, "-fcx-fortran-rules");
2963 GccRangeComplexOption
= "-fcx-fortran-rules";
2964 Range
= LangOptions::ComplexRangeKind::CX_Improved
;
2966 case options::OPT_fno_cx_fortran_rules
:
2967 if (GccRangeComplexOption
.empty()) {
2968 EmitComplexRangeDiag(D
, RenderComplexRangeOption(Range
),
2969 "-fno-cx-fortran-rules");
2971 if (GccRangeComplexOption
!= "-fno-cx-limited-range")
2972 EmitComplexRangeDiag(D
, GccRangeComplexOption
,
2973 "-fno-cx-fortran-rules");
2975 GccRangeComplexOption
= "-fno-cx-fortran-rules";
2976 Range
= LangOptions::ComplexRangeKind::CX_Full
;
2978 case options::OPT_fcomplex_arithmetic_EQ
: {
2979 LangOptions::ComplexRangeKind RangeVal
;
2980 StringRef Val
= A
->getValue();
2982 RangeVal
= LangOptions::ComplexRangeKind::CX_Full
;
2983 else if (Val
== "improved")
2984 RangeVal
= LangOptions::ComplexRangeKind::CX_Improved
;
2985 else if (Val
== "promoted")
2986 RangeVal
= LangOptions::ComplexRangeKind::CX_Promoted
;
2987 else if (Val
== "basic")
2988 RangeVal
= LangOptions::ComplexRangeKind::CX_Basic
;
2990 D
.Diag(diag::err_drv_unsupported_option_argument
)
2991 << A
->getSpelling() << Val
;
2994 if (!GccRangeComplexOption
.empty()) {
2995 if (GccRangeComplexOption
.compare("-fcx-limited-range") != 0) {
2996 if (GccRangeComplexOption
.compare("-fcx-fortran-rules") != 0) {
2997 if (RangeVal
!= LangOptions::ComplexRangeKind::CX_Improved
)
2998 EmitComplexRangeDiag(D
, GccRangeComplexOption
,
2999 ComplexArithmeticStr(RangeVal
));
3001 EmitComplexRangeDiag(D
, GccRangeComplexOption
,
3002 ComplexArithmeticStr(RangeVal
));
3005 if (RangeVal
!= LangOptions::ComplexRangeKind::CX_Basic
)
3006 EmitComplexRangeDiag(D
, GccRangeComplexOption
,
3007 ComplexArithmeticStr(RangeVal
));
3013 case options::OPT_ffp_model_EQ
: {
3014 // If -ffp-model= is seen, reset to fno-fast-math
3018 // Turning *off* -ffast-math restores the toolchain default.
3019 MathErrno
= TC
.IsMathErrnoDefault();
3020 AssociativeMath
= false;
3021 ReciprocalMath
= false;
3025 StringRef Val
= A
->getValue();
3026 if (OFastEnabled
&& Val
!= "fast") {
3027 // Only -ffp-model=fast is compatible with OFast, ignore.
3028 D
.Diag(clang::diag::warn_drv_overriding_option
)
3029 << Args
.MakeArgString("-ffp-model=" + Val
) << "-Ofast";
3032 StrictFPModel
= false;
3033 if (!FPModel
.empty() && FPModel
!= Val
)
3034 D
.Diag(clang::diag::warn_drv_overriding_option
)
3035 << Args
.MakeArgString("-ffp-model=" + FPModel
)
3036 << Args
.MakeArgString("-ffp-model=" + Val
);
3037 if (Val
== "fast") {
3040 } else if (Val
== "precise") {
3043 } else if (Val
== "strict") {
3044 StrictFPModel
= true;
3045 FPExceptionBehavior
= "strict";
3048 TrappingMath
= true;
3049 RoundingFPMath
= true;
3051 D
.Diag(diag::err_drv_unsupported_option_argument
)
3052 << A
->getSpelling() << Val
;
3056 // Options controlling individual features
3057 case options::OPT_fhonor_infinities
: HonorINFs
= true; break;
3058 case options::OPT_fno_honor_infinities
: HonorINFs
= false; break;
3059 case options::OPT_fhonor_nans
: HonorNaNs
= true; break;
3060 case options::OPT_fno_honor_nans
: HonorNaNs
= false; break;
3061 case options::OPT_fapprox_func
: ApproxFunc
= true; break;
3062 case options::OPT_fno_approx_func
: ApproxFunc
= false; break;
3063 case options::OPT_fmath_errno
: MathErrno
= true; break;
3064 case options::OPT_fno_math_errno
: MathErrno
= false; break;
3065 case options::OPT_fassociative_math
: AssociativeMath
= true; break;
3066 case options::OPT_fno_associative_math
: AssociativeMath
= false; break;
3067 case options::OPT_freciprocal_math
: ReciprocalMath
= true; break;
3068 case options::OPT_fno_reciprocal_math
: ReciprocalMath
= false; break;
3069 case options::OPT_fsigned_zeros
: SignedZeros
= true; break;
3070 case options::OPT_fno_signed_zeros
: SignedZeros
= false; break;
3071 case options::OPT_ftrapping_math
:
3072 if (!TrappingMathPresent
&& !FPExceptionBehavior
.empty() &&
3073 FPExceptionBehavior
!= "strict")
3074 // Warn that previous value of option is overridden.
3075 D
.Diag(clang::diag::warn_drv_overriding_option
)
3076 << Args
.MakeArgString("-ffp-exception-behavior=" +
3077 FPExceptionBehavior
)
3078 << "-ftrapping-math";
3079 TrappingMath
= true;
3080 TrappingMathPresent
= true;
3081 FPExceptionBehavior
= "strict";
3083 case options::OPT_fno_trapping_math
:
3084 if (!TrappingMathPresent
&& !FPExceptionBehavior
.empty() &&
3085 FPExceptionBehavior
!= "ignore")
3086 // Warn that previous value of option is overridden.
3087 D
.Diag(clang::diag::warn_drv_overriding_option
)
3088 << Args
.MakeArgString("-ffp-exception-behavior=" +
3089 FPExceptionBehavior
)
3090 << "-fno-trapping-math";
3091 TrappingMath
= false;
3092 TrappingMathPresent
= true;
3093 FPExceptionBehavior
= "ignore";
3096 case options::OPT_frounding_math
:
3097 RoundingFPMath
= true;
3100 case options::OPT_fno_rounding_math
:
3101 RoundingFPMath
= false;
3104 case options::OPT_fdenormal_fp_math_EQ
:
3105 DenormalFPMath
= llvm::parseDenormalFPAttribute(A
->getValue());
3106 DenormalFP32Math
= DenormalFPMath
;
3107 if (!DenormalFPMath
.isValid()) {
3108 D
.Diag(diag::err_drv_invalid_value
)
3109 << A
->getAsString(Args
) << A
->getValue();
3113 case options::OPT_fdenormal_fp_math_f32_EQ
:
3114 DenormalFP32Math
= llvm::parseDenormalFPAttribute(A
->getValue());
3115 if (!DenormalFP32Math
.isValid()) {
3116 D
.Diag(diag::err_drv_invalid_value
)
3117 << A
->getAsString(Args
) << A
->getValue();
3121 // Validate and pass through -ffp-contract option.
3122 case options::OPT_ffp_contract
: {
3123 StringRef Val
= A
->getValue();
3124 if (Val
== "fast" || Val
== "on" || Val
== "off" ||
3125 Val
== "fast-honor-pragmas") {
3127 LastSeenFfpContractOption
= Val
;
3129 D
.Diag(diag::err_drv_unsupported_option_argument
)
3130 << A
->getSpelling() << Val
;
3134 // Validate and pass through -ffp-exception-behavior option.
3135 case options::OPT_ffp_exception_behavior_EQ
: {
3136 StringRef Val
= A
->getValue();
3137 if (!TrappingMathPresent
&& !FPExceptionBehavior
.empty() &&
3138 FPExceptionBehavior
!= Val
)
3139 // Warn that previous value of option is overridden.
3140 D
.Diag(clang::diag::warn_drv_overriding_option
)
3141 << Args
.MakeArgString("-ffp-exception-behavior=" +
3142 FPExceptionBehavior
)
3143 << Args
.MakeArgString("-ffp-exception-behavior=" + Val
);
3144 TrappingMath
= TrappingMathPresent
= false;
3145 if (Val
== "ignore" || Val
== "maytrap")
3146 FPExceptionBehavior
= Val
;
3147 else if (Val
== "strict") {
3148 FPExceptionBehavior
= Val
;
3149 TrappingMath
= TrappingMathPresent
= true;
3151 D
.Diag(diag::err_drv_unsupported_option_argument
)
3152 << A
->getSpelling() << Val
;
3156 // Validate and pass through -ffp-eval-method option.
3157 case options::OPT_ffp_eval_method_EQ
: {
3158 StringRef Val
= A
->getValue();
3159 if (Val
== "double" || Val
== "extended" || Val
== "source")
3162 D
.Diag(diag::err_drv_unsupported_option_argument
)
3163 << A
->getSpelling() << Val
;
3167 case options::OPT_fexcess_precision_EQ
: {
3168 StringRef Val
= A
->getValue();
3169 const llvm::Triple::ArchType Arch
= TC
.getArch();
3170 if (Arch
== llvm::Triple::x86
|| Arch
== llvm::Triple::x86_64
) {
3171 if (Val
== "standard" || Val
== "fast")
3172 Float16ExcessPrecision
= Val
;
3173 // To make it GCC compatible, allow the value of "16" which
3174 // means disable excess precision, the same meaning than clang's
3175 // equivalent value "none".
3176 else if (Val
== "16")
3177 Float16ExcessPrecision
= "none";
3179 D
.Diag(diag::err_drv_unsupported_option_argument
)
3180 << A
->getSpelling() << Val
;
3182 if (!(Val
== "standard" || Val
== "fast"))
3183 D
.Diag(diag::err_drv_unsupported_option_argument
)
3184 << A
->getSpelling() << Val
;
3186 BFloat16ExcessPrecision
= Float16ExcessPrecision
;
3189 case options::OPT_ffinite_math_only
:
3193 case options::OPT_fno_finite_math_only
:
3198 case options::OPT_funsafe_math_optimizations
:
3199 AssociativeMath
= true;
3200 ReciprocalMath
= true;
3201 SignedZeros
= false;
3203 TrappingMath
= false;
3204 FPExceptionBehavior
= "";
3205 FPContract
= "fast";
3206 SeenUnsafeMathModeOption
= true;
3208 case options::OPT_fno_unsafe_math_optimizations
:
3209 AssociativeMath
= false;
3210 ReciprocalMath
= false;
3214 if (!JA
.isDeviceOffloading(Action::OFK_Cuda
) &&
3215 !JA
.isOffloading(Action::OFK_HIP
)) {
3216 if (LastSeenFfpContractOption
!= "") {
3217 FPContract
= LastSeenFfpContractOption
;
3218 } else if (SeenUnsafeMathModeOption
)
3223 case options::OPT_Ofast
:
3224 // If -Ofast is the optimization level, then -ffast-math should be enabled
3228 case options::OPT_ffast_math
: {
3232 case options::OPT_fno_fast_math
:
3235 // Turning on -ffast-math (with either flag) removes the need for
3236 // MathErrno. However, turning *off* -ffast-math merely restores the
3237 // toolchain default (which may be false).
3238 MathErrno
= TC
.IsMathErrnoDefault();
3239 AssociativeMath
= false;
3240 ReciprocalMath
= false;
3243 // -fno_fast_math restores default fpcontract handling
3244 if (!JA
.isDeviceOffloading(Action::OFK_Cuda
) &&
3245 !JA
.isOffloading(Action::OFK_HIP
)) {
3246 if (LastSeenFfpContractOption
!= "") {
3247 FPContract
= LastSeenFfpContractOption
;
3248 } else if (SeenUnsafeMathModeOption
)
3253 // The StrictFPModel local variable is needed to report warnings
3254 // in the way we intend. If -ffp-model=strict has been used, we
3255 // want to report a warning for the next option encountered that
3256 // takes us out of the settings described by fp-model=strict, but
3257 // we don't want to continue issuing warnings for other conflicting
3258 // options after that.
3259 if (StrictFPModel
) {
3260 // If -ffp-model=strict has been specified on command line but
3261 // subsequent options conflict then emit warning diagnostic.
3262 if (HonorINFs
&& HonorNaNs
&& !AssociativeMath
&& !ReciprocalMath
&&
3263 SignedZeros
&& TrappingMath
&& RoundingFPMath
&& !ApproxFunc
&&
3264 FPContract
== "off")
3265 // OK: Current Arg doesn't conflict with -ffp-model=strict
3268 StrictFPModel
= false;
3270 auto RHS
= (A
->getNumValues() == 0)
3272 : Args
.MakeArgString(A
->getSpelling() + A
->getValue());
3273 if (RHS
!= "-ffp-model=strict")
3274 D
.Diag(clang::diag::warn_drv_overriding_option
)
3275 << "-ffp-model=strict" << RHS
;
3279 // If we handled this option claim it
3284 CmdArgs
.push_back("-menable-no-infs");
3287 CmdArgs
.push_back("-menable-no-nans");
3290 CmdArgs
.push_back("-fapprox-func");
3293 CmdArgs
.push_back("-fmath-errno");
3295 if (AssociativeMath
&& ReciprocalMath
&& !SignedZeros
&& ApproxFunc
&&
3297 CmdArgs
.push_back("-funsafe-math-optimizations");
3300 CmdArgs
.push_back("-fno-signed-zeros");
3302 if (AssociativeMath
&& !SignedZeros
&& !TrappingMath
)
3303 CmdArgs
.push_back("-mreassociate");
3306 CmdArgs
.push_back("-freciprocal-math");
3309 // FP Exception Behavior is also set to strict
3310 assert(FPExceptionBehavior
== "strict");
3313 // The default is IEEE.
3314 if (DenormalFPMath
!= llvm::DenormalMode::getIEEE()) {
3315 llvm::SmallString
<64> DenormFlag
;
3316 llvm::raw_svector_ostream
ArgStr(DenormFlag
);
3317 ArgStr
<< "-fdenormal-fp-math=" << DenormalFPMath
;
3318 CmdArgs
.push_back(Args
.MakeArgString(ArgStr
.str()));
3321 // Add f32 specific denormal mode flag if it's different.
3322 if (DenormalFP32Math
!= DenormalFPMath
) {
3323 llvm::SmallString
<64> DenormFlag
;
3324 llvm::raw_svector_ostream
ArgStr(DenormFlag
);
3325 ArgStr
<< "-fdenormal-fp-math-f32=" << DenormalFP32Math
;
3326 CmdArgs
.push_back(Args
.MakeArgString(ArgStr
.str()));
3329 if (!FPContract
.empty())
3330 CmdArgs
.push_back(Args
.MakeArgString("-ffp-contract=" + FPContract
));
3333 CmdArgs
.push_back(Args
.MakeArgString("-frounding-math"));
3335 CmdArgs
.push_back(Args
.MakeArgString("-fno-rounding-math"));
3337 if (!FPExceptionBehavior
.empty())
3338 CmdArgs
.push_back(Args
.MakeArgString("-ffp-exception-behavior=" +
3339 FPExceptionBehavior
));
3341 if (!FPEvalMethod
.empty())
3342 CmdArgs
.push_back(Args
.MakeArgString("-ffp-eval-method=" + FPEvalMethod
));
3344 if (!Float16ExcessPrecision
.empty())
3345 CmdArgs
.push_back(Args
.MakeArgString("-ffloat16-excess-precision=" +
3346 Float16ExcessPrecision
));
3347 if (!BFloat16ExcessPrecision
.empty())
3348 CmdArgs
.push_back(Args
.MakeArgString("-fbfloat16-excess-precision=" +
3349 BFloat16ExcessPrecision
));
3351 ParseMRecip(D
, Args
, CmdArgs
);
3353 // -ffast-math enables the __FAST_MATH__ preprocessor macro, but check for the
3354 // individual features enabled by -ffast-math instead of the option itself as
3355 // that's consistent with gcc's behaviour.
3356 if (!HonorINFs
&& !HonorNaNs
&& !MathErrno
&& AssociativeMath
&& ApproxFunc
&&
3357 ReciprocalMath
&& !SignedZeros
&& !TrappingMath
&& !RoundingFPMath
) {
3358 CmdArgs
.push_back("-ffast-math");
3359 if (FPModel
== "fast") {
3360 if (FPContract
== "fast")
3361 // All set, do nothing.
3363 else if (FPContract
.empty())
3364 // Enable -ffp-contract=fast
3365 CmdArgs
.push_back(Args
.MakeArgString("-ffp-contract=fast"));
3367 D
.Diag(clang::diag::warn_drv_overriding_option
)
3368 << "-ffp-model=fast"
3369 << Args
.MakeArgString("-ffp-contract=" + FPContract
);
3373 // Handle __FINITE_MATH_ONLY__ similarly.
3374 if (!HonorINFs
&& !HonorNaNs
)
3375 CmdArgs
.push_back("-ffinite-math-only");
3377 if (const Arg
*A
= Args
.getLastArg(options::OPT_mfpmath_EQ
)) {
3378 CmdArgs
.push_back("-mfpmath");
3379 CmdArgs
.push_back(A
->getValue());
3382 // Disable a codegen optimization for floating-point casts.
3383 if (Args
.hasFlag(options::OPT_fno_strict_float_cast_overflow
,
3384 options::OPT_fstrict_float_cast_overflow
, false))
3385 CmdArgs
.push_back("-fno-strict-float-cast-overflow");
3387 if (Range
!= LangOptions::ComplexRangeKind::CX_None
)
3388 ComplexRangeStr
= RenderComplexRangeOption(Range
);
3389 if (!ComplexRangeStr
.empty()) {
3390 CmdArgs
.push_back(Args
.MakeArgString(ComplexRangeStr
));
3391 if (Args
.hasArg(options::OPT_fcomplex_arithmetic_EQ
))
3392 CmdArgs
.push_back(Args
.MakeArgString("-fcomplex-arithmetic=" +
3393 ComplexRangeKindToStr(Range
)));
3395 if (Args
.hasArg(options::OPT_fcx_limited_range
))
3396 CmdArgs
.push_back("-fcx-limited-range");
3397 if (Args
.hasArg(options::OPT_fcx_fortran_rules
))
3398 CmdArgs
.push_back("-fcx-fortran-rules");
3399 if (Args
.hasArg(options::OPT_fno_cx_limited_range
))
3400 CmdArgs
.push_back("-fno-cx-limited-range");
3401 if (Args
.hasArg(options::OPT_fno_cx_fortran_rules
))
3402 CmdArgs
.push_back("-fno-cx-fortran-rules");
3405 static void RenderAnalyzerOptions(const ArgList
&Args
, ArgStringList
&CmdArgs
,
3406 const llvm::Triple
&Triple
,
3407 const InputInfo
&Input
) {
3408 // Add default argument set.
3409 if (!Args
.hasArg(options::OPT__analyzer_no_default_checks
)) {
3410 CmdArgs
.push_back("-analyzer-checker=core");
3411 CmdArgs
.push_back("-analyzer-checker=apiModeling");
3413 if (!Triple
.isWindowsMSVCEnvironment()) {
3414 CmdArgs
.push_back("-analyzer-checker=unix");
3416 // Enable "unix" checkers that also work on Windows.
3417 CmdArgs
.push_back("-analyzer-checker=unix.API");
3418 CmdArgs
.push_back("-analyzer-checker=unix.Malloc");
3419 CmdArgs
.push_back("-analyzer-checker=unix.MallocSizeof");
3420 CmdArgs
.push_back("-analyzer-checker=unix.MismatchedDeallocator");
3421 CmdArgs
.push_back("-analyzer-checker=unix.cstring.BadSizeArg");
3422 CmdArgs
.push_back("-analyzer-checker=unix.cstring.NullArg");
3425 // Disable some unix checkers for PS4/PS5.
3426 if (Triple
.isPS()) {
3427 CmdArgs
.push_back("-analyzer-disable-checker=unix.API");
3428 CmdArgs
.push_back("-analyzer-disable-checker=unix.Vfork");
3431 if (Triple
.isOSDarwin()) {
3432 CmdArgs
.push_back("-analyzer-checker=osx");
3434 "-analyzer-checker=security.insecureAPI.decodeValueOfObjCType");
3436 else if (Triple
.isOSFuchsia())
3437 CmdArgs
.push_back("-analyzer-checker=fuchsia");
3439 CmdArgs
.push_back("-analyzer-checker=deadcode");
3441 if (types::isCXX(Input
.getType()))
3442 CmdArgs
.push_back("-analyzer-checker=cplusplus");
3444 if (!Triple
.isPS()) {
3445 CmdArgs
.push_back("-analyzer-checker=security.insecureAPI.UncheckedReturn");
3446 CmdArgs
.push_back("-analyzer-checker=security.insecureAPI.getpw");
3447 CmdArgs
.push_back("-analyzer-checker=security.insecureAPI.gets");
3448 CmdArgs
.push_back("-analyzer-checker=security.insecureAPI.mktemp");
3449 CmdArgs
.push_back("-analyzer-checker=security.insecureAPI.mkstemp");
3450 CmdArgs
.push_back("-analyzer-checker=security.insecureAPI.vfork");
3453 // Default nullability checks.
3454 CmdArgs
.push_back("-analyzer-checker=nullability.NullPassedToNonnull");
3455 CmdArgs
.push_back("-analyzer-checker=nullability.NullReturnedFromNonnull");
3458 // Set the output format. The default is plist, for (lame) historical reasons.
3459 CmdArgs
.push_back("-analyzer-output");
3460 if (Arg
*A
= Args
.getLastArg(options::OPT__analyzer_output
))
3461 CmdArgs
.push_back(A
->getValue());
3463 CmdArgs
.push_back("plist");
3465 // Disable the presentation of standard compiler warnings when using
3466 // --analyze. We only want to show static analyzer diagnostics or frontend
3468 CmdArgs
.push_back("-w");
3470 // Add -Xanalyzer arguments when running as analyzer.
3471 Args
.AddAllArgValues(CmdArgs
, options::OPT_Xanalyzer
);
3474 static bool isValidSymbolName(StringRef S
) {
3478 if (std::isdigit(S
[0]))
3481 return llvm::all_of(S
, [](char C
) { return std::isalnum(C
) || C
== '_'; });
3484 static void RenderSSPOptions(const Driver
&D
, const ToolChain
&TC
,
3485 const ArgList
&Args
, ArgStringList
&CmdArgs
,
3486 bool KernelOrKext
) {
3487 const llvm::Triple
&EffectiveTriple
= TC
.getEffectiveTriple();
3489 // NVPTX doesn't support stack protectors; from the compiler's perspective, it
3490 // doesn't even have a stack!
3491 if (EffectiveTriple
.isNVPTX())
3494 // -stack-protector=0 is default.
3495 LangOptions::StackProtectorMode StackProtectorLevel
= LangOptions::SSPOff
;
3496 LangOptions::StackProtectorMode DefaultStackProtectorLevel
=
3497 TC
.GetDefaultStackProtectorLevel(KernelOrKext
);
3499 if (Arg
*A
= Args
.getLastArg(options::OPT_fno_stack_protector
,
3500 options::OPT_fstack_protector_all
,
3501 options::OPT_fstack_protector_strong
,
3502 options::OPT_fstack_protector
)) {
3503 if (A
->getOption().matches(options::OPT_fstack_protector
))
3504 StackProtectorLevel
=
3505 std::max
<>(LangOptions::SSPOn
, DefaultStackProtectorLevel
);
3506 else if (A
->getOption().matches(options::OPT_fstack_protector_strong
))
3507 StackProtectorLevel
= LangOptions::SSPStrong
;
3508 else if (A
->getOption().matches(options::OPT_fstack_protector_all
))
3509 StackProtectorLevel
= LangOptions::SSPReq
;
3511 if (EffectiveTriple
.isBPF() && StackProtectorLevel
!= LangOptions::SSPOff
) {
3512 D
.Diag(diag::warn_drv_unsupported_option_for_target
)
3513 << A
->getSpelling() << EffectiveTriple
.getTriple();
3514 StackProtectorLevel
= DefaultStackProtectorLevel
;
3517 StackProtectorLevel
= DefaultStackProtectorLevel
;
3520 if (StackProtectorLevel
) {
3521 CmdArgs
.push_back("-stack-protector");
3522 CmdArgs
.push_back(Args
.MakeArgString(Twine(StackProtectorLevel
)));
3525 // --param ssp-buffer-size=
3526 for (const Arg
*A
: Args
.filtered(options::OPT__param
)) {
3527 StringRef
Str(A
->getValue());
3528 if (Str
.starts_with("ssp-buffer-size=")) {
3529 if (StackProtectorLevel
) {
3530 CmdArgs
.push_back("-stack-protector-buffer-size");
3531 // FIXME: Verify the argument is a valid integer.
3532 CmdArgs
.push_back(Args
.MakeArgString(Str
.drop_front(16)));
3538 const std::string
&TripleStr
= EffectiveTriple
.getTriple();
3539 if (Arg
*A
= Args
.getLastArg(options::OPT_mstack_protector_guard_EQ
)) {
3540 StringRef Value
= A
->getValue();
3541 if (!EffectiveTriple
.isX86() && !EffectiveTriple
.isAArch64() &&
3542 !EffectiveTriple
.isARM() && !EffectiveTriple
.isThumb())
3543 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
3544 << A
->getAsString(Args
) << TripleStr
;
3545 if ((EffectiveTriple
.isX86() || EffectiveTriple
.isARM() ||
3546 EffectiveTriple
.isThumb()) &&
3547 Value
!= "tls" && Value
!= "global") {
3548 D
.Diag(diag::err_drv_invalid_value_with_suggestion
)
3549 << A
->getOption().getName() << Value
<< "tls global";
3552 if ((EffectiveTriple
.isARM() || EffectiveTriple
.isThumb()) &&
3554 if (!Args
.hasArg(options::OPT_mstack_protector_guard_offset_EQ
)) {
3555 D
.Diag(diag::err_drv_ssp_missing_offset_argument
)
3556 << A
->getAsString(Args
);
3559 // Check whether the target subarch supports the hardware TLS register
3560 if (!arm::isHardTPSupported(EffectiveTriple
)) {
3561 D
.Diag(diag::err_target_unsupported_tp_hard
)
3562 << EffectiveTriple
.getArchName();
3565 // Check whether the user asked for something other than -mtp=cp15
3566 if (Arg
*A
= Args
.getLastArg(options::OPT_mtp_mode_EQ
)) {
3567 StringRef Value
= A
->getValue();
3568 if (Value
!= "cp15") {
3569 D
.Diag(diag::err_drv_argument_not_allowed_with
)
3570 << A
->getAsString(Args
) << "-mstack-protector-guard=tls";
3574 CmdArgs
.push_back("-target-feature");
3575 CmdArgs
.push_back("+read-tp-tpidruro");
3577 if (EffectiveTriple
.isAArch64() && Value
!= "sysreg" && Value
!= "global") {
3578 D
.Diag(diag::err_drv_invalid_value_with_suggestion
)
3579 << A
->getOption().getName() << Value
<< "sysreg global";
3582 A
->render(Args
, CmdArgs
);
3585 if (Arg
*A
= Args
.getLastArg(options::OPT_mstack_protector_guard_offset_EQ
)) {
3586 StringRef Value
= A
->getValue();
3587 if (!EffectiveTriple
.isX86() && !EffectiveTriple
.isAArch64() &&
3588 !EffectiveTriple
.isARM() && !EffectiveTriple
.isThumb())
3589 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
3590 << A
->getAsString(Args
) << TripleStr
;
3592 if (Value
.getAsInteger(10, Offset
)) {
3593 D
.Diag(diag::err_drv_invalid_value
) << A
->getOption().getName() << Value
;
3596 if ((EffectiveTriple
.isARM() || EffectiveTriple
.isThumb()) &&
3597 (Offset
< 0 || Offset
> 0xfffff)) {
3598 D
.Diag(diag::err_drv_invalid_int_value
)
3599 << A
->getOption().getName() << Value
;
3602 A
->render(Args
, CmdArgs
);
3605 if (Arg
*A
= Args
.getLastArg(options::OPT_mstack_protector_guard_reg_EQ
)) {
3606 StringRef Value
= A
->getValue();
3607 if (!EffectiveTriple
.isX86() && !EffectiveTriple
.isAArch64())
3608 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
3609 << A
->getAsString(Args
) << TripleStr
;
3610 if (EffectiveTriple
.isX86() && (Value
!= "fs" && Value
!= "gs")) {
3611 D
.Diag(diag::err_drv_invalid_value_with_suggestion
)
3612 << A
->getOption().getName() << Value
<< "fs gs";
3615 if (EffectiveTriple
.isAArch64() && Value
!= "sp_el0") {
3616 D
.Diag(diag::err_drv_invalid_value
) << A
->getOption().getName() << Value
;
3619 A
->render(Args
, CmdArgs
);
3622 if (Arg
*A
= Args
.getLastArg(options::OPT_mstack_protector_guard_symbol_EQ
)) {
3623 StringRef Value
= A
->getValue();
3624 if (!isValidSymbolName(Value
)) {
3625 D
.Diag(diag::err_drv_argument_only_allowed_with
)
3626 << A
->getOption().getName() << "legal symbol name";
3629 A
->render(Args
, CmdArgs
);
3633 static void RenderSCPOptions(const ToolChain
&TC
, const ArgList
&Args
,
3634 ArgStringList
&CmdArgs
) {
3635 const llvm::Triple
&EffectiveTriple
= TC
.getEffectiveTriple();
3637 if (!EffectiveTriple
.isOSFreeBSD() && !EffectiveTriple
.isOSLinux())
3640 if (!EffectiveTriple
.isX86() && !EffectiveTriple
.isSystemZ() &&
3641 !EffectiveTriple
.isPPC64() && !EffectiveTriple
.isAArch64())
3644 Args
.addOptInFlag(CmdArgs
, options::OPT_fstack_clash_protection
,
3645 options::OPT_fno_stack_clash_protection
);
3648 static void RenderTrivialAutoVarInitOptions(const Driver
&D
,
3649 const ToolChain
&TC
,
3650 const ArgList
&Args
,
3651 ArgStringList
&CmdArgs
) {
3652 auto DefaultTrivialAutoVarInit
= TC
.GetDefaultTrivialAutoVarInit();
3653 StringRef TrivialAutoVarInit
= "";
3655 for (const Arg
*A
: Args
) {
3656 switch (A
->getOption().getID()) {
3659 case options::OPT_ftrivial_auto_var_init
: {
3661 StringRef Val
= A
->getValue();
3662 if (Val
== "uninitialized" || Val
== "zero" || Val
== "pattern")
3663 TrivialAutoVarInit
= Val
;
3665 D
.Diag(diag::err_drv_unsupported_option_argument
)
3666 << A
->getSpelling() << Val
;
3672 if (TrivialAutoVarInit
.empty())
3673 switch (DefaultTrivialAutoVarInit
) {
3674 case LangOptions::TrivialAutoVarInitKind::Uninitialized
:
3676 case LangOptions::TrivialAutoVarInitKind::Pattern
:
3677 TrivialAutoVarInit
= "pattern";
3679 case LangOptions::TrivialAutoVarInitKind::Zero
:
3680 TrivialAutoVarInit
= "zero";
3684 if (!TrivialAutoVarInit
.empty()) {
3686 Args
.MakeArgString("-ftrivial-auto-var-init=" + TrivialAutoVarInit
));
3690 Args
.getLastArg(options::OPT_ftrivial_auto_var_init_stop_after
)) {
3691 if (!Args
.hasArg(options::OPT_ftrivial_auto_var_init
) ||
3693 Args
.getLastArg(options::OPT_ftrivial_auto_var_init
)->getValue()) ==
3695 D
.Diag(diag::err_drv_trivial_auto_var_init_stop_after_missing_dependency
);
3697 StringRef Val
= A
->getValue();
3698 if (std::stoi(Val
.str()) <= 0)
3699 D
.Diag(diag::err_drv_trivial_auto_var_init_stop_after_invalid_value
);
3701 Args
.MakeArgString("-ftrivial-auto-var-init-stop-after=" + Val
));
3704 if (Arg
*A
= Args
.getLastArg(options::OPT_ftrivial_auto_var_init_max_size
)) {
3705 if (!Args
.hasArg(options::OPT_ftrivial_auto_var_init
) ||
3707 Args
.getLastArg(options::OPT_ftrivial_auto_var_init
)->getValue()) ==
3709 D
.Diag(diag::err_drv_trivial_auto_var_init_max_size_missing_dependency
);
3711 StringRef Val
= A
->getValue();
3712 if (std::stoi(Val
.str()) <= 0)
3713 D
.Diag(diag::err_drv_trivial_auto_var_init_max_size_invalid_value
);
3715 Args
.MakeArgString("-ftrivial-auto-var-init-max-size=" + Val
));
3719 static void RenderOpenCLOptions(const ArgList
&Args
, ArgStringList
&CmdArgs
,
3720 types::ID InputType
) {
3721 // cl-denorms-are-zero is not forwarded. It is translated into a generic flag
3722 // for denormal flushing handling based on the target.
3723 const unsigned ForwardedArguments
[] = {
3724 options::OPT_cl_opt_disable
,
3725 options::OPT_cl_strict_aliasing
,
3726 options::OPT_cl_single_precision_constant
,
3727 options::OPT_cl_finite_math_only
,
3728 options::OPT_cl_kernel_arg_info
,
3729 options::OPT_cl_unsafe_math_optimizations
,
3730 options::OPT_cl_fast_relaxed_math
,
3731 options::OPT_cl_mad_enable
,
3732 options::OPT_cl_no_signed_zeros
,
3733 options::OPT_cl_fp32_correctly_rounded_divide_sqrt
,
3734 options::OPT_cl_uniform_work_group_size
3737 if (Arg
*A
= Args
.getLastArg(options::OPT_cl_std_EQ
)) {
3738 std::string CLStdStr
= std::string("-cl-std=") + A
->getValue();
3739 CmdArgs
.push_back(Args
.MakeArgString(CLStdStr
));
3740 } else if (Arg
*A
= Args
.getLastArg(options::OPT_cl_ext_EQ
)) {
3741 std::string CLExtStr
= std::string("-cl-ext=") + A
->getValue();
3742 CmdArgs
.push_back(Args
.MakeArgString(CLExtStr
));
3745 for (const auto &Arg
: ForwardedArguments
)
3746 if (const auto *A
= Args
.getLastArg(Arg
))
3747 CmdArgs
.push_back(Args
.MakeArgString(A
->getOption().getPrefixedName()));
3749 // Only add the default headers if we are compiling OpenCL sources.
3750 if ((types::isOpenCL(InputType
) ||
3751 (Args
.hasArg(options::OPT_cl_std_EQ
) && types::isSrcFile(InputType
))) &&
3752 !Args
.hasArg(options::OPT_cl_no_stdinc
)) {
3753 CmdArgs
.push_back("-finclude-default-header");
3754 CmdArgs
.push_back("-fdeclare-opencl-builtins");
3758 static void RenderHLSLOptions(const ArgList
&Args
, ArgStringList
&CmdArgs
,
3759 types::ID InputType
) {
3760 const unsigned ForwardedArguments
[] = {options::OPT_dxil_validator_version
,
3764 options::OPT_emit_llvm
,
3765 options::OPT_emit_obj
,
3766 options::OPT_disable_llvm_passes
,
3767 options::OPT_fnative_half_type
,
3768 options::OPT_hlsl_entrypoint
};
3769 if (!types::isHLSL(InputType
))
3771 for (const auto &Arg
: ForwardedArguments
)
3772 if (const auto *A
= Args
.getLastArg(Arg
))
3773 A
->renderAsInput(Args
, CmdArgs
);
3774 // Add the default headers if dxc_no_stdinc is not set.
3775 if (!Args
.hasArg(options::OPT_dxc_no_stdinc
) &&
3776 !Args
.hasArg(options::OPT_nostdinc
))
3777 CmdArgs
.push_back("-finclude-default-header");
3780 static void RenderOpenACCOptions(const Driver
&D
, const ArgList
&Args
,
3781 ArgStringList
&CmdArgs
, types::ID InputType
) {
3782 if (!Args
.hasArg(options::OPT_fopenacc
))
3785 CmdArgs
.push_back("-fopenacc");
3787 if (Arg
*A
= Args
.getLastArg(options::OPT_openacc_macro_override
)) {
3788 StringRef Value
= A
->getValue();
3790 if (!Value
.getAsInteger(10, Version
))
3791 A
->renderAsInput(Args
, CmdArgs
);
3793 D
.Diag(diag::err_drv_clang_unsupported
) << Value
;
3797 static void RenderARCMigrateToolOptions(const Driver
&D
, const ArgList
&Args
,
3798 ArgStringList
&CmdArgs
) {
3799 bool ARCMTEnabled
= false;
3800 if (!Args
.hasArg(options::OPT_fno_objc_arc
, options::OPT_fobjc_arc
)) {
3801 if (const Arg
*A
= Args
.getLastArg(options::OPT_ccc_arcmt_check
,
3802 options::OPT_ccc_arcmt_modify
,
3803 options::OPT_ccc_arcmt_migrate
)) {
3804 ARCMTEnabled
= true;
3805 switch (A
->getOption().getID()) {
3806 default: llvm_unreachable("missed a case");
3807 case options::OPT_ccc_arcmt_check
:
3808 CmdArgs
.push_back("-arcmt-action=check");
3810 case options::OPT_ccc_arcmt_modify
:
3811 CmdArgs
.push_back("-arcmt-action=modify");
3813 case options::OPT_ccc_arcmt_migrate
:
3814 CmdArgs
.push_back("-arcmt-action=migrate");
3815 CmdArgs
.push_back("-mt-migrate-directory");
3816 CmdArgs
.push_back(A
->getValue());
3818 Args
.AddLastArg(CmdArgs
, options::OPT_arcmt_migrate_report_output
);
3819 Args
.AddLastArg(CmdArgs
, options::OPT_arcmt_migrate_emit_arc_errors
);
3824 Args
.ClaimAllArgs(options::OPT_ccc_arcmt_check
);
3825 Args
.ClaimAllArgs(options::OPT_ccc_arcmt_modify
);
3826 Args
.ClaimAllArgs(options::OPT_ccc_arcmt_migrate
);
3829 if (const Arg
*A
= Args
.getLastArg(options::OPT_ccc_objcmt_migrate
)) {
3831 D
.Diag(diag::err_drv_argument_not_allowed_with
)
3832 << A
->getAsString(Args
) << "-ccc-arcmt-migrate";
3834 CmdArgs
.push_back("-mt-migrate-directory");
3835 CmdArgs
.push_back(A
->getValue());
3837 if (!Args
.hasArg(options::OPT_objcmt_migrate_literals
,
3838 options::OPT_objcmt_migrate_subscripting
,
3839 options::OPT_objcmt_migrate_property
)) {
3840 // None specified, means enable them all.
3841 CmdArgs
.push_back("-objcmt-migrate-literals");
3842 CmdArgs
.push_back("-objcmt-migrate-subscripting");
3843 CmdArgs
.push_back("-objcmt-migrate-property");
3845 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_migrate_literals
);
3846 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_migrate_subscripting
);
3847 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_migrate_property
);
3850 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_migrate_literals
);
3851 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_migrate_subscripting
);
3852 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_migrate_property
);
3853 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_migrate_all
);
3854 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_migrate_readonly_property
);
3855 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_migrate_readwrite_property
);
3856 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_migrate_property_dot_syntax
);
3857 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_migrate_annotation
);
3858 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_migrate_instancetype
);
3859 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_migrate_nsmacros
);
3860 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_migrate_protocol_conformance
);
3861 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_atomic_property
);
3862 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_returns_innerpointer_property
);
3863 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_ns_nonatomic_iosonly
);
3864 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_migrate_designated_init
);
3865 Args
.AddLastArg(CmdArgs
, options::OPT_objcmt_allowlist_dir_path
);
3869 static void RenderBuiltinOptions(const ToolChain
&TC
, const llvm::Triple
&T
,
3870 const ArgList
&Args
, ArgStringList
&CmdArgs
) {
3871 // -fbuiltin is default unless -mkernel is used.
3873 Args
.hasFlag(options::OPT_fbuiltin
, options::OPT_fno_builtin
,
3874 !Args
.hasArg(options::OPT_mkernel
));
3876 CmdArgs
.push_back("-fno-builtin");
3878 // -ffreestanding implies -fno-builtin.
3879 if (Args
.hasArg(options::OPT_ffreestanding
))
3880 UseBuiltins
= false;
3882 // Process the -fno-builtin-* options.
3883 for (const Arg
*A
: Args
.filtered(options::OPT_fno_builtin_
)) {
3886 // If -fno-builtin is specified, then there's no need to pass the option to
3889 A
->render(Args
, CmdArgs
);
3892 // le32-specific flags:
3893 // -fno-math-builtin: clang should not convert math builtins to intrinsics
3895 if (TC
.getArch() == llvm::Triple::le32
)
3896 CmdArgs
.push_back("-fno-math-builtin");
3899 bool Driver::getDefaultModuleCachePath(SmallVectorImpl
<char> &Result
) {
3900 if (const char *Str
= std::getenv("CLANG_MODULE_CACHE_PATH")) {
3902 Path
.toVector(Result
);
3903 return Path
.getSingleStringRef() != "";
3905 if (llvm::sys::path::cache_directory(Result
)) {
3906 llvm::sys::path::append(Result
, "clang");
3907 llvm::sys::path::append(Result
, "ModuleCache");
3913 llvm::SmallString
<256>
3914 clang::driver::tools::getCXX20NamedModuleOutputPath(const ArgList
&Args
,
3915 const char *BaseInput
) {
3916 if (Arg
*ModuleOutputEQ
= Args
.getLastArg(options::OPT_fmodule_output_EQ
))
3917 return StringRef(ModuleOutputEQ
->getValue());
3919 SmallString
<256> OutputPath
;
3920 if (Arg
*FinalOutput
= Args
.getLastArg(options::OPT_o
);
3921 FinalOutput
&& Args
.hasArg(options::OPT_c
))
3922 OutputPath
= FinalOutput
->getValue();
3924 OutputPath
= BaseInput
;
3926 const char *Extension
= types::getTypeTempSuffix(types::TY_ModuleFile
);
3927 llvm::sys::path::replace_extension(OutputPath
, Extension
);
3931 static bool RenderModulesOptions(Compilation
&C
, const Driver
&D
,
3932 const ArgList
&Args
, const InputInfo
&Input
,
3933 const InputInfo
&Output
, bool HaveStd20
,
3934 ArgStringList
&CmdArgs
) {
3935 bool IsCXX
= types::isCXX(Input
.getType());
3936 bool HaveStdCXXModules
= IsCXX
&& HaveStd20
;
3937 bool HaveModules
= HaveStdCXXModules
;
3939 // -fmodules enables the use of precompiled modules (off by default).
3940 // Users can pass -fno-cxx-modules to turn off modules support for
3941 // C++/Objective-C++ programs.
3942 bool HaveClangModules
= false;
3943 if (Args
.hasFlag(options::OPT_fmodules
, options::OPT_fno_modules
, false)) {
3944 bool AllowedInCXX
= Args
.hasFlag(options::OPT_fcxx_modules
,
3945 options::OPT_fno_cxx_modules
, true);
3946 if (AllowedInCXX
|| !IsCXX
) {
3947 CmdArgs
.push_back("-fmodules");
3948 HaveClangModules
= true;
3952 HaveModules
|= HaveClangModules
;
3954 // -fmodule-maps enables implicit reading of module map files. By default,
3955 // this is enabled if we are using Clang's flavor of precompiled modules.
3956 if (Args
.hasFlag(options::OPT_fimplicit_module_maps
,
3957 options::OPT_fno_implicit_module_maps
, HaveClangModules
))
3958 CmdArgs
.push_back("-fimplicit-module-maps");
3960 // -fmodules-decluse checks that modules used are declared so (off by default)
3961 Args
.addOptInFlag(CmdArgs
, options::OPT_fmodules_decluse
,
3962 options::OPT_fno_modules_decluse
);
3964 // -fmodules-strict-decluse is like -fmodule-decluse, but also checks that
3965 // all #included headers are part of modules.
3966 if (Args
.hasFlag(options::OPT_fmodules_strict_decluse
,
3967 options::OPT_fno_modules_strict_decluse
, false))
3968 CmdArgs
.push_back("-fmodules-strict-decluse");
3970 // -fno-implicit-modules turns off implicitly compiling modules on demand.
3971 bool ImplicitModules
= false;
3972 if (!Args
.hasFlag(options::OPT_fimplicit_modules
,
3973 options::OPT_fno_implicit_modules
, HaveClangModules
)) {
3975 CmdArgs
.push_back("-fno-implicit-modules");
3976 } else if (HaveModules
) {
3977 ImplicitModules
= true;
3978 // -fmodule-cache-path specifies where our implicitly-built module files
3979 // should be written.
3980 SmallString
<128> Path
;
3981 if (Arg
*A
= Args
.getLastArg(options::OPT_fmodules_cache_path
))
3982 Path
= A
->getValue();
3984 bool HasPath
= true;
3985 if (C
.isForDiagnostics()) {
3986 // When generating crash reports, we want to emit the modules along with
3987 // the reproduction sources, so we ignore any provided module path.
3988 Path
= Output
.getFilename();
3989 llvm::sys::path::replace_extension(Path
, ".cache");
3990 llvm::sys::path::append(Path
, "modules");
3991 } else if (Path
.empty()) {
3992 // No module path was provided: use the default.
3993 HasPath
= Driver::getDefaultModuleCachePath(Path
);
3996 // `HasPath` will only be false if getDefaultModuleCachePath() fails.
3997 // That being said, that failure is unlikely and not caching is harmless.
3999 const char Arg
[] = "-fmodules-cache-path=";
4000 Path
.insert(Path
.begin(), Arg
, Arg
+ strlen(Arg
));
4001 CmdArgs
.push_back(Args
.MakeArgString(Path
));
4006 if (Args
.hasFlag(options::OPT_fprebuilt_implicit_modules
,
4007 options::OPT_fno_prebuilt_implicit_modules
, false))
4008 CmdArgs
.push_back("-fprebuilt-implicit-modules");
4009 if (Args
.hasFlag(options::OPT_fmodules_validate_input_files_content
,
4010 options::OPT_fno_modules_validate_input_files_content
,
4012 CmdArgs
.push_back("-fvalidate-ast-input-files-content");
4015 // -fmodule-name specifies the module that is currently being built (or
4016 // used for header checking by -fmodule-maps).
4017 Args
.AddLastArg(CmdArgs
, options::OPT_fmodule_name_EQ
);
4019 // -fmodule-map-file can be used to specify files containing module
4021 Args
.AddAllArgs(CmdArgs
, options::OPT_fmodule_map_file
);
4023 // -fbuiltin-module-map can be used to load the clang
4024 // builtin headers modulemap file.
4025 if (Args
.hasArg(options::OPT_fbuiltin_module_map
)) {
4026 SmallString
<128> BuiltinModuleMap(D
.ResourceDir
);
4027 llvm::sys::path::append(BuiltinModuleMap
, "include");
4028 llvm::sys::path::append(BuiltinModuleMap
, "module.modulemap");
4029 if (llvm::sys::fs::exists(BuiltinModuleMap
))
4031 Args
.MakeArgString("-fmodule-map-file=" + BuiltinModuleMap
));
4034 // The -fmodule-file=<name>=<file> form specifies the mapping of module
4035 // names to precompiled module files (the module is loaded only if used).
4036 // The -fmodule-file=<file> form can be used to unconditionally load
4037 // precompiled module files (whether used or not).
4038 if (HaveModules
|| Input
.getType() == clang::driver::types::TY_ModuleFile
) {
4039 Args
.AddAllArgs(CmdArgs
, options::OPT_fmodule_file
);
4041 // -fprebuilt-module-path specifies where to load the prebuilt module files.
4042 for (const Arg
*A
: Args
.filtered(options::OPT_fprebuilt_module_path
)) {
4043 CmdArgs
.push_back(Args
.MakeArgString(
4044 std::string("-fprebuilt-module-path=") + A
->getValue()));
4048 Args
.ClaimAllArgs(options::OPT_fmodule_file
);
4050 // When building modules and generating crashdumps, we need to dump a module
4051 // dependency VFS alongside the output.
4052 if (HaveClangModules
&& C
.isForDiagnostics()) {
4053 SmallString
<128> VFSDir(Output
.getFilename());
4054 llvm::sys::path::replace_extension(VFSDir
, ".cache");
4055 // Add the cache directory as a temp so the crash diagnostics pick it up.
4056 C
.addTempFile(Args
.MakeArgString(VFSDir
));
4058 llvm::sys::path::append(VFSDir
, "vfs");
4059 CmdArgs
.push_back("-module-dependency-dir");
4060 CmdArgs
.push_back(Args
.MakeArgString(VFSDir
));
4063 if (HaveClangModules
)
4064 Args
.AddLastArg(CmdArgs
, options::OPT_fmodules_user_build_path
);
4066 // Pass through all -fmodules-ignore-macro arguments.
4067 Args
.AddAllArgs(CmdArgs
, options::OPT_fmodules_ignore_macro
);
4068 Args
.AddLastArg(CmdArgs
, options::OPT_fmodules_prune_interval
);
4069 Args
.AddLastArg(CmdArgs
, options::OPT_fmodules_prune_after
);
4071 if (HaveClangModules
) {
4072 Args
.AddLastArg(CmdArgs
, options::OPT_fbuild_session_timestamp
);
4074 if (Arg
*A
= Args
.getLastArg(options::OPT_fbuild_session_file
)) {
4075 if (Args
.hasArg(options::OPT_fbuild_session_timestamp
))
4076 D
.Diag(diag::err_drv_argument_not_allowed_with
)
4077 << A
->getAsString(Args
) << "-fbuild-session-timestamp";
4079 llvm::sys::fs::file_status Status
;
4080 if (llvm::sys::fs::status(A
->getValue(), Status
))
4081 D
.Diag(diag::err_drv_no_such_file
) << A
->getValue();
4082 CmdArgs
.push_back(Args
.MakeArgString(
4083 "-fbuild-session-timestamp=" +
4084 Twine((uint64_t)std::chrono::duration_cast
<std::chrono::seconds
>(
4085 Status
.getLastModificationTime().time_since_epoch())
4089 if (Args
.getLastArg(
4090 options::OPT_fmodules_validate_once_per_build_session
)) {
4091 if (!Args
.getLastArg(options::OPT_fbuild_session_timestamp
,
4092 options::OPT_fbuild_session_file
))
4093 D
.Diag(diag::err_drv_modules_validate_once_requires_timestamp
);
4095 Args
.AddLastArg(CmdArgs
,
4096 options::OPT_fmodules_validate_once_per_build_session
);
4099 if (Args
.hasFlag(options::OPT_fmodules_validate_system_headers
,
4100 options::OPT_fno_modules_validate_system_headers
,
4102 CmdArgs
.push_back("-fmodules-validate-system-headers");
4104 Args
.AddLastArg(CmdArgs
,
4105 options::OPT_fmodules_disable_diagnostic_validation
);
4107 Args
.ClaimAllArgs(options::OPT_fbuild_session_timestamp
);
4108 Args
.ClaimAllArgs(options::OPT_fbuild_session_file
);
4109 Args
.ClaimAllArgs(options::OPT_fmodules_validate_once_per_build_session
);
4110 Args
.ClaimAllArgs(options::OPT_fmodules_validate_system_headers
);
4111 Args
.ClaimAllArgs(options::OPT_fno_modules_validate_system_headers
);
4112 Args
.ClaimAllArgs(options::OPT_fmodules_disable_diagnostic_validation
);
4115 // FIXME: We provisionally don't check ODR violations for decls in the global
4117 CmdArgs
.push_back("-fskip-odr-check-in-gmf");
4119 if (Args
.hasArg(options::OPT_modules_reduced_bmi
) &&
4120 (Input
.getType() == driver::types::TY_CXXModule
||
4121 Input
.getType() == driver::types::TY_PP_CXXModule
)) {
4122 CmdArgs
.push_back("-fexperimental-modules-reduced-bmi");
4124 if (Args
.hasArg(options::OPT_fmodule_output_EQ
))
4125 Args
.AddLastArg(CmdArgs
, options::OPT_fmodule_output_EQ
);
4127 CmdArgs
.push_back(Args
.MakeArgString(
4128 "-fmodule-output=" +
4129 getCXX20NamedModuleOutputPath(Args
, Input
.getBaseInput())));
4132 // Noop if we see '-fexperimental-modules-reduced-bmi' with other translation
4133 // units than module units. This is more user friendly to allow end uers to
4134 // enable this feature without asking for help from build systems.
4135 Args
.ClaimAllArgs(options::OPT_modules_reduced_bmi
);
4137 // We need to include the case the input file is a module file here.
4138 // Since the default compilation model for C++ module interface unit will
4139 // create temporary module file and compile the temporary module file
4140 // to get the object file. Then the `-fmodule-output` flag will be
4141 // brought to the second compilation process. So we have to claim it for
4143 if (Input
.getType() == driver::types::TY_CXXModule
||
4144 Input
.getType() == driver::types::TY_PP_CXXModule
||
4145 Input
.getType() == driver::types::TY_ModuleFile
) {
4146 Args
.ClaimAllArgs(options::OPT_fmodule_output
);
4147 Args
.ClaimAllArgs(options::OPT_fmodule_output_EQ
);
4153 static void RenderCharacterOptions(const ArgList
&Args
, const llvm::Triple
&T
,
4154 ArgStringList
&CmdArgs
) {
4155 // -fsigned-char is default.
4156 if (const Arg
*A
= Args
.getLastArg(options::OPT_fsigned_char
,
4157 options::OPT_fno_signed_char
,
4158 options::OPT_funsigned_char
,
4159 options::OPT_fno_unsigned_char
)) {
4160 if (A
->getOption().matches(options::OPT_funsigned_char
) ||
4161 A
->getOption().matches(options::OPT_fno_signed_char
)) {
4162 CmdArgs
.push_back("-fno-signed-char");
4164 } else if (!isSignedCharDefault(T
)) {
4165 CmdArgs
.push_back("-fno-signed-char");
4168 // The default depends on the language standard.
4169 Args
.AddLastArg(CmdArgs
, options::OPT_fchar8__t
, options::OPT_fno_char8__t
);
4171 if (const Arg
*A
= Args
.getLastArg(options::OPT_fshort_wchar
,
4172 options::OPT_fno_short_wchar
)) {
4173 if (A
->getOption().matches(options::OPT_fshort_wchar
)) {
4174 CmdArgs
.push_back("-fwchar-type=short");
4175 CmdArgs
.push_back("-fno-signed-wchar");
4177 bool IsARM
= T
.isARM() || T
.isThumb() || T
.isAArch64();
4178 CmdArgs
.push_back("-fwchar-type=int");
4180 (IsARM
&& !(T
.isOSWindows() || T
.isOSNetBSD() || T
.isOSOpenBSD())))
4181 CmdArgs
.push_back("-fno-signed-wchar");
4183 CmdArgs
.push_back("-fsigned-wchar");
4185 } else if (T
.isOSzOS())
4186 CmdArgs
.push_back("-fno-signed-wchar");
4189 static void RenderObjCOptions(const ToolChain
&TC
, const Driver
&D
,
4190 const llvm::Triple
&T
, const ArgList
&Args
,
4191 ObjCRuntime
&Runtime
, bool InferCovariantReturns
,
4192 const InputInfo
&Input
, ArgStringList
&CmdArgs
) {
4193 const llvm::Triple::ArchType Arch
= TC
.getArch();
4195 // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and legacy
4196 // is the default. Except for deployment target of 10.5, next runtime is
4197 // always legacy dispatch and -fno-objc-legacy-dispatch gets ignored silently.
4198 if (Runtime
.isNonFragile()) {
4199 if (!Args
.hasFlag(options::OPT_fobjc_legacy_dispatch
,
4200 options::OPT_fno_objc_legacy_dispatch
,
4201 Runtime
.isLegacyDispatchDefaultForArch(Arch
))) {
4202 if (TC
.UseObjCMixedDispatch())
4203 CmdArgs
.push_back("-fobjc-dispatch-method=mixed");
4205 CmdArgs
.push_back("-fobjc-dispatch-method=non-legacy");
4209 // When ObjectiveC legacy runtime is in effect on MacOSX, turn on the option
4210 // to do Array/Dictionary subscripting by default.
4211 if (Arch
== llvm::Triple::x86
&& T
.isMacOSX() &&
4212 Runtime
.getKind() == ObjCRuntime::FragileMacOSX
&& Runtime
.isNeXTFamily())
4213 CmdArgs
.push_back("-fobjc-subscripting-legacy-runtime");
4215 // Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc.
4216 // NOTE: This logic is duplicated in ToolChains.cpp.
4217 if (isObjCAutoRefCount(Args
)) {
4220 CmdArgs
.push_back("-fobjc-arc");
4222 // FIXME: It seems like this entire block, and several around it should be
4223 // wrapped in isObjC, but for now we just use it here as this is where it
4224 // was being used previously.
4225 if (types::isCXX(Input
.getType()) && types::isObjC(Input
.getType())) {
4226 if (TC
.GetCXXStdlibType(Args
) == ToolChain::CST_Libcxx
)
4227 CmdArgs
.push_back("-fobjc-arc-cxxlib=libc++");
4229 CmdArgs
.push_back("-fobjc-arc-cxxlib=libstdc++");
4232 // Allow the user to enable full exceptions code emission.
4233 // We default off for Objective-C, on for Objective-C++.
4234 if (Args
.hasFlag(options::OPT_fobjc_arc_exceptions
,
4235 options::OPT_fno_objc_arc_exceptions
,
4236 /*Default=*/types::isCXX(Input
.getType())))
4237 CmdArgs
.push_back("-fobjc-arc-exceptions");
4240 // Silence warning for full exception code emission options when explicitly
4241 // set to use no ARC.
4242 if (Args
.hasArg(options::OPT_fno_objc_arc
)) {
4243 Args
.ClaimAllArgs(options::OPT_fobjc_arc_exceptions
);
4244 Args
.ClaimAllArgs(options::OPT_fno_objc_arc_exceptions
);
4247 // Allow the user to control whether messages can be converted to runtime
4249 if (types::isObjC(Input
.getType())) {
4250 auto *Arg
= Args
.getLastArg(
4251 options::OPT_fobjc_convert_messages_to_runtime_calls
,
4252 options::OPT_fno_objc_convert_messages_to_runtime_calls
);
4254 Arg
->getOption().matches(
4255 options::OPT_fno_objc_convert_messages_to_runtime_calls
))
4256 CmdArgs
.push_back("-fno-objc-convert-messages-to-runtime-calls");
4259 // -fobjc-infer-related-result-type is the default, except in the Objective-C
4261 if (InferCovariantReturns
)
4262 CmdArgs
.push_back("-fno-objc-infer-related-result-type");
4264 // Pass down -fobjc-weak or -fno-objc-weak if present.
4265 if (types::isObjC(Input
.getType())) {
4267 Args
.getLastArg(options::OPT_fobjc_weak
, options::OPT_fno_objc_weak
);
4270 } else if (!Runtime
.allowsWeak()) {
4271 if (WeakArg
->getOption().matches(options::OPT_fobjc_weak
))
4272 D
.Diag(diag::err_objc_weak_unsupported
);
4274 WeakArg
->render(Args
, CmdArgs
);
4278 if (Args
.hasArg(options::OPT_fobjc_disable_direct_methods_for_testing
))
4279 CmdArgs
.push_back("-fobjc-disable-direct-methods-for-testing");
4282 static void RenderDiagnosticsOptions(const Driver
&D
, const ArgList
&Args
,
4283 ArgStringList
&CmdArgs
) {
4284 bool CaretDefault
= true;
4285 bool ColumnDefault
= true;
4287 if (const Arg
*A
= Args
.getLastArg(options::OPT__SLASH_diagnostics_classic
,
4288 options::OPT__SLASH_diagnostics_column
,
4289 options::OPT__SLASH_diagnostics_caret
)) {
4290 switch (A
->getOption().getID()) {
4291 case options::OPT__SLASH_diagnostics_caret
:
4292 CaretDefault
= true;
4293 ColumnDefault
= true;
4295 case options::OPT__SLASH_diagnostics_column
:
4296 CaretDefault
= false;
4297 ColumnDefault
= true;
4299 case options::OPT__SLASH_diagnostics_classic
:
4300 CaretDefault
= false;
4301 ColumnDefault
= false;
4306 // -fcaret-diagnostics is default.
4307 if (!Args
.hasFlag(options::OPT_fcaret_diagnostics
,
4308 options::OPT_fno_caret_diagnostics
, CaretDefault
))
4309 CmdArgs
.push_back("-fno-caret-diagnostics");
4311 Args
.addOptOutFlag(CmdArgs
, options::OPT_fdiagnostics_fixit_info
,
4312 options::OPT_fno_diagnostics_fixit_info
);
4313 Args
.addOptOutFlag(CmdArgs
, options::OPT_fdiagnostics_show_option
,
4314 options::OPT_fno_diagnostics_show_option
);
4317 Args
.getLastArg(options::OPT_fdiagnostics_show_category_EQ
)) {
4318 CmdArgs
.push_back("-fdiagnostics-show-category");
4319 CmdArgs
.push_back(A
->getValue());
4322 Args
.addOptInFlag(CmdArgs
, options::OPT_fdiagnostics_show_hotness
,
4323 options::OPT_fno_diagnostics_show_hotness
);
4326 Args
.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ
)) {
4328 std::string("-fdiagnostics-hotness-threshold=") + A
->getValue();
4329 CmdArgs
.push_back(Args
.MakeArgString(Opt
));
4333 Args
.getLastArg(options::OPT_fdiagnostics_misexpect_tolerance_EQ
)) {
4335 std::string("-fdiagnostics-misexpect-tolerance=") + A
->getValue();
4336 CmdArgs
.push_back(Args
.MakeArgString(Opt
));
4339 if (const Arg
*A
= Args
.getLastArg(options::OPT_fdiagnostics_format_EQ
)) {
4340 CmdArgs
.push_back("-fdiagnostics-format");
4341 CmdArgs
.push_back(A
->getValue());
4342 if (StringRef(A
->getValue()) == "sarif" ||
4343 StringRef(A
->getValue()) == "SARIF")
4344 D
.Diag(diag::warn_drv_sarif_format_unstable
);
4347 if (const Arg
*A
= Args
.getLastArg(
4348 options::OPT_fdiagnostics_show_note_include_stack
,
4349 options::OPT_fno_diagnostics_show_note_include_stack
)) {
4350 const Option
&O
= A
->getOption();
4351 if (O
.matches(options::OPT_fdiagnostics_show_note_include_stack
))
4352 CmdArgs
.push_back("-fdiagnostics-show-note-include-stack");
4354 CmdArgs
.push_back("-fno-diagnostics-show-note-include-stack");
4357 // Color diagnostics are parsed by the driver directly from argv and later
4358 // re-parsed to construct this job; claim any possible color diagnostic here
4359 // to avoid warn_drv_unused_argument and diagnose bad
4360 // OPT_fdiagnostics_color_EQ values.
4361 Args
.getLastArg(options::OPT_fcolor_diagnostics
,
4362 options::OPT_fno_color_diagnostics
);
4363 if (const Arg
*A
= Args
.getLastArg(options::OPT_fdiagnostics_color_EQ
)) {
4364 StringRef
Value(A
->getValue());
4365 if (Value
!= "always" && Value
!= "never" && Value
!= "auto")
4366 D
.Diag(diag::err_drv_invalid_argument_to_option
)
4367 << Value
<< A
->getOption().getName();
4370 if (D
.getDiags().getDiagnosticOptions().ShowColors
)
4371 CmdArgs
.push_back("-fcolor-diagnostics");
4373 if (Args
.hasArg(options::OPT_fansi_escape_codes
))
4374 CmdArgs
.push_back("-fansi-escape-codes");
4376 Args
.addOptOutFlag(CmdArgs
, options::OPT_fshow_source_location
,
4377 options::OPT_fno_show_source_location
);
4379 Args
.addOptOutFlag(CmdArgs
, options::OPT_fdiagnostics_show_line_numbers
,
4380 options::OPT_fno_diagnostics_show_line_numbers
);
4382 if (Args
.hasArg(options::OPT_fdiagnostics_absolute_paths
))
4383 CmdArgs
.push_back("-fdiagnostics-absolute-paths");
4385 if (!Args
.hasFlag(options::OPT_fshow_column
, options::OPT_fno_show_column
,
4387 CmdArgs
.push_back("-fno-show-column");
4389 Args
.addOptOutFlag(CmdArgs
, options::OPT_fspell_checking
,
4390 options::OPT_fno_spell_checking
);
4393 DwarfFissionKind
tools::getDebugFissionKind(const Driver
&D
,
4394 const ArgList
&Args
, Arg
*&Arg
) {
4395 Arg
= Args
.getLastArg(options::OPT_gsplit_dwarf
, options::OPT_gsplit_dwarf_EQ
,
4396 options::OPT_gno_split_dwarf
);
4397 if (!Arg
|| Arg
->getOption().matches(options::OPT_gno_split_dwarf
))
4398 return DwarfFissionKind::None
;
4400 if (Arg
->getOption().matches(options::OPT_gsplit_dwarf
))
4401 return DwarfFissionKind::Split
;
4403 StringRef Value
= Arg
->getValue();
4404 if (Value
== "split")
4405 return DwarfFissionKind::Split
;
4406 if (Value
== "single")
4407 return DwarfFissionKind::Single
;
4409 D
.Diag(diag::err_drv_unsupported_option_argument
)
4410 << Arg
->getSpelling() << Arg
->getValue();
4411 return DwarfFissionKind::None
;
4414 static void renderDwarfFormat(const Driver
&D
, const llvm::Triple
&T
,
4415 const ArgList
&Args
, ArgStringList
&CmdArgs
,
4416 unsigned DwarfVersion
) {
4417 auto *DwarfFormatArg
=
4418 Args
.getLastArg(options::OPT_gdwarf64
, options::OPT_gdwarf32
);
4419 if (!DwarfFormatArg
)
4422 if (DwarfFormatArg
->getOption().matches(options::OPT_gdwarf64
)) {
4423 if (DwarfVersion
< 3)
4424 D
.Diag(diag::err_drv_argument_only_allowed_with
)
4425 << DwarfFormatArg
->getAsString(Args
) << "DWARFv3 or greater";
4426 else if (!T
.isArch64Bit())
4427 D
.Diag(diag::err_drv_argument_only_allowed_with
)
4428 << DwarfFormatArg
->getAsString(Args
) << "64 bit architecture";
4429 else if (!T
.isOSBinFormatELF())
4430 D
.Diag(diag::err_drv_argument_only_allowed_with
)
4431 << DwarfFormatArg
->getAsString(Args
) << "ELF platforms";
4434 DwarfFormatArg
->render(Args
, CmdArgs
);
4438 renderDebugOptions(const ToolChain
&TC
, const Driver
&D
, const llvm::Triple
&T
,
4439 const ArgList
&Args
, bool IRInput
, ArgStringList
&CmdArgs
,
4440 const InputInfo
&Output
,
4441 llvm::codegenoptions::DebugInfoKind
&DebugInfoKind
,
4442 DwarfFissionKind
&DwarfFission
) {
4443 if (Args
.hasFlag(options::OPT_fdebug_info_for_profiling
,
4444 options::OPT_fno_debug_info_for_profiling
, false) &&
4445 checkDebugInfoOption(
4446 Args
.getLastArg(options::OPT_fdebug_info_for_profiling
), Args
, D
, TC
))
4447 CmdArgs
.push_back("-fdebug-info-for-profiling");
4449 // The 'g' groups options involve a somewhat intricate sequence of decisions
4450 // about what to pass from the driver to the frontend, but by the time they
4451 // reach cc1 they've been factored into three well-defined orthogonal choices:
4452 // * what level of debug info to generate
4453 // * what dwarf version to write
4454 // * what debugger tuning to use
4455 // This avoids having to monkey around further in cc1 other than to disable
4456 // codeview if not running in a Windows environment. Perhaps even that
4457 // decision should be made in the driver as well though.
4458 llvm::DebuggerKind DebuggerTuning
= TC
.getDefaultDebuggerTuning();
4460 bool SplitDWARFInlining
=
4461 Args
.hasFlag(options::OPT_fsplit_dwarf_inlining
,
4462 options::OPT_fno_split_dwarf_inlining
, false);
4464 // Normally -gsplit-dwarf is only useful with -gN. For IR input, Clang does
4465 // object file generation and no IR generation, -gN should not be needed. So
4466 // allow -gsplit-dwarf with either -gN or IR input.
4467 if (IRInput
|| Args
.hasArg(options::OPT_g_Group
)) {
4469 DwarfFission
= getDebugFissionKind(D
, Args
, SplitDWARFArg
);
4470 if (DwarfFission
!= DwarfFissionKind::None
&&
4471 !checkDebugInfoOption(SplitDWARFArg
, Args
, D
, TC
)) {
4472 DwarfFission
= DwarfFissionKind::None
;
4473 SplitDWARFInlining
= false;
4476 if (const Arg
*A
= Args
.getLastArg(options::OPT_g_Group
)) {
4477 DebugInfoKind
= llvm::codegenoptions::DebugInfoConstructor
;
4479 // If the last option explicitly specified a debug-info level, use it.
4480 if (checkDebugInfoOption(A
, Args
, D
, TC
) &&
4481 A
->getOption().matches(options::OPT_gN_Group
)) {
4482 DebugInfoKind
= debugLevelToInfoKind(*A
);
4483 // For -g0 or -gline-tables-only, drop -gsplit-dwarf. This gets a bit more
4484 // complicated if you've disabled inline info in the skeleton CUs
4485 // (SplitDWARFInlining) - then there's value in composing split-dwarf and
4486 // line-tables-only, so let those compose naturally in that case.
4487 if (DebugInfoKind
== llvm::codegenoptions::NoDebugInfo
||
4488 DebugInfoKind
== llvm::codegenoptions::DebugDirectivesOnly
||
4489 (DebugInfoKind
== llvm::codegenoptions::DebugLineTablesOnly
&&
4490 SplitDWARFInlining
))
4491 DwarfFission
= DwarfFissionKind::None
;
4495 // If a debugger tuning argument appeared, remember it.
4496 bool HasDebuggerTuning
= false;
4498 Args
.getLastArg(options::OPT_gTune_Group
, options::OPT_ggdbN_Group
)) {
4499 HasDebuggerTuning
= true;
4500 if (checkDebugInfoOption(A
, Args
, D
, TC
)) {
4501 if (A
->getOption().matches(options::OPT_glldb
))
4502 DebuggerTuning
= llvm::DebuggerKind::LLDB
;
4503 else if (A
->getOption().matches(options::OPT_gsce
))
4504 DebuggerTuning
= llvm::DebuggerKind::SCE
;
4505 else if (A
->getOption().matches(options::OPT_gdbx
))
4506 DebuggerTuning
= llvm::DebuggerKind::DBX
;
4508 DebuggerTuning
= llvm::DebuggerKind::GDB
;
4512 // If a -gdwarf argument appeared, remember it.
4513 bool EmitDwarf
= false;
4514 if (const Arg
*A
= getDwarfNArg(Args
))
4515 EmitDwarf
= checkDebugInfoOption(A
, Args
, D
, TC
);
4517 bool EmitCodeView
= false;
4518 if (const Arg
*A
= Args
.getLastArg(options::OPT_gcodeview
))
4519 EmitCodeView
= checkDebugInfoOption(A
, Args
, D
, TC
);
4521 // If the user asked for debug info but did not explicitly specify -gcodeview
4522 // or -gdwarf, ask the toolchain for the default format.
4523 if (!EmitCodeView
&& !EmitDwarf
&&
4524 DebugInfoKind
!= llvm::codegenoptions::NoDebugInfo
) {
4525 switch (TC
.getDefaultDebugFormat()) {
4526 case llvm::codegenoptions::DIF_CodeView
:
4527 EmitCodeView
= true;
4529 case llvm::codegenoptions::DIF_DWARF
:
4535 unsigned RequestedDWARFVersion
= 0; // DWARF version requested by the user
4536 unsigned EffectiveDWARFVersion
= 0; // DWARF version TC can generate. It may
4537 // be lower than what the user wanted.
4539 RequestedDWARFVersion
= getDwarfVersion(TC
, Args
);
4540 // Clamp effective DWARF version to the max supported by the toolchain.
4541 EffectiveDWARFVersion
=
4542 std::min(RequestedDWARFVersion
, TC
.getMaxDwarfVersion());
4544 Args
.ClaimAllArgs(options::OPT_fdebug_default_version
);
4547 // -gline-directives-only supported only for the DWARF debug info.
4548 if (RequestedDWARFVersion
== 0 &&
4549 DebugInfoKind
== llvm::codegenoptions::DebugDirectivesOnly
)
4550 DebugInfoKind
= llvm::codegenoptions::NoDebugInfo
;
4552 // strict DWARF is set to false by default. But for DBX, we need it to be set
4553 // as true by default.
4554 if (const Arg
*A
= Args
.getLastArg(options::OPT_gstrict_dwarf
))
4555 (void)checkDebugInfoOption(A
, Args
, D
, TC
);
4556 if (Args
.hasFlag(options::OPT_gstrict_dwarf
, options::OPT_gno_strict_dwarf
,
4557 DebuggerTuning
== llvm::DebuggerKind::DBX
))
4558 CmdArgs
.push_back("-gstrict-dwarf");
4560 // And we handle flag -grecord-gcc-switches later with DWARFDebugFlags.
4561 Args
.ClaimAllArgs(options::OPT_g_flags_Group
);
4563 // Column info is included by default for everything except SCE and
4564 // CodeView. Clang doesn't track end columns, just starting columns, which,
4565 // in theory, is fine for CodeView (and PDB). In practice, however, the
4566 // Microsoft debuggers don't handle missing end columns well, and the AIX
4567 // debugger DBX also doesn't handle the columns well, so it's better not to
4568 // include any column info.
4569 if (const Arg
*A
= Args
.getLastArg(options::OPT_gcolumn_info
))
4570 (void)checkDebugInfoOption(A
, Args
, D
, TC
);
4571 if (!Args
.hasFlag(options::OPT_gcolumn_info
, options::OPT_gno_column_info
,
4573 (DebuggerTuning
!= llvm::DebuggerKind::SCE
&&
4574 DebuggerTuning
!= llvm::DebuggerKind::DBX
)))
4575 CmdArgs
.push_back("-gno-column-info");
4577 // FIXME: Move backend command line options to the module.
4578 if (Args
.hasFlag(options::OPT_gmodules
, options::OPT_gno_modules
, false)) {
4579 // If -gline-tables-only or -gline-directives-only is the last option it
4581 if (checkDebugInfoOption(Args
.getLastArg(options::OPT_gmodules
), Args
, D
,
4583 if (DebugInfoKind
!= llvm::codegenoptions::DebugLineTablesOnly
&&
4584 DebugInfoKind
!= llvm::codegenoptions::DebugDirectivesOnly
) {
4585 DebugInfoKind
= llvm::codegenoptions::DebugInfoConstructor
;
4586 CmdArgs
.push_back("-dwarf-ext-refs");
4587 CmdArgs
.push_back("-fmodule-format=obj");
4592 if (T
.isOSBinFormatELF() && SplitDWARFInlining
)
4593 CmdArgs
.push_back("-fsplit-dwarf-inlining");
4595 // After we've dealt with all combinations of things that could
4596 // make DebugInfoKind be other than None or DebugLineTablesOnly,
4597 // figure out if we need to "upgrade" it to standalone debug info.
4598 // We parse these two '-f' options whether or not they will be used,
4599 // to claim them even if you wrote "-fstandalone-debug -gline-tables-only"
4600 bool NeedFullDebug
= Args
.hasFlag(
4601 options::OPT_fstandalone_debug
, options::OPT_fno_standalone_debug
,
4602 DebuggerTuning
== llvm::DebuggerKind::LLDB
||
4603 TC
.GetDefaultStandaloneDebug());
4604 if (const Arg
*A
= Args
.getLastArg(options::OPT_fstandalone_debug
))
4605 (void)checkDebugInfoOption(A
, Args
, D
, TC
);
4607 if (DebugInfoKind
== llvm::codegenoptions::LimitedDebugInfo
||
4608 DebugInfoKind
== llvm::codegenoptions::DebugInfoConstructor
) {
4609 if (Args
.hasFlag(options::OPT_fno_eliminate_unused_debug_types
,
4610 options::OPT_feliminate_unused_debug_types
, false))
4611 DebugInfoKind
= llvm::codegenoptions::UnusedTypeInfo
;
4612 else if (NeedFullDebug
)
4613 DebugInfoKind
= llvm::codegenoptions::FullDebugInfo
;
4616 if (Args
.hasFlag(options::OPT_gembed_source
, options::OPT_gno_embed_source
,
4618 // Source embedding is a vendor extension to DWARF v5. By now we have
4619 // checked if a DWARF version was stated explicitly, and have otherwise
4620 // fallen back to the target default, so if this is still not at least 5
4621 // we emit an error.
4622 const Arg
*A
= Args
.getLastArg(options::OPT_gembed_source
);
4623 if (RequestedDWARFVersion
< 5)
4624 D
.Diag(diag::err_drv_argument_only_allowed_with
)
4625 << A
->getAsString(Args
) << "-gdwarf-5";
4626 else if (EffectiveDWARFVersion
< 5)
4627 // The toolchain has reduced allowed dwarf version, so we can't enable
4629 D
.Diag(diag::warn_drv_dwarf_version_limited_by_target
)
4630 << A
->getAsString(Args
) << TC
.getTripleString() << 5
4631 << EffectiveDWARFVersion
;
4632 else if (checkDebugInfoOption(A
, Args
, D
, TC
))
4633 CmdArgs
.push_back("-gembed-source");
4637 CmdArgs
.push_back("-gcodeview");
4639 Args
.addOptInFlag(CmdArgs
, options::OPT_gcodeview_ghash
,
4640 options::OPT_gno_codeview_ghash
);
4642 Args
.addOptOutFlag(CmdArgs
, options::OPT_gcodeview_command_line
,
4643 options::OPT_gno_codeview_command_line
);
4646 Args
.addOptOutFlag(CmdArgs
, options::OPT_ginline_line_tables
,
4647 options::OPT_gno_inline_line_tables
);
4649 // When emitting remarks, we need at least debug lines in the output.
4650 if (willEmitRemarks(Args
) &&
4651 DebugInfoKind
<= llvm::codegenoptions::DebugDirectivesOnly
)
4652 DebugInfoKind
= llvm::codegenoptions::DebugLineTablesOnly
;
4654 // Adjust the debug info kind for the given toolchain.
4655 TC
.adjustDebugInfoKind(DebugInfoKind
, Args
);
4657 // On AIX, the debugger tuning option can be omitted if it is not explicitly
4659 RenderDebugEnablingArgs(Args
, CmdArgs
, DebugInfoKind
, EffectiveDWARFVersion
,
4660 T
.isOSAIX() && !HasDebuggerTuning
4661 ? llvm::DebuggerKind::Default
4664 // -fdebug-macro turns on macro debug info generation.
4665 if (Args
.hasFlag(options::OPT_fdebug_macro
, options::OPT_fno_debug_macro
,
4667 if (checkDebugInfoOption(Args
.getLastArg(options::OPT_fdebug_macro
), Args
,
4669 CmdArgs
.push_back("-debug-info-macro");
4671 // -ggnu-pubnames turns on gnu style pubnames in the backend.
4672 const auto *PubnamesArg
=
4673 Args
.getLastArg(options::OPT_ggnu_pubnames
, options::OPT_gno_gnu_pubnames
,
4674 options::OPT_gpubnames
, options::OPT_gno_pubnames
);
4675 if (DwarfFission
!= DwarfFissionKind::None
||
4676 (PubnamesArg
&& checkDebugInfoOption(PubnamesArg
, Args
, D
, TC
))) {
4677 const bool OptionSet
=
4679 (PubnamesArg
->getOption().matches(options::OPT_gpubnames
) ||
4680 PubnamesArg
->getOption().matches(options::OPT_ggnu_pubnames
)));
4681 if ((DebuggerTuning
!= llvm::DebuggerKind::LLDB
|| OptionSet
) &&
4683 (!PubnamesArg
->getOption().matches(options::OPT_gno_gnu_pubnames
) &&
4684 !PubnamesArg
->getOption().matches(options::OPT_gno_pubnames
))))
4685 CmdArgs
.push_back(PubnamesArg
&& PubnamesArg
->getOption().matches(
4686 options::OPT_gpubnames
)
4688 : "-ggnu-pubnames");
4690 const auto *SimpleTemplateNamesArg
=
4691 Args
.getLastArg(options::OPT_gsimple_template_names
,
4692 options::OPT_gno_simple_template_names
);
4693 bool ForwardTemplateParams
= DebuggerTuning
== llvm::DebuggerKind::SCE
;
4694 if (SimpleTemplateNamesArg
&&
4695 checkDebugInfoOption(SimpleTemplateNamesArg
, Args
, D
, TC
)) {
4696 const auto &Opt
= SimpleTemplateNamesArg
->getOption();
4697 if (Opt
.matches(options::OPT_gsimple_template_names
)) {
4698 ForwardTemplateParams
= true;
4699 CmdArgs
.push_back("-gsimple-template-names=simple");
4703 // Emit DW_TAG_template_alias for template aliases? True by default for SCE.
4704 bool UseDebugTemplateAlias
=
4705 DebuggerTuning
== llvm::DebuggerKind::SCE
&& RequestedDWARFVersion
>= 4;
4706 if (const auto *DebugTemplateAlias
= Args
.getLastArg(
4707 options::OPT_gtemplate_alias
, options::OPT_gno_template_alias
)) {
4708 // DW_TAG_template_alias is only supported from DWARFv5 but if a user
4709 // asks for it we should let them have it (if the target supports it).
4710 if (checkDebugInfoOption(DebugTemplateAlias
, Args
, D
, TC
)) {
4711 const auto &Opt
= DebugTemplateAlias
->getOption();
4712 UseDebugTemplateAlias
= Opt
.matches(options::OPT_gtemplate_alias
);
4715 if (UseDebugTemplateAlias
)
4716 CmdArgs
.push_back("-gtemplate-alias");
4718 if (const Arg
*A
= Args
.getLastArg(options::OPT_gsrc_hash_EQ
)) {
4719 StringRef v
= A
->getValue();
4720 CmdArgs
.push_back(Args
.MakeArgString("-gsrc-hash=" + v
));
4723 Args
.addOptInFlag(CmdArgs
, options::OPT_fdebug_ranges_base_address
,
4724 options::OPT_fno_debug_ranges_base_address
);
4726 // -gdwarf-aranges turns on the emission of the aranges section in the
4728 // Always enabled for SCE tuning.
4729 bool NeedAranges
= DebuggerTuning
== llvm::DebuggerKind::SCE
;
4730 if (const Arg
*A
= Args
.getLastArg(options::OPT_gdwarf_aranges
))
4731 NeedAranges
= checkDebugInfoOption(A
, Args
, D
, TC
) || NeedAranges
;
4733 CmdArgs
.push_back("-mllvm");
4734 CmdArgs
.push_back("-generate-arange-section");
4737 Args
.addOptInFlag(CmdArgs
, options::OPT_fforce_dwarf_frame
,
4738 options::OPT_fno_force_dwarf_frame
);
4740 bool EnableTypeUnits
= false;
4741 if (Args
.hasFlag(options::OPT_fdebug_types_section
,
4742 options::OPT_fno_debug_types_section
, false)) {
4743 if (!(T
.isOSBinFormatELF() || T
.isOSBinFormatWasm())) {
4744 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
4745 << Args
.getLastArg(options::OPT_fdebug_types_section
)
4748 } else if (checkDebugInfoOption(
4749 Args
.getLastArg(options::OPT_fdebug_types_section
), Args
, D
,
4751 EnableTypeUnits
= true;
4752 CmdArgs
.push_back("-mllvm");
4753 CmdArgs
.push_back("-generate-type-units");
4758 Args
.getLastArg(options::OPT_gomit_unreferenced_methods
,
4759 options::OPT_gno_omit_unreferenced_methods
))
4760 (void)checkDebugInfoOption(A
, Args
, D
, TC
);
4761 if (Args
.hasFlag(options::OPT_gomit_unreferenced_methods
,
4762 options::OPT_gno_omit_unreferenced_methods
, false) &&
4763 (DebugInfoKind
== llvm::codegenoptions::DebugInfoConstructor
||
4764 DebugInfoKind
== llvm::codegenoptions::LimitedDebugInfo
) &&
4766 CmdArgs
.push_back("-gomit-unreferenced-methods");
4769 // To avoid join/split of directory+filename, the integrated assembler prefers
4770 // the directory form of .file on all DWARF versions. GNU as doesn't allow the
4771 // form before DWARF v5.
4772 if (!Args
.hasFlag(options::OPT_fdwarf_directory_asm
,
4773 options::OPT_fno_dwarf_directory_asm
,
4774 TC
.useIntegratedAs() || EffectiveDWARFVersion
>= 5))
4775 CmdArgs
.push_back("-fno-dwarf-directory-asm");
4777 // Decide how to render forward declarations of template instantiations.
4778 // SCE wants full descriptions, others just get them in the name.
4779 if (ForwardTemplateParams
)
4780 CmdArgs
.push_back("-debug-forward-template-params");
4782 // Do we need to explicitly import anonymous namespaces into the parent
4784 if (DebuggerTuning
== llvm::DebuggerKind::SCE
)
4785 CmdArgs
.push_back("-dwarf-explicit-import");
4787 renderDwarfFormat(D
, T
, Args
, CmdArgs
, EffectiveDWARFVersion
);
4788 RenderDebugInfoCompressionArgs(Args
, CmdArgs
, D
, TC
);
4790 // This controls whether or not we perform JustMyCode instrumentation.
4791 if (Args
.hasFlag(options::OPT_fjmc
, options::OPT_fno_jmc
, false)) {
4792 if (TC
.getTriple().isOSBinFormatELF() || D
.IsCLMode()) {
4793 if (DebugInfoKind
>= llvm::codegenoptions::DebugInfoConstructor
)
4794 CmdArgs
.push_back("-fjmc");
4795 else if (D
.IsCLMode())
4796 D
.Diag(clang::diag::warn_drv_jmc_requires_debuginfo
) << "/JMC"
4799 D
.Diag(clang::diag::warn_drv_jmc_requires_debuginfo
) << "-fjmc"
4802 D
.Diag(clang::diag::warn_drv_fjmc_for_elf_only
);
4806 // Add in -fdebug-compilation-dir if necessary.
4807 const char *DebugCompilationDir
=
4808 addDebugCompDirArg(Args
, CmdArgs
, D
.getVFS());
4810 addDebugPrefixMapArg(D
, TC
, Args
, CmdArgs
);
4812 // Add the output path to the object file for CodeView debug infos.
4813 if (EmitCodeView
&& Output
.isFilename())
4814 addDebugObjectName(Args
, CmdArgs
, DebugCompilationDir
,
4815 Output
.getFilename());
4818 static void ProcessVSRuntimeLibrary(const ToolChain
&TC
, const ArgList
&Args
,
4819 ArgStringList
&CmdArgs
) {
4820 unsigned RTOptionID
= options::OPT__SLASH_MT
;
4822 if (Args
.hasArg(options::OPT__SLASH_LDd
))
4823 // The /LDd option implies /MTd. The dependent lib part can be overridden,
4824 // but defining _DEBUG is sticky.
4825 RTOptionID
= options::OPT__SLASH_MTd
;
4827 if (Arg
*A
= Args
.getLastArg(options::OPT__SLASH_M_Group
))
4828 RTOptionID
= A
->getOption().getID();
4830 if (Arg
*A
= Args
.getLastArg(options::OPT_fms_runtime_lib_EQ
)) {
4831 RTOptionID
= llvm::StringSwitch
<unsigned>(A
->getValue())
4832 .Case("static", options::OPT__SLASH_MT
)
4833 .Case("static_dbg", options::OPT__SLASH_MTd
)
4834 .Case("dll", options::OPT__SLASH_MD
)
4835 .Case("dll_dbg", options::OPT__SLASH_MDd
)
4836 .Default(options::OPT__SLASH_MT
);
4839 StringRef FlagForCRT
;
4840 switch (RTOptionID
) {
4841 case options::OPT__SLASH_MD
:
4842 if (Args
.hasArg(options::OPT__SLASH_LDd
))
4843 CmdArgs
.push_back("-D_DEBUG");
4844 CmdArgs
.push_back("-D_MT");
4845 CmdArgs
.push_back("-D_DLL");
4846 FlagForCRT
= "--dependent-lib=msvcrt";
4848 case options::OPT__SLASH_MDd
:
4849 CmdArgs
.push_back("-D_DEBUG");
4850 CmdArgs
.push_back("-D_MT");
4851 CmdArgs
.push_back("-D_DLL");
4852 FlagForCRT
= "--dependent-lib=msvcrtd";
4854 case options::OPT__SLASH_MT
:
4855 if (Args
.hasArg(options::OPT__SLASH_LDd
))
4856 CmdArgs
.push_back("-D_DEBUG");
4857 CmdArgs
.push_back("-D_MT");
4858 CmdArgs
.push_back("-flto-visibility-public-std");
4859 FlagForCRT
= "--dependent-lib=libcmt";
4861 case options::OPT__SLASH_MTd
:
4862 CmdArgs
.push_back("-D_DEBUG");
4863 CmdArgs
.push_back("-D_MT");
4864 CmdArgs
.push_back("-flto-visibility-public-std");
4865 FlagForCRT
= "--dependent-lib=libcmtd";
4868 llvm_unreachable("Unexpected option ID.");
4871 if (Args
.hasArg(options::OPT_fms_omit_default_lib
)) {
4872 CmdArgs
.push_back("-D_VC_NODEFAULTLIB");
4874 CmdArgs
.push_back(FlagForCRT
.data());
4876 // This provides POSIX compatibility (maps 'open' to '_open'), which most
4877 // users want. The /Za flag to cl.exe turns this off, but it's not
4878 // implemented in clang.
4879 CmdArgs
.push_back("--dependent-lib=oldnames");
4882 // All Arm64EC object files implicitly add softintrin.lib. This is necessary
4883 // even if the file doesn't actually refer to any of the routines because
4884 // the CRT itself has incomplete dependency markings.
4885 if (TC
.getTriple().isWindowsArm64EC())
4886 CmdArgs
.push_back("--dependent-lib=softintrin");
4889 void Clang::ConstructJob(Compilation
&C
, const JobAction
&JA
,
4890 const InputInfo
&Output
, const InputInfoList
&Inputs
,
4891 const ArgList
&Args
, const char *LinkingOutput
) const {
4892 const auto &TC
= getToolChain();
4893 const llvm::Triple
&RawTriple
= TC
.getTriple();
4894 const llvm::Triple
&Triple
= TC
.getEffectiveTriple();
4895 const std::string
&TripleStr
= Triple
.getTriple();
4898 Args
.hasArg(options::OPT_mkernel
, options::OPT_fapple_kext
);
4899 const Driver
&D
= TC
.getDriver();
4900 ArgStringList CmdArgs
;
4902 assert(Inputs
.size() >= 1 && "Must have at least one input.");
4903 // CUDA/HIP compilation may have multiple inputs (source file + results of
4904 // device-side compilations). OpenMP device jobs also take the host IR as a
4905 // second input. Module precompilation accepts a list of header files to
4906 // include as part of the module. API extraction accepts a list of header
4907 // files whose API information is emitted in the output. All other jobs are
4908 // expected to have exactly one input.
4909 bool IsCuda
= JA
.isOffloading(Action::OFK_Cuda
);
4910 bool IsCudaDevice
= JA
.isDeviceOffloading(Action::OFK_Cuda
);
4911 bool IsHIP
= JA
.isOffloading(Action::OFK_HIP
);
4912 bool IsHIPDevice
= JA
.isDeviceOffloading(Action::OFK_HIP
);
4913 bool IsOpenMPDevice
= JA
.isDeviceOffloading(Action::OFK_OpenMP
);
4914 bool IsExtractAPI
= isa
<ExtractAPIJobAction
>(JA
);
4915 bool IsDeviceOffloadAction
= !(JA
.isDeviceOffloading(Action::OFK_None
) ||
4916 JA
.isDeviceOffloading(Action::OFK_Host
));
4917 bool IsHostOffloadingAction
=
4918 JA
.isHostOffloading(Action::OFK_OpenMP
) ||
4919 (JA
.isHostOffloading(C
.getActiveOffloadKinds()) &&
4920 Args
.hasFlag(options::OPT_offload_new_driver
,
4921 options::OPT_no_offload_new_driver
, false));
4924 Args
.hasFlag(options::OPT_fgpu_rdc
, options::OPT_fno_gpu_rdc
, false);
4925 bool IsUsingLTO
= D
.isUsingLTO(IsDeviceOffloadAction
);
4926 auto LTOMode
= D
.getLTOMode(IsDeviceOffloadAction
);
4928 // Extract API doesn't have a main input file, so invent a fake one as a
4930 InputInfo
ExtractAPIPlaceholderInput(Inputs
[0].getType(), "extract-api",
4933 const InputInfo
&Input
=
4934 IsExtractAPI
? ExtractAPIPlaceholderInput
: Inputs
[0];
4936 InputInfoList ExtractAPIInputs
;
4937 InputInfoList HostOffloadingInputs
;
4938 const InputInfo
*CudaDeviceInput
= nullptr;
4939 const InputInfo
*OpenMPDeviceInput
= nullptr;
4940 for (const InputInfo
&I
: Inputs
) {
4941 if (&I
== &Input
|| I
.getType() == types::TY_Nothing
) {
4942 // This is the primary input or contains nothing.
4943 } else if (IsExtractAPI
) {
4944 auto ExpectedInputType
= ExtractAPIPlaceholderInput
.getType();
4945 if (I
.getType() != ExpectedInputType
) {
4946 D
.Diag(diag::err_drv_extract_api_wrong_kind
)
4947 << I
.getFilename() << types::getTypeName(I
.getType())
4948 << types::getTypeName(ExpectedInputType
);
4950 ExtractAPIInputs
.push_back(I
);
4951 } else if (IsHostOffloadingAction
) {
4952 HostOffloadingInputs
.push_back(I
);
4953 } else if ((IsCuda
|| IsHIP
) && !CudaDeviceInput
) {
4954 CudaDeviceInput
= &I
;
4955 } else if (IsOpenMPDevice
&& !OpenMPDeviceInput
) {
4956 OpenMPDeviceInput
= &I
;
4958 llvm_unreachable("unexpectedly given multiple inputs");
4962 const llvm::Triple
*AuxTriple
=
4963 (IsCuda
|| IsHIP
) ? TC
.getAuxTriple() : nullptr;
4964 bool IsWindowsMSVC
= RawTriple
.isWindowsMSVCEnvironment();
4965 bool IsIAMCU
= RawTriple
.isOSIAMCU();
4967 // Adjust IsWindowsXYZ for CUDA/HIP compilations. Even when compiling in
4968 // device mode (i.e., getToolchain().getTriple() is NVPTX/AMDGCN, not
4969 // Windows), we need to pass Windows-specific flags to cc1.
4970 if (IsCuda
|| IsHIP
)
4971 IsWindowsMSVC
|= AuxTriple
&& AuxTriple
->isWindowsMSVCEnvironment();
4973 // C++ is not supported for IAMCU.
4974 if (IsIAMCU
&& types::isCXX(Input
.getType()))
4975 D
.Diag(diag::err_drv_clang_unsupported
) << "C++ for IAMCU";
4977 // Invoke ourselves in -cc1 mode.
4979 // FIXME: Implement custom jobs for internal actions.
4980 CmdArgs
.push_back("-cc1");
4982 // Add the "effective" target triple.
4983 CmdArgs
.push_back("-triple");
4984 CmdArgs
.push_back(Args
.MakeArgString(TripleStr
));
4986 if (const Arg
*MJ
= Args
.getLastArg(options::OPT_MJ
)) {
4987 DumpCompilationDatabase(C
, MJ
->getValue(), TripleStr
, Output
, Input
, Args
);
4988 Args
.ClaimAllArgs(options::OPT_MJ
);
4989 } else if (const Arg
*GenCDBFragment
=
4990 Args
.getLastArg(options::OPT_gen_cdb_fragment_path
)) {
4991 DumpCompilationDatabaseFragmentToDir(GenCDBFragment
->getValue(), C
,
4992 TripleStr
, Output
, Input
, Args
);
4993 Args
.ClaimAllArgs(options::OPT_gen_cdb_fragment_path
);
4996 if (IsCuda
|| IsHIP
) {
4997 // We have to pass the triple of the host if compiling for a CUDA/HIP device
4999 std::string NormalizedTriple
;
5000 if (JA
.isDeviceOffloading(Action::OFK_Cuda
) ||
5001 JA
.isDeviceOffloading(Action::OFK_HIP
))
5002 NormalizedTriple
= C
.getSingleOffloadToolChain
<Action::OFK_Host
>()
5006 // Host-side compilation.
5008 (IsCuda
? C
.getSingleOffloadToolChain
<Action::OFK_Cuda
>()
5009 : C
.getSingleOffloadToolChain
<Action::OFK_HIP
>())
5013 // We need to figure out which CUDA version we're compiling for, as that
5014 // determines how we load and launch GPU kernels.
5015 auto *CTC
= static_cast<const toolchains::CudaToolChain
*>(
5016 C
.getSingleOffloadToolChain
<Action::OFK_Cuda
>());
5017 assert(CTC
&& "Expected valid CUDA Toolchain.");
5018 if (CTC
&& CTC
->CudaInstallation
.version() != CudaVersion::UNKNOWN
)
5019 CmdArgs
.push_back(Args
.MakeArgString(
5020 Twine("-target-sdk-version=") +
5021 CudaVersionToString(CTC
->CudaInstallation
.version())));
5022 // Unsized function arguments used for variadics were introduced in
5023 // CUDA-9.0. We still do not support generating code that actually uses
5024 // variadic arguments yet, but we do need to allow parsing them as
5025 // recent CUDA headers rely on that.
5026 // https://github.com/llvm/llvm-project/issues/58410
5027 if (CTC
->CudaInstallation
.version() >= CudaVersion::CUDA_90
)
5028 CmdArgs
.push_back("-fcuda-allow-variadic-functions");
5031 CmdArgs
.push_back("-aux-triple");
5032 CmdArgs
.push_back(Args
.MakeArgString(NormalizedTriple
));
5034 if (JA
.isDeviceOffloading(Action::OFK_HIP
) &&
5035 (getToolChain().getTriple().isAMDGPU() ||
5036 (getToolChain().getTriple().isSPIRV() &&
5037 getToolChain().getTriple().getVendor() == llvm::Triple::AMD
))) {
5038 // Device side compilation printf
5039 if (Args
.getLastArg(options::OPT_mprintf_kind_EQ
)) {
5040 CmdArgs
.push_back(Args
.MakeArgString(
5042 Args
.getLastArgValue(options::OPT_mprintf_kind_EQ
)));
5043 // Force compiler error on invalid conversion specifiers
5045 Args
.MakeArgString("-Werror=format-invalid-specifier"));
5050 // Unconditionally claim the printf option now to avoid unused diagnostic.
5051 if (const Arg
*PF
= Args
.getLastArg(options::OPT_mprintf_kind_EQ
))
5054 if (Args
.hasFlag(options::OPT_fsycl
, options::OPT_fno_sycl
, false)) {
5055 CmdArgs
.push_back("-fsycl-is-device");
5057 if (Arg
*A
= Args
.getLastArg(options::OPT_sycl_std_EQ
)) {
5058 A
->render(Args
, CmdArgs
);
5060 // Ensure the default version in SYCL mode is 2020.
5061 CmdArgs
.push_back("-sycl-std=2020");
5065 if (IsOpenMPDevice
) {
5066 // We have to pass the triple of the host if compiling for an OpenMP device.
5067 std::string NormalizedTriple
=
5068 C
.getSingleOffloadToolChain
<Action::OFK_Host
>()
5071 CmdArgs
.push_back("-aux-triple");
5072 CmdArgs
.push_back(Args
.MakeArgString(NormalizedTriple
));
5075 if (Triple
.isOSWindows() && (Triple
.getArch() == llvm::Triple::arm
||
5076 Triple
.getArch() == llvm::Triple::thumb
)) {
5077 unsigned Offset
= Triple
.getArch() == llvm::Triple::arm
? 4 : 6;
5078 unsigned Version
= 0;
5080 Triple
.getArchName().substr(Offset
).consumeInteger(10, Version
);
5081 if (Failure
|| Version
< 7)
5082 D
.Diag(diag::err_target_unsupported_arch
) << Triple
.getArchName()
5086 // Push all default warning arguments that are specific to
5087 // the given target. These come before user provided warning options
5089 TC
.addClangWarningOptions(CmdArgs
);
5091 // FIXME: Subclass ToolChain for SPIR and move this to addClangWarningOptions.
5092 if (Triple
.isSPIR() || Triple
.isSPIRV())
5093 CmdArgs
.push_back("-Wspir-compat");
5095 // Select the appropriate action.
5096 RewriteKind rewriteKind
= RK_None
;
5098 bool UnifiedLTO
= false;
5100 UnifiedLTO
= Args
.hasFlag(options::OPT_funified_lto
,
5101 options::OPT_fno_unified_lto
, Triple
.isPS());
5103 CmdArgs
.push_back("-funified-lto");
5106 // If CollectArgsForIntegratedAssembler() isn't called below, claim the args
5107 // it claims when not running an assembler. Otherwise, clang would emit
5108 // "argument unused" warnings for assembler flags when e.g. adding "-E" to
5109 // flags while debugging something. That'd be somewhat inconvenient, and it's
5110 // also inconsistent with most other flags -- we don't warn on
5111 // -ffunction-sections not being used in -E mode either for example, even
5112 // though it's not really used either.
5113 if (!isa
<AssembleJobAction
>(JA
)) {
5114 // The args claimed here should match the args used in
5115 // CollectArgsForIntegratedAssembler().
5116 if (TC
.useIntegratedAs()) {
5117 Args
.ClaimAllArgs(options::OPT_mrelax_all
);
5118 Args
.ClaimAllArgs(options::OPT_mno_relax_all
);
5119 Args
.ClaimAllArgs(options::OPT_mincremental_linker_compatible
);
5120 Args
.ClaimAllArgs(options::OPT_mno_incremental_linker_compatible
);
5121 switch (C
.getDefaultToolChain().getArch()) {
5122 case llvm::Triple::arm
:
5123 case llvm::Triple::armeb
:
5124 case llvm::Triple::thumb
:
5125 case llvm::Triple::thumbeb
:
5126 Args
.ClaimAllArgs(options::OPT_mimplicit_it_EQ
);
5132 Args
.ClaimAllArgs(options::OPT_Wa_COMMA
);
5133 Args
.ClaimAllArgs(options::OPT_Xassembler
);
5134 Args
.ClaimAllArgs(options::OPT_femit_dwarf_unwind_EQ
);
5137 if (isa
<AnalyzeJobAction
>(JA
)) {
5138 assert(JA
.getType() == types::TY_Plist
&& "Invalid output type.");
5139 CmdArgs
.push_back("-analyze");
5140 } else if (isa
<MigrateJobAction
>(JA
)) {
5141 CmdArgs
.push_back("-migrate");
5142 } else if (isa
<PreprocessJobAction
>(JA
)) {
5143 if (Output
.getType() == types::TY_Dependencies
)
5144 CmdArgs
.push_back("-Eonly");
5146 CmdArgs
.push_back("-E");
5147 if (Args
.hasArg(options::OPT_rewrite_objc
) &&
5148 !Args
.hasArg(options::OPT_g_Group
))
5149 CmdArgs
.push_back("-P");
5150 else if (JA
.getType() == types::TY_PP_CXXHeaderUnit
)
5151 CmdArgs
.push_back("-fdirectives-only");
5153 } else if (isa
<AssembleJobAction
>(JA
)) {
5154 CmdArgs
.push_back("-emit-obj");
5156 CollectArgsForIntegratedAssembler(C
, Args
, CmdArgs
, D
);
5158 // Also ignore explicit -force_cpusubtype_ALL option.
5159 (void)Args
.hasArg(options::OPT_force__cpusubtype__ALL
);
5160 } else if (isa
<PrecompileJobAction
>(JA
)) {
5161 if (JA
.getType() == types::TY_Nothing
)
5162 CmdArgs
.push_back("-fsyntax-only");
5163 else if (JA
.getType() == types::TY_ModuleFile
)
5164 CmdArgs
.push_back("-emit-module-interface");
5165 else if (JA
.getType() == types::TY_HeaderUnit
)
5166 CmdArgs
.push_back("-emit-header-unit");
5168 CmdArgs
.push_back("-emit-pch");
5169 } else if (isa
<VerifyPCHJobAction
>(JA
)) {
5170 CmdArgs
.push_back("-verify-pch");
5171 } else if (isa
<ExtractAPIJobAction
>(JA
)) {
5172 assert(JA
.getType() == types::TY_API_INFO
&&
5173 "Extract API actions must generate a API information.");
5174 CmdArgs
.push_back("-extract-api");
5176 if (Arg
*PrettySGFArg
= Args
.getLastArg(options::OPT_emit_pretty_sgf
))
5177 PrettySGFArg
->render(Args
, CmdArgs
);
5179 Arg
*SymbolGraphDirArg
= Args
.getLastArg(options::OPT_symbol_graph_dir_EQ
);
5181 if (Arg
*ProductNameArg
= Args
.getLastArg(options::OPT_product_name_EQ
))
5182 ProductNameArg
->render(Args
, CmdArgs
);
5183 if (Arg
*ExtractAPIIgnoresFileArg
=
5184 Args
.getLastArg(options::OPT_extract_api_ignores_EQ
))
5185 ExtractAPIIgnoresFileArg
->render(Args
, CmdArgs
);
5186 if (Arg
*EmitExtensionSymbolGraphs
=
5187 Args
.getLastArg(options::OPT_emit_extension_symbol_graphs
)) {
5188 if (!SymbolGraphDirArg
)
5189 D
.Diag(diag::err_drv_missing_symbol_graph_dir
);
5191 EmitExtensionSymbolGraphs
->render(Args
, CmdArgs
);
5193 if (SymbolGraphDirArg
)
5194 SymbolGraphDirArg
->render(Args
, CmdArgs
);
5196 assert((isa
<CompileJobAction
>(JA
) || isa
<BackendJobAction
>(JA
)) &&
5197 "Invalid action for clang tool.");
5198 if (JA
.getType() == types::TY_Nothing
) {
5199 CmdArgs
.push_back("-fsyntax-only");
5200 } else if (JA
.getType() == types::TY_LLVM_IR
||
5201 JA
.getType() == types::TY_LTO_IR
) {
5202 CmdArgs
.push_back("-emit-llvm");
5203 } else if (JA
.getType() == types::TY_LLVM_BC
||
5204 JA
.getType() == types::TY_LTO_BC
) {
5205 // Emit textual llvm IR for AMDGPU offloading for -emit-llvm -S
5206 if (Triple
.isAMDGCN() && IsOpenMPDevice
&& Args
.hasArg(options::OPT_S
) &&
5207 Args
.hasArg(options::OPT_emit_llvm
)) {
5208 CmdArgs
.push_back("-emit-llvm");
5210 CmdArgs
.push_back("-emit-llvm-bc");
5212 } else if (JA
.getType() == types::TY_IFS
||
5213 JA
.getType() == types::TY_IFS_CPP
) {
5215 Args
.hasArg(options::OPT_interface_stub_version_EQ
)
5216 ? Args
.getLastArgValue(options::OPT_interface_stub_version_EQ
)
5218 CmdArgs
.push_back("-emit-interface-stubs");
5220 Args
.MakeArgString(Twine("-interface-stub-version=") + ArgStr
.str()));
5221 } else if (JA
.getType() == types::TY_PP_Asm
) {
5222 CmdArgs
.push_back("-S");
5223 } else if (JA
.getType() == types::TY_AST
) {
5224 CmdArgs
.push_back("-emit-pch");
5225 } else if (JA
.getType() == types::TY_ModuleFile
) {
5226 CmdArgs
.push_back("-module-file-info");
5227 } else if (JA
.getType() == types::TY_RewrittenObjC
) {
5228 CmdArgs
.push_back("-rewrite-objc");
5229 rewriteKind
= RK_NonFragile
;
5230 } else if (JA
.getType() == types::TY_RewrittenLegacyObjC
) {
5231 CmdArgs
.push_back("-rewrite-objc");
5232 rewriteKind
= RK_Fragile
;
5234 assert(JA
.getType() == types::TY_PP_Asm
&& "Unexpected output type!");
5237 // Preserve use-list order by default when emitting bitcode, so that
5238 // loading the bitcode up in 'opt' or 'llc' and running passes gives the
5239 // same result as running passes here. For LTO, we don't need to preserve
5240 // the use-list order, since serialization to bitcode is part of the flow.
5241 if (JA
.getType() == types::TY_LLVM_BC
)
5242 CmdArgs
.push_back("-emit-llvm-uselists");
5245 if (IsDeviceOffloadAction
&& !JA
.isDeviceOffloading(Action::OFK_OpenMP
) &&
5246 !Args
.hasFlag(options::OPT_offload_new_driver
,
5247 options::OPT_no_offload_new_driver
, false) &&
5248 !Triple
.isAMDGPU()) {
5249 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
5250 << Args
.getLastArg(options::OPT_foffload_lto
,
5251 options::OPT_foffload_lto_EQ
)
5253 << Triple
.getTriple();
5254 } else if (Triple
.isNVPTX() && !IsRDCMode
&&
5255 JA
.isDeviceOffloading(Action::OFK_Cuda
)) {
5256 D
.Diag(diag::err_drv_unsupported_opt_for_language_mode
)
5257 << Args
.getLastArg(options::OPT_foffload_lto
,
5258 options::OPT_foffload_lto_EQ
)
5262 assert(LTOMode
== LTOK_Full
|| LTOMode
== LTOK_Thin
);
5263 CmdArgs
.push_back(Args
.MakeArgString(
5264 Twine("-flto=") + (LTOMode
== LTOK_Thin
? "thin" : "full")));
5265 // PS4 uses the legacy LTO API, which does not support some of the
5266 // features enabled by -flto-unit.
5267 if (!RawTriple
.isPS4() ||
5268 (D
.getLTOMode() == LTOK_Full
) || !UnifiedLTO
)
5269 CmdArgs
.push_back("-flto-unit");
5274 Args
.AddLastArg(CmdArgs
, options::OPT_dumpdir
);
5276 if (const Arg
*A
= Args
.getLastArg(options::OPT_fthinlto_index_EQ
)) {
5277 if (!types::isLLVMIR(Input
.getType()))
5278 D
.Diag(diag::err_drv_arg_requires_bitcode_input
) << A
->getAsString(Args
);
5279 Args
.AddLastArg(CmdArgs
, options::OPT_fthinlto_index_EQ
);
5283 Args
.addOptInFlag(CmdArgs
, options::OPT_mregnames
,
5284 options::OPT_mno_regnames
);
5286 if (Args
.getLastArg(options::OPT_fthin_link_bitcode_EQ
))
5287 Args
.AddLastArg(CmdArgs
, options::OPT_fthin_link_bitcode_EQ
);
5289 if (Args
.getLastArg(options::OPT_save_temps_EQ
))
5290 Args
.AddLastArg(CmdArgs
, options::OPT_save_temps_EQ
);
5292 auto *MemProfArg
= Args
.getLastArg(options::OPT_fmemory_profile
,
5293 options::OPT_fmemory_profile_EQ
,
5294 options::OPT_fno_memory_profile
);
5296 !MemProfArg
->getOption().matches(options::OPT_fno_memory_profile
))
5297 MemProfArg
->render(Args
, CmdArgs
);
5299 if (auto *MemProfUseArg
=
5300 Args
.getLastArg(options::OPT_fmemory_profile_use_EQ
)) {
5302 D
.Diag(diag::err_drv_argument_not_allowed_with
)
5303 << MemProfUseArg
->getAsString(Args
) << MemProfArg
->getAsString(Args
);
5304 if (auto *PGOInstrArg
= Args
.getLastArg(options::OPT_fprofile_generate
,
5305 options::OPT_fprofile_generate_EQ
))
5306 D
.Diag(diag::err_drv_argument_not_allowed_with
)
5307 << MemProfUseArg
->getAsString(Args
) << PGOInstrArg
->getAsString(Args
);
5308 MemProfUseArg
->render(Args
, CmdArgs
);
5311 // Embed-bitcode option.
5312 // Only white-listed flags below are allowed to be embedded.
5313 if (C
.getDriver().embedBitcodeInObject() && !IsUsingLTO
&&
5314 (isa
<BackendJobAction
>(JA
) || isa
<AssembleJobAction
>(JA
))) {
5315 // Add flags implied by -fembed-bitcode.
5316 Args
.AddLastArg(CmdArgs
, options::OPT_fembed_bitcode_EQ
);
5317 // Disable all llvm IR level optimizations.
5318 CmdArgs
.push_back("-disable-llvm-passes");
5320 // Render target options.
5321 TC
.addClangTargetOptions(Args
, CmdArgs
, JA
.getOffloadingDeviceKind());
5323 // reject options that shouldn't be supported in bitcode
5324 // also reject kernel/kext
5325 static const constexpr unsigned kBitcodeOptionIgnorelist
[] = {
5326 options::OPT_mkernel
,
5327 options::OPT_fapple_kext
,
5328 options::OPT_ffunction_sections
,
5329 options::OPT_fno_function_sections
,
5330 options::OPT_fdata_sections
,
5331 options::OPT_fno_data_sections
,
5332 options::OPT_fbasic_block_sections_EQ
,
5333 options::OPT_funique_internal_linkage_names
,
5334 options::OPT_fno_unique_internal_linkage_names
,
5335 options::OPT_funique_section_names
,
5336 options::OPT_fno_unique_section_names
,
5337 options::OPT_funique_basic_block_section_names
,
5338 options::OPT_fno_unique_basic_block_section_names
,
5339 options::OPT_mrestrict_it
,
5340 options::OPT_mno_restrict_it
,
5341 options::OPT_mstackrealign
,
5342 options::OPT_mno_stackrealign
,
5343 options::OPT_mstack_alignment
,
5344 options::OPT_mcmodel_EQ
,
5345 options::OPT_mlong_calls
,
5346 options::OPT_mno_long_calls
,
5347 options::OPT_ggnu_pubnames
,
5348 options::OPT_gdwarf_aranges
,
5349 options::OPT_fdebug_types_section
,
5350 options::OPT_fno_debug_types_section
,
5351 options::OPT_fdwarf_directory_asm
,
5352 options::OPT_fno_dwarf_directory_asm
,
5353 options::OPT_mrelax_all
,
5354 options::OPT_mno_relax_all
,
5355 options::OPT_ftrap_function_EQ
,
5356 options::OPT_ffixed_r9
,
5357 options::OPT_mfix_cortex_a53_835769
,
5358 options::OPT_mno_fix_cortex_a53_835769
,
5359 options::OPT_ffixed_x18
,
5360 options::OPT_mglobal_merge
,
5361 options::OPT_mno_global_merge
,
5362 options::OPT_mred_zone
,
5363 options::OPT_mno_red_zone
,
5364 options::OPT_Wa_COMMA
,
5365 options::OPT_Xassembler
,
5368 for (const auto &A
: Args
)
5369 if (llvm::is_contained(kBitcodeOptionIgnorelist
, A
->getOption().getID()))
5370 D
.Diag(diag::err_drv_unsupported_embed_bitcode
) << A
->getSpelling();
5372 // Render the CodeGen options that need to be passed.
5373 Args
.addOptOutFlag(CmdArgs
, options::OPT_foptimize_sibling_calls
,
5374 options::OPT_fno_optimize_sibling_calls
);
5376 RenderFloatingPointOptions(TC
, D
, isOptimizationLevelFast(Args
), Args
,
5379 // Render ABI arguments
5380 switch (TC
.getArch()) {
5382 case llvm::Triple::arm
:
5383 case llvm::Triple::armeb
:
5384 case llvm::Triple::thumbeb
:
5385 RenderARMABI(D
, Triple
, Args
, CmdArgs
);
5387 case llvm::Triple::aarch64
:
5388 case llvm::Triple::aarch64_32
:
5389 case llvm::Triple::aarch64_be
:
5390 RenderAArch64ABI(Triple
, Args
, CmdArgs
);
5394 // Optimization level for CodeGen.
5395 if (const Arg
*A
= Args
.getLastArg(options::OPT_O_Group
)) {
5396 if (A
->getOption().matches(options::OPT_O4
)) {
5397 CmdArgs
.push_back("-O3");
5398 D
.Diag(diag::warn_O4_is_O3
);
5400 A
->render(Args
, CmdArgs
);
5404 // Input/Output file.
5405 if (Output
.getType() == types::TY_Dependencies
) {
5406 // Handled with other dependency code.
5407 } else if (Output
.isFilename()) {
5408 CmdArgs
.push_back("-o");
5409 CmdArgs
.push_back(Output
.getFilename());
5411 assert(Output
.isNothing() && "Input output.");
5414 for (const auto &II
: Inputs
) {
5415 addDashXForInput(Args
, II
, CmdArgs
);
5416 if (II
.isFilename())
5417 CmdArgs
.push_back(II
.getFilename());
5419 II
.getInputArg().renderAsInput(Args
, CmdArgs
);
5422 C
.addCommand(std::make_unique
<Command
>(
5423 JA
, *this, ResponseFileSupport::AtFileUTF8(), D
.getClangProgramPath(),
5424 CmdArgs
, Inputs
, Output
, D
.getPrependArg()));
5428 if (C
.getDriver().embedBitcodeMarkerOnly() && !IsUsingLTO
)
5429 CmdArgs
.push_back("-fembed-bitcode=marker");
5431 // We normally speed up the clang process a bit by skipping destructors at
5432 // exit, but when we're generating diagnostics we can rely on some of the
5434 if (!C
.isForDiagnostics())
5435 CmdArgs
.push_back("-disable-free");
5436 CmdArgs
.push_back("-clear-ast-before-backend");
5439 const bool IsAssertBuild
= false;
5441 const bool IsAssertBuild
= true;
5444 // Disable the verification pass in asserts builds unless otherwise specified.
5445 if (Args
.hasFlag(options::OPT_fno_verify_intermediate_code
,
5446 options::OPT_fverify_intermediate_code
, !IsAssertBuild
)) {
5447 CmdArgs
.push_back("-disable-llvm-verifier");
5450 // Discard value names in assert builds unless otherwise specified.
5451 if (Args
.hasFlag(options::OPT_fdiscard_value_names
,
5452 options::OPT_fno_discard_value_names
, !IsAssertBuild
)) {
5453 if (Args
.hasArg(options::OPT_fdiscard_value_names
) &&
5454 llvm::any_of(Inputs
, [](const clang::driver::InputInfo
&II
) {
5455 return types::isLLVMIR(II
.getType());
5457 D
.Diag(diag::warn_ignoring_fdiscard_for_bitcode
);
5459 CmdArgs
.push_back("-discard-value-names");
5462 // Set the main file name, so that debug info works even with
5464 CmdArgs
.push_back("-main-file-name");
5465 CmdArgs
.push_back(getBaseInputName(Args
, Input
));
5467 // Some flags which affect the language (via preprocessor
5469 if (Args
.hasArg(options::OPT_static
))
5470 CmdArgs
.push_back("-static-define");
5472 if (Args
.hasArg(options::OPT_municode
))
5473 CmdArgs
.push_back("-DUNICODE");
5475 if (isa
<AnalyzeJobAction
>(JA
))
5476 RenderAnalyzerOptions(Args
, CmdArgs
, Triple
, Input
);
5478 if (isa
<AnalyzeJobAction
>(JA
) ||
5479 (isa
<PreprocessJobAction
>(JA
) && Args
.hasArg(options::OPT__analyze
)))
5480 CmdArgs
.push_back("-setup-static-analyzer");
5482 // Enable compatilibily mode to avoid analyzer-config related errors.
5483 // Since we can't access frontend flags through hasArg, let's manually iterate
5485 bool FoundAnalyzerConfig
= false;
5486 for (auto *Arg
: Args
.filtered(options::OPT_Xclang
))
5487 if (StringRef(Arg
->getValue()) == "-analyzer-config") {
5488 FoundAnalyzerConfig
= true;
5491 if (!FoundAnalyzerConfig
)
5492 for (auto *Arg
: Args
.filtered(options::OPT_Xanalyzer
))
5493 if (StringRef(Arg
->getValue()) == "-analyzer-config") {
5494 FoundAnalyzerConfig
= true;
5497 if (FoundAnalyzerConfig
)
5498 CmdArgs
.push_back("-analyzer-config-compatibility-mode=true");
5500 CheckCodeGenerationOptions(D
, Args
);
5502 unsigned FunctionAlignment
= ParseFunctionAlignment(TC
, Args
);
5503 assert(FunctionAlignment
<= 31 && "function alignment will be truncated!");
5504 if (FunctionAlignment
) {
5505 CmdArgs
.push_back("-function-alignment");
5506 CmdArgs
.push_back(Args
.MakeArgString(std::to_string(FunctionAlignment
)));
5509 // We support -falign-loops=N where N is a power of 2. GCC supports more
5511 if (const Arg
*A
= Args
.getLastArg(options::OPT_falign_loops_EQ
)) {
5513 if (StringRef(A
->getValue()).getAsInteger(10, Value
) || Value
> 65536)
5514 TC
.getDriver().Diag(diag::err_drv_invalid_int_value
)
5515 << A
->getAsString(Args
) << A
->getValue();
5516 else if (Value
& (Value
- 1))
5517 TC
.getDriver().Diag(diag::err_drv_alignment_not_power_of_two
)
5518 << A
->getAsString(Args
) << A
->getValue();
5519 // Treat =0 as unspecified (use the target preference).
5521 CmdArgs
.push_back(Args
.MakeArgString("-falign-loops=" +
5522 Twine(std::min(Value
, 65536u))));
5525 if (Triple
.isOSzOS()) {
5526 // On z/OS some of the system header feature macros need to
5527 // be defined to enable most cross platform projects to build
5528 // successfully. Ths include the libc++ library. A
5529 // complicating factor is that users can define these
5530 // macros to the same or different values. We need to add
5531 // the definition for these macros to the compilation command
5532 // if the user hasn't already defined them.
5534 auto findMacroDefinition
= [&](const std::string
&Macro
) {
5535 auto MacroDefs
= Args
.getAllArgValues(options::OPT_D
);
5536 return llvm::any_of(MacroDefs
, [&](const std::string
&M
) {
5537 return M
== Macro
|| M
.find(Macro
+ '=') != std::string::npos
;
5541 // _UNIX03_WITHDRAWN is required for libcxx & porting.
5542 if (!findMacroDefinition("_UNIX03_WITHDRAWN"))
5543 CmdArgs
.push_back("-D_UNIX03_WITHDRAWN");
5544 // _OPEN_DEFAULT is required for XL compat
5545 if (!findMacroDefinition("_OPEN_DEFAULT"))
5546 CmdArgs
.push_back("-D_OPEN_DEFAULT");
5547 if (D
.CCCIsCXX() || types::isCXX(Input
.getType())) {
5548 // _XOPEN_SOURCE=600 is required for libcxx.
5549 if (!findMacroDefinition("_XOPEN_SOURCE"))
5550 CmdArgs
.push_back("-D_XOPEN_SOURCE=600");
5554 llvm::Reloc::Model RelocationModel
;
5557 std::tie(RelocationModel
, PICLevel
, IsPIE
) = ParsePICArgs(TC
, Args
);
5558 Arg
*LastPICDataRelArg
=
5559 Args
.getLastArg(options::OPT_mno_pic_data_is_text_relative
,
5560 options::OPT_mpic_data_is_text_relative
);
5561 bool NoPICDataIsTextRelative
= false;
5562 if (LastPICDataRelArg
) {
5563 if (LastPICDataRelArg
->getOption().matches(
5564 options::OPT_mno_pic_data_is_text_relative
)) {
5565 NoPICDataIsTextRelative
= true;
5567 D
.Diag(diag::err_drv_argument_only_allowed_with
)
5568 << "-mno-pic-data-is-text-relative"
5571 if (!Triple
.isSystemZ())
5572 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
5573 << (NoPICDataIsTextRelative
? "-mno-pic-data-is-text-relative"
5574 : "-mpic-data-is-text-relative")
5578 bool IsROPI
= RelocationModel
== llvm::Reloc::ROPI
||
5579 RelocationModel
== llvm::Reloc::ROPI_RWPI
;
5580 bool IsRWPI
= RelocationModel
== llvm::Reloc::RWPI
||
5581 RelocationModel
== llvm::Reloc::ROPI_RWPI
;
5583 if (Args
.hasArg(options::OPT_mcmse
) &&
5584 !Args
.hasArg(options::OPT_fallow_unsupported
)) {
5586 D
.Diag(diag::err_cmse_pi_are_incompatible
) << IsROPI
;
5588 D
.Diag(diag::err_cmse_pi_are_incompatible
) << !IsRWPI
;
5591 if (IsROPI
&& types::isCXX(Input
.getType()) &&
5592 !Args
.hasArg(options::OPT_fallow_unsupported
))
5593 D
.Diag(diag::err_drv_ropi_incompatible_with_cxx
);
5595 const char *RMName
= RelocationModelName(RelocationModel
);
5597 CmdArgs
.push_back("-mrelocation-model");
5598 CmdArgs
.push_back(RMName
);
5601 CmdArgs
.push_back("-pic-level");
5602 CmdArgs
.push_back(PICLevel
== 1 ? "1" : "2");
5604 CmdArgs
.push_back("-pic-is-pie");
5605 if (NoPICDataIsTextRelative
)
5606 CmdArgs
.push_back("-mcmodel=medium");
5609 if (RelocationModel
== llvm::Reloc::ROPI
||
5610 RelocationModel
== llvm::Reloc::ROPI_RWPI
)
5611 CmdArgs
.push_back("-fropi");
5612 if (RelocationModel
== llvm::Reloc::RWPI
||
5613 RelocationModel
== llvm::Reloc::ROPI_RWPI
)
5614 CmdArgs
.push_back("-frwpi");
5616 if (Arg
*A
= Args
.getLastArg(options::OPT_meabi
)) {
5617 CmdArgs
.push_back("-meabi");
5618 CmdArgs
.push_back(A
->getValue());
5621 // -fsemantic-interposition is forwarded to CC1: set the
5622 // "SemanticInterposition" metadata to 1 (make some linkages interposable) and
5623 // make default visibility external linkage definitions dso_preemptable.
5625 // -fno-semantic-interposition: if the target supports .Lfoo$local local
5626 // aliases (make default visibility external linkage definitions dso_local).
5627 // This is the CC1 default for ELF to match COFF/Mach-O.
5629 // Otherwise use Clang's traditional behavior: like
5630 // -fno-semantic-interposition but local aliases are not used. So references
5631 // can be interposed if not optimized out.
5632 if (Triple
.isOSBinFormatELF()) {
5633 Arg
*A
= Args
.getLastArg(options::OPT_fsemantic_interposition
,
5634 options::OPT_fno_semantic_interposition
);
5635 if (RelocationModel
!= llvm::Reloc::Static
&& !IsPIE
) {
5636 // The supported targets need to call AsmPrinter::getSymbolPreferLocal.
5637 bool SupportsLocalAlias
=
5638 Triple
.isAArch64() || Triple
.isRISCV() || Triple
.isX86();
5640 CmdArgs
.push_back("-fhalf-no-semantic-interposition");
5641 else if (A
->getOption().matches(options::OPT_fsemantic_interposition
))
5642 A
->render(Args
, CmdArgs
);
5643 else if (!SupportsLocalAlias
)
5644 CmdArgs
.push_back("-fhalf-no-semantic-interposition");
5650 if (Arg
*A
= Args
.getLastArg(options::OPT_mthread_model
)) {
5651 if (!TC
.isThreadModelSupported(A
->getValue()))
5652 D
.Diag(diag::err_drv_invalid_thread_model_for_target
)
5653 << A
->getValue() << A
->getAsString(Args
);
5654 Model
= A
->getValue();
5656 Model
= TC
.getThreadModel();
5657 if (Model
!= "posix") {
5658 CmdArgs
.push_back("-mthread-model");
5659 CmdArgs
.push_back(Args
.MakeArgString(Model
));
5663 if (Arg
*A
= Args
.getLastArg(options::OPT_fveclib
)) {
5664 StringRef Name
= A
->getValue();
5665 if (Name
== "SVML") {
5666 if (Triple
.getArch() != llvm::Triple::x86
&&
5667 Triple
.getArch() != llvm::Triple::x86_64
)
5668 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
5669 << Name
<< Triple
.getArchName();
5670 } else if (Name
== "LIBMVEC-X86") {
5671 if (Triple
.getArch() != llvm::Triple::x86
&&
5672 Triple
.getArch() != llvm::Triple::x86_64
)
5673 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
5674 << Name
<< Triple
.getArchName();
5675 } else if (Name
== "SLEEF" || Name
== "ArmPL") {
5676 if (Triple
.getArch() != llvm::Triple::aarch64
&&
5677 Triple
.getArch() != llvm::Triple::aarch64_be
)
5678 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
5679 << Name
<< Triple
.getArchName();
5681 A
->render(Args
, CmdArgs
);
5684 if (Args
.hasFlag(options::OPT_fmerge_all_constants
,
5685 options::OPT_fno_merge_all_constants
, false))
5686 CmdArgs
.push_back("-fmerge-all-constants");
5688 Args
.addOptOutFlag(CmdArgs
, options::OPT_fdelete_null_pointer_checks
,
5689 options::OPT_fno_delete_null_pointer_checks
);
5691 // LLVM Code Generator Options.
5693 if (Arg
*A
= Args
.getLastArg(options::OPT_mabi_EQ_quadword_atomics
)) {
5694 if (!Triple
.isOSAIX() || Triple
.isPPC32())
5695 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
5696 << A
->getSpelling() << RawTriple
.str();
5697 CmdArgs
.push_back("-mabi=quadword-atomics");
5700 if (Arg
*A
= Args
.getLastArg(options::OPT_mlong_double_128
)) {
5701 // Emit the unsupported option error until the Clang's library integration
5702 // support for 128-bit long double is available for AIX.
5703 if (Triple
.isOSAIX())
5704 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
5705 << A
->getSpelling() << RawTriple
.str();
5708 if (Arg
*A
= Args
.getLastArg(options::OPT_Wframe_larger_than_EQ
)) {
5709 StringRef V
= A
->getValue(), V1
= V
;
5711 if (V1
.consumeInteger(10, Size
) || !V1
.empty())
5712 D
.Diag(diag::err_drv_invalid_argument_to_option
)
5713 << V
<< A
->getOption().getName();
5715 CmdArgs
.push_back(Args
.MakeArgString("-fwarn-stack-size=" + V
));
5718 Args
.addOptOutFlag(CmdArgs
, options::OPT_fjump_tables
,
5719 options::OPT_fno_jump_tables
);
5720 Args
.addOptInFlag(CmdArgs
, options::OPT_fprofile_sample_accurate
,
5721 options::OPT_fno_profile_sample_accurate
);
5722 Args
.addOptOutFlag(CmdArgs
, options::OPT_fpreserve_as_comments
,
5723 options::OPT_fno_preserve_as_comments
);
5725 if (Arg
*A
= Args
.getLastArg(options::OPT_mregparm_EQ
)) {
5726 CmdArgs
.push_back("-mregparm");
5727 CmdArgs
.push_back(A
->getValue());
5730 if (Arg
*A
= Args
.getLastArg(options::OPT_maix_struct_return
,
5731 options::OPT_msvr4_struct_return
)) {
5732 if (!TC
.getTriple().isPPC32()) {
5733 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
5734 << A
->getSpelling() << RawTriple
.str();
5735 } else if (A
->getOption().matches(options::OPT_maix_struct_return
)) {
5736 CmdArgs
.push_back("-maix-struct-return");
5738 assert(A
->getOption().matches(options::OPT_msvr4_struct_return
));
5739 CmdArgs
.push_back("-msvr4-struct-return");
5743 if (Arg
*A
= Args
.getLastArg(options::OPT_fpcc_struct_return
,
5744 options::OPT_freg_struct_return
)) {
5745 if (TC
.getArch() != llvm::Triple::x86
) {
5746 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
5747 << A
->getSpelling() << RawTriple
.str();
5748 } else if (A
->getOption().matches(options::OPT_fpcc_struct_return
)) {
5749 CmdArgs
.push_back("-fpcc-struct-return");
5751 assert(A
->getOption().matches(options::OPT_freg_struct_return
));
5752 CmdArgs
.push_back("-freg-struct-return");
5756 if (Args
.hasFlag(options::OPT_mrtd
, options::OPT_mno_rtd
, false)) {
5757 if (Triple
.getArch() == llvm::Triple::m68k
)
5758 CmdArgs
.push_back("-fdefault-calling-conv=rtdcall");
5760 CmdArgs
.push_back("-fdefault-calling-conv=stdcall");
5763 if (Args
.hasArg(options::OPT_fenable_matrix
)) {
5764 // enable-matrix is needed by both the LangOpts and by LLVM.
5765 CmdArgs
.push_back("-fenable-matrix");
5766 CmdArgs
.push_back("-mllvm");
5767 CmdArgs
.push_back("-enable-matrix");
5770 CodeGenOptions::FramePointerKind FPKeepKind
=
5771 getFramePointerKind(Args
, RawTriple
);
5772 const char *FPKeepKindStr
= nullptr;
5773 switch (FPKeepKind
) {
5774 case CodeGenOptions::FramePointerKind::None
:
5775 FPKeepKindStr
= "-mframe-pointer=none";
5777 case CodeGenOptions::FramePointerKind::Reserved
:
5778 FPKeepKindStr
= "-mframe-pointer=reserved";
5780 case CodeGenOptions::FramePointerKind::NonLeaf
:
5781 FPKeepKindStr
= "-mframe-pointer=non-leaf";
5783 case CodeGenOptions::FramePointerKind::All
:
5784 FPKeepKindStr
= "-mframe-pointer=all";
5787 assert(FPKeepKindStr
&& "unknown FramePointerKind");
5788 CmdArgs
.push_back(FPKeepKindStr
);
5790 Args
.addOptOutFlag(CmdArgs
, options::OPT_fzero_initialized_in_bss
,
5791 options::OPT_fno_zero_initialized_in_bss
);
5793 bool OFastEnabled
= isOptimizationLevelFast(Args
);
5795 D
.Diag(diag::warn_drv_deprecated_arg_ofast
);
5796 // If -Ofast is the optimization level, then -fstrict-aliasing should be
5797 // enabled. This alias option is being used to simplify the hasFlag logic.
5798 OptSpecifier StrictAliasingAliasOption
=
5799 OFastEnabled
? options::OPT_Ofast
: options::OPT_fstrict_aliasing
;
5800 // We turn strict aliasing off by default if we're Windows MSVC since MSVC
5801 // doesn't do any TBAA.
5802 if (!Args
.hasFlag(options::OPT_fstrict_aliasing
, StrictAliasingAliasOption
,
5803 options::OPT_fno_strict_aliasing
, !IsWindowsMSVC
))
5804 CmdArgs
.push_back("-relaxed-aliasing");
5805 if (Args
.hasFlag(options::OPT_fpointer_tbaa
, options::OPT_fno_pointer_tbaa
,
5807 CmdArgs
.push_back("-pointer-tbaa");
5808 if (!Args
.hasFlag(options::OPT_fstruct_path_tbaa
,
5809 options::OPT_fno_struct_path_tbaa
, true))
5810 CmdArgs
.push_back("-no-struct-path-tbaa");
5811 Args
.addOptInFlag(CmdArgs
, options::OPT_fstrict_enums
,
5812 options::OPT_fno_strict_enums
);
5813 Args
.addOptOutFlag(CmdArgs
, options::OPT_fstrict_return
,
5814 options::OPT_fno_strict_return
);
5815 Args
.addOptInFlag(CmdArgs
, options::OPT_fallow_editor_placeholders
,
5816 options::OPT_fno_allow_editor_placeholders
);
5817 Args
.addOptInFlag(CmdArgs
, options::OPT_fstrict_vtable_pointers
,
5818 options::OPT_fno_strict_vtable_pointers
);
5819 Args
.addOptInFlag(CmdArgs
, options::OPT_fforce_emit_vtables
,
5820 options::OPT_fno_force_emit_vtables
);
5821 Args
.addOptOutFlag(CmdArgs
, options::OPT_foptimize_sibling_calls
,
5822 options::OPT_fno_optimize_sibling_calls
);
5823 Args
.addOptOutFlag(CmdArgs
, options::OPT_fescaping_block_tail_calls
,
5824 options::OPT_fno_escaping_block_tail_calls
);
5826 Args
.AddLastArg(CmdArgs
, options::OPT_ffine_grained_bitfield_accesses
,
5827 options::OPT_fno_fine_grained_bitfield_accesses
);
5829 Args
.AddLastArg(CmdArgs
, options::OPT_fexperimental_relative_cxx_abi_vtables
,
5830 options::OPT_fno_experimental_relative_cxx_abi_vtables
);
5832 Args
.AddLastArg(CmdArgs
, options::OPT_fexperimental_omit_vtable_rtti
,
5833 options::OPT_fno_experimental_omit_vtable_rtti
);
5835 Args
.AddLastArg(CmdArgs
, options::OPT_fdisable_block_signature_string
,
5836 options::OPT_fno_disable_block_signature_string
);
5838 // Handle segmented stacks.
5839 Args
.addOptInFlag(CmdArgs
, options::OPT_fsplit_stack
,
5840 options::OPT_fno_split_stack
);
5842 // -fprotect-parens=0 is default.
5843 if (Args
.hasFlag(options::OPT_fprotect_parens
,
5844 options::OPT_fno_protect_parens
, false))
5845 CmdArgs
.push_back("-fprotect-parens");
5847 RenderFloatingPointOptions(TC
, D
, OFastEnabled
, Args
, CmdArgs
, JA
);
5849 if (Arg
*A
= Args
.getLastArg(options::OPT_fextend_args_EQ
)) {
5850 const llvm::Triple::ArchType Arch
= TC
.getArch();
5851 if (Arch
== llvm::Triple::x86
|| Arch
== llvm::Triple::x86_64
) {
5852 StringRef V
= A
->getValue();
5854 CmdArgs
.push_back("-fextend-arguments=64");
5856 D
.Diag(diag::err_drv_invalid_argument_to_option
)
5857 << A
->getValue() << A
->getOption().getName();
5859 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
5860 << A
->getOption().getName() << TripleStr
;
5863 if (Arg
*A
= Args
.getLastArg(options::OPT_mdouble_EQ
)) {
5864 if (TC
.getArch() == llvm::Triple::avr
)
5865 A
->render(Args
, CmdArgs
);
5867 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
5868 << A
->getAsString(Args
) << TripleStr
;
5871 if (Arg
*A
= Args
.getLastArg(options::OPT_LongDouble_Group
)) {
5872 if (TC
.getTriple().isX86())
5873 A
->render(Args
, CmdArgs
);
5874 else if (TC
.getTriple().isPPC() &&
5875 (A
->getOption().getID() != options::OPT_mlong_double_80
))
5876 A
->render(Args
, CmdArgs
);
5878 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
5879 << A
->getAsString(Args
) << TripleStr
;
5882 // Decide whether to use verbose asm. Verbose assembly is the default on
5883 // toolchains which have the integrated assembler on by default.
5884 bool IsIntegratedAssemblerDefault
= TC
.IsIntegratedAssemblerDefault();
5885 if (!Args
.hasFlag(options::OPT_fverbose_asm
, options::OPT_fno_verbose_asm
,
5886 IsIntegratedAssemblerDefault
))
5887 CmdArgs
.push_back("-fno-verbose-asm");
5889 // Parse 'none' or '$major.$minor'. Disallow -fbinutils-version=0 because we
5890 // use that to indicate the MC default in the backend.
5891 if (Arg
*A
= Args
.getLastArg(options::OPT_fbinutils_version_EQ
)) {
5892 StringRef V
= A
->getValue();
5895 A
->render(Args
, CmdArgs
);
5896 else if (!V
.consumeInteger(10, Num
) && Num
> 0 &&
5897 (V
.empty() || (V
.consume_front(".") &&
5898 !V
.consumeInteger(10, Num
) && V
.empty())))
5899 A
->render(Args
, CmdArgs
);
5901 D
.Diag(diag::err_drv_invalid_argument_to_option
)
5902 << A
->getValue() << A
->getOption().getName();
5905 // If toolchain choose to use MCAsmParser for inline asm don't pass the
5906 // option to disable integrated-as explicitly.
5907 if (!TC
.useIntegratedAs() && !TC
.parseInlineAsmUsingAsmParser())
5908 CmdArgs
.push_back("-no-integrated-as");
5910 if (Args
.hasArg(options::OPT_fdebug_pass_structure
)) {
5911 CmdArgs
.push_back("-mdebug-pass");
5912 CmdArgs
.push_back("Structure");
5914 if (Args
.hasArg(options::OPT_fdebug_pass_arguments
)) {
5915 CmdArgs
.push_back("-mdebug-pass");
5916 CmdArgs
.push_back("Arguments");
5919 // Enable -mconstructor-aliases except on darwin, where we have to work around
5920 // a linker bug (see https://openradar.appspot.com/7198997), and CUDA device
5921 // code, where aliases aren't supported.
5922 if (!RawTriple
.isOSDarwin() && !RawTriple
.isNVPTX())
5923 CmdArgs
.push_back("-mconstructor-aliases");
5925 // Darwin's kernel doesn't support guard variables; just die if we
5927 if (KernelOrKext
&& RawTriple
.isOSDarwin())
5928 CmdArgs
.push_back("-fforbid-guard-variables");
5930 if (Args
.hasFlag(options::OPT_mms_bitfields
, options::OPT_mno_ms_bitfields
,
5931 Triple
.isWindowsGNUEnvironment())) {
5932 CmdArgs
.push_back("-mms-bitfields");
5935 if (Triple
.isWindowsGNUEnvironment()) {
5936 Args
.addOptOutFlag(CmdArgs
, options::OPT_fauto_import
,
5937 options::OPT_fno_auto_import
);
5940 if (Args
.hasFlag(options::OPT_fms_volatile
, options::OPT_fno_ms_volatile
,
5941 Triple
.isX86() && D
.IsCLMode()))
5942 CmdArgs
.push_back("-fms-volatile");
5944 // Non-PIC code defaults to -fdirect-access-external-data while PIC code
5945 // defaults to -fno-direct-access-external-data. Pass the option if different
5946 // from the default.
5947 if (Arg
*A
= Args
.getLastArg(options::OPT_fdirect_access_external_data
,
5948 options::OPT_fno_direct_access_external_data
)) {
5949 if (A
->getOption().matches(options::OPT_fdirect_access_external_data
) !=
5951 A
->render(Args
, CmdArgs
);
5952 } else if (PICLevel
== 0 && Triple
.isLoongArch()) {
5953 // Some targets default to -fno-direct-access-external-data even for
5955 CmdArgs
.push_back("-fno-direct-access-external-data");
5958 if (Args
.hasFlag(options::OPT_fno_plt
, options::OPT_fplt
, false)) {
5959 CmdArgs
.push_back("-fno-plt");
5962 // -fhosted is default.
5963 // TODO: Audit uses of KernelOrKext and see where it'd be more appropriate to
5964 // use Freestanding.
5966 Args
.hasFlag(options::OPT_ffreestanding
, options::OPT_fhosted
, false) ||
5969 CmdArgs
.push_back("-ffreestanding");
5971 Args
.AddLastArg(CmdArgs
, options::OPT_fno_knr_functions
);
5973 // This is a coarse approximation of what llvm-gcc actually does, both
5974 // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
5975 // complicated ways.
5976 auto SanitizeArgs
= TC
.getSanitizerArgs(Args
);
5978 bool IsAsyncUnwindTablesDefault
=
5979 TC
.getDefaultUnwindTableLevel(Args
) == ToolChain::UnwindTableLevel::Asynchronous
;
5980 bool IsSyncUnwindTablesDefault
=
5981 TC
.getDefaultUnwindTableLevel(Args
) == ToolChain::UnwindTableLevel::Synchronous
;
5983 bool AsyncUnwindTables
= Args
.hasFlag(
5984 options::OPT_fasynchronous_unwind_tables
,
5985 options::OPT_fno_asynchronous_unwind_tables
,
5986 (IsAsyncUnwindTablesDefault
|| SanitizeArgs
.needsUnwindTables()) &&
5989 Args
.hasFlag(options::OPT_funwind_tables
, options::OPT_fno_unwind_tables
,
5990 IsSyncUnwindTablesDefault
&& !Freestanding
);
5991 if (AsyncUnwindTables
)
5992 CmdArgs
.push_back("-funwind-tables=2");
5993 else if (UnwindTables
)
5994 CmdArgs
.push_back("-funwind-tables=1");
5996 // Prepare `-aux-target-cpu` and `-aux-target-feature` unless
5997 // `--gpu-use-aux-triple-only` is specified.
5998 if (!Args
.getLastArg(options::OPT_gpu_use_aux_triple_only
) &&
5999 (IsCudaDevice
|| IsHIPDevice
)) {
6000 const ArgList
&HostArgs
=
6001 C
.getArgsForToolChain(nullptr, StringRef(), Action::OFK_None
);
6002 std::string HostCPU
=
6003 getCPUName(D
, HostArgs
, *TC
.getAuxTriple(), /*FromAs*/ false);
6004 if (!HostCPU
.empty()) {
6005 CmdArgs
.push_back("-aux-target-cpu");
6006 CmdArgs
.push_back(Args
.MakeArgString(HostCPU
));
6008 getTargetFeatures(D
, *TC
.getAuxTriple(), HostArgs
, CmdArgs
,
6009 /*ForAS*/ false, /*IsAux*/ true);
6012 TC
.addClangTargetOptions(Args
, CmdArgs
, JA
.getOffloadingDeviceKind());
6014 addMCModel(D
, Args
, Triple
, RelocationModel
, CmdArgs
);
6016 if (Arg
*A
= Args
.getLastArg(options::OPT_mtls_size_EQ
)) {
6017 StringRef Value
= A
->getValue();
6018 unsigned TLSSize
= 0;
6019 Value
.getAsInteger(10, TLSSize
);
6020 if (!Triple
.isAArch64() || !Triple
.isOSBinFormatELF())
6021 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
6022 << A
->getOption().getName() << TripleStr
;
6023 if (TLSSize
!= 12 && TLSSize
!= 24 && TLSSize
!= 32 && TLSSize
!= 48)
6024 D
.Diag(diag::err_drv_invalid_int_value
)
6025 << A
->getOption().getName() << Value
;
6026 Args
.AddLastArg(CmdArgs
, options::OPT_mtls_size_EQ
);
6029 if (isTLSDESCEnabled(TC
, Args
))
6030 CmdArgs
.push_back("-enable-tlsdesc");
6032 // Add the target cpu
6033 std::string CPU
= getCPUName(D
, Args
, Triple
, /*FromAs*/ false);
6035 CmdArgs
.push_back("-target-cpu");
6036 CmdArgs
.push_back(Args
.MakeArgString(CPU
));
6039 RenderTargetOptions(Triple
, Args
, KernelOrKext
, CmdArgs
);
6041 // Add clang-cl arguments.
6042 types::ID InputType
= Input
.getType();
6044 AddClangCLArgs(Args
, InputType
, CmdArgs
);
6046 llvm::codegenoptions::DebugInfoKind DebugInfoKind
=
6047 llvm::codegenoptions::NoDebugInfo
;
6048 DwarfFissionKind DwarfFission
= DwarfFissionKind::None
;
6049 renderDebugOptions(TC
, D
, RawTriple
, Args
, types::isLLVMIR(InputType
),
6050 CmdArgs
, Output
, DebugInfoKind
, DwarfFission
);
6052 // Add the split debug info name to the command lines here so we
6053 // can propagate it to the backend.
6054 bool SplitDWARF
= (DwarfFission
!= DwarfFissionKind::None
) &&
6055 (TC
.getTriple().isOSBinFormatELF() ||
6056 TC
.getTriple().isOSBinFormatWasm() ||
6057 TC
.getTriple().isOSBinFormatCOFF()) &&
6058 (isa
<AssembleJobAction
>(JA
) || isa
<CompileJobAction
>(JA
) ||
6059 isa
<BackendJobAction
>(JA
));
6061 const char *SplitDWARFOut
= SplitDebugName(JA
, Args
, Input
, Output
);
6062 CmdArgs
.push_back("-split-dwarf-file");
6063 CmdArgs
.push_back(SplitDWARFOut
);
6064 if (DwarfFission
== DwarfFissionKind::Split
) {
6065 CmdArgs
.push_back("-split-dwarf-output");
6066 CmdArgs
.push_back(SplitDWARFOut
);
6070 // Pass the linker version in use.
6071 if (Arg
*A
= Args
.getLastArg(options::OPT_mlinker_version_EQ
)) {
6072 CmdArgs
.push_back("-target-linker-version");
6073 CmdArgs
.push_back(A
->getValue());
6076 // Explicitly error on some things we know we don't support and can't just
6078 if (!Args
.hasArg(options::OPT_fallow_unsupported
)) {
6080 if (types::isCXX(InputType
) && RawTriple
.isOSDarwin() &&
6081 TC
.getArch() == llvm::Triple::x86
) {
6082 if ((Unsupported
= Args
.getLastArg(options::OPT_fapple_kext
)) ||
6083 (Unsupported
= Args
.getLastArg(options::OPT_mkernel
)))
6084 D
.Diag(diag::err_drv_clang_unsupported_opt_cxx_darwin_i386
)
6085 << Unsupported
->getOption().getName();
6087 // The faltivec option has been superseded by the maltivec option.
6088 if ((Unsupported
= Args
.getLastArg(options::OPT_faltivec
)))
6089 D
.Diag(diag::err_drv_clang_unsupported_opt_faltivec
)
6090 << Unsupported
->getOption().getName()
6091 << "please use -maltivec and include altivec.h explicitly";
6092 if ((Unsupported
= Args
.getLastArg(options::OPT_fno_altivec
)))
6093 D
.Diag(diag::err_drv_clang_unsupported_opt_faltivec
)
6094 << Unsupported
->getOption().getName() << "please use -mno-altivec";
6097 Args
.AddAllArgs(CmdArgs
, options::OPT_v
);
6099 if (Args
.getLastArg(options::OPT_H
)) {
6100 CmdArgs
.push_back("-H");
6101 CmdArgs
.push_back("-sys-header-deps");
6103 Args
.AddAllArgs(CmdArgs
, options::OPT_fshow_skipped_includes
);
6105 if (D
.CCPrintHeadersFormat
&& !D
.CCGenDiagnostics
) {
6106 CmdArgs
.push_back("-header-include-file");
6107 CmdArgs
.push_back(!D
.CCPrintHeadersFilename
.empty()
6108 ? D
.CCPrintHeadersFilename
.c_str()
6110 CmdArgs
.push_back("-sys-header-deps");
6111 CmdArgs
.push_back(Args
.MakeArgString(
6112 "-header-include-format=" +
6113 std::string(headerIncludeFormatKindToString(D
.CCPrintHeadersFormat
))));
6115 Args
.MakeArgString("-header-include-filtering=" +
6116 std::string(headerIncludeFilteringKindToString(
6117 D
.CCPrintHeadersFiltering
))));
6119 Args
.AddLastArg(CmdArgs
, options::OPT_P
);
6120 Args
.AddLastArg(CmdArgs
, options::OPT_print_ivar_layout
);
6122 if (D
.CCLogDiagnostics
&& !D
.CCGenDiagnostics
) {
6123 CmdArgs
.push_back("-diagnostic-log-file");
6124 CmdArgs
.push_back(!D
.CCLogDiagnosticsFilename
.empty()
6125 ? D
.CCLogDiagnosticsFilename
.c_str()
6129 // Give the gen diagnostics more chances to succeed, by avoiding intentional
6131 if (D
.CCGenDiagnostics
)
6132 CmdArgs
.push_back("-disable-pragma-debug-crash");
6134 // Allow backend to put its diagnostic files in the same place as frontend
6135 // crash diagnostics files.
6136 if (Args
.hasArg(options::OPT_fcrash_diagnostics_dir
)) {
6137 StringRef Dir
= Args
.getLastArgValue(options::OPT_fcrash_diagnostics_dir
);
6138 CmdArgs
.push_back("-mllvm");
6139 CmdArgs
.push_back(Args
.MakeArgString("-crash-diagnostics-dir=" + Dir
));
6142 bool UseSeparateSections
= isUseSeparateSections(Triple
);
6144 if (Args
.hasFlag(options::OPT_ffunction_sections
,
6145 options::OPT_fno_function_sections
, UseSeparateSections
)) {
6146 CmdArgs
.push_back("-ffunction-sections");
6149 if (Arg
*A
= Args
.getLastArg(options::OPT_fbasic_block_address_map
,
6150 options::OPT_fno_basic_block_address_map
)) {
6151 if ((Triple
.isX86() || Triple
.isAArch64()) && Triple
.isOSBinFormatELF()) {
6152 if (A
->getOption().matches(options::OPT_fbasic_block_address_map
))
6153 A
->render(Args
, CmdArgs
);
6155 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
6156 << A
->getAsString(Args
) << TripleStr
;
6160 if (Arg
*A
= Args
.getLastArg(options::OPT_fbasic_block_sections_EQ
)) {
6161 StringRef Val
= A
->getValue();
6162 if (Triple
.isX86() && Triple
.isOSBinFormatELF()) {
6163 if (Val
!= "all" && Val
!= "labels" && Val
!= "none" &&
6164 !Val
.starts_with("list="))
6165 D
.Diag(diag::err_drv_invalid_value
)
6166 << A
->getAsString(Args
) << A
->getValue();
6168 A
->render(Args
, CmdArgs
);
6169 } else if (Triple
.isAArch64() && Triple
.isOSBinFormatELF()) {
6170 // "all" is not supported on AArch64 since branch relaxation creates new
6171 // basic blocks for some cross-section branches.
6172 if (Val
!= "labels" && Val
!= "none" && !Val
.starts_with("list="))
6173 D
.Diag(diag::err_drv_invalid_value
)
6174 << A
->getAsString(Args
) << A
->getValue();
6176 A
->render(Args
, CmdArgs
);
6177 } else if (Triple
.isNVPTX()) {
6178 // Do not pass the option to the GPU compilation. We still want it enabled
6179 // for the host-side compilation, so seeing it here is not an error.
6180 } else if (Val
!= "none") {
6181 // =none is allowed everywhere. It's useful for overriding the option
6182 // and is the same as not specifying the option.
6183 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
6184 << A
->getAsString(Args
) << TripleStr
;
6188 bool HasDefaultDataSections
= Triple
.isOSBinFormatXCOFF();
6189 if (Args
.hasFlag(options::OPT_fdata_sections
, options::OPT_fno_data_sections
,
6190 UseSeparateSections
|| HasDefaultDataSections
)) {
6191 CmdArgs
.push_back("-fdata-sections");
6194 Args
.addOptOutFlag(CmdArgs
, options::OPT_funique_section_names
,
6195 options::OPT_fno_unique_section_names
);
6196 Args
.addOptInFlag(CmdArgs
, options::OPT_fseparate_named_sections
,
6197 options::OPT_fno_separate_named_sections
);
6198 Args
.addOptInFlag(CmdArgs
, options::OPT_funique_internal_linkage_names
,
6199 options::OPT_fno_unique_internal_linkage_names
);
6200 Args
.addOptInFlag(CmdArgs
, options::OPT_funique_basic_block_section_names
,
6201 options::OPT_fno_unique_basic_block_section_names
);
6202 Args
.addOptInFlag(CmdArgs
, options::OPT_fconvergent_functions
,
6203 options::OPT_fno_convergent_functions
);
6205 if (Arg
*A
= Args
.getLastArg(options::OPT_fsplit_machine_functions
,
6206 options::OPT_fno_split_machine_functions
)) {
6207 if (!A
->getOption().matches(options::OPT_fno_split_machine_functions
)) {
6208 // This codegen pass is only available on x86 and AArch64 ELF targets.
6209 if ((Triple
.isX86() || Triple
.isAArch64()) && Triple
.isOSBinFormatELF())
6210 A
->render(Args
, CmdArgs
);
6212 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
6213 << A
->getAsString(Args
) << TripleStr
;
6217 Args
.AddLastArg(CmdArgs
, options::OPT_finstrument_functions
,
6218 options::OPT_finstrument_functions_after_inlining
,
6219 options::OPT_finstrument_function_entry_bare
);
6221 // NVPTX/AMDGCN doesn't support PGO or coverage. There's no runtime support
6222 // for sampling, overhead of call arc collection is way too high and there's
6223 // no way to collect the output.
6224 if (!Triple
.isNVPTX() && !Triple
.isAMDGCN())
6225 addPGOAndCoverageFlags(TC
, C
, JA
, Output
, Args
, SanitizeArgs
, CmdArgs
);
6227 Args
.AddLastArg(CmdArgs
, options::OPT_fclang_abi_compat_EQ
);
6229 if (getLastProfileSampleUseArg(Args
) &&
6230 Args
.hasArg(options::OPT_fsample_profile_use_profi
)) {
6231 CmdArgs
.push_back("-mllvm");
6232 CmdArgs
.push_back("-sample-profile-use-profi");
6235 // Add runtime flag for PS4/PS5 when PGO, coverage, or sanitizers are enabled.
6236 if (RawTriple
.isPS() &&
6237 !Args
.hasArg(options::OPT_nostdlib
, options::OPT_nodefaultlibs
)) {
6238 PScpu::addProfileRTArgs(TC
, Args
, CmdArgs
);
6239 PScpu::addSanitizerArgs(TC
, Args
, CmdArgs
);
6242 // Pass options for controlling the default header search paths.
6243 if (Args
.hasArg(options::OPT_nostdinc
)) {
6244 CmdArgs
.push_back("-nostdsysteminc");
6245 CmdArgs
.push_back("-nobuiltininc");
6247 if (Args
.hasArg(options::OPT_nostdlibinc
))
6248 CmdArgs
.push_back("-nostdsysteminc");
6249 Args
.AddLastArg(CmdArgs
, options::OPT_nostdincxx
);
6250 Args
.AddLastArg(CmdArgs
, options::OPT_nobuiltininc
);
6253 // Pass the path to compiler resource files.
6254 CmdArgs
.push_back("-resource-dir");
6255 CmdArgs
.push_back(D
.ResourceDir
.c_str());
6257 Args
.AddLastArg(CmdArgs
, options::OPT_working_directory
);
6259 RenderARCMigrateToolOptions(D
, Args
, CmdArgs
);
6261 // Add preprocessing options like -I, -D, etc. if we are using the
6264 // FIXME: Support -fpreprocessed
6265 if (types::getPreprocessedType(InputType
) != types::TY_INVALID
)
6266 AddPreprocessingOptions(C
, JA
, D
, Args
, CmdArgs
, Output
, Inputs
);
6268 // Don't warn about "clang -c -DPIC -fPIC test.i" because libtool.m4 assumes
6269 // that "The compiler can only warn and ignore the option if not recognized".
6270 // When building with ccache, it will pass -D options to clang even on
6271 // preprocessed inputs and configure concludes that -fPIC is not supported.
6272 Args
.ClaimAllArgs(options::OPT_D
);
6274 // Manually translate -O4 to -O3; let clang reject others.
6275 if (Arg
*A
= Args
.getLastArg(options::OPT_O_Group
)) {
6276 if (A
->getOption().matches(options::OPT_O4
)) {
6277 CmdArgs
.push_back("-O3");
6278 D
.Diag(diag::warn_O4_is_O3
);
6280 A
->render(Args
, CmdArgs
);
6284 // Warn about ignored options to clang.
6286 Args
.filtered(options::OPT_clang_ignored_gcc_optimization_f_Group
)) {
6287 D
.Diag(diag::warn_ignored_gcc_optimization
) << A
->getAsString(Args
);
6292 Args
.filtered(options::OPT_clang_ignored_legacy_options_Group
)) {
6293 D
.Diag(diag::warn_ignored_clang_option
) << A
->getAsString(Args
);
6297 claimNoWarnArgs(Args
);
6299 Args
.AddAllArgs(CmdArgs
, options::OPT_R_Group
);
6302 Args
.filtered(options::OPT_W_Group
, options::OPT__SLASH_wd
)) {
6304 if (A
->getOption().getID() == options::OPT__SLASH_wd
) {
6305 unsigned WarningNumber
;
6306 if (StringRef(A
->getValue()).getAsInteger(10, WarningNumber
)) {
6307 D
.Diag(diag::err_drv_invalid_int_value
)
6308 << A
->getAsString(Args
) << A
->getValue();
6312 if (auto Group
= diagGroupFromCLWarningID(WarningNumber
)) {
6313 CmdArgs
.push_back(Args
.MakeArgString(
6314 "-Wno-" + DiagnosticIDs::getWarningOptionForGroup(*Group
)));
6318 A
->render(Args
, CmdArgs
);
6321 Args
.AddAllArgs(CmdArgs
, options::OPT_Wsystem_headers_in_module_EQ
);
6323 if (Args
.hasFlag(options::OPT_pedantic
, options::OPT_no_pedantic
, false))
6324 CmdArgs
.push_back("-pedantic");
6325 Args
.AddLastArg(CmdArgs
, options::OPT_pedantic_errors
);
6326 Args
.AddLastArg(CmdArgs
, options::OPT_w
);
6328 Args
.addOptInFlag(CmdArgs
, options::OPT_ffixed_point
,
6329 options::OPT_fno_fixed_point
);
6331 if (Arg
*A
= Args
.getLastArg(options::OPT_fcxx_abi_EQ
))
6332 A
->render(Args
, CmdArgs
);
6334 Args
.AddLastArg(CmdArgs
, options::OPT_fexperimental_relative_cxx_abi_vtables
,
6335 options::OPT_fno_experimental_relative_cxx_abi_vtables
);
6337 Args
.AddLastArg(CmdArgs
, options::OPT_fexperimental_omit_vtable_rtti
,
6338 options::OPT_fno_experimental_omit_vtable_rtti
);
6340 if (Arg
*A
= Args
.getLastArg(options::OPT_ffuchsia_api_level_EQ
))
6341 A
->render(Args
, CmdArgs
);
6343 // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
6344 // (-ansi is equivalent to -std=c89 or -std=c++98).
6346 // If a std is supplied, only add -trigraphs if it follows the
6348 bool ImplyVCPPCVer
= false;
6349 bool ImplyVCPPCXXVer
= false;
6350 const Arg
*Std
= Args
.getLastArg(options::OPT_std_EQ
, options::OPT_ansi
);
6352 if (Std
->getOption().matches(options::OPT_ansi
))
6353 if (types::isCXX(InputType
))
6354 CmdArgs
.push_back("-std=c++98");
6356 CmdArgs
.push_back("-std=c89");
6358 Std
->render(Args
, CmdArgs
);
6360 // If -f(no-)trigraphs appears after the language standard flag, honor it.
6361 if (Arg
*A
= Args
.getLastArg(options::OPT_std_EQ
, options::OPT_ansi
,
6362 options::OPT_ftrigraphs
,
6363 options::OPT_fno_trigraphs
))
6365 A
->render(Args
, CmdArgs
);
6367 // Honor -std-default.
6369 // FIXME: Clang doesn't correctly handle -std= when the input language
6370 // doesn't match. For the time being just ignore this for C++ inputs;
6371 // eventually we want to do all the standard defaulting here instead of
6372 // splitting it between the driver and clang -cc1.
6373 if (!types::isCXX(InputType
)) {
6374 if (!Args
.hasArg(options::OPT__SLASH_std
)) {
6375 Args
.AddAllArgsTranslated(CmdArgs
, options::OPT_std_default_EQ
, "-std=",
6378 ImplyVCPPCVer
= true;
6380 else if (IsWindowsMSVC
)
6381 ImplyVCPPCXXVer
= true;
6383 Args
.AddLastArg(CmdArgs
, options::OPT_ftrigraphs
,
6384 options::OPT_fno_trigraphs
);
6387 // GCC's behavior for -Wwrite-strings is a bit strange:
6388 // * In C, this "warning flag" changes the types of string literals from
6389 // 'char[N]' to 'const char[N]', and thus triggers an unrelated warning
6390 // for the discarded qualifier.
6391 // * In C++, this is just a normal warning flag.
6393 // Implementing this warning correctly in C is hard, so we follow GCC's
6394 // behavior for now. FIXME: Directly diagnose uses of a string literal as
6395 // a non-const char* in C, rather than using this crude hack.
6396 if (!types::isCXX(InputType
)) {
6397 // FIXME: This should behave just like a warning flag, and thus should also
6398 // respect -Weverything, -Wno-everything, -Werror=write-strings, and so on.
6400 Args
.getLastArg(options::OPT_Wwrite_strings
,
6401 options::OPT_Wno_write_strings
, options::OPT_w
);
6403 WriteStrings
->getOption().matches(options::OPT_Wwrite_strings
))
6404 CmdArgs
.push_back("-fconst-strings");
6407 // GCC provides a macro definition '__DEPRECATED' when -Wdeprecated is active
6408 // during C++ compilation, which it is by default. GCC keeps this define even
6409 // in the presence of '-w', match this behavior bug-for-bug.
6410 if (types::isCXX(InputType
) &&
6411 Args
.hasFlag(options::OPT_Wdeprecated
, options::OPT_Wno_deprecated
,
6413 CmdArgs
.push_back("-fdeprecated-macro");
6416 // Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'.
6417 if (Arg
*Asm
= Args
.getLastArg(options::OPT_fasm
, options::OPT_fno_asm
)) {
6418 if (Asm
->getOption().matches(options::OPT_fasm
))
6419 CmdArgs
.push_back("-fgnu-keywords");
6421 CmdArgs
.push_back("-fno-gnu-keywords");
6424 if (!ShouldEnableAutolink(Args
, TC
, JA
))
6425 CmdArgs
.push_back("-fno-autolink");
6427 Args
.AddLastArg(CmdArgs
, options::OPT_ftemplate_depth_EQ
);
6428 Args
.AddLastArg(CmdArgs
, options::OPT_foperator_arrow_depth_EQ
);
6429 Args
.AddLastArg(CmdArgs
, options::OPT_fconstexpr_depth_EQ
);
6430 Args
.AddLastArg(CmdArgs
, options::OPT_fconstexpr_steps_EQ
);
6432 Args
.AddLastArg(CmdArgs
, options::OPT_fexperimental_library
);
6434 if (Args
.hasArg(options::OPT_fexperimental_new_constant_interpreter
))
6435 CmdArgs
.push_back("-fexperimental-new-constant-interpreter");
6437 if (Arg
*A
= Args
.getLastArg(options::OPT_fbracket_depth_EQ
)) {
6438 CmdArgs
.push_back("-fbracket-depth");
6439 CmdArgs
.push_back(A
->getValue());
6442 if (Arg
*A
= Args
.getLastArg(options::OPT_Wlarge_by_value_copy_EQ
,
6443 options::OPT_Wlarge_by_value_copy_def
)) {
6444 if (A
->getNumValues()) {
6445 StringRef bytes
= A
->getValue();
6446 CmdArgs
.push_back(Args
.MakeArgString("-Wlarge-by-value-copy=" + bytes
));
6448 CmdArgs
.push_back("-Wlarge-by-value-copy=64"); // default value
6451 if (Args
.hasArg(options::OPT_relocatable_pch
))
6452 CmdArgs
.push_back("-relocatable-pch");
6454 if (const Arg
*A
= Args
.getLastArg(options::OPT_fcf_runtime_abi_EQ
)) {
6455 static const char *kCFABIs
[] = {
6456 "standalone", "objc", "swift", "swift-5.0", "swift-4.2", "swift-4.1",
6459 if (!llvm::is_contained(kCFABIs
, StringRef(A
->getValue())))
6460 D
.Diag(diag::err_drv_invalid_cf_runtime_abi
) << A
->getValue();
6462 A
->render(Args
, CmdArgs
);
6465 if (Arg
*A
= Args
.getLastArg(options::OPT_fconstant_string_class_EQ
)) {
6466 CmdArgs
.push_back("-fconstant-string-class");
6467 CmdArgs
.push_back(A
->getValue());
6470 if (Arg
*A
= Args
.getLastArg(options::OPT_ftabstop_EQ
)) {
6471 CmdArgs
.push_back("-ftabstop");
6472 CmdArgs
.push_back(A
->getValue());
6475 Args
.addOptInFlag(CmdArgs
, options::OPT_fstack_size_section
,
6476 options::OPT_fno_stack_size_section
);
6478 if (Args
.hasArg(options::OPT_fstack_usage
)) {
6479 CmdArgs
.push_back("-stack-usage-file");
6481 if (Arg
*OutputOpt
= Args
.getLastArg(options::OPT_o
)) {
6482 SmallString
<128> OutputFilename(OutputOpt
->getValue());
6483 llvm::sys::path::replace_extension(OutputFilename
, "su");
6484 CmdArgs
.push_back(Args
.MakeArgString(OutputFilename
));
6487 Args
.MakeArgString(Twine(getBaseInputStem(Args
, Inputs
)) + ".su"));
6490 CmdArgs
.push_back("-ferror-limit");
6491 if (Arg
*A
= Args
.getLastArg(options::OPT_ferror_limit_EQ
))
6492 CmdArgs
.push_back(A
->getValue());
6494 CmdArgs
.push_back("19");
6496 Args
.AddLastArg(CmdArgs
, options::OPT_fconstexpr_backtrace_limit_EQ
);
6497 Args
.AddLastArg(CmdArgs
, options::OPT_fmacro_backtrace_limit_EQ
);
6498 Args
.AddLastArg(CmdArgs
, options::OPT_ftemplate_backtrace_limit_EQ
);
6499 Args
.AddLastArg(CmdArgs
, options::OPT_fspell_checking_limit_EQ
);
6500 Args
.AddLastArg(CmdArgs
, options::OPT_fcaret_diagnostics_max_lines_EQ
);
6502 // Pass -fmessage-length=.
6503 unsigned MessageLength
= 0;
6504 if (Arg
*A
= Args
.getLastArg(options::OPT_fmessage_length_EQ
)) {
6505 StringRef
V(A
->getValue());
6506 if (V
.getAsInteger(0, MessageLength
))
6507 D
.Diag(diag::err_drv_invalid_argument_to_option
)
6508 << V
<< A
->getOption().getName();
6510 // If -fmessage-length=N was not specified, determine whether this is a
6511 // terminal and, if so, implicitly define -fmessage-length appropriately.
6512 MessageLength
= llvm::sys::Process::StandardErrColumns();
6514 if (MessageLength
!= 0)
6516 Args
.MakeArgString("-fmessage-length=" + Twine(MessageLength
)));
6518 if (Arg
*A
= Args
.getLastArg(options::OPT_frandomize_layout_seed_EQ
))
6520 Args
.MakeArgString("-frandomize-layout-seed=" + Twine(A
->getValue(0))));
6522 if (Arg
*A
= Args
.getLastArg(options::OPT_frandomize_layout_seed_file_EQ
))
6523 CmdArgs
.push_back(Args
.MakeArgString("-frandomize-layout-seed-file=" +
6524 Twine(A
->getValue(0))));
6526 // -fvisibility= and -fvisibility-ms-compat are of a piece.
6527 if (const Arg
*A
= Args
.getLastArg(options::OPT_fvisibility_EQ
,
6528 options::OPT_fvisibility_ms_compat
)) {
6529 if (A
->getOption().matches(options::OPT_fvisibility_EQ
)) {
6530 A
->render(Args
, CmdArgs
);
6532 assert(A
->getOption().matches(options::OPT_fvisibility_ms_compat
));
6533 CmdArgs
.push_back("-fvisibility=hidden");
6534 CmdArgs
.push_back("-ftype-visibility=default");
6536 } else if (IsOpenMPDevice
) {
6537 // When compiling for the OpenMP device we want protected visibility by
6538 // default. This prevents the device from accidentally preempting code on
6539 // the host, makes the system more robust, and improves performance.
6540 CmdArgs
.push_back("-fvisibility=protected");
6543 // PS4/PS5 process these options in addClangTargetOptions.
6544 if (!RawTriple
.isPS()) {
6546 Args
.getLastArg(options::OPT_fvisibility_from_dllstorageclass
,
6547 options::OPT_fno_visibility_from_dllstorageclass
)) {
6548 if (A
->getOption().matches(
6549 options::OPT_fvisibility_from_dllstorageclass
)) {
6550 CmdArgs
.push_back("-fvisibility-from-dllstorageclass");
6551 Args
.AddLastArg(CmdArgs
, options::OPT_fvisibility_dllexport_EQ
);
6552 Args
.AddLastArg(CmdArgs
, options::OPT_fvisibility_nodllstorageclass_EQ
);
6553 Args
.AddLastArg(CmdArgs
, options::OPT_fvisibility_externs_dllimport_EQ
);
6554 Args
.AddLastArg(CmdArgs
,
6555 options::OPT_fvisibility_externs_nodllstorageclass_EQ
);
6560 if (Args
.hasFlag(options::OPT_fvisibility_inlines_hidden
,
6561 options::OPT_fno_visibility_inlines_hidden
, false))
6562 CmdArgs
.push_back("-fvisibility-inlines-hidden");
6564 Args
.AddLastArg(CmdArgs
, options::OPT_fvisibility_inlines_hidden_static_local_var
,
6565 options::OPT_fno_visibility_inlines_hidden_static_local_var
);
6567 // -fvisibility-global-new-delete-hidden is a deprecated spelling of
6568 // -fvisibility-global-new-delete=force-hidden.
6570 Args
.getLastArg(options::OPT_fvisibility_global_new_delete_hidden
)) {
6571 D
.Diag(diag::warn_drv_deprecated_arg
)
6572 << A
->getAsString(Args
) << /*hasReplacement=*/true
6573 << "-fvisibility-global-new-delete=force-hidden";
6577 Args
.getLastArg(options::OPT_fvisibility_global_new_delete_EQ
,
6578 options::OPT_fvisibility_global_new_delete_hidden
)) {
6579 if (A
->getOption().matches(options::OPT_fvisibility_global_new_delete_EQ
)) {
6580 A
->render(Args
, CmdArgs
);
6582 assert(A
->getOption().matches(
6583 options::OPT_fvisibility_global_new_delete_hidden
));
6584 CmdArgs
.push_back("-fvisibility-global-new-delete=force-hidden");
6588 Args
.AddLastArg(CmdArgs
, options::OPT_ftlsmodel_EQ
);
6590 if (Args
.hasFlag(options::OPT_fnew_infallible
,
6591 options::OPT_fno_new_infallible
, false))
6592 CmdArgs
.push_back("-fnew-infallible");
6594 if (Args
.hasFlag(options::OPT_fno_operator_names
,
6595 options::OPT_foperator_names
, false))
6596 CmdArgs
.push_back("-fno-operator-names");
6598 // Forward -f (flag) options which we can pass directly.
6599 Args
.AddLastArg(CmdArgs
, options::OPT_femit_all_decls
);
6600 Args
.AddLastArg(CmdArgs
, options::OPT_fheinous_gnu_extensions
);
6601 Args
.AddLastArg(CmdArgs
, options::OPT_fdigraphs
, options::OPT_fno_digraphs
);
6602 Args
.AddLastArg(CmdArgs
, options::OPT_fzero_call_used_regs_EQ
);
6603 Args
.AddLastArg(CmdArgs
, options::OPT_fraw_string_literals
,
6604 options::OPT_fno_raw_string_literals
);
6606 if (Args
.hasFlag(options::OPT_femulated_tls
, options::OPT_fno_emulated_tls
,
6607 Triple
.hasDefaultEmulatedTLS()))
6608 CmdArgs
.push_back("-femulated-tls");
6610 Args
.addOptInFlag(CmdArgs
, options::OPT_fcheck_new
,
6611 options::OPT_fno_check_new
);
6613 if (Arg
*A
= Args
.getLastArg(options::OPT_fzero_call_used_regs_EQ
)) {
6614 // FIXME: There's no reason for this to be restricted to X86. The backend
6615 // code needs to be changed to include the appropriate function calls
6617 if (!Triple
.isX86() && !Triple
.isAArch64())
6618 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
6619 << A
->getAsString(Args
) << TripleStr
;
6622 // AltiVec-like language extensions aren't relevant for assembling.
6623 if (!isa
<PreprocessJobAction
>(JA
) || Output
.getType() != types::TY_PP_Asm
)
6624 Args
.AddLastArg(CmdArgs
, options::OPT_fzvector
);
6626 Args
.AddLastArg(CmdArgs
, options::OPT_fdiagnostics_show_template_tree
);
6627 Args
.AddLastArg(CmdArgs
, options::OPT_fno_elide_type
);
6629 // Forward flags for OpenMP. We don't do this if the current action is an
6630 // device offloading action other than OpenMP.
6631 if (Args
.hasFlag(options::OPT_fopenmp
, options::OPT_fopenmp_EQ
,
6632 options::OPT_fno_openmp
, false) &&
6633 (JA
.isDeviceOffloading(Action::OFK_None
) ||
6634 JA
.isDeviceOffloading(Action::OFK_OpenMP
))) {
6635 switch (D
.getOpenMPRuntime(Args
)) {
6636 case Driver::OMPRT_OMP
:
6637 case Driver::OMPRT_IOMP5
:
6638 // Clang can generate useful OpenMP code for these two runtime libraries.
6639 CmdArgs
.push_back("-fopenmp");
6641 // If no option regarding the use of TLS in OpenMP codegeneration is
6642 // given, decide a default based on the target. Otherwise rely on the
6643 // options and pass the right information to the frontend.
6644 if (!Args
.hasFlag(options::OPT_fopenmp_use_tls
,
6645 options::OPT_fnoopenmp_use_tls
, /*Default=*/true))
6646 CmdArgs
.push_back("-fnoopenmp-use-tls");
6647 Args
.AddLastArg(CmdArgs
, options::OPT_fopenmp_simd
,
6648 options::OPT_fno_openmp_simd
);
6649 Args
.AddAllArgs(CmdArgs
, options::OPT_fopenmp_enable_irbuilder
);
6650 Args
.AddAllArgs(CmdArgs
, options::OPT_fopenmp_version_EQ
);
6651 if (!Args
.hasFlag(options::OPT_fopenmp_extensions
,
6652 options::OPT_fno_openmp_extensions
, /*Default=*/true))
6653 CmdArgs
.push_back("-fno-openmp-extensions");
6654 Args
.AddAllArgs(CmdArgs
, options::OPT_fopenmp_cuda_number_of_sm_EQ
);
6655 Args
.AddAllArgs(CmdArgs
, options::OPT_fopenmp_cuda_blocks_per_sm_EQ
);
6656 Args
.AddAllArgs(CmdArgs
,
6657 options::OPT_fopenmp_cuda_teams_reduction_recs_num_EQ
);
6658 if (Args
.hasFlag(options::OPT_fopenmp_optimistic_collapse
,
6659 options::OPT_fno_openmp_optimistic_collapse
,
6661 CmdArgs
.push_back("-fopenmp-optimistic-collapse");
6663 // When in OpenMP offloading mode with NVPTX target, forward
6665 if (Args
.hasFlag(options::OPT_fopenmp_cuda_mode
,
6666 options::OPT_fno_openmp_cuda_mode
, /*Default=*/false))
6667 CmdArgs
.push_back("-fopenmp-cuda-mode");
6669 // When in OpenMP offloading mode, enable debugging on the device.
6670 Args
.AddAllArgs(CmdArgs
, options::OPT_fopenmp_target_debug_EQ
);
6671 if (Args
.hasFlag(options::OPT_fopenmp_target_debug
,
6672 options::OPT_fno_openmp_target_debug
, /*Default=*/false))
6673 CmdArgs
.push_back("-fopenmp-target-debug");
6675 // When in OpenMP offloading mode, forward assumptions information about
6676 // thread and team counts in the device.
6677 if (Args
.hasFlag(options::OPT_fopenmp_assume_teams_oversubscription
,
6678 options::OPT_fno_openmp_assume_teams_oversubscription
,
6680 CmdArgs
.push_back("-fopenmp-assume-teams-oversubscription");
6681 if (Args
.hasFlag(options::OPT_fopenmp_assume_threads_oversubscription
,
6682 options::OPT_fno_openmp_assume_threads_oversubscription
,
6684 CmdArgs
.push_back("-fopenmp-assume-threads-oversubscription");
6685 if (Args
.hasArg(options::OPT_fopenmp_assume_no_thread_state
))
6686 CmdArgs
.push_back("-fopenmp-assume-no-thread-state");
6687 if (Args
.hasArg(options::OPT_fopenmp_assume_no_nested_parallelism
))
6688 CmdArgs
.push_back("-fopenmp-assume-no-nested-parallelism");
6689 if (Args
.hasArg(options::OPT_fopenmp_offload_mandatory
))
6690 CmdArgs
.push_back("-fopenmp-offload-mandatory");
6691 if (Args
.hasArg(options::OPT_fopenmp_force_usm
))
6692 CmdArgs
.push_back("-fopenmp-force-usm");
6695 // By default, if Clang doesn't know how to generate useful OpenMP code
6696 // for a specific runtime library, we just don't pass the '-fopenmp' flag
6697 // down to the actual compilation.
6698 // FIXME: It would be better to have a mode which *only* omits IR
6699 // generation based on the OpenMP support so that we get consistent
6700 // semantic analysis, etc.
6704 Args
.AddLastArg(CmdArgs
, options::OPT_fopenmp_simd
,
6705 options::OPT_fno_openmp_simd
);
6706 Args
.AddAllArgs(CmdArgs
, options::OPT_fopenmp_version_EQ
);
6707 Args
.addOptOutFlag(CmdArgs
, options::OPT_fopenmp_extensions
,
6708 options::OPT_fno_openmp_extensions
);
6711 // Forward the new driver to change offloading code generation.
6712 if (Args
.hasFlag(options::OPT_offload_new_driver
,
6713 options::OPT_no_offload_new_driver
, false))
6714 CmdArgs
.push_back("--offload-new-driver");
6716 SanitizeArgs
.addArgs(TC
, Args
, CmdArgs
, InputType
);
6718 const XRayArgs
&XRay
= TC
.getXRayArgs();
6719 XRay
.addArgs(TC
, Args
, CmdArgs
, InputType
);
6721 for (const auto &Filename
:
6722 Args
.getAllArgValues(options::OPT_fprofile_list_EQ
)) {
6723 if (D
.getVFS().exists(Filename
))
6724 CmdArgs
.push_back(Args
.MakeArgString("-fprofile-list=" + Filename
));
6726 D
.Diag(clang::diag::err_drv_no_such_file
) << Filename
;
6729 if (Arg
*A
= Args
.getLastArg(options::OPT_fpatchable_function_entry_EQ
)) {
6730 StringRef S0
= A
->getValue(), S
= S0
;
6731 unsigned Size
, Offset
= 0;
6732 if (!Triple
.isAArch64() && !Triple
.isLoongArch() && !Triple
.isRISCV() &&
6734 !(!Triple
.isOSAIX() && (Triple
.getArch() == llvm::Triple::ppc
||
6735 Triple
.getArch() == llvm::Triple::ppc64
)))
6736 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
6737 << A
->getAsString(Args
) << TripleStr
;
6738 else if (S
.consumeInteger(10, Size
) ||
6739 (!S
.empty() && (!S
.consume_front(",") ||
6740 S
.consumeInteger(10, Offset
) || !S
.empty())))
6741 D
.Diag(diag::err_drv_invalid_argument_to_option
)
6742 << S0
<< A
->getOption().getName();
6743 else if (Size
< Offset
)
6744 D
.Diag(diag::err_drv_unsupported_fpatchable_function_entry_argument
);
6746 CmdArgs
.push_back(Args
.MakeArgString(A
->getSpelling() + Twine(Size
)));
6747 CmdArgs
.push_back(Args
.MakeArgString(
6748 "-fpatchable-function-entry-offset=" + Twine(Offset
)));
6752 Args
.AddLastArg(CmdArgs
, options::OPT_fms_hotpatch
);
6754 if (TC
.SupportsProfiling()) {
6755 Args
.AddLastArg(CmdArgs
, options::OPT_pg
);
6757 llvm::Triple::ArchType Arch
= TC
.getArch();
6758 if (Arg
*A
= Args
.getLastArg(options::OPT_mfentry
)) {
6759 if (Arch
== llvm::Triple::systemz
|| TC
.getTriple().isX86())
6760 A
->render(Args
, CmdArgs
);
6762 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
6763 << A
->getAsString(Args
) << TripleStr
;
6765 if (Arg
*A
= Args
.getLastArg(options::OPT_mnop_mcount
)) {
6766 if (Arch
== llvm::Triple::systemz
)
6767 A
->render(Args
, CmdArgs
);
6769 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
6770 << A
->getAsString(Args
) << TripleStr
;
6772 if (Arg
*A
= Args
.getLastArg(options::OPT_mrecord_mcount
)) {
6773 if (Arch
== llvm::Triple::systemz
)
6774 A
->render(Args
, CmdArgs
);
6776 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
6777 << A
->getAsString(Args
) << TripleStr
;
6781 if (Arg
*A
= Args
.getLastArgNoClaim(options::OPT_pg
)) {
6782 if (TC
.getTriple().isOSzOS()) {
6783 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
6784 << A
->getAsString(Args
) << TripleStr
;
6787 if (Arg
*A
= Args
.getLastArgNoClaim(options::OPT_p
)) {
6788 if (!(TC
.getTriple().isOSAIX() || TC
.getTriple().isOSOpenBSD())) {
6789 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
6790 << A
->getAsString(Args
) << TripleStr
;
6793 if (Arg
*A
= Args
.getLastArgNoClaim(options::OPT_p
, options::OPT_pg
)) {
6794 if (A
->getOption().matches(options::OPT_p
)) {
6796 if (TC
.getTriple().isOSAIX() && !Args
.hasArgNoClaim(options::OPT_pg
))
6797 CmdArgs
.push_back("-pg");
6801 // Reject AIX-specific link options on other targets.
6802 if (!TC
.getTriple().isOSAIX()) {
6803 for (const Arg
*A
: Args
.filtered(options::OPT_b
, options::OPT_K
,
6804 options::OPT_mxcoff_build_id_EQ
)) {
6805 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
6806 << A
->getSpelling() << TripleStr
;
6810 if (Args
.getLastArg(options::OPT_fapple_kext
) ||
6811 (Args
.hasArg(options::OPT_mkernel
) && types::isCXX(InputType
)))
6812 CmdArgs
.push_back("-fapple-kext");
6814 Args
.AddLastArg(CmdArgs
, options::OPT_altivec_src_compat
);
6815 Args
.AddLastArg(CmdArgs
, options::OPT_flax_vector_conversions_EQ
);
6816 Args
.AddLastArg(CmdArgs
, options::OPT_fobjc_sender_dependent_dispatch
);
6817 Args
.AddLastArg(CmdArgs
, options::OPT_fdiagnostics_print_source_range_info
);
6818 Args
.AddLastArg(CmdArgs
, options::OPT_fdiagnostics_parseable_fixits
);
6819 Args
.AddLastArg(CmdArgs
, options::OPT_ftime_report
);
6820 Args
.AddLastArg(CmdArgs
, options::OPT_ftime_report_EQ
);
6821 Args
.AddLastArg(CmdArgs
, options::OPT_ftrapv
);
6822 Args
.AddLastArg(CmdArgs
, options::OPT_malign_double
);
6823 Args
.AddLastArg(CmdArgs
, options::OPT_fno_temp_file
);
6825 if (const char *Name
= C
.getTimeTraceFile(&JA
)) {
6826 CmdArgs
.push_back(Args
.MakeArgString("-ftime-trace=" + Twine(Name
)));
6827 Args
.AddLastArg(CmdArgs
, options::OPT_ftime_trace_granularity_EQ
);
6828 Args
.AddLastArg(CmdArgs
, options::OPT_ftime_trace_verbose
);
6831 if (Arg
*A
= Args
.getLastArg(options::OPT_ftrapv_handler_EQ
)) {
6832 CmdArgs
.push_back("-ftrapv-handler");
6833 CmdArgs
.push_back(A
->getValue());
6836 Args
.AddLastArg(CmdArgs
, options::OPT_ftrap_function_EQ
);
6838 // -fno-strict-overflow implies -fwrapv if it isn't disabled, but
6839 // -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
6840 if (Arg
*A
= Args
.getLastArg(options::OPT_fwrapv
, options::OPT_fno_wrapv
)) {
6841 if (A
->getOption().matches(options::OPT_fwrapv
))
6842 CmdArgs
.push_back("-fwrapv");
6843 } else if (Arg
*A
= Args
.getLastArg(options::OPT_fstrict_overflow
,
6844 options::OPT_fno_strict_overflow
)) {
6845 if (A
->getOption().matches(options::OPT_fno_strict_overflow
))
6846 CmdArgs
.push_back("-fwrapv");
6849 Args
.AddLastArg(CmdArgs
, options::OPT_ffinite_loops
,
6850 options::OPT_fno_finite_loops
);
6852 Args
.AddLastArg(CmdArgs
, options::OPT_fwritable_strings
);
6853 Args
.AddLastArg(CmdArgs
, options::OPT_funroll_loops
,
6854 options::OPT_fno_unroll_loops
);
6856 Args
.AddLastArg(CmdArgs
, options::OPT_fstrict_flex_arrays_EQ
);
6858 Args
.AddLastArg(CmdArgs
, options::OPT_pthread
);
6860 Args
.addOptInFlag(CmdArgs
, options::OPT_mspeculative_load_hardening
,
6861 options::OPT_mno_speculative_load_hardening
);
6863 RenderSSPOptions(D
, TC
, Args
, CmdArgs
, KernelOrKext
);
6864 RenderSCPOptions(TC
, Args
, CmdArgs
);
6865 RenderTrivialAutoVarInitOptions(D
, TC
, Args
, CmdArgs
);
6867 Args
.AddLastArg(CmdArgs
, options::OPT_fswift_async_fp_EQ
);
6869 Args
.addOptInFlag(CmdArgs
, options::OPT_mstackrealign
,
6870 options::OPT_mno_stackrealign
);
6872 if (Args
.hasArg(options::OPT_mstack_alignment
)) {
6873 StringRef alignment
= Args
.getLastArgValue(options::OPT_mstack_alignment
);
6874 CmdArgs
.push_back(Args
.MakeArgString("-mstack-alignment=" + alignment
));
6877 if (Args
.hasArg(options::OPT_mstack_probe_size
)) {
6878 StringRef Size
= Args
.getLastArgValue(options::OPT_mstack_probe_size
);
6881 CmdArgs
.push_back(Args
.MakeArgString("-mstack-probe-size=" + Size
));
6883 CmdArgs
.push_back("-mstack-probe-size=0");
6886 Args
.addOptOutFlag(CmdArgs
, options::OPT_mstack_arg_probe
,
6887 options::OPT_mno_stack_arg_probe
);
6889 if (Arg
*A
= Args
.getLastArg(options::OPT_mrestrict_it
,
6890 options::OPT_mno_restrict_it
)) {
6891 if (A
->getOption().matches(options::OPT_mrestrict_it
)) {
6892 CmdArgs
.push_back("-mllvm");
6893 CmdArgs
.push_back("-arm-restrict-it");
6895 CmdArgs
.push_back("-mllvm");
6896 CmdArgs
.push_back("-arm-default-it");
6900 // Forward -cl options to -cc1
6901 RenderOpenCLOptions(Args
, CmdArgs
, InputType
);
6903 // Forward hlsl options to -cc1
6904 RenderHLSLOptions(Args
, CmdArgs
, InputType
);
6906 // Forward OpenACC options to -cc1
6907 RenderOpenACCOptions(D
, Args
, CmdArgs
, InputType
);
6910 if (Args
.hasFlag(options::OPT_fhip_new_launch_api
,
6911 options::OPT_fno_hip_new_launch_api
, true))
6912 CmdArgs
.push_back("-fhip-new-launch-api");
6913 Args
.addOptInFlag(CmdArgs
, options::OPT_fgpu_allow_device_init
,
6914 options::OPT_fno_gpu_allow_device_init
);
6915 Args
.AddLastArg(CmdArgs
, options::OPT_hipstdpar
);
6916 Args
.AddLastArg(CmdArgs
, options::OPT_hipstdpar_interpose_alloc
);
6917 Args
.addOptInFlag(CmdArgs
, options::OPT_fhip_kernel_arg_name
,
6918 options::OPT_fno_hip_kernel_arg_name
);
6921 if (IsCuda
|| IsHIP
) {
6923 CmdArgs
.push_back("-fgpu-rdc");
6924 Args
.addOptInFlag(CmdArgs
, options::OPT_fgpu_defer_diag
,
6925 options::OPT_fno_gpu_defer_diag
);
6926 if (Args
.hasFlag(options::OPT_fgpu_exclude_wrong_side_overloads
,
6927 options::OPT_fno_gpu_exclude_wrong_side_overloads
,
6929 CmdArgs
.push_back("-fgpu-exclude-wrong-side-overloads");
6930 CmdArgs
.push_back("-fgpu-defer-diag");
6934 // Forward -nogpulib to -cc1.
6935 if (Args
.hasArg(options::OPT_nogpulib
))
6936 CmdArgs
.push_back("-nogpulib");
6938 if (Arg
*A
= Args
.getLastArg(options::OPT_fcf_protection_EQ
)) {
6940 Args
.MakeArgString(Twine("-fcf-protection=") + A
->getValue()));
6943 if (Arg
*A
= Args
.getLastArg(options::OPT_mfunction_return_EQ
))
6945 Args
.MakeArgString(Twine("-mfunction-return=") + A
->getValue()));
6947 Args
.AddLastArg(CmdArgs
, options::OPT_mindirect_branch_cs_prefix
);
6949 // Forward -f options with positive and negative forms; we translate these by
6950 // hand. Do not propagate PGO options to the GPU-side compilations as the
6951 // profile info is for the host-side compilation only.
6952 if (!(IsCudaDevice
|| IsHIPDevice
)) {
6953 if (Arg
*A
= getLastProfileSampleUseArg(Args
)) {
6954 auto *PGOArg
= Args
.getLastArg(
6955 options::OPT_fprofile_generate
, options::OPT_fprofile_generate_EQ
,
6956 options::OPT_fcs_profile_generate
,
6957 options::OPT_fcs_profile_generate_EQ
, options::OPT_fprofile_use
,
6958 options::OPT_fprofile_use_EQ
);
6960 D
.Diag(diag::err_drv_argument_not_allowed_with
)
6961 << "SampleUse with PGO options";
6963 StringRef fname
= A
->getValue();
6964 if (!llvm::sys::fs::exists(fname
))
6965 D
.Diag(diag::err_drv_no_such_file
) << fname
;
6967 A
->render(Args
, CmdArgs
);
6969 Args
.AddLastArg(CmdArgs
, options::OPT_fprofile_remapping_file_EQ
);
6971 if (Args
.hasFlag(options::OPT_fpseudo_probe_for_profiling
,
6972 options::OPT_fno_pseudo_probe_for_profiling
, false)) {
6973 CmdArgs
.push_back("-fpseudo-probe-for-profiling");
6974 // Enforce -funique-internal-linkage-names if it's not explicitly turned
6976 if (Args
.hasFlag(options::OPT_funique_internal_linkage_names
,
6977 options::OPT_fno_unique_internal_linkage_names
, true))
6978 CmdArgs
.push_back("-funique-internal-linkage-names");
6981 RenderBuiltinOptions(TC
, RawTriple
, Args
, CmdArgs
);
6983 Args
.addOptOutFlag(CmdArgs
, options::OPT_fassume_sane_operator_new
,
6984 options::OPT_fno_assume_sane_operator_new
);
6986 if (Args
.hasFlag(options::OPT_fapinotes
, options::OPT_fno_apinotes
, false))
6987 CmdArgs
.push_back("-fapinotes");
6988 if (Args
.hasFlag(options::OPT_fapinotes_modules
,
6989 options::OPT_fno_apinotes_modules
, false))
6990 CmdArgs
.push_back("-fapinotes-modules");
6991 Args
.AddLastArg(CmdArgs
, options::OPT_fapinotes_swift_version
);
6993 // -fblocks=0 is default.
6994 if (Args
.hasFlag(options::OPT_fblocks
, options::OPT_fno_blocks
,
6995 TC
.IsBlocksDefault()) ||
6996 (Args
.hasArg(options::OPT_fgnu_runtime
) &&
6997 Args
.hasArg(options::OPT_fobjc_nonfragile_abi
) &&
6998 !Args
.hasArg(options::OPT_fno_blocks
))) {
6999 CmdArgs
.push_back("-fblocks");
7001 if (!Args
.hasArg(options::OPT_fgnu_runtime
) && !TC
.hasBlocksRuntime())
7002 CmdArgs
.push_back("-fblocks-runtime-optional");
7005 // -fencode-extended-block-signature=1 is default.
7006 if (TC
.IsEncodeExtendedBlockSignatureDefault())
7007 CmdArgs
.push_back("-fencode-extended-block-signature");
7009 if (Args
.hasFlag(options::OPT_fcoro_aligned_allocation
,
7010 options::OPT_fno_coro_aligned_allocation
, false) &&
7011 types::isCXX(InputType
))
7012 CmdArgs
.push_back("-fcoro-aligned-allocation");
7014 Args
.AddLastArg(CmdArgs
, options::OPT_fdouble_square_bracket_attributes
,
7015 options::OPT_fno_double_square_bracket_attributes
);
7017 Args
.addOptOutFlag(CmdArgs
, options::OPT_faccess_control
,
7018 options::OPT_fno_access_control
);
7019 Args
.addOptOutFlag(CmdArgs
, options::OPT_felide_constructors
,
7020 options::OPT_fno_elide_constructors
);
7022 ToolChain::RTTIMode RTTIMode
= TC
.getRTTIMode();
7024 if (KernelOrKext
|| (types::isCXX(InputType
) &&
7025 (RTTIMode
== ToolChain::RM_Disabled
)))
7026 CmdArgs
.push_back("-fno-rtti");
7028 // -fshort-enums=0 is default for all architectures except Hexagon and z/OS.
7029 if (Args
.hasFlag(options::OPT_fshort_enums
, options::OPT_fno_short_enums
,
7030 TC
.getArch() == llvm::Triple::hexagon
|| Triple
.isOSzOS()))
7031 CmdArgs
.push_back("-fshort-enums");
7033 RenderCharacterOptions(Args
, AuxTriple
? *AuxTriple
: RawTriple
, CmdArgs
);
7035 // -fuse-cxa-atexit is default.
7037 options::OPT_fuse_cxa_atexit
, options::OPT_fno_use_cxa_atexit
,
7038 !RawTriple
.isOSAIX() && !RawTriple
.isOSWindows() &&
7039 ((RawTriple
.getVendor() != llvm::Triple::MipsTechnologies
) ||
7040 RawTriple
.hasEnvironment())) ||
7042 CmdArgs
.push_back("-fno-use-cxa-atexit");
7044 if (Args
.hasFlag(options::OPT_fregister_global_dtors_with_atexit
,
7045 options::OPT_fno_register_global_dtors_with_atexit
,
7046 RawTriple
.isOSDarwin() && !KernelOrKext
))
7047 CmdArgs
.push_back("-fregister-global-dtors-with-atexit");
7049 Args
.addOptInFlag(CmdArgs
, options::OPT_fuse_line_directives
,
7050 options::OPT_fno_use_line_directives
);
7052 // -fno-minimize-whitespace is default.
7053 if (Args
.hasFlag(options::OPT_fminimize_whitespace
,
7054 options::OPT_fno_minimize_whitespace
, false)) {
7055 types::ID InputType
= Inputs
[0].getType();
7056 if (!isDerivedFromC(InputType
))
7057 D
.Diag(diag::err_drv_opt_unsupported_input_type
)
7058 << "-fminimize-whitespace" << types::getTypeName(InputType
);
7059 CmdArgs
.push_back("-fminimize-whitespace");
7062 // -fno-keep-system-includes is default.
7063 if (Args
.hasFlag(options::OPT_fkeep_system_includes
,
7064 options::OPT_fno_keep_system_includes
, false)) {
7065 types::ID InputType
= Inputs
[0].getType();
7066 if (!isDerivedFromC(InputType
))
7067 D
.Diag(diag::err_drv_opt_unsupported_input_type
)
7068 << "-fkeep-system-includes" << types::getTypeName(InputType
);
7069 CmdArgs
.push_back("-fkeep-system-includes");
7072 // -fms-extensions=0 is default.
7073 if (Args
.hasFlag(options::OPT_fms_extensions
, options::OPT_fno_ms_extensions
,
7075 CmdArgs
.push_back("-fms-extensions");
7077 // -fms-compatibility=0 is default.
7078 bool IsMSVCCompat
= Args
.hasFlag(
7079 options::OPT_fms_compatibility
, options::OPT_fno_ms_compatibility
,
7080 (IsWindowsMSVC
&& Args
.hasFlag(options::OPT_fms_extensions
,
7081 options::OPT_fno_ms_extensions
, true)));
7083 CmdArgs
.push_back("-fms-compatibility");
7084 if (!types::isCXX(Input
.getType()) &&
7085 Args
.hasArg(options::OPT_fms_define_stdc
))
7086 CmdArgs
.push_back("-fms-define-stdc");
7089 if (Triple
.isWindowsMSVCEnvironment() && !D
.IsCLMode() &&
7090 Args
.hasArg(options::OPT_fms_runtime_lib_EQ
))
7091 ProcessVSRuntimeLibrary(getToolChain(), Args
, CmdArgs
);
7093 // Handle -fgcc-version, if present.
7094 VersionTuple GNUCVer
;
7095 if (Arg
*A
= Args
.getLastArg(options::OPT_fgnuc_version_EQ
)) {
7096 // Check that the version has 1 to 3 components and the minor and patch
7097 // versions fit in two decimal digits.
7098 StringRef Val
= A
->getValue();
7099 Val
= Val
.empty() ? "0" : Val
; // Treat "" as 0 or disable.
7100 bool Invalid
= GNUCVer
.tryParse(Val
);
7101 unsigned Minor
= GNUCVer
.getMinor().value_or(0);
7102 unsigned Patch
= GNUCVer
.getSubminor().value_or(0);
7103 if (Invalid
|| GNUCVer
.getBuild() || Minor
>= 100 || Patch
>= 100) {
7104 D
.Diag(diag::err_drv_invalid_value
)
7105 << A
->getAsString(Args
) << A
->getValue();
7107 } else if (!IsMSVCCompat
) {
7108 // Imitate GCC 4.2.1 by default if -fms-compatibility is not in effect.
7109 GNUCVer
= VersionTuple(4, 2, 1);
7111 if (!GNUCVer
.empty()) {
7113 Args
.MakeArgString("-fgnuc-version=" + GNUCVer
.getAsString()));
7116 VersionTuple MSVT
= TC
.computeMSVCVersion(&D
, Args
);
7119 Args
.MakeArgString("-fms-compatibility-version=" + MSVT
.getAsString()));
7121 bool IsMSVC2015Compatible
= MSVT
.getMajor() >= 19;
7122 if (ImplyVCPPCVer
) {
7123 StringRef LanguageStandard
;
7124 if (const Arg
*StdArg
= Args
.getLastArg(options::OPT__SLASH_std
)) {
7126 LanguageStandard
= llvm::StringSwitch
<StringRef
>(StdArg
->getValue())
7127 .Case("c11", "-std=c11")
7128 .Case("c17", "-std=c17")
7130 if (LanguageStandard
.empty())
7131 D
.Diag(clang::diag::warn_drv_unused_argument
)
7132 << StdArg
->getAsString(Args
);
7134 CmdArgs
.push_back(LanguageStandard
.data());
7136 if (ImplyVCPPCXXVer
) {
7137 StringRef LanguageStandard
;
7138 if (const Arg
*StdArg
= Args
.getLastArg(options::OPT__SLASH_std
)) {
7140 LanguageStandard
= llvm::StringSwitch
<StringRef
>(StdArg
->getValue())
7141 .Case("c++14", "-std=c++14")
7142 .Case("c++17", "-std=c++17")
7143 .Case("c++20", "-std=c++20")
7144 // TODO add c++23 and c++26 when MSVC supports it.
7145 .Case("c++latest", "-std=c++26")
7147 if (LanguageStandard
.empty())
7148 D
.Diag(clang::diag::warn_drv_unused_argument
)
7149 << StdArg
->getAsString(Args
);
7152 if (LanguageStandard
.empty()) {
7153 if (IsMSVC2015Compatible
)
7154 LanguageStandard
= "-std=c++14";
7156 LanguageStandard
= "-std=c++11";
7159 CmdArgs
.push_back(LanguageStandard
.data());
7162 Args
.addOptInFlag(CmdArgs
, options::OPT_fborland_extensions
,
7163 options::OPT_fno_borland_extensions
);
7165 // -fno-declspec is default, except for PS4/PS5.
7166 if (Args
.hasFlag(options::OPT_fdeclspec
, options::OPT_fno_declspec
,
7168 CmdArgs
.push_back("-fdeclspec");
7169 else if (Args
.hasArg(options::OPT_fno_declspec
))
7170 CmdArgs
.push_back("-fno-declspec"); // Explicitly disabling __declspec.
7172 // -fthreadsafe-static is default, except for MSVC compatibility versions less
7174 if (!Args
.hasFlag(options::OPT_fthreadsafe_statics
,
7175 options::OPT_fno_threadsafe_statics
,
7176 !types::isOpenCL(InputType
) &&
7177 (!IsWindowsMSVC
|| IsMSVC2015Compatible
)))
7178 CmdArgs
.push_back("-fno-threadsafe-statics");
7180 // Add -fno-assumptions, if it was specified.
7181 if (!Args
.hasFlag(options::OPT_fassumptions
, options::OPT_fno_assumptions
,
7183 CmdArgs
.push_back("-fno-assumptions");
7185 // -fgnu-keywords default varies depending on language; only pass if
7187 Args
.AddLastArg(CmdArgs
, options::OPT_fgnu_keywords
,
7188 options::OPT_fno_gnu_keywords
);
7190 Args
.addOptInFlag(CmdArgs
, options::OPT_fgnu89_inline
,
7191 options::OPT_fno_gnu89_inline
);
7193 const Arg
*InlineArg
= Args
.getLastArg(options::OPT_finline_functions
,
7194 options::OPT_finline_hint_functions
,
7195 options::OPT_fno_inline_functions
);
7196 if (Arg
*A
= Args
.getLastArg(options::OPT_finline
, options::OPT_fno_inline
)) {
7197 if (A
->getOption().matches(options::OPT_fno_inline
))
7198 A
->render(Args
, CmdArgs
);
7199 } else if (InlineArg
) {
7200 InlineArg
->render(Args
, CmdArgs
);
7203 Args
.AddLastArg(CmdArgs
, options::OPT_finline_max_stacksize_EQ
);
7205 // FIXME: Find a better way to determine whether we are in C++20.
7208 (Std
->containsValue("c++2a") || Std
->containsValue("gnu++2a") ||
7209 Std
->containsValue("c++20") || Std
->containsValue("gnu++20") ||
7210 Std
->containsValue("c++2b") || Std
->containsValue("gnu++2b") ||
7211 Std
->containsValue("c++23") || Std
->containsValue("gnu++23") ||
7212 Std
->containsValue("c++2c") || Std
->containsValue("gnu++2c") ||
7213 Std
->containsValue("c++26") || Std
->containsValue("gnu++26") ||
7214 Std
->containsValue("c++latest") || Std
->containsValue("gnu++latest"));
7216 RenderModulesOptions(C
, D
, Args
, Input
, Output
, HaveCxx20
, CmdArgs
);
7218 // -fdelayed-template-parsing is default when targeting MSVC.
7219 // Many old Windows SDK versions require this to parse.
7222 // https://learn.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=msvc-170,
7223 // MSVC actually defaults to -fno-delayed-template-parsing (/Zc:twoPhase-
7224 // with MSVC CLI) if using C++20. So we match the behavior with MSVC here to
7225 // not enable -fdelayed-template-parsing by default after C++20.
7227 // FIXME: Given -fdelayed-template-parsing is a source of bugs, we should be
7228 // able to disable this by default at some point.
7229 if (Args
.hasFlag(options::OPT_fdelayed_template_parsing
,
7230 options::OPT_fno_delayed_template_parsing
,
7231 IsWindowsMSVC
&& !HaveCxx20
)) {
7233 D
.Diag(clang::diag::warn_drv_delayed_template_parsing_after_cxx20
);
7235 CmdArgs
.push_back("-fdelayed-template-parsing");
7238 if (Args
.hasFlag(options::OPT_fpch_validate_input_files_content
,
7239 options::OPT_fno_pch_validate_input_files_content
, false))
7240 CmdArgs
.push_back("-fvalidate-ast-input-files-content");
7241 if (Args
.hasFlag(options::OPT_fpch_instantiate_templates
,
7242 options::OPT_fno_pch_instantiate_templates
, false))
7243 CmdArgs
.push_back("-fpch-instantiate-templates");
7244 if (Args
.hasFlag(options::OPT_fpch_codegen
, options::OPT_fno_pch_codegen
,
7246 CmdArgs
.push_back("-fmodules-codegen");
7247 if (Args
.hasFlag(options::OPT_fpch_debuginfo
, options::OPT_fno_pch_debuginfo
,
7249 CmdArgs
.push_back("-fmodules-debuginfo");
7251 ObjCRuntime Runtime
= AddObjCRuntimeArgs(Args
, Inputs
, CmdArgs
, rewriteKind
);
7252 RenderObjCOptions(TC
, D
, RawTriple
, Args
, Runtime
, rewriteKind
!= RK_None
,
7255 if (types::isObjC(Input
.getType()) &&
7256 Args
.hasFlag(options::OPT_fobjc_encode_cxx_class_template_spec
,
7257 options::OPT_fno_objc_encode_cxx_class_template_spec
,
7258 !Runtime
.isNeXTFamily()))
7259 CmdArgs
.push_back("-fobjc-encode-cxx-class-template-spec");
7261 if (Args
.hasFlag(options::OPT_fapplication_extension
,
7262 options::OPT_fno_application_extension
, false))
7263 CmdArgs
.push_back("-fapplication-extension");
7265 // Handle GCC-style exception args.
7267 if (!C
.getDriver().IsCLMode())
7268 EH
= addExceptionArgs(Args
, InputType
, TC
, KernelOrKext
, Runtime
, CmdArgs
);
7270 // Handle exception personalities
7271 Arg
*A
= Args
.getLastArg(
7272 options::OPT_fsjlj_exceptions
, options::OPT_fseh_exceptions
,
7273 options::OPT_fdwarf_exceptions
, options::OPT_fwasm_exceptions
);
7275 const Option
&Opt
= A
->getOption();
7276 if (Opt
.matches(options::OPT_fsjlj_exceptions
))
7277 CmdArgs
.push_back("-exception-model=sjlj");
7278 if (Opt
.matches(options::OPT_fseh_exceptions
))
7279 CmdArgs
.push_back("-exception-model=seh");
7280 if (Opt
.matches(options::OPT_fdwarf_exceptions
))
7281 CmdArgs
.push_back("-exception-model=dwarf");
7282 if (Opt
.matches(options::OPT_fwasm_exceptions
))
7283 CmdArgs
.push_back("-exception-model=wasm");
7285 switch (TC
.GetExceptionModel(Args
)) {
7288 case llvm::ExceptionHandling::DwarfCFI
:
7289 CmdArgs
.push_back("-exception-model=dwarf");
7291 case llvm::ExceptionHandling::SjLj
:
7292 CmdArgs
.push_back("-exception-model=sjlj");
7294 case llvm::ExceptionHandling::WinEH
:
7295 CmdArgs
.push_back("-exception-model=seh");
7300 // C++ "sane" operator new.
7301 Args
.addOptOutFlag(CmdArgs
, options::OPT_fassume_sane_operator_new
,
7302 options::OPT_fno_assume_sane_operator_new
);
7304 // -fassume-unique-vtables is on by default.
7305 Args
.addOptOutFlag(CmdArgs
, options::OPT_fassume_unique_vtables
,
7306 options::OPT_fno_assume_unique_vtables
);
7308 // -frelaxed-template-template-args is deprecated.
7310 Args
.getLastArg(options::OPT_frelaxed_template_template_args
,
7311 options::OPT_fno_relaxed_template_template_args
)) {
7312 if (A
->getOption().matches(
7313 options::OPT_fno_relaxed_template_template_args
)) {
7314 D
.Diag(diag::warn_drv_deprecated_arg_no_relaxed_template_template_args
);
7315 CmdArgs
.push_back("-fno-relaxed-template-template-args");
7317 D
.Diag(diag::warn_drv_deprecated_arg
)
7318 << A
->getAsString(Args
) << /*hasReplacement=*/false;
7322 // -fsized-deallocation is on by default in C++14 onwards and otherwise off
7324 Args
.addLastArg(CmdArgs
, options::OPT_fsized_deallocation
,
7325 options::OPT_fno_sized_deallocation
);
7327 // -faligned-allocation is on by default in C++17 onwards and otherwise off
7329 if (Arg
*A
= Args
.getLastArg(options::OPT_faligned_allocation
,
7330 options::OPT_fno_aligned_allocation
,
7331 options::OPT_faligned_new_EQ
)) {
7332 if (A
->getOption().matches(options::OPT_fno_aligned_allocation
))
7333 CmdArgs
.push_back("-fno-aligned-allocation");
7335 CmdArgs
.push_back("-faligned-allocation");
7338 // The default new alignment can be specified using a dedicated option or via
7339 // a GCC-compatible option that also turns on aligned allocation.
7340 if (Arg
*A
= Args
.getLastArg(options::OPT_fnew_alignment_EQ
,
7341 options::OPT_faligned_new_EQ
))
7343 Args
.MakeArgString(Twine("-fnew-alignment=") + A
->getValue()));
7345 // -fconstant-cfstrings is default, and may be subject to argument translation
7347 if (!Args
.hasFlag(options::OPT_fconstant_cfstrings
,
7348 options::OPT_fno_constant_cfstrings
, true) ||
7349 !Args
.hasFlag(options::OPT_mconstant_cfstrings
,
7350 options::OPT_mno_constant_cfstrings
, true))
7351 CmdArgs
.push_back("-fno-constant-cfstrings");
7353 Args
.addOptInFlag(CmdArgs
, options::OPT_fpascal_strings
,
7354 options::OPT_fno_pascal_strings
);
7356 // Honor -fpack-struct= and -fpack-struct, if given. Note that
7357 // -fno-pack-struct doesn't apply to -fpack-struct=.
7358 if (Arg
*A
= Args
.getLastArg(options::OPT_fpack_struct_EQ
)) {
7359 std::string PackStructStr
= "-fpack-struct=";
7360 PackStructStr
+= A
->getValue();
7361 CmdArgs
.push_back(Args
.MakeArgString(PackStructStr
));
7362 } else if (Args
.hasFlag(options::OPT_fpack_struct
,
7363 options::OPT_fno_pack_struct
, false)) {
7364 CmdArgs
.push_back("-fpack-struct=1");
7367 // Handle -fmax-type-align=N and -fno-type-align
7368 bool SkipMaxTypeAlign
= Args
.hasArg(options::OPT_fno_max_type_align
);
7369 if (Arg
*A
= Args
.getLastArg(options::OPT_fmax_type_align_EQ
)) {
7370 if (!SkipMaxTypeAlign
) {
7371 std::string MaxTypeAlignStr
= "-fmax-type-align=";
7372 MaxTypeAlignStr
+= A
->getValue();
7373 CmdArgs
.push_back(Args
.MakeArgString(MaxTypeAlignStr
));
7375 } else if (RawTriple
.isOSDarwin()) {
7376 if (!SkipMaxTypeAlign
) {
7377 std::string MaxTypeAlignStr
= "-fmax-type-align=16";
7378 CmdArgs
.push_back(Args
.MakeArgString(MaxTypeAlignStr
));
7382 if (!Args
.hasFlag(options::OPT_Qy
, options::OPT_Qn
, true))
7383 CmdArgs
.push_back("-Qn");
7385 // -fno-common is the default, set -fcommon only when that flag is set.
7386 Args
.addOptInFlag(CmdArgs
, options::OPT_fcommon
, options::OPT_fno_common
);
7388 // -fsigned-bitfields is default, and clang doesn't yet support
7389 // -funsigned-bitfields.
7390 if (!Args
.hasFlag(options::OPT_fsigned_bitfields
,
7391 options::OPT_funsigned_bitfields
, true))
7392 D
.Diag(diag::warn_drv_clang_unsupported
)
7393 << Args
.getLastArg(options::OPT_funsigned_bitfields
)->getAsString(Args
);
7395 // -fsigned-bitfields is default, and clang doesn't support -fno-for-scope.
7396 if (!Args
.hasFlag(options::OPT_ffor_scope
, options::OPT_fno_for_scope
, true))
7397 D
.Diag(diag::err_drv_clang_unsupported
)
7398 << Args
.getLastArg(options::OPT_fno_for_scope
)->getAsString(Args
);
7400 // -finput_charset=UTF-8 is default. Reject others
7401 if (Arg
*inputCharset
= Args
.getLastArg(options::OPT_finput_charset_EQ
)) {
7402 StringRef value
= inputCharset
->getValue();
7403 if (!value
.equals_insensitive("utf-8"))
7404 D
.Diag(diag::err_drv_invalid_value
) << inputCharset
->getAsString(Args
)
7408 // -fexec_charset=UTF-8 is default. Reject others
7409 if (Arg
*execCharset
= Args
.getLastArg(options::OPT_fexec_charset_EQ
)) {
7410 StringRef value
= execCharset
->getValue();
7411 if (!value
.equals_insensitive("utf-8"))
7412 D
.Diag(diag::err_drv_invalid_value
) << execCharset
->getAsString(Args
)
7416 RenderDiagnosticsOptions(D
, Args
, CmdArgs
);
7418 Args
.addOptInFlag(CmdArgs
, options::OPT_fasm_blocks
,
7419 options::OPT_fno_asm_blocks
);
7421 Args
.addOptOutFlag(CmdArgs
, options::OPT_fgnu_inline_asm
,
7422 options::OPT_fno_gnu_inline_asm
);
7424 // Enable vectorization per default according to the optimization level
7425 // selected. For optimization levels that want vectorization we use the alias
7426 // option to simplify the hasFlag logic.
7427 bool EnableVec
= shouldEnableVectorizerAtOLevel(Args
, false);
7428 OptSpecifier VectorizeAliasOption
=
7429 EnableVec
? options::OPT_O_Group
: options::OPT_fvectorize
;
7430 if (Args
.hasFlag(options::OPT_fvectorize
, VectorizeAliasOption
,
7431 options::OPT_fno_vectorize
, EnableVec
))
7432 CmdArgs
.push_back("-vectorize-loops");
7434 // -fslp-vectorize is enabled based on the optimization level selected.
7435 bool EnableSLPVec
= shouldEnableVectorizerAtOLevel(Args
, true);
7436 OptSpecifier SLPVectAliasOption
=
7437 EnableSLPVec
? options::OPT_O_Group
: options::OPT_fslp_vectorize
;
7438 if (Args
.hasFlag(options::OPT_fslp_vectorize
, SLPVectAliasOption
,
7439 options::OPT_fno_slp_vectorize
, EnableSLPVec
))
7440 CmdArgs
.push_back("-vectorize-slp");
7442 ParseMPreferVectorWidth(D
, Args
, CmdArgs
);
7444 Args
.AddLastArg(CmdArgs
, options::OPT_fshow_overloads_EQ
);
7445 Args
.AddLastArg(CmdArgs
,
7446 options::OPT_fsanitize_undefined_strip_path_components_EQ
);
7448 // -fdollars-in-identifiers default varies depending on platform and
7449 // language; only pass if specified.
7450 if (Arg
*A
= Args
.getLastArg(options::OPT_fdollars_in_identifiers
,
7451 options::OPT_fno_dollars_in_identifiers
)) {
7452 if (A
->getOption().matches(options::OPT_fdollars_in_identifiers
))
7453 CmdArgs
.push_back("-fdollars-in-identifiers");
7455 CmdArgs
.push_back("-fno-dollars-in-identifiers");
7458 Args
.addOptInFlag(CmdArgs
, options::OPT_fapple_pragma_pack
,
7459 options::OPT_fno_apple_pragma_pack
);
7461 // Remarks can be enabled with any of the `-f.*optimization-record.*` flags.
7462 if (willEmitRemarks(Args
) && checkRemarksOptions(D
, Args
, Triple
))
7463 renderRemarksOptions(Args
, CmdArgs
, Triple
, Input
, Output
, JA
);
7465 bool RewriteImports
= Args
.hasFlag(options::OPT_frewrite_imports
,
7466 options::OPT_fno_rewrite_imports
, false);
7468 CmdArgs
.push_back("-frewrite-imports");
7470 Args
.addOptInFlag(CmdArgs
, options::OPT_fdirectives_only
,
7471 options::OPT_fno_directives_only
);
7473 // Enable rewrite includes if the user's asked for it or if we're generating
7475 // TODO: Once -module-dependency-dir works with -frewrite-includes it'd be
7476 // nice to enable this when doing a crashdump for modules as well.
7477 if (Args
.hasFlag(options::OPT_frewrite_includes
,
7478 options::OPT_fno_rewrite_includes
, false) ||
7479 (C
.isForDiagnostics() && !HaveModules
))
7480 CmdArgs
.push_back("-frewrite-includes");
7482 // Only allow -traditional or -traditional-cpp outside in preprocessing modes.
7483 if (Arg
*A
= Args
.getLastArg(options::OPT_traditional
,
7484 options::OPT_traditional_cpp
)) {
7485 if (isa
<PreprocessJobAction
>(JA
))
7486 CmdArgs
.push_back("-traditional-cpp");
7488 D
.Diag(diag::err_drv_clang_unsupported
) << A
->getAsString(Args
);
7491 Args
.AddLastArg(CmdArgs
, options::OPT_dM
);
7492 Args
.AddLastArg(CmdArgs
, options::OPT_dD
);
7493 Args
.AddLastArg(CmdArgs
, options::OPT_dI
);
7495 Args
.AddLastArg(CmdArgs
, options::OPT_fmax_tokens_EQ
);
7497 // Handle serialized diagnostics.
7498 if (Arg
*A
= Args
.getLastArg(options::OPT__serialize_diags
)) {
7499 CmdArgs
.push_back("-serialize-diagnostic-file");
7500 CmdArgs
.push_back(Args
.MakeArgString(A
->getValue()));
7503 if (Args
.hasArg(options::OPT_fretain_comments_from_system_headers
))
7504 CmdArgs
.push_back("-fretain-comments-from-system-headers");
7506 // Forward -fcomment-block-commands to -cc1.
7507 Args
.AddAllArgs(CmdArgs
, options::OPT_fcomment_block_commands
);
7508 // Forward -fparse-all-comments to -cc1.
7509 Args
.AddAllArgs(CmdArgs
, options::OPT_fparse_all_comments
);
7511 // Turn -fplugin=name.so into -load name.so
7512 for (const Arg
*A
: Args
.filtered(options::OPT_fplugin_EQ
)) {
7513 CmdArgs
.push_back("-load");
7514 CmdArgs
.push_back(A
->getValue());
7518 // Turn -fplugin-arg-pluginname-key=value into
7519 // -plugin-arg-pluginname key=value
7520 // GCC has an actual plugin_argument struct with key/value pairs that it
7521 // passes to its plugins, but we don't, so just pass it on as-is.
7523 // The syntax for -fplugin-arg- is ambiguous if both plugin name and
7524 // argument key are allowed to contain dashes. GCC therefore only
7525 // allows dashes in the key. We do the same.
7526 for (const Arg
*A
: Args
.filtered(options::OPT_fplugin_arg
)) {
7527 auto ArgValue
= StringRef(A
->getValue());
7528 auto FirstDashIndex
= ArgValue
.find('-');
7529 StringRef PluginName
= ArgValue
.substr(0, FirstDashIndex
);
7530 StringRef Arg
= ArgValue
.substr(FirstDashIndex
+ 1);
7533 if (FirstDashIndex
== StringRef::npos
|| Arg
.empty()) {
7534 if (PluginName
.empty()) {
7535 D
.Diag(diag::warn_drv_missing_plugin_name
) << A
->getAsString(Args
);
7537 D
.Diag(diag::warn_drv_missing_plugin_arg
)
7538 << PluginName
<< A
->getAsString(Args
);
7543 CmdArgs
.push_back(Args
.MakeArgString(Twine("-plugin-arg-") + PluginName
));
7544 CmdArgs
.push_back(Args
.MakeArgString(Arg
));
7547 // Forward -fpass-plugin=name.so to -cc1.
7548 for (const Arg
*A
: Args
.filtered(options::OPT_fpass_plugin_EQ
)) {
7550 Args
.MakeArgString(Twine("-fpass-plugin=") + A
->getValue()));
7554 // Forward --vfsoverlay to -cc1.
7555 for (const Arg
*A
: Args
.filtered(options::OPT_vfsoverlay
)) {
7556 CmdArgs
.push_back("--vfsoverlay");
7557 CmdArgs
.push_back(A
->getValue());
7561 Args
.addOptInFlag(CmdArgs
, options::OPT_fsafe_buffer_usage_suggestions
,
7562 options::OPT_fno_safe_buffer_usage_suggestions
);
7564 Args
.addOptInFlag(CmdArgs
, options::OPT_fexperimental_late_parse_attributes
,
7565 options::OPT_fno_experimental_late_parse_attributes
);
7567 // Setup statistics file output.
7568 SmallString
<128> StatsFile
= getStatsFileName(Args
, Output
, Input
, D
);
7569 if (!StatsFile
.empty()) {
7570 CmdArgs
.push_back(Args
.MakeArgString(Twine("-stats-file=") + StatsFile
));
7571 if (D
.CCPrintInternalStats
)
7572 CmdArgs
.push_back("-stats-file-append");
7575 // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
7577 for (auto Arg
: Args
.filtered(options::OPT_Xclang
)) {
7579 // -finclude-default-header flag is for preprocessor,
7580 // do not pass it to other cc1 commands when save-temps is enabled
7581 if (C
.getDriver().isSaveTempsEnabled() &&
7582 !isa
<PreprocessJobAction
>(JA
)) {
7583 if (StringRef(Arg
->getValue()) == "-finclude-default-header")
7586 CmdArgs
.push_back(Arg
->getValue());
7588 for (const Arg
*A
: Args
.filtered(options::OPT_mllvm
)) {
7591 // We translate this by hand to the -cc1 argument, since nightly test uses
7592 // it and developers have been trained to spell it with -mllvm. Both
7593 // spellings are now deprecated and should be removed.
7594 if (StringRef(A
->getValue(0)) == "-disable-llvm-optzns") {
7595 CmdArgs
.push_back("-disable-llvm-optzns");
7597 A
->render(Args
, CmdArgs
);
7601 // With -save-temps, we want to save the unoptimized bitcode output from the
7602 // CompileJobAction, use -disable-llvm-passes to get pristine IR generated
7604 // When -fembed-bitcode is enabled, optimized bitcode is emitted because it
7605 // has slightly different breakdown between stages.
7606 // FIXME: -fembed-bitcode -save-temps will save optimized bitcode instead of
7607 // pristine IR generated by the frontend. Ideally, a new compile action should
7608 // be added so both IR can be captured.
7609 if ((C
.getDriver().isSaveTempsEnabled() ||
7610 JA
.isHostOffloading(Action::OFK_OpenMP
)) &&
7611 !(C
.getDriver().embedBitcodeInObject() && !IsUsingLTO
) &&
7612 isa
<CompileJobAction
>(JA
))
7613 CmdArgs
.push_back("-disable-llvm-passes");
7615 Args
.AddAllArgs(CmdArgs
, options::OPT_undef
);
7617 const char *Exec
= D
.getClangProgramPath();
7619 // Optionally embed the -cc1 level arguments into the debug info or a
7620 // section, for build analysis.
7621 // Also record command line arguments into the debug info if
7622 // -grecord-gcc-switches options is set on.
7623 // By default, -gno-record-gcc-switches is set on and no recording.
7624 auto GRecordSwitches
=
7625 Args
.hasFlag(options::OPT_grecord_command_line
,
7626 options::OPT_gno_record_command_line
, false);
7627 auto FRecordSwitches
=
7628 Args
.hasFlag(options::OPT_frecord_command_line
,
7629 options::OPT_fno_record_command_line
, false);
7630 if (FRecordSwitches
&& !Triple
.isOSBinFormatELF() &&
7631 !Triple
.isOSBinFormatXCOFF() && !Triple
.isOSBinFormatMachO())
7632 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
7633 << Args
.getLastArg(options::OPT_frecord_command_line
)->getAsString(Args
)
7635 if (TC
.UseDwarfDebugFlags() || GRecordSwitches
|| FRecordSwitches
) {
7636 ArgStringList OriginalArgs
;
7637 for (const auto &Arg
: Args
)
7638 Arg
->render(Args
, OriginalArgs
);
7640 SmallString
<256> Flags
;
7641 EscapeSpacesAndBackslashes(Exec
, Flags
);
7642 for (const char *OriginalArg
: OriginalArgs
) {
7643 SmallString
<128> EscapedArg
;
7644 EscapeSpacesAndBackslashes(OriginalArg
, EscapedArg
);
7646 Flags
+= EscapedArg
;
7648 auto FlagsArgString
= Args
.MakeArgString(Flags
);
7649 if (TC
.UseDwarfDebugFlags() || GRecordSwitches
) {
7650 CmdArgs
.push_back("-dwarf-debug-flags");
7651 CmdArgs
.push_back(FlagsArgString
);
7653 if (FRecordSwitches
) {
7654 CmdArgs
.push_back("-record-command-line");
7655 CmdArgs
.push_back(FlagsArgString
);
7659 // Host-side offloading compilation receives all device-side outputs. Include
7660 // them in the host compilation depending on the target. If the host inputs
7661 // are not empty we use the new-driver scheme, otherwise use the old scheme.
7662 if ((IsCuda
|| IsHIP
) && CudaDeviceInput
) {
7663 CmdArgs
.push_back("-fcuda-include-gpubinary");
7664 CmdArgs
.push_back(CudaDeviceInput
->getFilename());
7665 } else if (!HostOffloadingInputs
.empty()) {
7666 if ((IsCuda
|| IsHIP
) && !IsRDCMode
) {
7667 assert(HostOffloadingInputs
.size() == 1 && "Only one input expected");
7668 CmdArgs
.push_back("-fcuda-include-gpubinary");
7669 CmdArgs
.push_back(HostOffloadingInputs
.front().getFilename());
7671 for (const InputInfo Input
: HostOffloadingInputs
)
7672 CmdArgs
.push_back(Args
.MakeArgString("-fembed-offload-object=" +
7673 TC
.getInputFilename(Input
)));
7678 if (Args
.hasFlag(options::OPT_fcuda_short_ptr
,
7679 options::OPT_fno_cuda_short_ptr
, false))
7680 CmdArgs
.push_back("-fcuda-short-ptr");
7683 if (IsCuda
|| IsHIP
) {
7684 // Determine the original source input.
7685 const Action
*SourceAction
= &JA
;
7686 while (SourceAction
->getKind() != Action::InputClass
) {
7687 assert(!SourceAction
->getInputs().empty() && "unexpected root action!");
7688 SourceAction
= SourceAction
->getInputs()[0];
7690 auto CUID
= cast
<InputAction
>(SourceAction
)->getId();
7692 CmdArgs
.push_back(Args
.MakeArgString(Twine("-cuid=") + Twine(CUID
)));
7694 // -ffast-math turns on -fgpu-approx-transcendentals implicitly, but will
7695 // be overriden by -fno-gpu-approx-transcendentals.
7696 bool UseApproxTranscendentals
= Args
.hasFlag(
7697 options::OPT_ffast_math
, options::OPT_fno_fast_math
, false);
7698 if (Args
.hasFlag(options::OPT_fgpu_approx_transcendentals
,
7699 options::OPT_fno_gpu_approx_transcendentals
,
7700 UseApproxTranscendentals
))
7701 CmdArgs
.push_back("-fgpu-approx-transcendentals");
7703 Args
.claimAllArgs(options::OPT_fgpu_approx_transcendentals
,
7704 options::OPT_fno_gpu_approx_transcendentals
);
7708 CmdArgs
.push_back("-fcuda-allow-variadic-functions");
7709 Args
.AddLastArg(CmdArgs
, options::OPT_fgpu_default_stream_EQ
);
7712 Args
.AddLastArg(CmdArgs
, options::OPT_foffload_uniform_block
,
7713 options::OPT_fno_offload_uniform_block
);
7715 Args
.AddLastArg(CmdArgs
, options::OPT_foffload_implicit_host_device_templates
,
7716 options::OPT_fno_offload_implicit_host_device_templates
);
7718 if (IsCudaDevice
|| IsHIPDevice
) {
7719 StringRef InlineThresh
=
7720 Args
.getLastArgValue(options::OPT_fgpu_inline_threshold_EQ
);
7721 if (!InlineThresh
.empty()) {
7722 std::string ArgStr
=
7723 std::string("-inline-threshold=") + InlineThresh
.str();
7724 CmdArgs
.append({"-mllvm", Args
.MakeArgStringRef(ArgStr
)});
7729 Args
.addOptOutFlag(CmdArgs
,
7730 options::OPT_fhip_fp32_correctly_rounded_divide_sqrt
,
7731 options::OPT_fno_hip_fp32_correctly_rounded_divide_sqrt
);
7733 // OpenMP offloading device jobs take the argument -fopenmp-host-ir-file-path
7734 // to specify the result of the compile phase on the host, so the meaningful
7735 // device declarations can be identified. Also, -fopenmp-is-target-device is
7736 // passed along to tell the frontend that it is generating code for a device,
7737 // so that only the relevant declarations are emitted.
7738 if (IsOpenMPDevice
) {
7739 CmdArgs
.push_back("-fopenmp-is-target-device");
7740 if (OpenMPDeviceInput
) {
7741 CmdArgs
.push_back("-fopenmp-host-ir-file-path");
7742 CmdArgs
.push_back(Args
.MakeArgString(OpenMPDeviceInput
->getFilename()));
7746 if (Triple
.isAMDGPU()) {
7747 handleAMDGPUCodeObjectVersionOptions(D
, Args
, CmdArgs
);
7749 Args
.addOptInFlag(CmdArgs
, options::OPT_munsafe_fp_atomics
,
7750 options::OPT_mno_unsafe_fp_atomics
);
7751 Args
.addOptOutFlag(CmdArgs
, options::OPT_mamdgpu_ieee
,
7752 options::OPT_mno_amdgpu_ieee
);
7755 // For all the host OpenMP offloading compile jobs we need to pass the targets
7756 // information using -fopenmp-targets= option.
7757 if (JA
.isHostOffloading(Action::OFK_OpenMP
)) {
7758 SmallString
<128> Targets("-fopenmp-targets=");
7760 SmallVector
<std::string
, 4> Triples
;
7761 auto TCRange
= C
.getOffloadToolChains
<Action::OFK_OpenMP
>();
7762 std::transform(TCRange
.first
, TCRange
.second
, std::back_inserter(Triples
),
7763 [](auto TC
) { return TC
.second
->getTripleString(); });
7764 CmdArgs
.push_back(Args
.MakeArgString(Targets
+ llvm::join(Triples
, ",")));
7767 bool VirtualFunctionElimination
=
7768 Args
.hasFlag(options::OPT_fvirtual_function_elimination
,
7769 options::OPT_fno_virtual_function_elimination
, false);
7770 if (VirtualFunctionElimination
) {
7771 // VFE requires full LTO (currently, this might be relaxed to allow ThinLTO
7773 if (LTOMode
!= LTOK_Full
)
7774 D
.Diag(diag::err_drv_argument_only_allowed_with
)
7775 << "-fvirtual-function-elimination"
7778 CmdArgs
.push_back("-fvirtual-function-elimination");
7781 // VFE requires whole-program-vtables, and enables it by default.
7782 bool WholeProgramVTables
= Args
.hasFlag(
7783 options::OPT_fwhole_program_vtables
,
7784 options::OPT_fno_whole_program_vtables
, VirtualFunctionElimination
);
7785 if (VirtualFunctionElimination
&& !WholeProgramVTables
) {
7786 D
.Diag(diag::err_drv_argument_not_allowed_with
)
7787 << "-fno-whole-program-vtables"
7788 << "-fvirtual-function-elimination";
7791 if (WholeProgramVTables
) {
7792 // PS4 uses the legacy LTO API, which does not support this feature in
7794 bool IsPS4
= getToolChain().getTriple().isPS4();
7796 // Check if we passed LTO options but they were suppressed because this is a
7797 // device offloading action, or we passed device offload LTO options which
7798 // were suppressed because this is not the device offload action.
7799 // Check if we are using PS4 in regular LTO mode.
7800 // Otherwise, issue an error.
7801 if ((!IsUsingLTO
&& !D
.isUsingLTO(!IsDeviceOffloadAction
)) ||
7802 (IsPS4
&& !UnifiedLTO
&& (D
.getLTOMode() != LTOK_Full
)))
7803 D
.Diag(diag::err_drv_argument_only_allowed_with
)
7804 << "-fwhole-program-vtables"
7805 << ((IsPS4
&& !UnifiedLTO
) ? "-flto=full" : "-flto");
7807 // Propagate -fwhole-program-vtables if this is an LTO compile.
7809 CmdArgs
.push_back("-fwhole-program-vtables");
7812 bool DefaultsSplitLTOUnit
=
7813 ((WholeProgramVTables
|| SanitizeArgs
.needsLTO()) &&
7814 (LTOMode
== LTOK_Full
|| TC
.canSplitThinLTOUnit())) ||
7815 (!Triple
.isPS4() && UnifiedLTO
);
7817 Args
.hasFlag(options::OPT_fsplit_lto_unit
,
7818 options::OPT_fno_split_lto_unit
, DefaultsSplitLTOUnit
);
7819 if (SanitizeArgs
.needsLTO() && !SplitLTOUnit
)
7820 D
.Diag(diag::err_drv_argument_not_allowed_with
) << "-fno-split-lto-unit"
7821 << "-fsanitize=cfi";
7823 CmdArgs
.push_back("-fsplit-lto-unit");
7825 if (Arg
*A
= Args
.getLastArg(options::OPT_ffat_lto_objects
,
7826 options::OPT_fno_fat_lto_objects
)) {
7827 if (IsUsingLTO
&& A
->getOption().matches(options::OPT_ffat_lto_objects
)) {
7828 assert(LTOMode
== LTOK_Full
|| LTOMode
== LTOK_Thin
);
7829 if (!Triple
.isOSBinFormatELF()) {
7830 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
7831 << A
->getAsString(Args
) << TC
.getTripleString();
7833 CmdArgs
.push_back(Args
.MakeArgString(
7834 Twine("-flto=") + (LTOMode
== LTOK_Thin
? "thin" : "full")));
7835 CmdArgs
.push_back("-flto-unit");
7836 CmdArgs
.push_back("-ffat-lto-objects");
7837 A
->render(Args
, CmdArgs
);
7841 if (Arg
*A
= Args
.getLastArg(options::OPT_fglobal_isel
,
7842 options::OPT_fno_global_isel
)) {
7843 CmdArgs
.push_back("-mllvm");
7844 if (A
->getOption().matches(options::OPT_fglobal_isel
)) {
7845 CmdArgs
.push_back("-global-isel=1");
7847 // GISel is on by default on AArch64 -O0, so don't bother adding
7848 // the fallback remarks for it. Other combinations will add a warning of
7850 bool IsArchSupported
= Triple
.getArch() == llvm::Triple::aarch64
;
7851 bool IsOptLevelSupported
= false;
7853 Arg
*A
= Args
.getLastArg(options::OPT_O_Group
);
7854 if (Triple
.getArch() == llvm::Triple::aarch64
) {
7855 if (!A
|| A
->getOption().matches(options::OPT_O0
))
7856 IsOptLevelSupported
= true;
7858 if (!IsArchSupported
|| !IsOptLevelSupported
) {
7859 CmdArgs
.push_back("-mllvm");
7860 CmdArgs
.push_back("-global-isel-abort=2");
7862 if (!IsArchSupported
)
7863 D
.Diag(diag::warn_drv_global_isel_incomplete
) << Triple
.getArchName();
7865 D
.Diag(diag::warn_drv_global_isel_incomplete_opt
);
7868 CmdArgs
.push_back("-global-isel=0");
7872 if (Args
.hasArg(options::OPT_forder_file_instrumentation
)) {
7873 CmdArgs
.push_back("-forder-file-instrumentation");
7874 // Enable order file instrumentation when ThinLTO is not on. When ThinLTO is
7875 // on, we need to pass these flags as linker flags and that will be handled
7876 // outside of the compiler.
7878 CmdArgs
.push_back("-mllvm");
7879 CmdArgs
.push_back("-enable-order-file-instrumentation");
7883 if (Arg
*A
= Args
.getLastArg(options::OPT_fforce_enable_int128
,
7884 options::OPT_fno_force_enable_int128
)) {
7885 if (A
->getOption().matches(options::OPT_fforce_enable_int128
))
7886 CmdArgs
.push_back("-fforce-enable-int128");
7889 Args
.addOptInFlag(CmdArgs
, options::OPT_fkeep_static_consts
,
7890 options::OPT_fno_keep_static_consts
);
7891 Args
.addOptInFlag(CmdArgs
, options::OPT_fkeep_persistent_storage_variables
,
7892 options::OPT_fno_keep_persistent_storage_variables
);
7893 Args
.addOptInFlag(CmdArgs
, options::OPT_fcomplete_member_pointers
,
7894 options::OPT_fno_complete_member_pointers
);
7895 Args
.addOptOutFlag(CmdArgs
, options::OPT_fcxx_static_destructors
,
7896 options::OPT_fno_cxx_static_destructors
);
7898 addMachineOutlinerArgs(D
, Args
, CmdArgs
, Triple
, /*IsLTO=*/false);
7900 addOutlineAtomicsArgs(D
, getToolChain(), Args
, CmdArgs
, Triple
);
7902 if (Triple
.isAArch64() &&
7903 (Args
.hasArg(options::OPT_mno_fmv
) ||
7904 (Triple
.isAndroid() && Triple
.isAndroidVersionLT(23)) ||
7905 getToolChain().GetRuntimeLibType(Args
) != ToolChain::RLT_CompilerRT
)) {
7906 // Disable Function Multiversioning on AArch64 target.
7907 CmdArgs
.push_back("-target-feature");
7908 CmdArgs
.push_back("-fmv");
7911 if (Args
.hasFlag(options::OPT_faddrsig
, options::OPT_fno_addrsig
,
7912 (TC
.getTriple().isOSBinFormatELF() ||
7913 TC
.getTriple().isOSBinFormatCOFF()) &&
7914 !TC
.getTriple().isPS4() && !TC
.getTriple().isVE() &&
7915 !TC
.getTriple().isOSNetBSD() &&
7916 !Distro(D
.getVFS(), TC
.getTriple()).IsGentoo() &&
7917 !TC
.getTriple().isAndroid() && TC
.useIntegratedAs()))
7918 CmdArgs
.push_back("-faddrsig");
7920 if ((Triple
.isOSBinFormatELF() || Triple
.isOSBinFormatMachO()) &&
7921 (EH
|| UnwindTables
|| AsyncUnwindTables
||
7922 DebugInfoKind
!= llvm::codegenoptions::NoDebugInfo
))
7923 CmdArgs
.push_back("-D__GCC_HAVE_DWARF2_CFI_ASM=1");
7925 if (Arg
*A
= Args
.getLastArg(options::OPT_fsymbol_partition_EQ
)) {
7926 std::string Str
= A
->getAsString(Args
);
7927 if (!TC
.getTriple().isOSBinFormatELF())
7928 D
.Diag(diag::err_drv_unsupported_opt_for_target
)
7929 << Str
<< TC
.getTripleString();
7930 CmdArgs
.push_back(Args
.MakeArgString(Str
));
7933 // Add the "-o out -x type src.c" flags last. This is done primarily to make
7934 // the -cc1 command easier to edit when reproducing compiler crashes.
7935 if (Output
.getType() == types::TY_Dependencies
) {
7936 // Handled with other dependency code.
7937 } else if (Output
.isFilename()) {
7938 if (Output
.getType() == clang::driver::types::TY_IFS_CPP
||
7939 Output
.getType() == clang::driver::types::TY_IFS
) {
7940 SmallString
<128> OutputFilename(Output
.getFilename());
7941 llvm::sys::path::replace_extension(OutputFilename
, "ifs");
7942 CmdArgs
.push_back("-o");
7943 CmdArgs
.push_back(Args
.MakeArgString(OutputFilename
));
7945 CmdArgs
.push_back("-o");
7946 CmdArgs
.push_back(Output
.getFilename());
7949 assert(Output
.isNothing() && "Invalid output.");
7952 addDashXForInput(Args
, Input
, CmdArgs
);
7954 ArrayRef
<InputInfo
> FrontendInputs
= Input
;
7956 FrontendInputs
= ExtractAPIInputs
;
7957 else if (Input
.isNothing())
7958 FrontendInputs
= {};
7960 for (const InputInfo
&Input
: FrontendInputs
) {
7961 if (Input
.isFilename())
7962 CmdArgs
.push_back(Input
.getFilename());
7964 Input
.getInputArg().renderAsInput(Args
, CmdArgs
);
7967 if (D
.CC1Main
&& !D
.CCGenDiagnostics
) {
7968 // Invoke the CC1 directly in this process
7969 C
.addCommand(std::make_unique
<CC1Command
>(
7970 JA
, *this, ResponseFileSupport::AtFileUTF8(), Exec
, CmdArgs
, Inputs
,
7971 Output
, D
.getPrependArg()));
7973 C
.addCommand(std::make_unique
<Command
>(
7974 JA
, *this, ResponseFileSupport::AtFileUTF8(), Exec
, CmdArgs
, Inputs
,
7975 Output
, D
.getPrependArg()));
7978 // Make the compile command echo its inputs for /showFilenames.
7979 if (Output
.getType() == types::TY_Object
&&
7980 Args
.hasFlag(options::OPT__SLASH_showFilenames
,
7981 options::OPT__SLASH_showFilenames_
, false)) {
7982 C
.getJobs().getJobs().back()->PrintInputFilenames
= true;
7985 if (Arg
*A
= Args
.getLastArg(options::OPT_pg
))
7986 if (FPKeepKind
== CodeGenOptions::FramePointerKind::None
&&
7987 !Args
.hasArg(options::OPT_mfentry
))
7988 D
.Diag(diag::err_drv_argument_not_allowed_with
) << "-fomit-frame-pointer"
7989 << A
->getAsString(Args
);
7991 // Claim some arguments which clang supports automatically.
7993 // -fpch-preprocess is used with gcc to add a special marker in the output to
7994 // include the PCH file.
7995 Args
.ClaimAllArgs(options::OPT_fpch_preprocess
);
7997 // Claim some arguments which clang doesn't support, but we don't
7998 // care to warn the user about.
7999 Args
.ClaimAllArgs(options::OPT_clang_ignored_f_Group
);
8000 Args
.ClaimAllArgs(options::OPT_clang_ignored_m_Group
);
8002 // Disable warnings for clang -E -emit-llvm foo.c
8003 Args
.ClaimAllArgs(options::OPT_emit_llvm
);
8006 Clang::Clang(const ToolChain
&TC
, bool HasIntegratedBackend
)
8007 // CAUTION! The first constructor argument ("clang") is not arbitrary,
8008 // as it is for other tools. Some operations on a Tool actually test
8009 // whether that tool is Clang based on the Tool's Name as a string.
8010 : Tool("clang", "clang frontend", TC
), HasBackend(HasIntegratedBackend
) {}
8014 /// Add options related to the Objective-C runtime/ABI.
8016 /// Returns true if the runtime is non-fragile.
8017 ObjCRuntime
Clang::AddObjCRuntimeArgs(const ArgList
&args
,
8018 const InputInfoList
&inputs
,
8019 ArgStringList
&cmdArgs
,
8020 RewriteKind rewriteKind
) const {
8021 // Look for the controlling runtime option.
8023 args
.getLastArg(options::OPT_fnext_runtime
, options::OPT_fgnu_runtime
,
8024 options::OPT_fobjc_runtime_EQ
);
8026 // Just forward -fobjc-runtime= to the frontend. This supercedes
8027 // options about fragility.
8029 runtimeArg
->getOption().matches(options::OPT_fobjc_runtime_EQ
)) {
8030 ObjCRuntime runtime
;
8031 StringRef value
= runtimeArg
->getValue();
8032 if (runtime
.tryParse(value
)) {
8033 getToolChain().getDriver().Diag(diag::err_drv_unknown_objc_runtime
)
8036 if ((runtime
.getKind() == ObjCRuntime::GNUstep
) &&
8037 (runtime
.getVersion() >= VersionTuple(2, 0)))
8038 if (!getToolChain().getTriple().isOSBinFormatELF() &&
8039 !getToolChain().getTriple().isOSBinFormatCOFF()) {
8040 getToolChain().getDriver().Diag(
8041 diag::err_drv_gnustep_objc_runtime_incompatible_binary
)
8042 << runtime
.getVersion().getMajor();
8045 runtimeArg
->render(args
, cmdArgs
);
8049 // Otherwise, we'll need the ABI "version". Version numbers are
8050 // slightly confusing for historical reasons:
8051 // 1 - Traditional "fragile" ABI
8052 // 2 - Non-fragile ABI, version 1
8053 // 3 - Non-fragile ABI, version 2
8054 unsigned objcABIVersion
= 1;
8055 // If -fobjc-abi-version= is present, use that to set the version.
8056 if (Arg
*abiArg
= args
.getLastArg(options::OPT_fobjc_abi_version_EQ
)) {
8057 StringRef value
= abiArg
->getValue();
8060 else if (value
== "2")
8062 else if (value
== "3")
8065 getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported
) << value
;
8067 // Otherwise, determine if we are using the non-fragile ABI.
8068 bool nonFragileABIIsDefault
=
8069 (rewriteKind
== RK_NonFragile
||
8070 (rewriteKind
== RK_None
&&
8071 getToolChain().IsObjCNonFragileABIDefault()));
8072 if (args
.hasFlag(options::OPT_fobjc_nonfragile_abi
,
8073 options::OPT_fno_objc_nonfragile_abi
,
8074 nonFragileABIIsDefault
)) {
8075 // Determine the non-fragile ABI version to use.
8076 #ifdef DISABLE_DEFAULT_NONFRAGILEABI_TWO
8077 unsigned nonFragileABIVersion
= 1;
8079 unsigned nonFragileABIVersion
= 2;
8083 args
.getLastArg(options::OPT_fobjc_nonfragile_abi_version_EQ
)) {
8084 StringRef value
= abiArg
->getValue();
8086 nonFragileABIVersion
= 1;
8087 else if (value
== "2")
8088 nonFragileABIVersion
= 2;
8090 getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported
)
8094 objcABIVersion
= 1 + nonFragileABIVersion
;
8100 // We don't actually care about the ABI version other than whether
8101 // it's non-fragile.
8102 bool isNonFragile
= objcABIVersion
!= 1;
8104 // If we have no runtime argument, ask the toolchain for its default runtime.
8105 // However, the rewriter only really supports the Mac runtime, so assume that.
8106 ObjCRuntime runtime
;
8108 switch (rewriteKind
) {
8110 runtime
= getToolChain().getDefaultObjCRuntime(isNonFragile
);
8113 runtime
= ObjCRuntime(ObjCRuntime::FragileMacOSX
, VersionTuple());
8116 runtime
= ObjCRuntime(ObjCRuntime::MacOSX
, VersionTuple());
8121 } else if (runtimeArg
->getOption().matches(options::OPT_fnext_runtime
)) {
8122 // On Darwin, make this use the default behavior for the toolchain.
8123 if (getToolChain().getTriple().isOSDarwin()) {
8124 runtime
= getToolChain().getDefaultObjCRuntime(isNonFragile
);
8126 // Otherwise, build for a generic macosx port.
8128 runtime
= ObjCRuntime(ObjCRuntime::MacOSX
, VersionTuple());
8133 assert(runtimeArg
->getOption().matches(options::OPT_fgnu_runtime
));
8134 // Legacy behaviour is to target the gnustep runtime if we are in
8135 // non-fragile mode or the GCC runtime in fragile mode.
8137 runtime
= ObjCRuntime(ObjCRuntime::GNUstep
, VersionTuple(2, 0));
8139 runtime
= ObjCRuntime(ObjCRuntime::GCC
, VersionTuple());
8142 if (llvm::any_of(inputs
, [](const InputInfo
&input
) {
8143 return types::isObjC(input
.getType());
8146 args
.MakeArgString("-fobjc-runtime=" + runtime
.getAsString()));
8150 static bool maybeConsumeDash(const std::string
&EH
, size_t &I
) {
8151 bool HaveDash
= (I
+ 1 < EH
.size() && EH
[I
+ 1] == '-');
8159 bool Asynch
= false;
8160 bool NoUnwindC
= false;
8162 } // end anonymous namespace
8164 /// /EH controls whether to run destructor cleanups when exceptions are
8165 /// thrown. There are three modifiers:
8166 /// - s: Cleanup after "synchronous" exceptions, aka C++ exceptions.
8167 /// - a: Cleanup after "asynchronous" exceptions, aka structured exceptions.
8168 /// The 'a' modifier is unimplemented and fundamentally hard in LLVM IR.
8169 /// - c: Assume that extern "C" functions are implicitly nounwind.
8170 /// The default is /EHs-c-, meaning cleanups are disabled.
8171 static EHFlags
parseClangCLEHFlags(const Driver
&D
, const ArgList
&Args
,
8172 bool isWindowsMSVC
) {
8175 std::vector
<std::string
> EHArgs
=
8176 Args
.getAllArgValues(options::OPT__SLASH_EH
);
8177 for (const auto &EHVal
: EHArgs
) {
8178 for (size_t I
= 0, E
= EHVal
.size(); I
!= E
; ++I
) {
8181 EH
.Asynch
= maybeConsumeDash(EHVal
, I
);
8183 // Async exceptions are Windows MSVC only.
8184 if (!isWindowsMSVC
) {
8186 D
.Diag(clang::diag::warn_drv_unused_argument
) << "/EHa" << EHVal
;
8193 EH
.NoUnwindC
= maybeConsumeDash(EHVal
, I
);
8196 EH
.Synch
= maybeConsumeDash(EHVal
, I
);
8203 D
.Diag(clang::diag::err_drv_invalid_value
) << "/EH" << EHVal
;
8207 // The /GX, /GX- flags are only processed if there are not /EH flags.
8208 // The default is that /GX is not specified.
8209 if (EHArgs
.empty() &&
8210 Args
.hasFlag(options::OPT__SLASH_GX
, options::OPT__SLASH_GX_
,
8211 /*Default=*/false)) {
8213 EH
.NoUnwindC
= true;
8216 if (Args
.hasArg(options::OPT__SLASH_kernel
)) {
8218 EH
.NoUnwindC
= false;
8225 void Clang::AddClangCLArgs(const ArgList
&Args
, types::ID InputType
,
8226 ArgStringList
&CmdArgs
) const {
8227 bool isNVPTX
= getToolChain().getTriple().isNVPTX();
8229 ProcessVSRuntimeLibrary(getToolChain(), Args
, CmdArgs
);
8231 if (Arg
*ShowIncludes
=
8232 Args
.getLastArg(options::OPT__SLASH_showIncludes
,
8233 options::OPT__SLASH_showIncludes_user
)) {
8234 CmdArgs
.push_back("--show-includes");
8235 if (ShowIncludes
->getOption().matches(options::OPT__SLASH_showIncludes
))
8236 CmdArgs
.push_back("-sys-header-deps");
8239 // This controls whether or not we emit RTTI data for polymorphic types.
8240 if (Args
.hasFlag(options::OPT__SLASH_GR_
, options::OPT__SLASH_GR
,
8242 CmdArgs
.push_back("-fno-rtti-data");
8244 // This controls whether or not we emit stack-protector instrumentation.
8245 // In MSVC, Buffer Security Check (/GS) is on by default.
8246 if (!isNVPTX
&& Args
.hasFlag(options::OPT__SLASH_GS
, options::OPT__SLASH_GS_
,
8247 /*Default=*/true)) {
8248 CmdArgs
.push_back("-stack-protector");
8249 CmdArgs
.push_back(Args
.MakeArgString(Twine(LangOptions::SSPStrong
)));
8252 const Driver
&D
= getToolChain().getDriver();
8254 bool IsWindowsMSVC
= getToolChain().getTriple().isWindowsMSVCEnvironment();
8255 EHFlags EH
= parseClangCLEHFlags(D
, Args
, IsWindowsMSVC
);
8256 if (!isNVPTX
&& (EH
.Synch
|| EH
.Asynch
)) {
8257 if (types::isCXX(InputType
))
8258 CmdArgs
.push_back("-fcxx-exceptions");
8259 CmdArgs
.push_back("-fexceptions");
8261 CmdArgs
.push_back("-fasync-exceptions");
8263 if (types::isCXX(InputType
) && EH
.Synch
&& EH
.NoUnwindC
)
8264 CmdArgs
.push_back("-fexternc-nounwind");
8266 // /EP should expand to -E -P.
8267 if (Args
.hasArg(options::OPT__SLASH_EP
)) {
8268 CmdArgs
.push_back("-E");
8269 CmdArgs
.push_back("-P");
8272 if (Args
.hasFlag(options::OPT__SLASH_Zc_dllexportInlines_
,
8273 options::OPT__SLASH_Zc_dllexportInlines
,
8275 CmdArgs
.push_back("-fno-dllexport-inlines");
8278 if (Args
.hasFlag(options::OPT__SLASH_Zc_wchar_t_
,
8279 options::OPT__SLASH_Zc_wchar_t
, false)) {
8280 CmdArgs
.push_back("-fno-wchar");
8283 if (Args
.hasArg(options::OPT__SLASH_kernel
)) {
8284 llvm::Triple::ArchType Arch
= getToolChain().getArch();
8285 std::vector
<std::string
> Values
=
8286 Args
.getAllArgValues(options::OPT__SLASH_arch
);
8287 if (!Values
.empty()) {
8288 llvm::SmallSet
<std::string
, 4> SupportedArches
;
8289 if (Arch
== llvm::Triple::x86
)
8290 SupportedArches
.insert("IA32");
8292 for (auto &V
: Values
)
8293 if (!SupportedArches
.contains(V
))
8294 D
.Diag(diag::err_drv_argument_not_allowed_with
)
8295 << std::string("/arch:").append(V
) << "/kernel";
8298 CmdArgs
.push_back("-fno-rtti");
8299 if (Args
.hasFlag(options::OPT__SLASH_GR
, options::OPT__SLASH_GR_
, false))
8300 D
.Diag(diag::err_drv_argument_not_allowed_with
) << "/GR"
8304 Arg
*MostGeneralArg
= Args
.getLastArg(options::OPT__SLASH_vmg
);
8305 Arg
*BestCaseArg
= Args
.getLastArg(options::OPT__SLASH_vmb
);
8306 if (MostGeneralArg
&& BestCaseArg
)
8307 D
.Diag(clang::diag::err_drv_argument_not_allowed_with
)
8308 << MostGeneralArg
->getAsString(Args
) << BestCaseArg
->getAsString(Args
);
8310 if (MostGeneralArg
) {
8311 Arg
*SingleArg
= Args
.getLastArg(options::OPT__SLASH_vms
);
8312 Arg
*MultipleArg
= Args
.getLastArg(options::OPT__SLASH_vmm
);
8313 Arg
*VirtualArg
= Args
.getLastArg(options::OPT__SLASH_vmv
);
8315 Arg
*FirstConflict
= SingleArg
? SingleArg
: MultipleArg
;
8316 Arg
*SecondConflict
= VirtualArg
? VirtualArg
: MultipleArg
;
8317 if (FirstConflict
&& SecondConflict
&& FirstConflict
!= SecondConflict
)
8318 D
.Diag(clang::diag::err_drv_argument_not_allowed_with
)
8319 << FirstConflict
->getAsString(Args
)
8320 << SecondConflict
->getAsString(Args
);
8323 CmdArgs
.push_back("-fms-memptr-rep=single");
8324 else if (MultipleArg
)
8325 CmdArgs
.push_back("-fms-memptr-rep=multiple");
8327 CmdArgs
.push_back("-fms-memptr-rep=virtual");
8330 if (Args
.hasArg(options::OPT_regcall4
))
8331 CmdArgs
.push_back("-regcall4");
8333 // Parse the default calling convention options.
8335 Args
.getLastArg(options::OPT__SLASH_Gd
, options::OPT__SLASH_Gr
,
8336 options::OPT__SLASH_Gz
, options::OPT__SLASH_Gv
,
8337 options::OPT__SLASH_Gregcall
)) {
8338 unsigned DCCOptId
= CCArg
->getOption().getID();
8339 const char *DCCFlag
= nullptr;
8340 bool ArchSupported
= !isNVPTX
;
8341 llvm::Triple::ArchType Arch
= getToolChain().getArch();
8343 case options::OPT__SLASH_Gd
:
8344 DCCFlag
= "-fdefault-calling-conv=cdecl";
8346 case options::OPT__SLASH_Gr
:
8347 ArchSupported
= Arch
== llvm::Triple::x86
;
8348 DCCFlag
= "-fdefault-calling-conv=fastcall";
8350 case options::OPT__SLASH_Gz
:
8351 ArchSupported
= Arch
== llvm::Triple::x86
;
8352 DCCFlag
= "-fdefault-calling-conv=stdcall";
8354 case options::OPT__SLASH_Gv
:
8355 ArchSupported
= Arch
== llvm::Triple::x86
|| Arch
== llvm::Triple::x86_64
;
8356 DCCFlag
= "-fdefault-calling-conv=vectorcall";
8358 case options::OPT__SLASH_Gregcall
:
8359 ArchSupported
= Arch
== llvm::Triple::x86
|| Arch
== llvm::Triple::x86_64
;
8360 DCCFlag
= "-fdefault-calling-conv=regcall";
8364 // MSVC doesn't warn if /Gr or /Gz is used on x64, so we don't either.
8365 if (ArchSupported
&& DCCFlag
)
8366 CmdArgs
.push_back(DCCFlag
);
8369 if (Args
.hasArg(options::OPT__SLASH_Gregcall4
))
8370 CmdArgs
.push_back("-regcall4");
8372 Args
.AddLastArg(CmdArgs
, options::OPT_vtordisp_mode_EQ
);
8374 if (!Args
.hasArg(options::OPT_fdiagnostics_format_EQ
)) {
8375 CmdArgs
.push_back("-fdiagnostics-format");
8376 CmdArgs
.push_back("msvc");
8379 if (Args
.hasArg(options::OPT__SLASH_kernel
))
8380 CmdArgs
.push_back("-fms-kernel");
8382 for (const Arg
*A
: Args
.filtered(options::OPT__SLASH_guard
)) {
8383 StringRef GuardArgs
= A
->getValue();
8384 // The only valid options are "cf", "cf,nochecks", "cf-", "ehcont" and
8386 if (GuardArgs
.equals_insensitive("cf")) {
8387 // Emit CFG instrumentation and the table of address-taken functions.
8388 CmdArgs
.push_back("-cfguard");
8389 } else if (GuardArgs
.equals_insensitive("cf,nochecks")) {
8390 // Emit only the table of address-taken functions.
8391 CmdArgs
.push_back("-cfguard-no-checks");
8392 } else if (GuardArgs
.equals_insensitive("ehcont")) {
8393 // Emit EH continuation table.
8394 CmdArgs
.push_back("-ehcontguard");
8395 } else if (GuardArgs
.equals_insensitive("cf-") ||
8396 GuardArgs
.equals_insensitive("ehcont-")) {
8397 // Do nothing, but we might want to emit a security warning in future.
8399 D
.Diag(diag::err_drv_invalid_value
) << A
->getSpelling() << GuardArgs
;
8405 const char *Clang::getBaseInputName(const ArgList
&Args
,
8406 const InputInfo
&Input
) {
8407 return Args
.MakeArgString(llvm::sys::path::filename(Input
.getBaseInput()));
8410 const char *Clang::getBaseInputStem(const ArgList
&Args
,
8411 const InputInfoList
&Inputs
) {
8412 const char *Str
= getBaseInputName(Args
, Inputs
[0]);
8414 if (const char *End
= strrchr(Str
, '.'))
8415 return Args
.MakeArgString(std::string(Str
, End
));
8420 const char *Clang::getDependencyFileName(const ArgList
&Args
,
8421 const InputInfoList
&Inputs
) {
8422 // FIXME: Think about this more.
8424 if (Arg
*OutputOpt
= Args
.getLastArg(options::OPT_o
)) {
8425 SmallString
<128> OutputFilename(OutputOpt
->getValue());
8426 llvm::sys::path::replace_extension(OutputFilename
, llvm::Twine('d'));
8427 return Args
.MakeArgString(OutputFilename
);
8430 return Args
.MakeArgString(Twine(getBaseInputStem(Args
, Inputs
)) + ".d");
8435 void ClangAs::AddMIPSTargetArgs(const ArgList
&Args
,
8436 ArgStringList
&CmdArgs
) const {
8439 const llvm::Triple
&Triple
= getToolChain().getTriple();
8440 mips::getMipsCPUAndABI(Args
, Triple
, CPUName
, ABIName
);
8442 CmdArgs
.push_back("-target-abi");
8443 CmdArgs
.push_back(ABIName
.data());
8446 void ClangAs::AddX86TargetArgs(const ArgList
&Args
,
8447 ArgStringList
&CmdArgs
) const {
8448 addX86AlignBranchArgs(getToolChain().getDriver(), Args
, CmdArgs
,
8451 if (Arg
*A
= Args
.getLastArg(options::OPT_masm_EQ
)) {
8452 StringRef Value
= A
->getValue();
8453 if (Value
== "intel" || Value
== "att") {
8454 CmdArgs
.push_back("-mllvm");
8455 CmdArgs
.push_back(Args
.MakeArgString("-x86-asm-syntax=" + Value
));
8457 getToolChain().getDriver().Diag(diag::err_drv_unsupported_option_argument
)
8458 << A
->getSpelling() << Value
;
8463 void ClangAs::AddLoongArchTargetArgs(const ArgList
&Args
,
8464 ArgStringList
&CmdArgs
) const {
8465 CmdArgs
.push_back("-target-abi");
8466 CmdArgs
.push_back(loongarch::getLoongArchABI(getToolChain().getDriver(), Args
,
8467 getToolChain().getTriple())
8471 void ClangAs::AddRISCVTargetArgs(const ArgList
&Args
,
8472 ArgStringList
&CmdArgs
) const {
8473 const llvm::Triple
&Triple
= getToolChain().getTriple();
8474 StringRef ABIName
= riscv::getRISCVABI(Args
, Triple
);
8476 CmdArgs
.push_back("-target-abi");
8477 CmdArgs
.push_back(ABIName
.data());
8479 if (Args
.hasFlag(options::OPT_mdefault_build_attributes
,
8480 options::OPT_mno_default_build_attributes
, true)) {
8481 CmdArgs
.push_back("-mllvm");
8482 CmdArgs
.push_back("-riscv-add-build-attributes");
8486 void ClangAs::ConstructJob(Compilation
&C
, const JobAction
&JA
,
8487 const InputInfo
&Output
, const InputInfoList
&Inputs
,
8488 const ArgList
&Args
,
8489 const char *LinkingOutput
) const {
8490 ArgStringList CmdArgs
;
8492 assert(Inputs
.size() == 1 && "Unexpected number of inputs.");
8493 const InputInfo
&Input
= Inputs
[0];
8495 const llvm::Triple
&Triple
= getToolChain().getEffectiveTriple();
8496 const std::string
&TripleStr
= Triple
.getTriple();
8497 const auto &D
= getToolChain().getDriver();
8499 // Don't warn about "clang -w -c foo.s"
8500 Args
.ClaimAllArgs(options::OPT_w
);
8501 // and "clang -emit-llvm -c foo.s"
8502 Args
.ClaimAllArgs(options::OPT_emit_llvm
);
8504 claimNoWarnArgs(Args
);
8506 // Invoke ourselves in -cc1as mode.
8508 // FIXME: Implement custom jobs for internal actions.
8509 CmdArgs
.push_back("-cc1as");
8511 // Add the "effective" target triple.
8512 CmdArgs
.push_back("-triple");
8513 CmdArgs
.push_back(Args
.MakeArgString(TripleStr
));
8515 getToolChain().addClangCC1ASTargetOptions(Args
, CmdArgs
);
8517 // Set the output mode, we currently only expect to be used as a real
8519 CmdArgs
.push_back("-filetype");
8520 CmdArgs
.push_back("obj");
8522 // Set the main file name, so that debug info works even with
8523 // -save-temps or preprocessed assembly.
8524 CmdArgs
.push_back("-main-file-name");
8525 CmdArgs
.push_back(Clang::getBaseInputName(Args
, Input
));
8527 // Add the target cpu
8528 std::string CPU
= getCPUName(D
, Args
, Triple
, /*FromAs*/ true);
8530 CmdArgs
.push_back("-target-cpu");
8531 CmdArgs
.push_back(Args
.MakeArgString(CPU
));
8534 // Add the target features
8535 getTargetFeatures(D
, Triple
, Args
, CmdArgs
, true);
8537 // Ignore explicit -force_cpusubtype_ALL option.
8538 (void)Args
.hasArg(options::OPT_force__cpusubtype__ALL
);
8540 // Pass along any -I options so we get proper .include search paths.
8541 Args
.AddAllArgs(CmdArgs
, options::OPT_I_Group
);
8543 // Pass along any --embed-dir or similar options so we get proper embed paths.
8544 Args
.AddAllArgs(CmdArgs
, options::OPT_embed_dir_EQ
);
8546 // Determine the original source input.
8547 auto FindSource
= [](const Action
*S
) -> const Action
* {
8548 while (S
->getKind() != Action::InputClass
) {
8549 assert(!S
->getInputs().empty() && "unexpected root action!");
8550 S
= S
->getInputs()[0];
8554 const Action
*SourceAction
= FindSource(&JA
);
8556 // Forward -g and handle debug info related flags, assuming we are dealing
8557 // with an actual assembly file.
8558 bool WantDebug
= false;
8559 Args
.ClaimAllArgs(options::OPT_g_Group
);
8560 if (Arg
*A
= Args
.getLastArg(options::OPT_g_Group
))
8561 WantDebug
= !A
->getOption().matches(options::OPT_g0
) &&
8562 !A
->getOption().matches(options::OPT_ggdb0
);
8564 // If a -gdwarf argument appeared, remember it.
8565 bool EmitDwarf
= false;
8566 if (const Arg
*A
= getDwarfNArg(Args
))
8567 EmitDwarf
= checkDebugInfoOption(A
, Args
, D
, getToolChain());
8569 bool EmitCodeView
= false;
8570 if (const Arg
*A
= Args
.getLastArg(options::OPT_gcodeview
))
8571 EmitCodeView
= checkDebugInfoOption(A
, Args
, D
, getToolChain());
8573 // If the user asked for debug info but did not explicitly specify -gcodeview
8574 // or -gdwarf, ask the toolchain for the default format.
8575 if (!EmitCodeView
&& !EmitDwarf
&& WantDebug
) {
8576 switch (getToolChain().getDefaultDebugFormat()) {
8577 case llvm::codegenoptions::DIF_CodeView
:
8578 EmitCodeView
= true;
8580 case llvm::codegenoptions::DIF_DWARF
:
8586 // If the arguments don't imply DWARF, don't emit any debug info here.
8590 llvm::codegenoptions::DebugInfoKind DebugInfoKind
=
8591 llvm::codegenoptions::NoDebugInfo
;
8593 // Add the -fdebug-compilation-dir flag if needed.
8594 const char *DebugCompilationDir
=
8595 addDebugCompDirArg(Args
, CmdArgs
, C
.getDriver().getVFS());
8597 if (SourceAction
->getType() == types::TY_Asm
||
8598 SourceAction
->getType() == types::TY_PP_Asm
) {
8599 // You might think that it would be ok to set DebugInfoKind outside of
8600 // the guard for source type, however there is a test which asserts
8601 // that some assembler invocation receives no -debug-info-kind,
8602 // and it's not clear whether that test is just overly restrictive.
8603 DebugInfoKind
= (WantDebug
? llvm::codegenoptions::DebugInfoConstructor
8604 : llvm::codegenoptions::NoDebugInfo
);
8606 addDebugPrefixMapArg(getToolChain().getDriver(), getToolChain(), Args
,
8609 // Set the AT_producer to the clang version when using the integrated
8610 // assembler on assembly source files.
8611 CmdArgs
.push_back("-dwarf-debug-producer");
8612 CmdArgs
.push_back(Args
.MakeArgString(getClangFullVersion()));
8614 // And pass along -I options
8615 Args
.AddAllArgs(CmdArgs
, options::OPT_I
);
8617 const unsigned DwarfVersion
= getDwarfVersion(getToolChain(), Args
);
8618 RenderDebugEnablingArgs(Args
, CmdArgs
, DebugInfoKind
, DwarfVersion
,
8619 llvm::DebuggerKind::Default
);
8620 renderDwarfFormat(D
, Triple
, Args
, CmdArgs
, DwarfVersion
);
8621 RenderDebugInfoCompressionArgs(Args
, CmdArgs
, D
, getToolChain());
8623 // Handle -fPIC et al -- the relocation-model affects the assembler
8624 // for some targets.
8625 llvm::Reloc::Model RelocationModel
;
8628 std::tie(RelocationModel
, PICLevel
, IsPIE
) =
8629 ParsePICArgs(getToolChain(), Args
);
8631 const char *RMName
= RelocationModelName(RelocationModel
);
8633 CmdArgs
.push_back("-mrelocation-model");
8634 CmdArgs
.push_back(RMName
);
8637 // Optionally embed the -cc1as level arguments into the debug info, for build
8639 if (getToolChain().UseDwarfDebugFlags()) {
8640 ArgStringList OriginalArgs
;
8641 for (const auto &Arg
: Args
)
8642 Arg
->render(Args
, OriginalArgs
);
8644 SmallString
<256> Flags
;
8645 const char *Exec
= getToolChain().getDriver().getClangProgramPath();
8646 EscapeSpacesAndBackslashes(Exec
, Flags
);
8647 for (const char *OriginalArg
: OriginalArgs
) {
8648 SmallString
<128> EscapedArg
;
8649 EscapeSpacesAndBackslashes(OriginalArg
, EscapedArg
);
8651 Flags
+= EscapedArg
;
8653 CmdArgs
.push_back("-dwarf-debug-flags");
8654 CmdArgs
.push_back(Args
.MakeArgString(Flags
));
8657 // FIXME: Add -static support, once we have it.
8659 // Add target specific flags.
8660 switch (getToolChain().getArch()) {
8664 case llvm::Triple::mips
:
8665 case llvm::Triple::mipsel
:
8666 case llvm::Triple::mips64
:
8667 case llvm::Triple::mips64el
:
8668 AddMIPSTargetArgs(Args
, CmdArgs
);
8671 case llvm::Triple::x86
:
8672 case llvm::Triple::x86_64
:
8673 AddX86TargetArgs(Args
, CmdArgs
);
8676 case llvm::Triple::arm
:
8677 case llvm::Triple::armeb
:
8678 case llvm::Triple::thumb
:
8679 case llvm::Triple::thumbeb
:
8680 // This isn't in AddARMTargetArgs because we want to do this for assembly
8682 if (Args
.hasFlag(options::OPT_mdefault_build_attributes
,
8683 options::OPT_mno_default_build_attributes
, true)) {
8684 CmdArgs
.push_back("-mllvm");
8685 CmdArgs
.push_back("-arm-add-build-attributes");
8689 case llvm::Triple::aarch64
:
8690 case llvm::Triple::aarch64_32
:
8691 case llvm::Triple::aarch64_be
:
8692 if (Args
.hasArg(options::OPT_mmark_bti_property
)) {
8693 CmdArgs
.push_back("-mllvm");
8694 CmdArgs
.push_back("-aarch64-mark-bti-property");
8698 case llvm::Triple::loongarch32
:
8699 case llvm::Triple::loongarch64
:
8700 AddLoongArchTargetArgs(Args
, CmdArgs
);
8703 case llvm::Triple::riscv32
:
8704 case llvm::Triple::riscv64
:
8705 AddRISCVTargetArgs(Args
, CmdArgs
);
8708 case llvm::Triple::hexagon
:
8709 if (Args
.hasFlag(options::OPT_mdefault_build_attributes
,
8710 options::OPT_mno_default_build_attributes
, true)) {
8711 CmdArgs
.push_back("-mllvm");
8712 CmdArgs
.push_back("-hexagon-add-build-attributes");
8717 // Consume all the warning flags. Usually this would be handled more
8718 // gracefully by -cc1 (warning about unknown warning flags, etc) but -cc1as
8719 // doesn't handle that so rather than warning about unused flags that are
8720 // actually used, we'll lie by omission instead.
8721 // FIXME: Stop lying and consume only the appropriate driver flags
8722 Args
.ClaimAllArgs(options::OPT_W_Group
);
8724 CollectArgsForIntegratedAssembler(C
, Args
, CmdArgs
,
8725 getToolChain().getDriver());
8727 Args
.AddAllArgs(CmdArgs
, options::OPT_mllvm
);
8729 if (DebugInfoKind
> llvm::codegenoptions::NoDebugInfo
&& Output
.isFilename())
8730 addDebugObjectName(Args
, CmdArgs
, DebugCompilationDir
,
8731 Output
.getFilename());
8733 // Fixup any previous commands that use -object-file-name because when we
8734 // generated them, the final .obj name wasn't yet known.
8735 for (Command
&J
: C
.getJobs()) {
8736 if (SourceAction
!= FindSource(&J
.getSource()))
8738 auto &JArgs
= J
.getArguments();
8739 for (unsigned I
= 0; I
< JArgs
.size(); ++I
) {
8740 if (StringRef(JArgs
[I
]).starts_with("-object-file-name=") &&
8741 Output
.isFilename()) {
8742 ArgStringList
NewArgs(JArgs
.begin(), JArgs
.begin() + I
);
8743 addDebugObjectName(Args
, NewArgs
, DebugCompilationDir
,
8744 Output
.getFilename());
8745 NewArgs
.append(JArgs
.begin() + I
+ 1, JArgs
.end());
8746 J
.replaceArguments(NewArgs
);
8752 assert(Output
.isFilename() && "Unexpected lipo output.");
8753 CmdArgs
.push_back("-o");
8754 CmdArgs
.push_back(Output
.getFilename());
8756 const llvm::Triple
&T
= getToolChain().getTriple();
8758 if (getDebugFissionKind(D
, Args
, A
) == DwarfFissionKind::Split
&&
8759 T
.isOSBinFormatELF()) {
8760 CmdArgs
.push_back("-split-dwarf-output");
8761 CmdArgs
.push_back(SplitDebugName(JA
, Args
, Input
, Output
));
8764 if (Triple
.isAMDGPU())
8765 handleAMDGPUCodeObjectVersionOptions(D
, Args
, CmdArgs
, /*IsCC1As=*/true);
8767 assert(Input
.isFilename() && "Invalid input.");
8768 CmdArgs
.push_back(Input
.getFilename());
8770 const char *Exec
= getToolChain().getDriver().getClangProgramPath();
8771 if (D
.CC1Main
&& !D
.CCGenDiagnostics
) {
8772 // Invoke cc1as directly in this process.
8773 C
.addCommand(std::make_unique
<CC1Command
>(
8774 JA
, *this, ResponseFileSupport::AtFileUTF8(), Exec
, CmdArgs
, Inputs
,
8775 Output
, D
.getPrependArg()));
8777 C
.addCommand(std::make_unique
<Command
>(
8778 JA
, *this, ResponseFileSupport::AtFileUTF8(), Exec
, CmdArgs
, Inputs
,
8779 Output
, D
.getPrependArg()));
8783 // Begin OffloadBundler
8784 void OffloadBundler::ConstructJob(Compilation
&C
, const JobAction
&JA
,
8785 const InputInfo
&Output
,
8786 const InputInfoList
&Inputs
,
8787 const llvm::opt::ArgList
&TCArgs
,
8788 const char *LinkingOutput
) const {
8789 // The version with only one output is expected to refer to a bundling job.
8790 assert(isa
<OffloadBundlingJobAction
>(JA
) && "Expecting bundling job!");
8792 // The bundling command looks like this:
8793 // clang-offload-bundler -type=bc
8794 // -targets=host-triple,openmp-triple1,openmp-triple2
8795 // -output=output_file
8796 // -input=unbundle_file_host
8797 // -input=unbundle_file_tgt1
8798 // -input=unbundle_file_tgt2
8800 ArgStringList CmdArgs
;
8803 CmdArgs
.push_back(TCArgs
.MakeArgString(
8804 Twine("-type=") + types::getTypeTempSuffix(Output
.getType())));
8806 assert(JA
.getInputs().size() == Inputs
.size() &&
8807 "Not have inputs for all dependence actions??");
8810 SmallString
<128> Triples
;
8811 Triples
+= "-targets=";
8812 for (unsigned I
= 0; I
< Inputs
.size(); ++I
) {
8816 // Find ToolChain for this input.
8817 Action::OffloadKind CurKind
= Action::OFK_Host
;
8818 const ToolChain
*CurTC
= &getToolChain();
8819 const Action
*CurDep
= JA
.getInputs()[I
];
8821 if (const auto *OA
= dyn_cast
<OffloadAction
>(CurDep
)) {
8823 OA
->doOnEachDependence([&](Action
*A
, const ToolChain
*TC
, const char *) {
8824 assert(CurTC
== nullptr && "Expected one dependence!");
8825 CurKind
= A
->getOffloadingDeviceKind();
8829 Triples
+= Action::GetOffloadKindName(CurKind
);
8831 Triples
+= CurTC
->getTriple().normalize();
8832 if ((CurKind
== Action::OFK_HIP
|| CurKind
== Action::OFK_Cuda
) &&
8833 !StringRef(CurDep
->getOffloadingArch()).empty()) {
8835 Triples
+= CurDep
->getOffloadingArch();
8838 // TODO: Replace parsing of -march flag. Can be done by storing GPUArch
8839 // with each toolchain.
8840 StringRef GPUArchName
;
8841 if (CurKind
== Action::OFK_OpenMP
) {
8842 // Extract GPUArch from -march argument in TC argument list.
8843 for (unsigned ArgIndex
= 0; ArgIndex
< TCArgs
.size(); ArgIndex
++) {
8844 auto ArchStr
= StringRef(TCArgs
.getArgString(ArgIndex
));
8845 auto Arch
= ArchStr
.starts_with_insensitive("-march=");
8847 GPUArchName
= ArchStr
.substr(7);
8852 Triples
+= GPUArchName
.str();
8855 CmdArgs
.push_back(TCArgs
.MakeArgString(Triples
));
8857 // Get bundled file command.
8859 TCArgs
.MakeArgString(Twine("-output=") + Output
.getFilename()));
8861 // Get unbundled files command.
8862 for (unsigned I
= 0; I
< Inputs
.size(); ++I
) {
8863 SmallString
<128> UB
;
8866 // Find ToolChain for this input.
8867 const ToolChain
*CurTC
= &getToolChain();
8868 if (const auto *OA
= dyn_cast
<OffloadAction
>(JA
.getInputs()[I
])) {
8870 OA
->doOnEachDependence([&](Action
*, const ToolChain
*TC
, const char *) {
8871 assert(CurTC
== nullptr && "Expected one dependence!");
8874 UB
+= C
.addTempFile(
8875 C
.getArgs().MakeArgString(CurTC
->getInputFilename(Inputs
[I
])));
8877 UB
+= CurTC
->getInputFilename(Inputs
[I
]);
8879 CmdArgs
.push_back(TCArgs
.MakeArgString(UB
));
8881 addOffloadCompressArgs(TCArgs
, CmdArgs
);
8882 // All the inputs are encoded as commands.
8883 C
.addCommand(std::make_unique
<Command
>(
8884 JA
, *this, ResponseFileSupport::None(),
8885 TCArgs
.MakeArgString(getToolChain().GetProgramPath(getShortName())),
8886 CmdArgs
, std::nullopt
, Output
));
8889 void OffloadBundler::ConstructJobMultipleOutputs(
8890 Compilation
&C
, const JobAction
&JA
, const InputInfoList
&Outputs
,
8891 const InputInfoList
&Inputs
, const llvm::opt::ArgList
&TCArgs
,
8892 const char *LinkingOutput
) const {
8893 // The version with multiple outputs is expected to refer to a unbundling job.
8894 auto &UA
= cast
<OffloadUnbundlingJobAction
>(JA
);
8896 // The unbundling command looks like this:
8897 // clang-offload-bundler -type=bc
8898 // -targets=host-triple,openmp-triple1,openmp-triple2
8899 // -input=input_file
8900 // -output=unbundle_file_host
8901 // -output=unbundle_file_tgt1
8902 // -output=unbundle_file_tgt2
8905 ArgStringList CmdArgs
;
8907 assert(Inputs
.size() == 1 && "Expecting to unbundle a single file!");
8908 InputInfo Input
= Inputs
.front();
8911 CmdArgs
.push_back(TCArgs
.MakeArgString(
8912 Twine("-type=") + types::getTypeTempSuffix(Input
.getType())));
8915 SmallString
<128> Triples
;
8916 Triples
+= "-targets=";
8917 auto DepInfo
= UA
.getDependentActionsInfo();
8918 for (unsigned I
= 0; I
< DepInfo
.size(); ++I
) {
8922 auto &Dep
= DepInfo
[I
];
8923 Triples
+= Action::GetOffloadKindName(Dep
.DependentOffloadKind
);
8925 Triples
+= Dep
.DependentToolChain
->getTriple().normalize();
8926 if ((Dep
.DependentOffloadKind
== Action::OFK_HIP
||
8927 Dep
.DependentOffloadKind
== Action::OFK_Cuda
) &&
8928 !Dep
.DependentBoundArch
.empty()) {
8930 Triples
+= Dep
.DependentBoundArch
;
8932 // TODO: Replace parsing of -march flag. Can be done by storing GPUArch
8933 // with each toolchain.
8934 StringRef GPUArchName
;
8935 if (Dep
.DependentOffloadKind
== Action::OFK_OpenMP
) {
8936 // Extract GPUArch from -march argument in TC argument list.
8937 for (unsigned ArgIndex
= 0; ArgIndex
< TCArgs
.size(); ArgIndex
++) {
8938 StringRef ArchStr
= StringRef(TCArgs
.getArgString(ArgIndex
));
8939 auto Arch
= ArchStr
.starts_with_insensitive("-march=");
8941 GPUArchName
= ArchStr
.substr(7);
8946 Triples
+= GPUArchName
.str();
8950 CmdArgs
.push_back(TCArgs
.MakeArgString(Triples
));
8952 // Get bundled file command.
8954 TCArgs
.MakeArgString(Twine("-input=") + Input
.getFilename()));
8956 // Get unbundled files command.
8957 for (unsigned I
= 0; I
< Outputs
.size(); ++I
) {
8958 SmallString
<128> UB
;
8960 UB
+= DepInfo
[I
].DependentToolChain
->getInputFilename(Outputs
[I
]);
8961 CmdArgs
.push_back(TCArgs
.MakeArgString(UB
));
8963 CmdArgs
.push_back("-unbundle");
8964 CmdArgs
.push_back("-allow-missing-bundles");
8965 if (TCArgs
.hasArg(options::OPT_v
))
8966 CmdArgs
.push_back("-verbose");
8968 // All the inputs are encoded as commands.
8969 C
.addCommand(std::make_unique
<Command
>(
8970 JA
, *this, ResponseFileSupport::None(),
8971 TCArgs
.MakeArgString(getToolChain().GetProgramPath(getShortName())),
8972 CmdArgs
, std::nullopt
, Outputs
));
8975 void OffloadPackager::ConstructJob(Compilation
&C
, const JobAction
&JA
,
8976 const InputInfo
&Output
,
8977 const InputInfoList
&Inputs
,
8978 const llvm::opt::ArgList
&Args
,
8979 const char *LinkingOutput
) const {
8980 ArgStringList CmdArgs
;
8982 // Add the output file name.
8983 assert(Output
.isFilename() && "Invalid output.");
8984 CmdArgs
.push_back("-o");
8985 CmdArgs
.push_back(Output
.getFilename());
8987 // Create the inputs to bundle the needed metadata.
8988 for (const InputInfo
&Input
: Inputs
) {
8989 const Action
*OffloadAction
= Input
.getAction();
8990 const ToolChain
*TC
= OffloadAction
->getOffloadingToolChain();
8991 const ArgList
&TCArgs
=
8992 C
.getArgsForToolChain(TC
, OffloadAction
->getOffloadingArch(),
8993 OffloadAction
->getOffloadingDeviceKind());
8994 StringRef File
= C
.getArgs().MakeArgString(TC
->getInputFilename(Input
));
8995 StringRef Arch
= OffloadAction
->getOffloadingArch()
8996 ? OffloadAction
->getOffloadingArch()
8997 : TCArgs
.getLastArgValue(options::OPT_march_EQ
);
8999 Action::GetOffloadKindName(OffloadAction
->getOffloadingDeviceKind());
9001 ArgStringList Features
;
9002 SmallVector
<StringRef
> FeatureArgs
;
9003 getTargetFeatures(TC
->getDriver(), TC
->getTriple(), TCArgs
, Features
,
9005 llvm::copy_if(Features
, std::back_inserter(FeatureArgs
),
9006 [](StringRef Arg
) { return !Arg
.starts_with("-target"); });
9008 if (TC
->getTriple().isAMDGPU()) {
9009 for (StringRef Feature
: llvm::split(Arch
.split(':').second
, ':')) {
9010 FeatureArgs
.emplace_back(
9011 Args
.MakeArgString(Feature
.take_back() + Feature
.drop_back()));
9015 // TODO: We need to pass in the full target-id and handle it properly in the
9017 SmallVector
<std::string
> Parts
{
9018 "file=" + File
.str(),
9019 "triple=" + TC
->getTripleString(),
9020 "arch=" + Arch
.str(),
9021 "kind=" + Kind
.str(),
9024 if (TC
->getDriver().isUsingLTO(/* IsOffload */ true) ||
9025 TC
->getTriple().isAMDGPU())
9026 for (StringRef Feature
: FeatureArgs
)
9027 Parts
.emplace_back("feature=" + Feature
.str());
9029 CmdArgs
.push_back(Args
.MakeArgString("--image=" + llvm::join(Parts
, ",")));
9032 C
.addCommand(std::make_unique
<Command
>(
9033 JA
, *this, ResponseFileSupport::None(),
9034 Args
.MakeArgString(getToolChain().GetProgramPath(getShortName())),
9035 CmdArgs
, Inputs
, Output
));
9038 void LinkerWrapper::ConstructJob(Compilation
&C
, const JobAction
&JA
,
9039 const InputInfo
&Output
,
9040 const InputInfoList
&Inputs
,
9041 const ArgList
&Args
,
9042 const char *LinkingOutput
) const {
9043 const Driver
&D
= getToolChain().getDriver();
9044 const llvm::Triple TheTriple
= getToolChain().getTriple();
9045 ArgStringList CmdArgs
;
9047 // Pass the CUDA path to the linker wrapper tool.
9048 for (Action::OffloadKind Kind
: {Action::OFK_Cuda
, Action::OFK_OpenMP
}) {
9049 auto TCRange
= C
.getOffloadToolChains(Kind
);
9050 for (auto &I
: llvm::make_range(TCRange
.first
, TCRange
.second
)) {
9051 const ToolChain
*TC
= I
.second
;
9052 if (TC
->getTriple().isNVPTX()) {
9053 CudaInstallationDetector
CudaInstallation(D
, TheTriple
, Args
);
9054 if (CudaInstallation
.isValid())
9055 CmdArgs
.push_back(Args
.MakeArgString(
9056 "--cuda-path=" + CudaInstallation
.getInstallPath()));
9062 // Pass in the optimization level to use for LTO.
9063 if (const Arg
*A
= Args
.getLastArg(options::OPT_O_Group
)) {
9065 if (A
->getOption().matches(options::OPT_O4
) ||
9066 A
->getOption().matches(options::OPT_Ofast
))
9068 else if (A
->getOption().matches(options::OPT_O
)) {
9069 OOpt
= A
->getValue();
9072 else if (OOpt
== "s" || OOpt
== "z")
9074 } else if (A
->getOption().matches(options::OPT_O0
))
9077 CmdArgs
.push_back(Args
.MakeArgString(Twine("--opt-level=O") + OOpt
));
9081 Args
.MakeArgString("--host-triple=" + TheTriple
.getTriple()));
9082 if (Args
.hasArg(options::OPT_v
))
9083 CmdArgs
.push_back("--wrapper-verbose");
9085 if (const Arg
*A
= Args
.getLastArg(options::OPT_g_Group
)) {
9086 if (!A
->getOption().matches(options::OPT_g0
))
9087 CmdArgs
.push_back("--device-debug");
9090 // code-object-version=X needs to be passed to clang-linker-wrapper to ensure
9091 // that it is used by lld.
9092 if (const Arg
*A
= Args
.getLastArg(options::OPT_mcode_object_version_EQ
)) {
9093 CmdArgs
.push_back(Args
.MakeArgString("-mllvm"));
9094 CmdArgs
.push_back(Args
.MakeArgString(
9095 Twine("--amdhsa-code-object-version=") + A
->getValue()));
9098 for (const auto &A
: Args
.getAllArgValues(options::OPT_Xcuda_ptxas
))
9099 CmdArgs
.push_back(Args
.MakeArgString("--ptxas-arg=" + A
));
9101 // Forward remarks passes to the LLVM backend in the wrapper.
9102 if (const Arg
*A
= Args
.getLastArg(options::OPT_Rpass_EQ
))
9103 CmdArgs
.push_back(Args
.MakeArgString(Twine("--offload-opt=-pass-remarks=") +
9105 if (const Arg
*A
= Args
.getLastArg(options::OPT_Rpass_missed_EQ
))
9106 CmdArgs
.push_back(Args
.MakeArgString(
9107 Twine("--offload-opt=-pass-remarks-missed=") + A
->getValue()));
9108 if (const Arg
*A
= Args
.getLastArg(options::OPT_Rpass_analysis_EQ
))
9109 CmdArgs
.push_back(Args
.MakeArgString(
9110 Twine("--offload-opt=-pass-remarks-analysis=") + A
->getValue()));
9111 if (Args
.getLastArg(options::OPT_save_temps_EQ
))
9112 CmdArgs
.push_back("--save-temps");
9114 // Construct the link job so we can wrap around it.
9115 Linker
->ConstructJob(C
, JA
, Output
, Inputs
, Args
, LinkingOutput
);
9116 const auto &LinkCommand
= C
.getJobs().getJobs().back();
9118 // Forward -Xoffload-linker<-triple> arguments to the device link job.
9119 for (Arg
*A
: Args
.filtered(options::OPT_Xoffload_linker
)) {
9120 StringRef Val
= A
->getValue(0);
9123 Args
.MakeArgString(Twine("--device-linker=") + A
->getValue(1)));
9125 CmdArgs
.push_back(Args
.MakeArgString(
9126 "--device-linker=" +
9127 ToolChain::getOpenMPTriple(Val
.drop_front()).getTriple() + "=" +
9130 Args
.ClaimAllArgs(options::OPT_Xoffload_linker
);
9132 // Embed bitcode instead of an object in JIT mode.
9133 if (Args
.hasFlag(options::OPT_fopenmp_target_jit
,
9134 options::OPT_fno_openmp_target_jit
, false))
9135 CmdArgs
.push_back("--embed-bitcode");
9137 // Forward `-mllvm` arguments to the LLVM invocations if present.
9138 for (Arg
*A
: Args
.filtered(options::OPT_mllvm
)) {
9139 CmdArgs
.push_back("-mllvm");
9140 CmdArgs
.push_back(A
->getValue());
9144 // Add the linker arguments to be forwarded by the wrapper.
9145 CmdArgs
.push_back(Args
.MakeArgString(Twine("--linker-path=") +
9146 LinkCommand
->getExecutable()));
9147 for (const char *LinkArg
: LinkCommand
->getArguments())
9148 CmdArgs
.push_back(LinkArg
);
9150 addOffloadCompressArgs(Args
, CmdArgs
);
9153 Args
.MakeArgString(getToolChain().GetProgramPath("clang-linker-wrapper"));
9155 // Replace the executable and arguments of the link job with the
9157 LinkCommand
->replaceExecutable(Exec
);
9158 LinkCommand
->replaceArguments(CmdArgs
);