Coverage Report

Created: 2023-09-12 09:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- Clang.cpp - Clang+LLVM ToolChain Implementations --------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "Clang.h"
10
#include "AMDGPU.h"
11
#include "Arch/AArch64.h"
12
#include "Arch/ARM.h"
13
#include "Arch/CSKY.h"
14
#include "Arch/LoongArch.h"
15
#include "Arch/M68k.h"
16
#include "Arch/Mips.h"
17
#include "Arch/PPC.h"
18
#include "Arch/RISCV.h"
19
#include "Arch/Sparc.h"
20
#include "Arch/SystemZ.h"
21
#include "Arch/VE.h"
22
#include "Arch/X86.h"
23
#include "CommonArgs.h"
24
#include "Hexagon.h"
25
#include "MSP430.h"
26
#include "PS4CPU.h"
27
#include "clang/Basic/CLWarnings.h"
28
#include "clang/Basic/CharInfo.h"
29
#include "clang/Basic/CodeGenOptions.h"
30
#include "clang/Basic/HeaderInclude.h"
31
#include "clang/Basic/LangOptions.h"
32
#include "clang/Basic/MakeSupport.h"
33
#include "clang/Basic/ObjCRuntime.h"
34
#include "clang/Basic/Version.h"
35
#include "clang/Config/config.h"
36
#include "clang/Driver/Action.h"
37
#include "clang/Driver/Distro.h"
38
#include "clang/Driver/DriverDiagnostic.h"
39
#include "clang/Driver/InputInfo.h"
40
#include "clang/Driver/Options.h"
41
#include "clang/Driver/SanitizerArgs.h"
42
#include "clang/Driver/Types.h"
43
#include "clang/Driver/XRayArgs.h"
44
#include "llvm/ADT/SmallSet.h"
45
#include "llvm/ADT/StringExtras.h"
46
#include "llvm/Config/llvm-config.h"
47
#include "llvm/Option/ArgList.h"
48
#include "llvm/Support/CodeGen.h"
49
#include "llvm/Support/Compiler.h"
50
#include "llvm/Support/Compression.h"
51
#include "llvm/Support/Error.h"
52
#include "llvm/Support/FileSystem.h"
53
#include "llvm/Support/Path.h"
54
#include "llvm/Support/Process.h"
55
#include "llvm/Support/RISCVISAInfo.h"
56
#include "llvm/Support/YAMLParser.h"
57
#include "llvm/TargetParser/ARMTargetParserCommon.h"
58
#include "llvm/TargetParser/Host.h"
59
#include "llvm/TargetParser/LoongArchTargetParser.h"
60
#include "llvm/TargetParser/RISCVTargetParser.h"
61
#include <cctype>
62
63
using namespace clang::driver;
64
using namespace clang::driver::tools;
65
using namespace clang;
66
using namespace llvm::opt;
67
68
47.5k
static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
69
47.5k
  if (Arg *A = Args.getLastArg(clang::driver::options::OPT_C, options::OPT_CC,
70
47.5k
                               options::OPT_fminimize_whitespace,
71
47.5k
                               options::OPT_fno_minimize_whitespace)) {
72
8
    if (!Args.hasArg(options::OPT_E) && 
!Args.hasArg(options::OPT__SLASH_P)4
&&
73
8
        
!Args.hasArg(options::OPT__SLASH_EP)3
&&
!D.CCCIsCPP()3
) {
74
3
      D.Diag(clang::diag::err_drv_argument_only_allowed_with)
75
3
          << A->getBaseArg().getAsString(Args)
76
3
          << (D.IsCLMode() ? 
"/E, /P or /EP"1
:
"-E"2
);
77
3
    }
78
8
  }
79
47.5k
}
80
81
47.7k
static void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) {
82
  // In gcc, only ARM checks this, but it seems reasonable to check universally.
83
47.7k
  if (Args.hasArg(options::OPT_static))
84
108
    if (const Arg *A =
85
108
            Args.getLastArg(options::OPT_dynamic, options::OPT_mdynamic_no_pic))
86
1
      D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
87
1
                                                      << "-static";
88
47.7k
}
89
90
// Add backslashes to escape spaces and other backslashes.
91
// This is used for the space-separated argument list specified with
92
// the -dwarf-debug-flags option.
93
static void EscapeSpacesAndBackslashes(const char *Arg,
94
364
                                       SmallVectorImpl<char> &Res) {
95
9.58k
  for (; *Arg; 
++Arg9.21k
) {
96
9.21k
    switch (*Arg) {
97
9.20k
    default:
98
9.20k
      break;
99
9.20k
    case ' ':
100
12
    case '\\':
101
12
      Res.push_back('\\');
102
12
      break;
103
9.21k
    }
104
9.21k
    Res.push_back(*Arg);
105
9.21k
  }
106
364
}
107
108
/// Apply \a Work on the current tool chain \a RegularToolChain and any other
109
/// offloading tool chain that is associated with the current action \a JA.
110
static void
111
forAllAssociatedToolChains(Compilation &C, const JobAction &JA,
112
                           const ToolChain &RegularToolChain,
113
78.9k
                           llvm::function_ref<void(const ToolChain &)> Work) {
114
  // Apply Work on the current/regular tool chain.
115
78.9k
  Work(RegularToolChain);
116
117
  // Apply Work on all the offloading tool chains associated with the current
118
  // action.
119
78.9k
  if (JA.isHostOffloading(Action::OFK_Cuda))
120
136
    Work(*C.getSingleOffloadToolChain<Action::OFK_Cuda>());
121
78.7k
  else if (JA.isDeviceOffloading(Action::OFK_Cuda))
122
142
    Work(*C.getSingleOffloadToolChain<Action::OFK_Host>());
123
78.6k
  else if (JA.isHostOffloading(Action::OFK_HIP))
124
486
    Work(*C.getSingleOffloadToolChain<Action::OFK_HIP>());
125
78.1k
  else if (JA.isDeviceOffloading(Action::OFK_HIP))
126
798
    Work(*C.getSingleOffloadToolChain<Action::OFK_Host>());
127
128
78.9k
  if (JA.isHostOffloading(Action::OFK_OpenMP)) {
129
8
    auto TCs = C.getOffloadToolChains<Action::OFK_OpenMP>();
130
16
    for (auto II = TCs.first, IE = TCs.second; II != IE; 
++II8
)
131
8
      Work(*II->second);
132
78.8k
  } else if (JA.isDeviceOffloading(Action::OFK_OpenMP))
133
9
    Work(*C.getSingleOffloadToolChain<Action::OFK_Host>());
134
135
  //
136
  // TODO: Add support for other offloading programming models here.
137
  //
138
78.9k
}
139
140
/// This is a helper function for validating the optional refinement step
141
/// parameter in reciprocal argument strings. Return false if there is an error
142
/// parsing the refinement step. Otherwise, return true and set the Position
143
/// of the refinement step in the input string.
144
static bool getRefinementStep(StringRef In, const Driver &D,
145
42
                              const Arg &A, size_t &Position) {
146
42
  const char RefinementStepToken = ':';
147
42
  Position = In.find(RefinementStepToken);
148
42
  if (Position != StringRef::npos) {
149
15
    StringRef Option = A.getOption().getName();
150
15
    StringRef RefStep = In.substr(Position + 1);
151
    // Allow exactly one numeric character for the additional refinement
152
    // step parameter. This is reasonable for all currently-supported
153
    // operations and architectures because we would expect that a larger value
154
    // of refinement steps would cause the estimate "optimization" to
155
    // under-perform the native operation. Also, if the estimate does not
156
    // converge quickly, it probably will not ever converge, so further
157
    // refinement steps will not produce a better answer.
158
15
    if (RefStep.size() != 1) {
159
2
      D.Diag(diag::err_drv_invalid_value) << Option << RefStep;
160
2
      return false;
161
2
    }
162
13
    char RefStepChar = RefStep[0];
163
13
    if (RefStepChar < '0' || RefStepChar > '9') {
164
0
      D.Diag(diag::err_drv_invalid_value) << Option << RefStep;
165
0
      return false;
166
0
    }
167
13
  }
168
40
  return true;
169
42
}
170
171
/// The -mrecip flag requires processing of many optional parameters.
172
static void ParseMRecip(const Driver &D, const ArgList &Args,
173
47.7k
                        ArgStringList &OutStrings) {
174
47.7k
  StringRef DisabledPrefixIn = "!";
175
47.7k
  StringRef DisabledPrefixOut = "!";
176
47.7k
  StringRef EnabledPrefixOut = "";
177
47.7k
  StringRef Out = "-mrecip=";
178
179
47.7k
  Arg *A = Args.getLastArg(options::OPT_mrecip, options::OPT_mrecip_EQ);
180
47.7k
  if (!A)
181
47.7k
    return;
182
183
29
  unsigned NumOptions = A->getNumValues();
184
29
  if (NumOptions == 0) {
185
    // No option is the same as "all".
186
1
    OutStrings.push_back(Args.MakeArgString(Out + "all"));
187
1
    return;
188
1
  }
189
190
  // Pass through "all", "none", or "default" with an optional refinement step.
191
28
  if (NumOptions == 1) {
192
14
    StringRef Val = A->getValue(0);
193
14
    size_t RefStepLoc;
194
14
    if (!getRefinementStep(Val, D, *A, RefStepLoc))
195
2
      return;
196
12
    StringRef ValBase = Val.slice(0, RefStepLoc);
197
12
    if (ValBase == "all" || 
ValBase == "none"10
||
ValBase == "default"9
) {
198
4
      OutStrings.push_back(Args.MakeArgString(Out + Val));
199
4
      return;
200
4
    }
201
12
  }
202
203
  // Each reciprocal type may be enabled or disabled individually.
204
  // Check each input value for validity, concatenate them all back together,
205
  // and pass through.
206
207
22
  llvm::StringMap<bool> OptionStrings;
208
22
  OptionStrings.insert(std::make_pair("divd", false));
209
22
  OptionStrings.insert(std::make_pair("divf", false));
210
22
  OptionStrings.insert(std::make_pair("divh", false));
211
22
  OptionStrings.insert(std::make_pair("vec-divd", false));
212
22
  OptionStrings.insert(std::make_pair("vec-divf", false));
213
22
  OptionStrings.insert(std::make_pair("vec-divh", false));
214
22
  OptionStrings.insert(std::make_pair("sqrtd", false));
215
22
  OptionStrings.insert(std::make_pair("sqrtf", false));
216
22
  OptionStrings.insert(std::make_pair("sqrth", false));
217
22
  OptionStrings.insert(std::make_pair("vec-sqrtd", false));
218
22
  OptionStrings.insert(std::make_pair("vec-sqrtf", false));
219
22
  OptionStrings.insert(std::make_pair("vec-sqrth", false));
220
221
44
  for (unsigned i = 0; i != NumOptions; 
++i22
) {
222
28
    StringRef Val = A->getValue(i);
223
224
28
    bool IsDisabled = Val.startswith(DisabledPrefixIn);
225
    // Ignore the disablement token for string matching.
226
28
    if (IsDisabled)
227
3
      Val = Val.substr(1);
228
229
28
    size_t RefStep;
230
28
    if (!getRefinementStep(Val, D, *A, RefStep))
231
0
      return;
232
233
28
    StringRef ValBase = Val.slice(0, RefStep);
234
28
    llvm::StringMap<bool>::iterator OptionIter = OptionStrings.find(ValBase);
235
28
    if (OptionIter == OptionStrings.end()) {
236
      // Try again specifying float suffix.
237
8
      OptionIter = OptionStrings.find(ValBase.str() + 'f');
238
8
      if (OptionIter == OptionStrings.end()) {
239
        // The input name did not match any known option string.
240
1
        D.Diag(diag::err_drv_unknown_argument) << Val;
241
1
        return;
242
1
      }
243
      // The option was specified without a half or float or double suffix.
244
      // Make sure that the double or half entry was not already specified.
245
      // The float entry will be checked below.
246
7
      if (OptionStrings[ValBase.str() + 'd'] ||
247
7
          OptionStrings[ValBase.str() + 'h']) {
248
1
        D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Val;
249
1
        return;
250
1
      }
251
7
    }
252
253
26
    if (OptionIter->second == true) {
254
      // Duplicate option specified.
255
4
      D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Val;
256
4
      return;
257
4
    }
258
259
    // Mark the matched option as found. Do not allow duplicate specifiers.
260
22
    OptionIter->second = true;
261
262
    // If the precision was not specified, also mark the double and half entry
263
    // as found.
264
22
    if (ValBase.back() != 'f' && 
ValBase.back() != 'd'16
&&
ValBase.back() != 'h'10
) {
265
6
      OptionStrings[ValBase.str() + 'd'] = true;
266
6
      OptionStrings[ValBase.str() + 'h'] = true;
267
6
    }
268
269
    // Build the output string.
270
22
    StringRef Prefix = IsDisabled ? 
DisabledPrefixOut3
:
EnabledPrefixOut19
;
271
22
    Out = Args.MakeArgString(Out + Prefix + Val);
272
22
    if (i != NumOptions - 1)
273
12
      Out = Args.MakeArgString(Out + ",");
274
22
  }
275
276
16
  OutStrings.push_back(Args.MakeArgString(Out));
277
16
}
278
279
/// The -mprefer-vector-width option accepts either a positive integer
280
/// or the string "none".
281
static void ParseMPreferVectorWidth(const Driver &D, const ArgList &Args,
282
47.7k
                                    ArgStringList &CmdArgs) {
283
47.7k
  Arg *A = Args.getLastArg(options::OPT_mprefer_vector_width_EQ);
284
47.7k
  if (!A)
285
47.7k
    return;
286
287
9
  StringRef Value = A->getValue();
288
9
  if (Value == "none") {
289
1
    CmdArgs.push_back("-mprefer-vector-width=none");
290
8
  } else {
291
8
    unsigned Width;
292
8
    if (Value.getAsInteger(10, Width)) {
293
3
      D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
294
3
      return;
295
3
    }
296
5
    CmdArgs.push_back(Args.MakeArgString("-mprefer-vector-width=" + Value));
297
5
  }
298
9
}
299
300
static bool
301
shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime,
302
3.03k
                                          const llvm::Triple &Triple) {
303
  // We use the zero-cost exception tables for Objective-C if the non-fragile
304
  // ABI is enabled or when compiling for x86_64 and ARM on Snow Leopard and
305
  // later.
306
3.03k
  if (runtime.isNonFragile())
307
2.90k
    return true;
308
309
124
  if (!Triple.isMacOSX())
310
107
    return false;
311
312
17
  return (!Triple.isMacOSXVersionLT(10, 5) &&
313
17
          
(13
Triple.getArch() == llvm::Triple::x86_6413
||
314
13
           
Triple.getArch() == llvm::Triple::arm9
));
315
124
}
316
317
/// Adds exception related arguments to the driver command arguments. There's a
318
/// main flag, -fexceptions and also language specific flags to enable/disable
319
/// C++ and Objective-C exceptions. This makes it possible to for example
320
/// disable C++ exceptions but enable Objective-C exceptions.
321
static bool addExceptionArgs(const ArgList &Args, types::ID InputType,
322
                             const ToolChain &TC, bool KernelOrKext,
323
                             const ObjCRuntime &objcRuntime,
324
47.0k
                             ArgStringList &CmdArgs) {
325
47.0k
  const llvm::Triple &Triple = TC.getTriple();
326
327
47.0k
  if (KernelOrKext) {
328
    // -mkernel and -fapple-kext imply no exceptions, so claim exception related
329
    // arguments now to avoid warnings about unused arguments.
330
30
    Args.ClaimAllArgs(options::OPT_fexceptions);
331
30
    Args.ClaimAllArgs(options::OPT_fno_exceptions);
332
30
    Args.ClaimAllArgs(options::OPT_fobjc_exceptions);
333
30
    Args.ClaimAllArgs(options::OPT_fno_objc_exceptions);
334
30
    Args.ClaimAllArgs(options::OPT_fcxx_exceptions);
335
30
    Args.ClaimAllArgs(options::OPT_fno_cxx_exceptions);
336
30
    Args.ClaimAllArgs(options::OPT_fasync_exceptions);
337
30
    Args.ClaimAllArgs(options::OPT_fno_async_exceptions);
338
30
    return false;
339
30
  }
340
341
  // See if the user explicitly enabled exceptions.
342
47.0k
  bool EH = Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
343
47.0k
                         false);
344
345
47.0k
  bool EHa = Args.hasFlag(options::OPT_fasync_exceptions,
346
47.0k
                          options::OPT_fno_async_exceptions, false);
347
47.0k
  if (EHa) {
348
0
    CmdArgs.push_back("-fasync-exceptions");
349
0
    EH = true;
350
0
  }
351
352
  // Obj-C exceptions are enabled by default, regardless of -fexceptions. This
353
  // is not necessarily sensible, but follows GCC.
354
47.0k
  if (types::isObjC(InputType) &&
355
47.0k
      Args.hasFlag(options::OPT_fobjc_exceptions,
356
3.03k
                   options::OPT_fno_objc_exceptions, true)) {
357
3.03k
    CmdArgs.push_back("-fobjc-exceptions");
358
359
3.03k
    EH |= shouldUseExceptionTablesForObjCExceptions(objcRuntime, Triple);
360
3.03k
  }
361
362
47.0k
  if (types::isCXX(InputType)) {
363
    // Disable C++ EH by default on XCore and PS4/PS5.
364
31.2k
    bool CXXExceptionsEnabled = Triple.getArch() != llvm::Triple::xcore &&
365
31.2k
                                
!Triple.isPS()31.2k
&&
!Triple.isDriverKit()31.2k
;
366
31.2k
    Arg *ExceptionArg = Args.getLastArg(
367
31.2k
        options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions,
368
31.2k
        options::OPT_fexceptions, options::OPT_fno_exceptions);
369
31.2k
    if (ExceptionArg)
370
13.7k
      CXXExceptionsEnabled =
371
13.7k
          ExceptionArg->getOption().matches(options::OPT_fcxx_exceptions) ||
372
13.7k
          
ExceptionArg->getOption().matches(options::OPT_fexceptions)13.7k
;
373
374
31.2k
    if (CXXExceptionsEnabled) {
375
31.1k
      CmdArgs.push_back("-fcxx-exceptions");
376
377
31.1k
      EH = true;
378
31.1k
    }
379
31.2k
  }
380
381
  // OPT_fignore_exceptions means exception could still be thrown,
382
  // but no clean up or catch would happen in current module.
383
  // So we do not set EH to false.
384
47.0k
  Args.AddLastArg(CmdArgs, options::OPT_fignore_exceptions);
385
386
47.0k
  if (EH)
387
34.4k
    CmdArgs.push_back("-fexceptions");
388
47.0k
  return EH;
389
47.0k
}
390
391
static bool ShouldEnableAutolink(const ArgList &Args, const ToolChain &TC,
392
47.7k
                                 const JobAction &JA) {
393
47.7k
  bool Default = true;
394
47.7k
  if (TC.getTriple().isOSDarwin()) {
395
    // The native darwin assembler doesn't support the linker_option directives,
396
    // so we disable them if we think the .s file will be passed to it.
397
17.7k
    Default = TC.useIntegratedAs();
398
17.7k
  }
399
  // The linker_option directives are intended for host compilation.
400
47.7k
  if (JA.isDeviceOffloading(Action::OFK_Cuda) ||
401
47.7k
      
JA.isDeviceOffloading(Action::OFK_HIP)47.6k
)
402
510
    Default = false;
403
47.7k
  return Args.hasFlag(options::OPT_fautolink, options::OPT_fno_autolink,
404
47.7k
                      Default);
405
47.7k
}
406
407
47.7k
static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) {
408
47.7k
  switch (Triple.getArch()){
409
45.8k
  default:
410
45.8k
    return false;
411
1.84k
  case llvm::Triple::arm:
412
1.90k
  case llvm::Triple::thumb:
413
    // ARM Darwin targets require a frame pointer to be always present to aid
414
    // offline debugging via backtraces.
415
1.90k
    return Triple.isOSDarwin();
416
47.7k
  }
417
47.7k
}
418
419
static bool useFramePointerForTargetByDefault(const ArgList &Args,
420
47.5k
                                              const llvm::Triple &Triple) {
421
47.5k
  if (Args.hasArg(options::OPT_pg) && 
!Args.hasArg(options::OPT_mfentry)49
)
422
45
    return true;
423
424
47.5k
  if (Triple.isAndroid()) {
425
198
    switch (Triple.getArch()) {
426
67
    case llvm::Triple::aarch64:
427
152
    case llvm::Triple::arm:
428
152
    case llvm::Triple::armeb:
429
154
    case llvm::Triple::thumb:
430
154
    case llvm::Triple::thumbeb:
431
166
    case llvm::Triple::riscv64:
432
166
      return true;
433
32
    default:
434
32
      break;
435
198
    }
436
198
  }
437
438
47.3k
  switch (Triple.getArch()) {
439
14
  case llvm::Triple::xcore:
440
111
  case llvm::Triple::wasm32:
441
143
  case llvm::Triple::wasm64:
442
192
  case llvm::Triple::msp430:
443
    // XCore never wants frame pointers, regardless of OS.
444
    // WebAssembly never wants frame pointers.
445
192
    return false;
446
231
  case llvm::Triple::ppc:
447
239
  case llvm::Triple::ppcle:
448
474
  case llvm::Triple::ppc64:
449
591
  case llvm::Triple::ppc64le:
450
983
  case llvm::Triple::riscv32:
451
1.31k
  case llvm::Triple::riscv64:
452
1.44k
  case llvm::Triple::sparc:
453
1.45k
  case llvm::Triple::sparcel:
454
1.52k
  case llvm::Triple::sparcv9:
455
2.19k
  case llvm::Triple::amdgcn:
456
2.25k
  case llvm::Triple::r600:
457
2.28k
  case llvm::Triple::csky:
458
2.32k
  case llvm::Triple::loongarch32:
459
2.43k
  case llvm::Triple::loongarch64:
460
2.43k
    return !areOptimizationsEnabled(Args);
461
44.7k
  default:
462
44.7k
    break;
463
47.3k
  }
464
465
44.7k
  if (Triple.isOSFuchsia() || 
Triple.isOSNetBSD()44.6k
) {
466
187
    return !areOptimizationsEnabled(Args);
467
187
  }
468
469
44.5k
  if (Triple.isOSLinux() || 
Triple.isOSHurd()40.4k
) {
470
4.07k
    switch (Triple.getArch()) {
471
    // Don't use a frame pointer on linux if optimizing for certain targets.
472
450
    case llvm::Triple::arm:
473
493
    case llvm::Triple::armeb:
474
506
    case llvm::Triple::thumb:
475
517
    case llvm::Triple::thumbeb:
476
565
    case llvm::Triple::mips64:
477
600
    case llvm::Triple::mips64el:
478
768
    case llvm::Triple::mips:
479
800
    case llvm::Triple::mipsel:
480
844
    case llvm::Triple::systemz:
481
1.24k
    case llvm::Triple::x86:
482
3.64k
    case llvm::Triple::x86_64:
483
3.64k
      return !areOptimizationsEnabled(Args);
484
433
    default:
485
433
      return true;
486
4.07k
    }
487
4.07k
  }
488
489
40.4k
  if (Triple.isOSWindows()) {
490
8.72k
    switch (Triple.getArch()) {
491
183
    case llvm::Triple::x86:
492
183
      return !areOptimizationsEnabled(Args);
493
8.44k
    case llvm::Triple::x86_64:
494
8.44k
      return Triple.isOSBinFormatMachO();
495
58
    case llvm::Triple::arm:
496
72
    case llvm::Triple::thumb:
497
      // Windows on ARM builds with FPO disabled to aid fast stack walking
498
72
      return true;
499
31
    default:
500
      // All other supported Windows ISAs use xdata unwind information, so frame
501
      // pointers are not generally useful.
502
31
      return false;
503
8.72k
    }
504
8.72k
  }
505
506
31.7k
  return true;
507
40.4k
}
508
509
static CodeGenOptions::FramePointerKind
510
47.7k
getFramePointerKind(const ArgList &Args, const llvm::Triple &Triple) {
511
  // We have 4 states:
512
  //
513
  //  00) leaf retained, non-leaf retained
514
  //  01) leaf retained, non-leaf omitted (this is invalid)
515
  //  10) leaf omitted, non-leaf retained
516
  //      (what -momit-leaf-frame-pointer was designed for)
517
  //  11) leaf omitted, non-leaf omitted
518
  //
519
  //  "omit" options taking precedence over "no-omit" options is the only way
520
  //  to make 3 valid states representable
521
47.7k
  Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
522
47.7k
                           options::OPT_fno_omit_frame_pointer);
523
47.7k
  bool OmitFP = A && 
A->getOption().matches(options::OPT_fomit_frame_pointer)55
;
524
47.7k
  bool NoOmitFP =
525
47.7k
      A && 
A->getOption().matches(options::OPT_fno_omit_frame_pointer)55
;
526
47.7k
  bool OmitLeafFP =
527
47.7k
      Args.hasFlag(options::OPT_momit_leaf_frame_pointer,
528
47.7k
                   options::OPT_mno_omit_leaf_frame_pointer,
529
47.7k
                   Triple.isAArch64() || 
Triple.isPS()45.9k
||
Triple.isVE()45.6k
||
530
47.7k
                   
(45.6k
Triple.isAndroid()45.6k
&&
Triple.isRISCV64()131
));
531
47.7k
  if (NoOmitFP || 
mustUseNonLeafFramePointerForTarget(Triple)47.7k
||
532
47.7k
      
(47.6k
!OmitFP47.6k
&&
useFramePointerForTargetByDefault(Args, Triple)47.5k
)) {
533
38.8k
    if (OmitLeafFP)
534
2.05k
      return CodeGenOptions::FramePointerKind::NonLeaf;
535
36.7k
    return CodeGenOptions::FramePointerKind::All;
536
38.8k
  }
537
8.90k
  return CodeGenOptions::FramePointerKind::None;
538
47.7k
}
539
540
/// Add a CC1 option to specify the debug compilation directory.
541
static const char *addDebugCompDirArg(const ArgList &Args,
542
                                      ArgStringList &CmdArgs,
543
48.2k
                                      const llvm::vfs::FileSystem &VFS) {
544
48.2k
  if (Arg *A = Args.getLastArg(options::OPT_ffile_compilation_dir_EQ,
545
48.2k
                               options::OPT_fdebug_compilation_dir_EQ)) {
546
18
    if (A->getOption().matches(options::OPT_ffile_compilation_dir_EQ))
547
3
      CmdArgs.push_back(Args.MakeArgString(Twine("-fdebug-compilation-dir=") +
548
3
                                           A->getValue()));
549
15
    else
550
15
      A->render(Args, CmdArgs);
551
48.2k
  } else if (llvm::ErrorOr<std::string> CWD =
552
48.2k
                 VFS.getCurrentWorkingDirectory()) {
553
48.2k
    CmdArgs.push_back(Args.MakeArgString("-fdebug-compilation-dir=" + *CWD));
554
48.2k
  }
555
48.2k
  StringRef Path(CmdArgs.back());
556
48.2k
  return Path.substr(Path.find('=') + 1).data();
557
48.2k
}
558
559
static void addDebugObjectName(const ArgList &Args, ArgStringList &CmdArgs,
560
                               const char *DebugCompilationDir,
561
102
                               const char *OutputFileName) {
562
  // No need to generate a value for -object-file-name if it was provided.
563
102
  for (auto *Arg : Args.filtered(options::OPT_Xclang))
564
4
    if (StringRef(Arg->getValue()).startswith("-object-file-name"))
565
0
      return;
566
567
102
  if (Args.hasArg(options::OPT_object_file_name_EQ))
568
0
    return;
569
570
102
  SmallString<128> ObjFileNameForDebug(OutputFileName);
571
102
  if (ObjFileNameForDebug != "-" &&
572
102
      
!llvm::sys::path::is_absolute(ObjFileNameForDebug)77
&&
573
102
      
(49
!DebugCompilationDir49
||
574
49
       llvm::sys::path::is_absolute(DebugCompilationDir))) {
575
    // Make the path absolute in the debug infos like MSVC does.
576
38
    llvm::sys::fs::make_absolute(ObjFileNameForDebug);
577
38
  }
578
  // If the object file name is a relative path, then always use Windows
579
  // backslash style as -object-file-name is used for embedding object file path
580
  // in codeview and it can only be generated when targeting on Windows.
581
  // Otherwise, just use native absolute path.
582
102
  llvm::sys::path::Style Style =
583
102
      llvm::sys::path::is_absolute(ObjFileNameForDebug)
584
102
          ? 
llvm::sys::path::Style::native66
585
102
          : 
llvm::sys::path::Style::windows_backslash36
;
586
102
  llvm::sys::path::remove_dots(ObjFileNameForDebug, /*remove_dot_dot=*/true,
587
102
                               Style);
588
102
  CmdArgs.push_back(
589
102
      Args.MakeArgString(Twine("-object-file-name=") + ObjFileNameForDebug));
590
102
}
591
592
/// Add a CC1 and CC1AS option to specify the debug file path prefix map.
593
static void addDebugPrefixMapArg(const Driver &D, const ToolChain &TC,
594
48.1k
                                 const ArgList &Args, ArgStringList &CmdArgs) {
595
48.1k
  auto AddOneArg = [&](StringRef Map, StringRef Name) {
596
31
    if (!Map.contains('='))
597
5
      D.Diag(diag::err_drv_invalid_argument_to_option) << Map << Name;
598
26
    else
599
26
      CmdArgs.push_back(Args.MakeArgString("-fdebug-prefix-map=" + Map));
600
31
  };
601
602
48.1k
  for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ,
603
48.1k
                                    options::OPT_fdebug_prefix_map_EQ)) {
604
25
    AddOneArg(A->getValue(), A->getOption().getName());
605
25
    A->claim();
606
25
  }
607
48.1k
  std::string GlobalRemapEntry = TC.GetGlobalDebugPathRemapping();
608
48.1k
  if (GlobalRemapEntry.empty())
609
48.1k
    return;
610
7
  AddOneArg(GlobalRemapEntry, "environment");
611
7
}
612
613
/// Add a CC1 and CC1AS option to specify the macro file path prefix map.
614
static void addMacroPrefixMapArg(const Driver &D, const ArgList &Args,
615
47.5k
                                 ArgStringList &CmdArgs) {
616
47.5k
  for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ,
617
47.5k
                                    options::OPT_fmacro_prefix_map_EQ)) {
618
25
    StringRef Map = A->getValue();
619
25
    if (!Map.contains('='))
620
2
      D.Diag(diag::err_drv_invalid_argument_to_option)
621
2
          << Map << A->getOption().getName();
622
23
    else
623
23
      CmdArgs.push_back(Args.MakeArgString("-fmacro-prefix-map=" + Map));
624
25
    A->claim();
625
25
  }
626
47.5k
}
627
628
/// Add a CC1 and CC1AS option to specify the coverage file path prefix map.
629
static void addCoveragePrefixMapArg(const Driver &D, const ArgList &Args,
630
47.4k
                                   ArgStringList &CmdArgs) {
631
47.4k
  for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ,
632
47.4k
                                    options::OPT_fcoverage_prefix_map_EQ)) {
633
20
    StringRef Map = A->getValue();
634
20
    if (!Map.contains('='))
635
2
      D.Diag(diag::err_drv_invalid_argument_to_option)
636
2
          << Map << A->getOption().getName();
637
18
    else
638
18
      CmdArgs.push_back(Args.MakeArgString("-fcoverage-prefix-map=" + Map));
639
20
    A->claim();
640
20
  }
641
47.4k
}
642
643
/// Vectorize at all optimization levels greater than 1 except for -Oz.
644
/// For -Oz the loop vectorizer is disabled, while the slp vectorizer is
645
/// enabled.
646
95.5k
static bool shouldEnableVectorizerAtOLevel(const ArgList &Args, bool isSlpVec) {
647
95.5k
  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
648
6.80k
    if (A->getOption().matches(options::OPT_O4) ||
649
6.80k
        
A->getOption().matches(options::OPT_Ofast)6.79k
)
650
60
      return true;
651
652
6.74k
    if (A->getOption().matches(options::OPT_O0))
653
5.64k
      return false;
654
655
1.09k
    assert(A->getOption().matches(options::OPT_O) && "Must have a -O flag");
656
657
    // Vectorize -Os.
658
1.09k
    StringRef S(A->getValue());
659
1.09k
    if (S == "s")
660
66
      return true;
661
662
    // Don't vectorize -Oz, unless it's the slp vectorizer.
663
1.03k
    if (S == "z")
664
16
      return isSlpVec;
665
666
1.01k
    unsigned OptLevel = 0;
667
1.01k
    if (S.getAsInteger(10, OptLevel))
668
14
      return false;
669
670
1.00k
    return OptLevel > 1;
671
1.01k
  }
672
673
88.7k
  return false;
674
95.5k
}
675
676
/// Add -x lang to \p CmdArgs for \p Input.
677
static void addDashXForInput(const ArgList &Args, const InputInfo &Input,
678
47.7k
                             ArgStringList &CmdArgs) {
679
  // When using -verify-pch, we don't want to provide the type
680
  // 'precompiled-header' if it was inferred from the file extension
681
47.7k
  if (Args.hasArg(options::OPT_verify_pch) && 
Input.getType() == types::TY_PCH2
)
682
1
    return;
683
684
47.7k
  CmdArgs.push_back("-x");
685
47.7k
  if (Args.hasArg(options::OPT_rewrite_objc))
686
10
    CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX));
687
47.7k
  else {
688
    // Map the driver type to the frontend type. This is mostly an identity
689
    // mapping, except that the distinction between module interface units
690
    // and other source files does not exist at the frontend layer.
691
47.7k
    const char *ClangType;
692
47.7k
    switch (Input.getType()) {
693
32
    case types::TY_CXXModule:
694
32
      ClangType = "c++";
695
32
      break;
696
0
    case types::TY_PP_CXXModule:
697
0
      ClangType = "c++-cpp-output";
698
0
      break;
699
47.7k
    default:
700
47.7k
      ClangType = types::getTypeName(Input.getType());
701
47.7k
      break;
702
47.7k
    }
703
47.7k
    CmdArgs.push_back(ClangType);
704
47.7k
  }
705
47.7k
}
706
707
static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C,
708
                                   const JobAction &JA, const InputInfo &Output,
709
                                   const ArgList &Args, SanitizerArgs &SanArgs,
710
47.0k
                                   ArgStringList &CmdArgs) {
711
47.0k
  const Driver &D = TC.getDriver();
712
47.0k
  auto *PGOGenerateArg = Args.getLastArg(options::OPT_fprofile_generate,
713
47.0k
                                         options::OPT_fprofile_generate_EQ,
714
47.0k
                                         options::OPT_fno_profile_generate);
715
47.0k
  if (PGOGenerateArg &&
716
47.0k
      
PGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate)44
)
717
7
    PGOGenerateArg = nullptr;
718
719
47.0k
  auto *CSPGOGenerateArg = getLastCSProfileGenerateArg(Args);
720
721
47.0k
  auto *ProfileGenerateArg = Args.getLastArg(
722
47.0k
      options::OPT_fprofile_instr_generate,
723
47.0k
      options::OPT_fprofile_instr_generate_EQ,
724
47.0k
      options::OPT_fno_profile_instr_generate);
725
47.0k
  if (ProfileGenerateArg &&
726
47.0k
      ProfileGenerateArg->getOption().matches(
727
63
          options::OPT_fno_profile_instr_generate))
728
7
    ProfileGenerateArg = nullptr;
729
730
47.0k
  if (PGOGenerateArg && 
ProfileGenerateArg37
)
731
2
    D.Diag(diag::err_drv_argument_not_allowed_with)
732
2
        << PGOGenerateArg->getSpelling() << ProfileGenerateArg->getSpelling();
733
734
47.0k
  auto *ProfileUseArg = getLastProfileUseArg(Args);
735
736
47.0k
  if (PGOGenerateArg && 
ProfileUseArg37
)
737
8
    D.Diag(diag::err_drv_argument_not_allowed_with)
738
8
        << ProfileUseArg->getSpelling() << PGOGenerateArg->getSpelling();
739
740
47.0k
  if (ProfileGenerateArg && 
ProfileUseArg56
)
741
12
    D.Diag(diag::err_drv_argument_not_allowed_with)
742
12
        << ProfileGenerateArg->getSpelling() << ProfileUseArg->getSpelling();
743
744
47.0k
  if (CSPGOGenerateArg && 
PGOGenerateArg7
) {
745
1
    D.Diag(diag::err_drv_argument_not_allowed_with)
746
1
        << CSPGOGenerateArg->getSpelling() << PGOGenerateArg->getSpelling();
747
1
    PGOGenerateArg = nullptr;
748
1
  }
749
750
47.0k
  if (TC.getTriple().isOSAIX()) {
751
241
    if (Arg *ProfileSampleUseArg = getLastProfileSampleUseArg(Args))
752
1
      D.Diag(diag::err_drv_unsupported_opt_for_target)
753
1
          << ProfileSampleUseArg->getSpelling() << TC.getTriple().str();
754
241
  }
755
756
47.0k
  if (ProfileGenerateArg) {
757
56
    if (ProfileGenerateArg->getOption().matches(
758
56
            options::OPT_fprofile_instr_generate_EQ))
759
9
      CmdArgs.push_back(Args.MakeArgString(Twine("-fprofile-instrument-path=") +
760
9
                                           ProfileGenerateArg->getValue()));
761
    // The default is to use Clang Instrumentation.
762
56
    CmdArgs.push_back("-fprofile-instrument=clang");
763
56
    if (TC.getTriple().isWindowsMSVCEnvironment()) {
764
      // Add dependent lib for clang_rt.profile
765
11
      CmdArgs.push_back(Args.MakeArgString(
766
11
          "--dependent-lib=" + TC.getCompilerRTBasename(Args, "profile")));
767
11
    }
768
56
  }
769
770
47.0k
  Arg *PGOGenArg = nullptr;
771
47.0k
  if (PGOGenerateArg) {
772
36
    assert(!CSPGOGenerateArg);
773
36
    PGOGenArg = PGOGenerateArg;
774
36
    CmdArgs.push_back("-fprofile-instrument=llvm");
775
36
  }
776
47.0k
  if (CSPGOGenerateArg) {
777
7
    assert(!PGOGenerateArg);
778
7
    PGOGenArg = CSPGOGenerateArg;
779
7
    CmdArgs.push_back("-fprofile-instrument=csllvm");
780
7
  }
781
47.0k
  if (PGOGenArg) {
782
43
    if (TC.getTriple().isWindowsMSVCEnvironment()) {
783
      // Add dependent lib for clang_rt.profile
784
2
      CmdArgs.push_back(Args.MakeArgString(
785
2
          "--dependent-lib=" + TC.getCompilerRTBasename(Args, "profile")));
786
2
    }
787
43
    if (PGOGenArg->getOption().matches(
788
43
            PGOGenerateArg ? 
options::OPT_fprofile_generate_EQ36
789
43
                           : 
options::OPT_fcs_profile_generate_EQ7
)) {
790
9
      SmallString<128> Path(PGOGenArg->getValue());
791
9
      llvm::sys::path::append(Path, "default_%m.profraw");
792
9
      CmdArgs.push_back(
793
9
          Args.MakeArgString(Twine("-fprofile-instrument-path=") + Path));
794
9
    }
795
43
  }
796
797
47.0k
  if (ProfileUseArg) {
798
50
    if (ProfileUseArg->getOption().matches(options::OPT_fprofile_instr_use_EQ))
799
11
      CmdArgs.push_back(Args.MakeArgString(
800
11
          Twine("-fprofile-instrument-use-path=") + ProfileUseArg->getValue()));
801
39
    else if ((ProfileUseArg->getOption().matches(
802
39
                  options::OPT_fprofile_use_EQ) ||
803
39
              ProfileUseArg->getOption().matches(
804
39
                  options::OPT_fprofile_instr_use))) {
805
39
      SmallString<128> Path(
806
39
          ProfileUseArg->getNumValues() == 0 ? 
""16
:
ProfileUseArg->getValue()23
);
807
39
      if (Path.empty() || 
llvm::sys::fs::is_directory(Path)23
)
808
21
        llvm::sys::path::append(Path, "default.profdata");
809
39
      CmdArgs.push_back(
810
39
          Args.MakeArgString(Twine("-fprofile-instrument-use-path=") + Path));
811
39
    }
812
50
  }
813
814
47.0k
  bool EmitCovNotes = Args.hasFlag(options::OPT_ftest_coverage,
815
47.0k
                                   options::OPT_fno_test_coverage, false) ||
816
47.0k
                      
Args.hasArg(options::OPT_coverage)47.0k
;
817
47.0k
  bool EmitCovData = TC.needsGCovInstrumentation(Args);
818
819
47.0k
  if (Args.hasFlag(options::OPT_fcoverage_mapping,
820
47.0k
                   options::OPT_fno_coverage_mapping, false)) {
821
5
    if (!ProfileGenerateArg)
822
1
      D.Diag(clang::diag::err_drv_argument_only_allowed_with)
823
1
          << "-fcoverage-mapping"
824
1
          << "-fprofile-instr-generate";
825
826
5
    CmdArgs.push_back("-fcoverage-mapping");
827
5
  }
828
829
47.0k
  if (Arg *A = Args.getLastArg(options::OPT_ffile_compilation_dir_EQ,
830
47.0k
                               options::OPT_fcoverage_compilation_dir_EQ)) {
831
4
    if (A->getOption().matches(options::OPT_ffile_compilation_dir_EQ))
832
2
      CmdArgs.push_back(Args.MakeArgString(
833
2
          Twine("-fcoverage-compilation-dir=") + A->getValue()));
834
2
    else
835
2
      A->render(Args, CmdArgs);
836
47.0k
  } else if (llvm::ErrorOr<std::string> CWD =
837
47.0k
                 D.getVFS().getCurrentWorkingDirectory()) {
838
47.0k
    CmdArgs.push_back(Args.MakeArgString("-fcoverage-compilation-dir=" + *CWD));
839
47.0k
  }
840
841
47.0k
  if (Args.hasArg(options::OPT_fprofile_exclude_files_EQ)) {
842
5
    auto *Arg = Args.getLastArg(options::OPT_fprofile_exclude_files_EQ);
843
5
    if (!Args.hasArg(options::OPT_coverage))
844
0
      D.Diag(clang::diag::err_drv_argument_only_allowed_with)
845
0
          << "-fprofile-exclude-files="
846
0
          << "--coverage";
847
848
5
    StringRef v = Arg->getValue();
849
5
    CmdArgs.push_back(
850
5
        Args.MakeArgString(Twine("-fprofile-exclude-files=" + v)));
851
5
  }
852
853
47.0k
  if (Args.hasArg(options::OPT_fprofile_filter_files_EQ)) {
854
4
    auto *Arg = Args.getLastArg(options::OPT_fprofile_filter_files_EQ);
855
4
    if (!Args.hasArg(options::OPT_coverage))
856
0
      D.Diag(clang::diag::err_drv_argument_only_allowed_with)
857
0
          << "-fprofile-filter-files="
858
0
          << "--coverage";
859
860
4
    StringRef v = Arg->getValue();
861
4
    CmdArgs.push_back(Args.MakeArgString(Twine("-fprofile-filter-files=" + v)));
862
4
  }
863
864
47.0k
  if (const auto *A = Args.getLastArg(options::OPT_fprofile_update_EQ)) {
865
9
    StringRef Val = A->getValue();
866
9
    if (Val == "atomic" || 
Val == "prefer-atomic"5
)
867
6
      CmdArgs.push_back("-fprofile-update=atomic");
868
3
    else if (Val != "single")
869
1
      D.Diag(diag::err_drv_unsupported_option_argument)
870
1
          << A->getSpelling() << Val;
871
9
  }
872
873
47.0k
  int FunctionGroups = 1;
874
47.0k
  int SelectedFunctionGroup = 0;
875
47.0k
  if (const auto *A = Args.getLastArg(options::OPT_fprofile_function_groups)) {
876
3
    StringRef Val = A->getValue();
877
3
    if (Val.getAsInteger(0, FunctionGroups) || FunctionGroups < 1)
878
0
      D.Diag(diag::err_drv_invalid_int_value) << A->getAsString(Args) << Val;
879
3
  }
880
47.0k
  if (const auto *A =
881
47.0k
          Args.getLastArg(options::OPT_fprofile_selected_function_group)) {
882
3
    StringRef Val = A->getValue();
883
3
    if (Val.getAsInteger(0, SelectedFunctionGroup) ||
884
3
        SelectedFunctionGroup < 0 || SelectedFunctionGroup >= FunctionGroups)
885
0
      D.Diag(diag::err_drv_invalid_int_value) << A->getAsString(Args) << Val;
886
3
  }
887
47.0k
  if (FunctionGroups != 1)
888
3
    CmdArgs.push_back(Args.MakeArgString("-fprofile-function-groups=" +
889
3
                                         Twine(FunctionGroups)));
890
47.0k
  if (SelectedFunctionGroup != 0)
891
2
    CmdArgs.push_back(Args.MakeArgString("-fprofile-selected-function-group=" +
892
2
                                         Twine(SelectedFunctionGroup)));
893
894
  // Leave -fprofile-dir= an unused argument unless .gcda emission is
895
  // enabled. To be polite, with '-fprofile-arcs -fno-profile-arcs' consider
896
  // the flag used. There is no -fno-profile-dir, so the user has no
897
  // targeted way to suppress the warning.
898
47.0k
  Arg *FProfileDir = nullptr;
899
47.0k
  if (Args.hasArg(options::OPT_fprofile_arcs) ||
900
47.0k
      
Args.hasArg(options::OPT_coverage)47.0k
)
901
36
    FProfileDir = Args.getLastArg(options::OPT_fprofile_dir);
902
903
  // TODO: Don't claim -c/-S to warn about -fsyntax-only -c/-S, -E -c/-S,
904
  // like we warn about -fsyntax-only -E.
905
47.0k
  (void)(Args.hasArg(options::OPT_c) || 
Args.hasArg(options::OPT_S)39.6k
);
906
907
  // Put the .gcno and .gcda files (if needed) next to the primary output file,
908
  // or fall back to a file in the current directory for `clang -c --coverage
909
  // d/a.c` in the absence of -o.
910
47.0k
  if (EmitCovNotes || 
EmitCovData46.9k
) {
911
39
    SmallString<128> CoverageFilename;
912
39
    if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
913
      // Form ${dumpdir}${basename}.gcno. Note that dumpdir may not end with a
914
      // path separator.
915
18
      CoverageFilename = DumpDir->getValue();
916
18
      CoverageFilename += llvm::sys::path::filename(Output.getBaseInput());
917
21
    } else if (Arg *FinalOutput =
918
21
                   C.getArgs().getLastArg(options::OPT__SLASH_Fo)) {
919
1
      CoverageFilename = FinalOutput->getValue();
920
20
    } else if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o)) {
921
11
      CoverageFilename = FinalOutput->getValue();
922
11
    } else {
923
9
      CoverageFilename = llvm::sys::path::filename(Output.getBaseInput());
924
9
    }
925
39
    if (llvm::sys::path::is_relative(CoverageFilename))
926
28
      (void)D.getVFS().makeAbsolute(CoverageFilename);
927
39
    llvm::sys::path::replace_extension(CoverageFilename, "gcno");
928
39
    if (EmitCovNotes) {
929
32
      CmdArgs.push_back(
930
32
          Args.MakeArgString("-coverage-notes-file=" + CoverageFilename));
931
32
    }
932
933
39
    if (EmitCovData) {
934
33
      if (FProfileDir) {
935
2
        SmallString<128> Gcno = std::move(CoverageFilename);
936
2
        CoverageFilename = FProfileDir->getValue();
937
2
        llvm::sys::path::append(CoverageFilename, Gcno);
938
2
      }
939
33
      llvm::sys::path::replace_extension(CoverageFilename, "gcda");
940
33
      CmdArgs.push_back(
941
33
          Args.MakeArgString("-coverage-data-file=" + CoverageFilename));
942
33
    }
943
39
  }
944
47.0k
}
945
946
/// Check whether the given input tree contains any compilation actions.
947
32.2k
static bool ContainsCompileAction(const Action *A) {
948
32.2k
  if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A))
949
11.1k
    return true;
950
951
21.0k
  return llvm::any_of(A->inputs(), ContainsCompileAction);
952
32.2k
}
953
954
/// Check if -relax-all should be passed to the internal assembler.
955
/// This is done by default when compiling non-assembler source with -O0.
956
11.7k
static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
957
11.7k
  bool RelaxDefault = true;
958
959
11.7k
  if (Arg *A = Args.getLastArg(options::OPT_O_Group))
960
2.95k
    RelaxDefault = A->getOption().matches(options::OPT_O0);
961
962
11.7k
  if (RelaxDefault) {
963
11.5k
    RelaxDefault = false;
964
11.5k
    for (const auto &Act : C.getActions()) {
965
11.5k
      if (ContainsCompileAction(Act)) {
966
11.1k
        RelaxDefault = true;
967
11.1k
        break;
968
11.1k
      }
969
11.5k
    }
970
11.5k
  }
971
972
11.7k
  return Args.hasFlag(options::OPT_mrelax_all, options::OPT_mno_relax_all,
973
11.7k
                      RelaxDefault);
974
11.7k
}
975
976
static void
977
RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs,
978
                        llvm::codegenoptions::DebugInfoKind DebugInfoKind,
979
                        unsigned DwarfVersion,
980
48.2k
                        llvm::DebuggerKind DebuggerTuning) {
981
48.2k
  addDebugInfoKind(CmdArgs, DebugInfoKind);
982
48.2k
  if (DwarfVersion > 0)
983
3.76k
    CmdArgs.push_back(
984
3.76k
        Args.MakeArgString("-dwarf-version=" + Twine(DwarfVersion)));
985
48.2k
  switch (DebuggerTuning) {
986
20.9k
  case llvm::DebuggerKind::GDB:
987
20.9k
    CmdArgs.push_back("-debugger-tuning=gdb");
988
20.9k
    break;
989
17.7k
  case llvm::DebuggerKind::LLDB:
990
17.7k
    CmdArgs.push_back("-debugger-tuning=lldb");
991
17.7k
    break;
992
286
  case llvm::DebuggerKind::SCE:
993
286
    CmdArgs.push_back("-debugger-tuning=sce");
994
286
    break;
995
5
  case llvm::DebuggerKind::DBX:
996
5
    CmdArgs.push_back("-debugger-tuning=dbx");
997
5
    break;
998
9.30k
  default:
999
9.30k
    break;
1000
48.2k
  }
1001
48.2k
}
1002
1003
static bool checkDebugInfoOption(const Arg *A, const ArgList &Args,
1004
6.51k
                                 const Driver &D, const ToolChain &TC) {
1005
6.51k
  assert(A && "Expected non-nullptr argument.");
1006
6.51k
  if (TC.supportsDebugInfoOption(A))
1007
6.51k
    return true;
1008
0
  D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target)
1009
0
      << A->getAsString(Args) << TC.getTripleString();
1010
0
  return false;
1011
6.51k
}
1012
1013
static void RenderDebugInfoCompressionArgs(const ArgList &Args,
1014
                                           ArgStringList &CmdArgs,
1015
                                           const Driver &D,
1016
48.2k
                                           const ToolChain &TC) {
1017
48.2k
  const Arg *A = Args.getLastArg(options::OPT_gz_EQ);
1018
48.2k
  if (!A)
1019
48.2k
    return;
1020
29
  if (checkDebugInfoOption(A, Args, D, TC)) {
1021
26
    StringRef Value = A->getValue();
1022
26
    if (Value == "none") {
1023
7
      CmdArgs.push_back("--compress-debug-sections=none");
1024
19
    } else if (Value == "zlib") {
1025
14
      if (llvm::compression::zlib::isAvailable()) {
1026
14
        CmdArgs.push_back(
1027
14
            Args.MakeArgString("--compress-debug-sections=" + Twine(Value)));
1028
14
      } else {
1029
0
        D.Diag(diag::warn_debug_compression_unavailable) << "zlib";
1030
0
      }
1031
14
    } else 
if (5
Value == "zstd"5
) {
1032
2
      if (llvm::compression::zstd::isAvailable()) {
1033
0
        CmdArgs.push_back(
1034
0
            Args.MakeArgString("--compress-debug-sections=" + Twine(Value)));
1035
2
      } else {
1036
2
        D.Diag(diag::warn_debug_compression_unavailable) << "zstd";
1037
2
      }
1038
3
    } else {
1039
3
      D.Diag(diag::err_drv_unsupported_option_argument)
1040
3
          << A->getSpelling() << Value;
1041
3
    }
1042
26
  }
1043
29
}
1044
1045
static void handleAMDGPUCodeObjectVersionOptions(const Driver &D,
1046
                                                 const ArgList &Args,
1047
                                                 ArgStringList &CmdArgs,
1048
755
                                                 bool IsCC1As = false) {
1049
  // If no version was requested by the user, use the default value from the
1050
  // back end. This is consistent with the value returned from
1051
  // getAMDGPUCodeObjectVersion. This lets clang emit IR for amdgpu without
1052
  // requiring the corresponding llvm to have the AMDGPU target enabled,
1053
  // provided the user (e.g. front end tests) can use the default.
1054
755
  if (haveAMDGPUCodeObjectVersionArgument(D, Args)) {
1055
19
    unsigned CodeObjVer = getAMDGPUCodeObjectVersion(D, Args);
1056
19
    CmdArgs.insert(CmdArgs.begin() + 1,
1057
19
                   Args.MakeArgString(Twine("--amdhsa-code-object-version=") +
1058
19
                                      Twine(CodeObjVer)));
1059
19
    CmdArgs.insert(CmdArgs.begin() + 1, "-mllvm");
1060
    // -cc1as does not accept -mcode-object-version option.
1061
19
    if (!IsCC1As)
1062
17
      CmdArgs.insert(CmdArgs.begin() + 1,
1063
17
                     Args.MakeArgString(Twine("-mcode-object-version=") +
1064
17
                                        Twine(CodeObjVer)));
1065
19
  }
1066
755
}
1067
1068
void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
1069
                                    const Driver &D, const ArgList &Args,
1070
                                    ArgStringList &CmdArgs,
1071
                                    const InputInfo &Output,
1072
47.5k
                                    const InputInfoList &Inputs) const {
1073
47.5k
  const bool IsIAMCU = getToolChain().getTriple().isOSIAMCU();
1074
1075
47.5k
  CheckPreprocessingOptions(D, Args);
1076
1077
47.5k
  Args.AddLastArg(CmdArgs, options::OPT_C);
1078
47.5k
  Args.AddLastArg(CmdArgs, options::OPT_CC);
1079
1080
  // Handle dependency file generation.
1081
47.5k
  Arg *ArgM = Args.getLastArg(options::OPT_MM);
1082
47.5k
  if (!ArgM)
1083
47.4k
    ArgM = Args.getLastArg(options::OPT_M);
1084
47.5k
  Arg *ArgMD = Args.getLastArg(options::OPT_MMD);
1085
47.5k
  if (!ArgMD)
1086
47.4k
    ArgMD = Args.getLastArg(options::OPT_MD);
1087
1088
  // -M and -MM imply -w.
1089
47.5k
  if (ArgM)
1090
15
    CmdArgs.push_back("-w");
1091
47.4k
  else
1092
47.4k
    ArgM = ArgMD;
1093
1094
47.5k
  if (ArgM) {
1095
    // Determine the output location.
1096
2.83k
    const char *DepFile;
1097
2.83k
    if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
1098
2.81k
      DepFile = MF->getValue();
1099
2.81k
      C.addFailureResultFile(DepFile, &JA);
1100
2.81k
    } else 
if (21
Output.getType() == types::TY_Dependencies21
) {
1101
12
      DepFile = Output.getFilename();
1102
12
    } else 
if (9
!ArgMD9
) {
1103
0
      DepFile = "-";
1104
9
    } else {
1105
9
      DepFile = getDependencyFileName(Args, Inputs);
1106
9
      C.addFailureResultFile(DepFile, &JA);
1107
9
    }
1108
2.83k
    CmdArgs.push_back("-dependency-file");
1109
2.83k
    CmdArgs.push_back(DepFile);
1110
1111
2.83k
    bool HasTarget = false;
1112
2.83k
    for (const Arg *A : Args.filtered(options::OPT_MT, options::OPT_MQ)) {
1113
2.77k
      HasTarget = true;
1114
2.77k
      A->claim();
1115
2.77k
      if (A->getOption().matches(options::OPT_MT)) {
1116
2.77k
        A->render(Args, CmdArgs);
1117
2.77k
      } else {
1118
5
        CmdArgs.push_back("-MT");
1119
5
        SmallString<128> Quoted;
1120
5
        quoteMakeTarget(A->getValue(), Quoted);
1121
5
        CmdArgs.push_back(Args.MakeArgString(Quoted));
1122
5
      }
1123
2.77k
    }
1124
1125
    // Add a default target if one wasn't specified.
1126
2.83k
    if (!HasTarget) {
1127
67
      const char *DepTarget;
1128
1129
      // If user provided -o, that is the dependency target, except
1130
      // when we are only generating a dependency file.
1131
67
      Arg *OutputOpt = Args.getLastArg(options::OPT_o);
1132
67
      if (OutputOpt && 
Output.getType() != types::TY_Dependencies8
) {
1133
6
        DepTarget = OutputOpt->getValue();
1134
61
      } else {
1135
        // Otherwise derive from the base input.
1136
        //
1137
        // FIXME: This should use the computed output file location.
1138
61
        SmallString<128> P(Inputs[0].getBaseInput());
1139
61
        llvm::sys::path::replace_extension(P, "o");
1140
61
        DepTarget = Args.MakeArgString(llvm::sys::path::filename(P));
1141
61
      }
1142
1143
67
      CmdArgs.push_back("-MT");
1144
67
      SmallString<128> Quoted;
1145
67
      quoteMakeTarget(DepTarget, Quoted);
1146
67
      CmdArgs.push_back(Args.MakeArgString(Quoted));
1147
67
    }
1148
1149
2.83k
    if (ArgM->getOption().matches(options::OPT_M) ||
1150
2.83k
        
ArgM->getOption().matches(options::OPT_MD)2.82k
)
1151
2.82k
      CmdArgs.push_back("-sys-header-deps");
1152
2.83k
    if (Args.hasFlag(options::OPT_canonical_prefixes,
1153
2.83k
                     options::OPT_no_canonical_prefixes, true))
1154
2.83k
      CmdArgs.push_back("-canonical-system-headers");
1155
2.83k
    if ((isa<PrecompileJobAction>(JA) &&
1156
2.83k
         
!Args.hasArg(options::OPT_fno_module_file_deps)10
) ||
1157
2.83k
        
Args.hasArg(options::OPT_fmodule_file_deps)2.83k
)
1158
10
      CmdArgs.push_back("-module-file-deps");
1159
2.83k
  }
1160
1161
47.5k
  if (Args.hasArg(options::OPT_MG)) {
1162
4
    if (!ArgM || ArgM->getOption().matches(options::OPT_MD) ||
1163
4
        ArgM->getOption().matches(options::OPT_MMD))
1164
0
      D.Diag(diag::err_drv_mg_requires_m_or_mm);
1165
4
    CmdArgs.push_back("-MG");
1166
4
  }
1167
1168
47.5k
  Args.AddLastArg(CmdArgs, options::OPT_MP);
1169
47.5k
  Args.AddLastArg(CmdArgs, options::OPT_MV);
1170
1171
  // Add offload include arguments specific for CUDA/HIP.  This must happen
1172
  // before we -I or -include anything else, because we must pick up the
1173
  // CUDA/HIP headers from the particular CUDA/ROCm installation, rather than
1174
  // from e.g. /usr/local/include.
1175
47.5k
  if (JA.isOffloading(Action::OFK_Cuda))
1176
139
    getToolChain().AddCudaIncludeArgs(Args, CmdArgs);
1177
47.5k
  if (JA.isOffloading(Action::OFK_HIP))
1178
642
    getToolChain().AddHIPIncludeArgs(Args, CmdArgs);
1179
1180
  // If we are compiling for a GPU target we want to override the system headers
1181
  // with ones created by the 'libc' project if present.
1182
47.5k
  if (!Args.hasArg(options::OPT_nostdinc) &&
1183
47.5k
      
!Args.hasArg(options::OPT_nogpuinc)47.4k
&&
1184
47.5k
      
!Args.hasArg(options::OPT_nobuiltininc)46.8k
) {
1185
    // Without an offloading language we will include these headers directly.
1186
    // Offloading languages will instead only use the declarations stored in
1187
    // the resource directory at clang/lib/Headers/llvm_libc_wrappers.
1188
46.8k
    if ((getToolChain().getTriple().isNVPTX() ||
1189
46.8k
         
getToolChain().getTriple().isAMDGCN()46.7k
) &&
1190
46.8k
        
C.getActiveOffloadKinds() == Action::OFK_None347
) {
1191
229
      SmallString<128> P(llvm::sys::path::parent_path(D.InstalledDir));
1192
229
      llvm::sys::path::append(P, "include");
1193
229
      llvm::sys::path::append(P, "gpu-none-llvm");
1194
229
      CmdArgs.push_back("-c-isystem");
1195
229
      CmdArgs.push_back(Args.MakeArgString(P));
1196
46.5k
    } else if (C.getActiveOffloadKinds() == Action::OFK_OpenMP) {
1197
      // TODO: CUDA / HIP include their own headers for some common functions
1198
      // implemented here. We'll need to clean those up so they do not conflict.
1199
17
      SmallString<128> P(D.ResourceDir);
1200
17
      llvm::sys::path::append(P, "include");
1201
17
      llvm::sys::path::append(P, "llvm_libc_wrappers");
1202
17
      CmdArgs.push_back("-internal-isystem");
1203
17
      CmdArgs.push_back(Args.MakeArgString(P));
1204
17
    }
1205
46.8k
  }
1206
1207
  // If we are offloading to a target via OpenMP we need to include the
1208
  // openmp_wrappers folder which contains alternative system headers.
1209
47.5k
  if (JA.isDeviceOffloading(Action::OFK_OpenMP) &&
1210
47.5k
      
!Args.hasArg(options::OPT_nostdinc)9
&&
1211
47.5k
      
!Args.hasArg(options::OPT_nogpuinc)9
&&
1212
47.5k
      
(9
getToolChain().getTriple().isNVPTX()9
||
1213
9
       getToolChain().getTriple().isAMDGCN())) {
1214
9
    if (!Args.hasArg(options::OPT_nobuiltininc)) {
1215
      // Add openmp_wrappers/* to our system include path.  This lets us wrap
1216
      // standard library headers.
1217
9
      SmallString<128> P(D.ResourceDir);
1218
9
      llvm::sys::path::append(P, "include");
1219
9
      llvm::sys::path::append(P, "openmp_wrappers");
1220
9
      CmdArgs.push_back("-internal-isystem");
1221
9
      CmdArgs.push_back(Args.MakeArgString(P));
1222
9
    }
1223
1224
9
    CmdArgs.push_back("-include");
1225
9
    CmdArgs.push_back("__clang_openmp_device_functions.h");
1226
9
  }
1227
1228
  // Add -i* options, and automatically translate to
1229
  // -include-pch/-include-pth for transparent PCH support. It's
1230
  // wonky, but we include looking for .gch so we can support seamless
1231
  // replacement into a build system already set up to be generating
1232
  // .gch files.
1233
1234
47.5k
  if (getToolChain().getDriver().IsCLMode()) {
1235
716
    const Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
1236
716
    const Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
1237
716
    if (YcArg && 
JA.getKind() >= Action::PrecompileJobClass36
&&
1238
716
        
JA.getKind() <= Action::AssembleJobClass36
) {
1239
36
      CmdArgs.push_back(Args.MakeArgString("-building-pch-with-obj"));
1240
      // -fpch-instantiate-templates is the default when creating
1241
      // precomp using /Yc
1242
36
      if (Args.hasFlag(options::OPT_fpch_instantiate_templates,
1243
36
                       options::OPT_fno_pch_instantiate_templates, true))
1244
34
        CmdArgs.push_back(Args.MakeArgString("-fpch-instantiate-templates"));
1245
36
    }
1246
716
    if (YcArg || 
YuArg680
) {
1247
49
      StringRef ThroughHeader = YcArg ? 
YcArg->getValue()36
:
YuArg->getValue()13
;
1248
49
      if (!isa<PrecompileJobAction>(JA)) {
1249
31
        CmdArgs.push_back("-include-pch");
1250
31
        CmdArgs.push_back(Args.MakeArgString(D.GetClPchPath(
1251
31
            C, !ThroughHeader.empty()
1252
31
                   ? 
ThroughHeader26
1253
31
                   : 
llvm::sys::path::filename(Inputs[0].getBaseInput())5
)));
1254
31
      }
1255
1256
49
      if (ThroughHeader.empty()) {
1257
9
        CmdArgs.push_back(Args.MakeArgString(
1258
9
            Twine("-pch-through-hdrstop-") + (YcArg ? 
"create"8
:
"use"1
)));
1259
40
      } else {
1260
40
        CmdArgs.push_back(
1261
40
            Args.MakeArgString(Twine("-pch-through-header=") + ThroughHeader));
1262
40
      }
1263
49
    }
1264
716
  }
1265
1266
47.5k
  bool RenderedImplicitInclude = false;
1267
47.5k
  for (const Arg *A : Args.filtered(options::OPT_clang_i_Group)) {
1268
11.0k
    if (A->getOption().matches(options::OPT_include) &&
1269
11.0k
        
D.getProbePrecompiled()2.91k
) {
1270
      // Handling of gcc-style gch precompiled headers.
1271
2.90k
      bool IsFirstImplicitInclude = !RenderedImplicitInclude;
1272
2.90k
      RenderedImplicitInclude = true;
1273
1274
2.90k
      bool FoundPCH = false;
1275
2.90k
      SmallString<128> P(A->getValue());
1276
      // We want the files to have a name like foo.h.pch. Add a dummy extension
1277
      // so that replace_extension does the right thing.
1278
2.90k
      P += ".dummy";
1279
2.90k
      llvm::sys::path::replace_extension(P, "pch");
1280
2.90k
      if (D.getVFS().exists(P))
1281
71
        FoundPCH = true;
1282
1283
2.90k
      if (!FoundPCH) {
1284
2.83k
        llvm::sys::path::replace_extension(P, "gch");
1285
2.83k
        if (D.getVFS().exists(P)) {
1286
17
          FoundPCH = true;
1287
17
        }
1288
2.83k
      }
1289
1290
2.90k
      if (FoundPCH) {
1291
88
        if (IsFirstImplicitInclude) {
1292
88
          A->claim();
1293
88
          CmdArgs.push_back("-include-pch");
1294
88
          CmdArgs.push_back(Args.MakeArgString(P));
1295
88
          continue;
1296
88
        } else {
1297
          // Ignore the PCH if not first on command line and emit warning.
1298
0
          D.Diag(diag::warn_drv_pch_not_first_include) << P
1299
0
                                                       << A->getAsString(Args);
1300
0
        }
1301
88
      }
1302
8.14k
    } else if (A->getOption().matches(options::OPT_isystem_after)) {
1303
      // Handling of paths which must come late.  These entries are handled by
1304
      // the toolchain itself after the resource dir is inserted in the right
1305
      // search order.
1306
      // Do not claim the argument so that the use of the argument does not
1307
      // silently go unnoticed on toolchains which do not honour the option.
1308
4
      continue;
1309
8.13k
    } else if (A->getOption().matches(options::OPT_stdlibxx_isystem)) {
1310
      // Translated to -internal-isystem by the driver, no need to pass to cc1.
1311
18
      continue;
1312
8.12k
    } else if (A->getOption().matches(options::OPT_ibuiltininc)) {
1313
      // This is used only by the driver. No need to pass to cc1.
1314
6
      continue;
1315
6
    }
1316
1317
    // Not translated, render as usual.
1318
10.9k
    A->claim();
1319
10.9k
    A->render(Args, CmdArgs);
1320
10.9k
  }
1321
1322
47.5k
  Args.AddAllArgs(CmdArgs,
1323
47.5k
                  {options::OPT_D, options::OPT_U, options::OPT_I_Group,
1324
47.5k
                   options::OPT_F, options::OPT_index_header_map});
1325
1326
  // Add -Wp, and -Xpreprocessor if using the preprocessor.
1327
1328
  // FIXME: There is a very unfortunate problem here, some troubled
1329
  // souls abuse -Wp, to pass preprocessor options in gcc syntax. To
1330
  // really support that we would have to parse and then translate
1331
  // those options. :(
1332
47.5k
  Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
1333
47.5k
                       options::OPT_Xpreprocessor);
1334
1335
  // -I- is a deprecated GCC feature, reject it.
1336
47.5k
  if (Arg *A = Args.getLastArg(options::OPT_I_))
1337
0
    D.Diag(diag::err_drv_I_dash_not_supported) << A->getAsString(Args);
1338
1339
  // If we have a --sysroot, and don't have an explicit -isysroot flag, add an
1340
  // -isysroot to the CC1 invocation.
1341
47.5k
  StringRef sysroot = C.getSysRoot();
1342
47.5k
  if (sysroot != "") {
1343
941
    if (!Args.hasArg(options::OPT_isysroot)) {
1344
935
      CmdArgs.push_back("-isysroot");
1345
935
      CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
1346
935
    }
1347
941
  }
1348
1349
  // Parse additional include paths from environment variables.
1350
  // FIXME: We should probably sink the logic for handling these from the
1351
  // frontend into the driver. It will allow deleting 4 otherwise unused flags.
1352
  // CPATH - included following the user specified includes (but prior to
1353
  // builtin and standard includes).
1354
47.5k
  addDirectoryList(Args, CmdArgs, "-I", "CPATH");
1355
  // C_INCLUDE_PATH - system includes enabled when compiling C.
1356
47.5k
  addDirectoryList(Args, CmdArgs, "-c-isystem", "C_INCLUDE_PATH");
1357
  // CPLUS_INCLUDE_PATH - system includes enabled when compiling C++.
1358
47.5k
  addDirectoryList(Args, CmdArgs, "-cxx-isystem", "CPLUS_INCLUDE_PATH");
1359
  // OBJC_INCLUDE_PATH - system includes enabled when compiling ObjC.
1360
47.5k
  addDirectoryList(Args, CmdArgs, "-objc-isystem", "OBJC_INCLUDE_PATH");
1361
  // OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++.
1362
47.5k
  addDirectoryList(Args, CmdArgs, "-objcxx-isystem", "OBJCPLUS_INCLUDE_PATH");
1363
1364
  // While adding the include arguments, we also attempt to retrieve the
1365
  // arguments of related offloading toolchains or arguments that are specific
1366
  // of an offloading programming model.
1367
1368
  // Add C++ include arguments, if needed.
1369
47.5k
  if (types::isCXX(Inputs[0].getType())) {
1370
31.4k
    bool HasStdlibxxIsystem = Args.hasArg(options::OPT_stdlibxx_isystem);
1371
31.4k
    forAllAssociatedToolChains(
1372
31.4k
        C, JA, getToolChain(),
1373
32.1k
        [&Args, &CmdArgs, HasStdlibxxIsystem](const ToolChain &TC) {
1374
32.1k
          HasStdlibxxIsystem ? 
TC.AddClangCXXStdlibIsystemArgs(Args, CmdArgs)10
1375
32.1k
                             : 
TC.AddClangCXXStdlibIncludeArgs(Args, CmdArgs)32.1k
;
1376
32.1k
        });
1377
31.4k
  }
1378
1379
  // Add system include arguments for all targets but IAMCU.
1380
47.5k
  if (!IsIAMCU)
1381
47.4k
    forAllAssociatedToolChains(C, JA, getToolChain(),
1382
48.2k
                               [&Args, &CmdArgs](const ToolChain &TC) {
1383
48.2k
                                 TC.AddClangSystemIncludeArgs(Args, CmdArgs);
1384
48.2k
                               });
1385
10
  else {
1386
    // For IAMCU add special include arguments.
1387
10
    getToolChain().AddIAMCUIncludeArgs(Args, CmdArgs);
1388
10
  }
1389
1390
47.5k
  addMacroPrefixMapArg(D, Args, CmdArgs);
1391
47.5k
  addCoveragePrefixMapArg(D, Args, CmdArgs);
1392
1393
47.5k
  Args.AddLastArg(CmdArgs, options::OPT_ffile_reproducible,
1394
47.5k
                  options::OPT_fno_file_reproducible);
1395
1396
47.5k
  if (const char *Epoch = std::getenv("SOURCE_DATE_EPOCH")) {
1397
1
    CmdArgs.push_back("-source-date-epoch");
1398
1
    CmdArgs.push_back(Args.MakeArgString(Epoch));
1399
1
  }
1400
47.5k
}
1401
1402
// FIXME: Move to target hook.
1403
47.7k
static bool isSignedCharDefault(const llvm::Triple &Triple) {
1404
47.7k
  switch (Triple.getArch()) {
1405
42.2k
  default:
1406
42.2k
    return true;
1407
1408
1.55k
  case llvm::Triple::aarch64:
1409
1.55k
  case llvm::Triple::aarch64_32:
1410
1.78k
  case llvm::Triple::aarch64_be:
1411
3.63k
  case llvm::Triple::arm:
1412
3.79k
  case llvm::Triple::armeb:
1413
3.86k
  case llvm::Triple::thumb:
1414
3.87k
  case llvm::Triple::thumbeb:
1415
3.87k
    if (Triple.isOSDarwin() || 
Triple.isOSWindows()3.57k
)
1416
420
      return true;
1417
3.45k
    return false;
1418
1419
234
  case llvm::Triple::ppc:
1420
472
  case llvm::Triple::ppc64:
1421
472
    if (Triple.isOSDarwin())
1422
0
      return true;
1423
472
    return false;
1424
1425
137
  case llvm::Triple::hexagon:
1426
145
  case llvm::Triple::ppcle:
1427
262
  case llvm::Triple::ppc64le:
1428
654
  case llvm::Triple::riscv32:
1429
997
  case llvm::Triple::riscv64:
1430
1.09k
  case llvm::Triple::systemz:
1431
1.10k
  case llvm::Triple::xcore:
1432
1.10k
    return false;
1433
47.7k
  }
1434
47.7k
}
1435
1436
static bool hasMultipleInvocations(const llvm::Triple &Triple,
1437
38
                                   const ArgList &Args) {
1438
  // Supported only on Darwin where we invoke the compiler multiple times
1439
  // followed by an invocation to lipo.
1440
38
  if (!Triple.isOSDarwin())
1441
7
    return false;
1442
  // If more than one "-arch <arch>" is specified, we're targeting multiple
1443
  // architectures resulting in a fat binary.
1444
31
  return Args.getAllArgValues(options::OPT_arch).size() > 1;
1445
38
}
1446
1447
static bool checkRemarksOptions(const Driver &D, const ArgList &Args,
1448
38
                                const llvm::Triple &Triple) {
1449
  // When enabling remarks, we need to error if:
1450
  // * The remark file is specified but we're targeting multiple architectures,
1451
  // which means more than one remark file is being generated.
1452
38
  bool hasMultipleInvocations = ::hasMultipleInvocations(Triple, Args);
1453
38
  bool hasExplicitOutputFile =
1454
38
      Args.getLastArg(options::OPT_foptimization_record_file_EQ);
1455
38
  if (hasMultipleInvocations && 
hasExplicitOutputFile4
) {
1456
2
    D.Diag(diag::err_drv_invalid_output_with_multiple_archs)
1457
2
        << "-foptimization-record-file";
1458
2
    return false;
1459
2
  }
1460
36
  return true;
1461
38
}
1462
1463
static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs,
1464
                                 const llvm::Triple &Triple,
1465
                                 const InputInfo &Input,
1466
36
                                 const InputInfo &Output, const JobAction &JA) {
1467
36
  StringRef Format = "yaml";
1468
36
  if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ))
1469
4
    Format = A->getValue();
1470
1471
36
  CmdArgs.push_back("-opt-record-file");
1472
1473
36
  const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ);
1474
36
  if (A) {
1475
3
    CmdArgs.push_back(A->getValue());
1476
33
  } else {
1477
33
    bool hasMultipleArchs =
1478
33
        Triple.isOSDarwin() && // Only supported on Darwin platforms.
1479
33
        
Args.getAllArgValues(options::OPT_arch).size() > 127
;
1480
1481
33
    SmallString<128> F;
1482
1483
33
    if (Args.hasArg(options::OPT_c) || 
Args.hasArg(options::OPT_S)19
) {
1484
24
      if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
1485
16
        F = FinalOutput->getValue();
1486
24
    } else {
1487
9
      if (Format != "yaml" && // For YAML, keep the original behavior.
1488
9
          
Triple.isOSDarwin()1
&& // Enable this only on darwin, since it's the only platform supporting .dSYM bundles.
1489
9
          
Output.isFilename()1
)
1490
1
        F = Output.getFilename();
1491
9
    }
1492
1493
33
    if (F.empty()) {
1494
      // Use the input filename.
1495
16
      F = llvm::sys::path::stem(Input.getBaseInput());
1496
1497
      // If we're compiling for an offload architecture (i.e. a CUDA device),
1498
      // we need to make the file name for the device compilation different
1499
      // from the host compilation.
1500
16
      if (!JA.isDeviceOffloading(Action::OFK_None) &&
1501
16
          
!JA.isDeviceOffloading(Action::OFK_Host)2
) {
1502
2
        llvm::sys::path::replace_extension(F, "");
1503
2
        F += Action::GetOffloadingFileNamePrefix(JA.getOffloadingDeviceKind(),
1504
2
                                                 Triple.normalize());
1505
2
        F += "-";
1506
2
        F += JA.getOffloadingArch();
1507
2
      }
1508
16
    }
1509
1510
    // If we're having more than one "-arch", we should name the files
1511
    // differently so that every cc1 invocation writes to a different file.
1512
    // We're doing that by appending "-<arch>" with "<arch>" being the arch
1513
    // name from the triple.
1514
33
    if (hasMultipleArchs) {
1515
      // First, remember the extension.
1516
2
      SmallString<64> OldExtension = llvm::sys::path::extension(F);
1517
      // then, remove it.
1518
2
      llvm::sys::path::replace_extension(F, "");
1519
      // attach -<arch> to it.
1520
2
      F += "-";
1521
2
      F += Triple.getArchName();
1522
      // put back the extension.
1523
2
      llvm::sys::path::replace_extension(F, OldExtension);
1524
2
    }
1525
1526
33
    SmallString<32> Extension;
1527
33
    Extension += "opt.";
1528
33
    Extension += Format;
1529
1530
33
    llvm::sys::path::replace_extension(F, Extension);
1531
33
    CmdArgs.push_back(Args.MakeArgString(F));
1532
33
  }
1533
1534
36
  if (const Arg *A =
1535
36
          Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) {
1536
4
    CmdArgs.push_back("-opt-record-passes");
1537
4
    CmdArgs.push_back(A->getValue());
1538
4
  }
1539
1540
36
  if (!Format.empty()) {
1541
36
    CmdArgs.push_back("-opt-record-format");
1542
36
    CmdArgs.push_back(Format.data());
1543
36
  }
1544
36
}
1545
1546
3.87k
void AddAAPCSVolatileBitfieldArgs(const ArgList &Args, ArgStringList &CmdArgs) {
1547
3.87k
  if (!Args.hasFlag(options::OPT_faapcs_bitfield_width,
1548
3.87k
                    options::OPT_fno_aapcs_bitfield_width, true))
1549
2
    CmdArgs.push_back("-fno-aapcs-bitfield-width");
1550
1551
3.87k
  if (Args.getLastArg(options::OPT_ForceAAPCSBitfieldLoad))
1552
2
    CmdArgs.push_back("-faapcs-bitfield-load");
1553
3.87k
}
1554
1555
namespace {
1556
void RenderARMABI(const Driver &D, const llvm::Triple &Triple,
1557
2.09k
                  const ArgList &Args, ArgStringList &CmdArgs) {
1558
  // Select the ABI to use.
1559
  // FIXME: Support -meabi.
1560
  // FIXME: Parts of this are duplicated in the backend, unify this somehow.
1561
2.09k
  const char *ABIName = nullptr;
1562
2.09k
  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
1563
4
    ABIName = A->getValue();
1564
2.08k
  } else {
1565
2.08k
    std::string CPU = getCPUName(D, Args, Triple, /*FromAs*/ false);
1566
2.08k
    ABIName = llvm::ARM::computeDefaultTargetABI(Triple, CPU).data();
1567
2.08k
  }
1568
1569
2.09k
  CmdArgs.push_back("-target-abi");
1570
2.09k
  CmdArgs.push_back(ABIName);
1571
2.09k
}
1572
1573
3.87k
void AddUnalignedAccessWarning(ArgStringList &CmdArgs) {
1574
3.87k
  auto StrictAlignIter =
1575
115k
      llvm::find_if(llvm::reverse(CmdArgs), [](StringRef Arg) {
1576
115k
        return Arg == "+strict-align" || 
Arg == "-strict-align"113k
;
1577
115k
      });
1578
3.87k
  if (StrictAlignIter != CmdArgs.rend() &&
1579
3.87k
      
StringRef(*StrictAlignIter) == "+strict-align"1.52k
)
1580
1.52k
    CmdArgs.push_back("-Wunaligned-access");
1581
3.87k
}
1582
}
1583
1584
static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
1585
3.87k
                                    ArgStringList &CmdArgs, bool isAArch64) {
1586
3.87k
  const Arg *A = isAArch64
1587
3.87k
                     ? Args.getLastArg(options::OPT_msign_return_address_EQ,
1588
1.78k
                                       options::OPT_mbranch_protection_EQ)
1589
3.87k
                     : 
Args.getLastArg(options::OPT_mbranch_protection_EQ)2.09k
;
1590
3.87k
  if (!A)
1591
3.79k
    return;
1592
1593
77
  const Driver &D = TC.getDriver();
1594
77
  const llvm::Triple &Triple = TC.getEffectiveTriple();
1595
77
  if (!(isAArch64 || 
(45
Triple.isArmT32()45
&&
Triple.isArmMClass()43
)))
1596
7
    D.Diag(diag::warn_incompatible_branch_protection_option)
1597
7
        << Triple.getArchName();
1598
1599
77
  StringRef Scope, Key;
1600
77
  bool IndirectBranches;
1601
1602
77
  if (A->getOption().matches(options::OPT_msign_return_address_EQ)) {
1603
8
    Scope = A->getValue();
1604
8
    if (Scope != "none" && 
Scope != "non-leaf"5
&&
Scope != "all"3
)
1605
1
      D.Diag(diag::err_drv_unsupported_option_argument)
1606
1
          << A->getSpelling() << Scope;
1607
8
    Key = "a_key";
1608
8
    IndirectBranches = false;
1609
69
  } else {
1610
69
    StringRef DiagMsg;
1611
69
    llvm::ARM::ParsedBranchProtection PBP;
1612
69
    if (!llvm::ARM::parseBranchProtection(A->getValue(), PBP, DiagMsg))
1613
4
      D.Diag(diag::err_drv_unsupported_option_argument)
1614
4
          << A->getSpelling() << DiagMsg;
1615
69
    if (!isAArch64 && 
PBP.Key == "b_key"45
)
1616
13
      D.Diag(diag::warn_unsupported_branch_protection)
1617
13
          << "b-key" << A->getAsString(Args);
1618
69
    Scope = PBP.Scope;
1619
69
    Key = PBP.Key;
1620
69
    IndirectBranches = PBP.BranchTargetEnforcement;
1621
69
  }
1622
1623
77
  CmdArgs.push_back(
1624
77
      Args.MakeArgString(Twine("-msign-return-address=") + Scope));
1625
77
  if (!Scope.equals("none"))
1626
49
    CmdArgs.push_back(
1627
49
        Args.MakeArgString(Twine("-msign-return-address-key=") + Key));
1628
77
  if (IndirectBranches)
1629
35
    CmdArgs.push_back("-mbranch-target-enforce");
1630
77
}
1631
1632
void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
1633
2.09k
                             ArgStringList &CmdArgs, bool KernelOrKext) const {
1634
2.09k
  RenderARMABI(getToolChain().getDriver(), Triple, Args, CmdArgs);
1635
1636
  // Determine floating point ABI from the options & target defaults.
1637
2.09k
  arm::FloatABI ABI = arm::getARMFloatABI(getToolChain(), Args);
1638
2.09k
  if (ABI == arm::FloatABI::Soft) {
1639
    // Floating point operations and argument passing are soft.
1640
    // FIXME: This changes CPP defines, we need -target-soft-float.
1641
885
    CmdArgs.push_back("-msoft-float");
1642
885
    CmdArgs.push_back("-mfloat-abi");
1643
885
    CmdArgs.push_back("soft");
1644
1.20k
  } else if (ABI == arm::FloatABI::SoftFP) {
1645
    // Floating point operations are hard, but argument passing is soft.
1646
969
    CmdArgs.push_back("-mfloat-abi");
1647
969
    CmdArgs.push_back("soft");
1648
969
  } else {
1649
    // Floating point operations and argument passing are hard.
1650
236
    assert(ABI == arm::FloatABI::Hard && "Invalid float abi!");
1651
236
    CmdArgs.push_back("-mfloat-abi");
1652
236
    CmdArgs.push_back("hard");
1653
236
  }
1654
1655
  // Forward the -mglobal-merge option for explicit control over the pass.
1656
2.09k
  if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
1657
2.09k
                               options::OPT_mno_global_merge)) {
1658
2
    CmdArgs.push_back("-mllvm");
1659
2
    if (A->getOption().matches(options::OPT_mno_global_merge))
1660
1
      CmdArgs.push_back("-arm-global-merge=false");
1661
1
    else
1662
1
      CmdArgs.push_back("-arm-global-merge=true");
1663
2
  }
1664
1665
2.09k
  if (!Args.hasFlag(options::OPT_mimplicit_float,
1666
2.09k
                    options::OPT_mno_implicit_float, true))
1667
1
    CmdArgs.push_back("-no-implicit-float");
1668
1669
2.09k
  if (Args.getLastArg(options::OPT_mcmse))
1670
21
    CmdArgs.push_back("-mcmse");
1671
1672
2.09k
  AddAAPCSVolatileBitfieldArgs(Args, CmdArgs);
1673
1674
  // Enable/disable return address signing and indirect branch targets.
1675
2.09k
  CollectARMPACBTIOptions(getToolChain(), Args, CmdArgs, false /*isAArch64*/);
1676
1677
2.09k
  AddUnalignedAccessWarning(CmdArgs);
1678
2.09k
}
1679
1680
void Clang::RenderTargetOptions(const llvm::Triple &EffectiveTriple,
1681
                                const ArgList &Args, bool KernelOrKext,
1682
47.7k
                                ArgStringList &CmdArgs) const {
1683
47.7k
  const ToolChain &TC = getToolChain();
1684
1685
  // Add the target features
1686
47.7k
  getTargetFeatures(TC.getDriver(), EffectiveTriple, Args, CmdArgs, false);
1687
1688
  // Add target specific flags.
1689
47.7k
  switch (TC.getArch()) {
1690
1.20k
  default:
1691
1.20k
    break;
1692
1693
1.85k
  case llvm::Triple::arm:
1694
2.00k
  case llvm::Triple::armeb:
1695
2.07k
  case llvm::Triple::thumb:
1696
2.09k
  case llvm::Triple::thumbeb:
1697
    // Use the effective triple, which takes into account the deployment target.
1698
2.09k
    AddARMTargetArgs(EffectiveTriple, Args, CmdArgs, KernelOrKext);
1699
2.09k
    break;
1700
1701
1.55k
  case llvm::Triple::aarch64:
1702
1.55k
  case llvm::Triple::aarch64_32:
1703
1.78k
  case llvm::Triple::aarch64_be:
1704
1.78k
    AddAArch64TargetArgs(Args, CmdArgs);
1705
1.78k
    break;
1706
1707
32
  case llvm::Triple::loongarch32:
1708
145
  case llvm::Triple::loongarch64:
1709
145
    AddLoongArchTargetArgs(Args, CmdArgs);
1710
145
    break;
1711
1712
189
  case llvm::Triple::mips:
1713
232
  case llvm::Triple::mipsel:
1714
301
  case llvm::Triple::mips64:
1715
349
  case llvm::Triple::mips64el:
1716
349
    AddMIPSTargetArgs(Args, CmdArgs);
1717
349
    break;
1718
1719
234
  case llvm::Triple::ppc:
1720
242
  case llvm::Triple::ppcle:
1721
478
  case llvm::Triple::ppc64:
1722
595
  case llvm::Triple::ppc64le:
1723
595
    AddPPCTargetArgs(Args, CmdArgs);
1724
595
    break;
1725
1726
392
  case llvm::Triple::riscv32:
1727
735
  case llvm::Triple::riscv64:
1728
735
    AddRISCVTargetArgs(Args, CmdArgs);
1729
735
    break;
1730
1731
133
  case llvm::Triple::sparc:
1732
139
  case llvm::Triple::sparcel:
1733
209
  case llvm::Triple::sparcv9:
1734
209
    AddSparcTargetArgs(Args, CmdArgs);
1735
209
    break;
1736
1737
98
  case llvm::Triple::systemz:
1738
98
    AddSystemZTargetArgs(Args, CmdArgs);
1739
98
    break;
1740
1741
11.2k
  case llvm::Triple::x86:
1742
40.2k
  case llvm::Triple::x86_64:
1743
40.2k
    AddX86TargetArgs(Args, CmdArgs);
1744
40.2k
    break;
1745
1746
3
  case llvm::Triple::lanai:
1747
3
    AddLanaiTargetArgs(Args, CmdArgs);
1748
3
    break;
1749
1750
137
  case llvm::Triple::hexagon:
1751
137
    AddHexagonTargetArgs(Args, CmdArgs);
1752
137
    break;
1753
1754
97
  case llvm::Triple::wasm32:
1755
129
  case llvm::Triple::wasm64:
1756
129
    AddWebAssemblyTargetArgs(Args, CmdArgs);
1757
129
    break;
1758
1759
4
  case llvm::Triple::ve:
1760
4
    AddVETargetArgs(Args, CmdArgs);
1761
4
    break;
1762
47.7k
  }
1763
47.7k
}
1764
1765
namespace {
1766
void RenderAArch64ABI(const llvm::Triple &Triple, const ArgList &Args,
1767
1.78k
                      ArgStringList &CmdArgs) {
1768
1.78k
  const char *ABIName = nullptr;
1769
1.78k
  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
1770
0
    ABIName = A->getValue();
1771
1.78k
  else if (Triple.isOSDarwin())
1772
181
    ABIName = "darwinpcs";
1773
1.60k
  else
1774
1.60k
    ABIName = "aapcs";
1775
1776
1.78k
  CmdArgs.push_back("-target-abi");
1777
1.78k
  CmdArgs.push_back(ABIName);
1778
1.78k
}
1779
}
1780
1781
void Clang::AddAArch64TargetArgs(const ArgList &Args,
1782
1.78k
                                 ArgStringList &CmdArgs) const {
1783
1.78k
  const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
1784
1785
1.78k
  if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) ||
1786
1.78k
      Args.hasArg(options::OPT_mkernel) ||
1787
1.78k
      
Args.hasArg(options::OPT_fapple_kext)1.78k
)
1788
3
    CmdArgs.push_back("-disable-red-zone");
1789
1790
1.78k
  if (!Args.hasFlag(options::OPT_mimplicit_float,
1791
1.78k
                    options::OPT_mno_implicit_float, true))
1792
0
    CmdArgs.push_back("-no-implicit-float");
1793
1794
1.78k
  RenderAArch64ABI(Triple, Args, CmdArgs);
1795
1796
  // Forward the -mglobal-merge option for explicit control over the pass.
1797
1.78k
  if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
1798
1.78k
                               options::OPT_mno_global_merge)) {
1799
2
    CmdArgs.push_back("-mllvm");
1800
2
    if (A->getOption().matches(options::OPT_mno_global_merge))
1801
1
      CmdArgs.push_back("-aarch64-enable-global-merge=false");
1802
1
    else
1803
1
      CmdArgs.push_back("-aarch64-enable-global-merge=true");
1804
2
  }
1805
1806
  // Enable/disable return address signing and indirect branch targets.
1807
1.78k
  CollectARMPACBTIOptions(getToolChain(), Args, CmdArgs, true /*isAArch64*/);
1808
1809
  // Handle -msve_vector_bits=<bits>
1810
1.78k
  if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) {
1811
22
    StringRef Val = A->getValue();
1812
22
    const Driver &D = getToolChain().getDriver();
1813
22
    if (Val.equals("128") || 
Val.equals("256")19
||
Val.equals("512")17
||
1814
22
        
Val.equals("1024")15
||
Val.equals("2048")13
||
Val.equals("128+")11
||
1815
22
        
Val.equals("256+")10
||
Val.equals("512+")8
||
Val.equals("1024+")6
||
1816
22
        
Val.equals("2048+")5
) {
1817
18
      unsigned Bits = 0;
1818
18
      if (Val.endswith("+"))
1819
7
        Val = Val.substr(0, Val.size() - 1);
1820
11
      else {
1821
11
        bool Invalid = Val.getAsInteger(10, Bits); (void)Invalid;
1822
11
        assert(!Invalid && "Failed to parse value");
1823
11
        CmdArgs.push_back(
1824
11
            Args.MakeArgString("-mvscale-max=" + llvm::Twine(Bits / 128)));
1825
11
      }
1826
1827
18
      bool Invalid = Val.getAsInteger(10, Bits); (void)Invalid;
1828
18
      assert(!Invalid && "Failed to parse value");
1829
18
      CmdArgs.push_back(
1830
18
          Args.MakeArgString("-mvscale-min=" + llvm::Twine(Bits / 128)));
1831
    // Silently drop requests for vector-length agnostic code as it's implied.
1832
18
    } else 
if (4
!Val.equals("scalable")4
)
1833
      // Handle the unsupported values passed to msve-vector-bits.
1834
2
      D.Diag(diag::err_drv_unsupported_option_argument)
1835
2
          << A->getSpelling() << Val;
1836
22
  }
1837
1838
1.78k
  AddAAPCSVolatileBitfieldArgs(Args, CmdArgs);
1839
1840
1.78k
  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)) {
1841
149
    CmdArgs.push_back("-tune-cpu");
1842
149
    if (strcmp(A->getValue(), "native") == 0)
1843
0
      CmdArgs.push_back(Args.MakeArgString(llvm::sys::getHostCPUName()));
1844
149
    else
1845
149
      CmdArgs.push_back(A->getValue());
1846
149
  }
1847
1848
1.78k
  AddUnalignedAccessWarning(CmdArgs);
1849
1.78k
}
1850
1851
void Clang::AddLoongArchTargetArgs(const ArgList &Args,
1852
145
                                   ArgStringList &CmdArgs) const {
1853
145
  const llvm::Triple &Triple = getToolChain().getTriple();
1854
1855
145
  CmdArgs.push_back("-target-abi");
1856
145
  CmdArgs.push_back(
1857
145
      loongarch::getLoongArchABI(getToolChain().getDriver(), Args, Triple)
1858
145
          .data());
1859
1860
  // Handle -mtune.
1861
145
  if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
1862
14
    std::string TuneCPU = A->getValue();
1863
14
    TuneCPU = loongarch::postProcessTargetCPUString(TuneCPU, Triple);
1864
14
    CmdArgs.push_back("-tune-cpu");
1865
14
    CmdArgs.push_back(Args.MakeArgString(TuneCPU));
1866
14
  }
1867
145
}
1868
1869
void Clang::AddMIPSTargetArgs(const ArgList &Args,
1870
349
                              ArgStringList &CmdArgs) const {
1871
349
  const Driver &D = getToolChain().getDriver();
1872
349
  StringRef CPUName;
1873
349
  StringRef ABIName;
1874
349
  const llvm::Triple &Triple = getToolChain().getTriple();
1875
349
  mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
1876
1877
349
  CmdArgs.push_back("-target-abi");
1878
349
  CmdArgs.push_back(ABIName.data());
1879
1880
349
  mips::FloatABI ABI = mips::getMipsFloatABI(D, Args, Triple);
1881
349
  if (ABI == mips::FloatABI::Soft) {
1882
    // Floating point operations and argument passing are soft.
1883
62
    CmdArgs.push_back("-msoft-float");
1884
62
    CmdArgs.push_back("-mfloat-abi");
1885
62
    CmdArgs.push_back("soft");
1886
287
  } else {
1887
    // Floating point operations and argument passing are hard.
1888
287
    assert(ABI == mips::FloatABI::Hard && "Invalid float abi!");
1889
287
    CmdArgs.push_back("-mfloat-abi");
1890
287
    CmdArgs.push_back("hard");
1891
287
  }
1892
1893
349
  if (Arg *A = Args.getLastArg(options::OPT_mldc1_sdc1,
1894
349
                               options::OPT_mno_ldc1_sdc1)) {
1895
2
    if (A->getOption().matches(options::OPT_mno_ldc1_sdc1)) {
1896
1
      CmdArgs.push_back("-mllvm");
1897
1
      CmdArgs.push_back("-mno-ldc1-sdc1");
1898
1
    }
1899
2
  }
1900
1901
349
  if (Arg *A = Args.getLastArg(options::OPT_mcheck_zero_division,
1902
349
                               options::OPT_mno_check_zero_division)) {
1903
2
    if (A->getOption().matches(options::OPT_mno_check_zero_division)) {
1904
1
      CmdArgs.push_back("-mllvm");
1905
1
      CmdArgs.push_back("-mno-check-zero-division");
1906
1
    }
1907
2
  }
1908
1909
349
  if (Args.getLastArg(options::OPT_mfix4300)) {
1910
0
    CmdArgs.push_back("-mllvm");
1911
0
    CmdArgs.push_back("-mfix4300");
1912
0
  }
1913
1914
349
  if (Arg *A = Args.getLastArg(options::OPT_G)) {
1915
3
    StringRef v = A->getValue();
1916
3
    CmdArgs.push_back("-mllvm");
1917
3
    CmdArgs.push_back(Args.MakeArgString("-mips-ssection-threshold=" + v));
1918
3
    A->claim();
1919
3
  }
1920
1921
349
  Arg *GPOpt = Args.getLastArg(options::OPT_mgpopt, options::OPT_mno_gpopt);
1922
349
  Arg *ABICalls =
1923
349
      Args.getLastArg(options::OPT_mabicalls, options::OPT_mno_abicalls);
1924
1925
  // -mabicalls is the default for many MIPS environments, even with -fno-pic.
1926
  // -mgpopt is the default for static, -fno-pic environments but these two
1927
  // options conflict. We want to be certain that -mno-abicalls -mgpopt is
1928
  // the only case where -mllvm -mgpopt is passed.
1929
  // NOTE: We need a warning here or in the backend to warn when -mgpopt is
1930
  //       passed explicitly when compiling something with -mabicalls
1931
  //       (implictly) in affect. Currently the warning is in the backend.
1932
  //
1933
  // When the ABI in use is  N64, we also need to determine the PIC mode that
1934
  // is in use, as -fno-pic for N64 implies -mno-abicalls.
1935
349
  bool NoABICalls =
1936
349
      ABICalls && 
ABICalls->getOption().matches(options::OPT_mno_abicalls)30
;
1937
1938
349
  llvm::Reloc::Model RelocationModel;
1939
349
  unsigned PICLevel;
1940
349
  bool IsPIE;
1941
349
  std::tie(RelocationModel, PICLevel, IsPIE) =
1942
349
      ParsePICArgs(getToolChain(), Args);
1943
1944
349
  NoABICalls = NoABICalls ||
1945
349
               
(321
RelocationModel == llvm::Reloc::Static321
&&
ABIName == "n64"66
);
1946
1947
349
  bool WantGPOpt = GPOpt && 
GPOpt->getOption().matches(options::OPT_mgpopt)15
;
1948
  // We quietly ignore -mno-gpopt as the backend defaults to -mno-gpopt.
1949
349
  if (NoABICalls && 
(28
!GPOpt28
||
WantGPOpt12
)) {
1950
26
    CmdArgs.push_back("-mllvm");
1951
26
    CmdArgs.push_back("-mgpopt");
1952
1953
26
    Arg *LocalSData = Args.getLastArg(options::OPT_mlocal_sdata,
1954
26
                                      options::OPT_mno_local_sdata);
1955
26
    Arg *ExternSData = Args.getLastArg(options::OPT_mextern_sdata,
1956
26
                                       options::OPT_mno_extern_sdata);
1957
26
    Arg *EmbeddedData = Args.getLastArg(options::OPT_membedded_data,
1958
26
                                        options::OPT_mno_embedded_data);
1959
26
    if (LocalSData) {
1960
2
      CmdArgs.push_back("-mllvm");
1961
2
      if (LocalSData->getOption().matches(options::OPT_mlocal_sdata)) {
1962
1
        CmdArgs.push_back("-mlocal-sdata=1");
1963
1
      } else {
1964
1
        CmdArgs.push_back("-mlocal-sdata=0");
1965
1
      }
1966
2
      LocalSData->claim();
1967
2
    }
1968
1969
26
    if (ExternSData) {
1970
2
      CmdArgs.push_back("-mllvm");
1971
2
      if (ExternSData->getOption().matches(options::OPT_mextern_sdata)) {
1972
1
        CmdArgs.push_back("-mextern-sdata=1");
1973
1
      } else {
1974
1
        CmdArgs.push_back("-mextern-sdata=0");
1975
1
      }
1976
2
      ExternSData->claim();
1977
2
    }
1978
1979
26
    if (EmbeddedData) {
1980
2
      CmdArgs.push_back("-mllvm");
1981
2
      if (EmbeddedData->getOption().matches(options::OPT_membedded_data)) {
1982
1
        CmdArgs.push_back("-membedded-data=1");
1983
1
      } else {
1984
1
        CmdArgs.push_back("-membedded-data=0");
1985
1
      }
1986
2
      EmbeddedData->claim();
1987
2
    }
1988
1989
323
  } else if ((!ABICalls || 
(4
!NoABICalls4
&&
ABICalls2
)) &&
WantGPOpt321
)
1990
3
    D.Diag(diag::warn_drv_unsupported_gpopt) << (ABICalls ? 
01
:
12
);
1991
1992
349
  if (GPOpt)
1993
15
    GPOpt->claim();
1994
1995
349
  if (Arg *A = Args.getLastArg(options::OPT_mcompact_branches_EQ)) {
1996
3
    StringRef Val = StringRef(A->getValue());
1997
3
    if (mips::hasCompactBranches(CPUName)) {
1998
3
      if (Val == "never" || 
Val == "always"2
||
Val == "optimal"1
) {
1999
3
        CmdArgs.push_back("-mllvm");
2000
3
        CmdArgs.push_back(Args.MakeArgString("-mips-compact-branches=" + Val));
2001
3
      } else
2002
0
        D.Diag(diag::err_drv_unsupported_option_argument)
2003
0
            << A->getSpelling() << Val;
2004
3
    } else
2005
0
      D.Diag(diag::warn_target_unsupported_compact_branches) << CPUName;
2006
3
  }
2007
2008
349
  if (Arg *A = Args.getLastArg(options::OPT_mrelax_pic_calls,
2009
349
                               options::OPT_mno_relax_pic_calls)) {
2010
2
    if (A->getOption().matches(options::OPT_mno_relax_pic_calls)) {
2011
1
      CmdArgs.push_back("-mllvm");
2012
1
      CmdArgs.push_back("-mips-jalr-reloc=0");
2013
1
    }
2014
2
  }
2015
349
}
2016
2017
void Clang::AddPPCTargetArgs(const ArgList &Args,
2018
595
                             ArgStringList &CmdArgs) const {
2019
595
  const Driver &D = getToolChain().getDriver();
2020
595
  const llvm::Triple &T = getToolChain().getTriple();
2021
595
  if (Args.getLastArg(options::OPT_mtune_EQ)) {
2022
2
    CmdArgs.push_back("-tune-cpu");
2023
2
    std::string CPU = ppc::getPPCTuneCPU(Args, T);
2024
2
    CmdArgs.push_back(Args.MakeArgString(CPU));
2025
2
  }
2026
2027
  // Select the ABI to use.
2028
595
  const char *ABIName = nullptr;
2029
595
  if (T.isOSBinFormatELF()) {
2030
354
    switch (getToolChain().getArch()) {
2031
154
    case llvm::Triple::ppc64: {
2032
154
      if (T.isPPC64ELFv2ABI())
2033
8
        ABIName = "elfv2";
2034
146
      else
2035
146
        ABIName = "elfv1";
2036
154
      break;
2037
0
    }
2038
117
    case llvm::Triple::ppc64le:
2039
117
      ABIName = "elfv2";
2040
117
      break;
2041
83
    default:
2042
83
      break;
2043
354
    }
2044
354
  }
2045
2046
595
  bool IEEELongDouble = getToolChain().defaultToIEEELongDouble();
2047
595
  bool VecExtabi = false;
2048
595
  for (const Arg *A : Args.filtered(options::OPT_mabi_EQ)) {
2049
42
    StringRef V = A->getValue();
2050
42
    if (V == "ieeelongdouble") {
2051
4
      IEEELongDouble = true;
2052
4
      A->claim();
2053
38
    } else if (V == "ibmlongdouble") {
2054
6
      IEEELongDouble = false;
2055
6
      A->claim();
2056
32
    } else if (V == "vec-default") {
2057
5
      VecExtabi = false;
2058
5
      A->claim();
2059
27
    } else if (V == "vec-extabi") {
2060
7
      VecExtabi = true;
2061
7
      A->claim();
2062
20
    } else if (V == "elfv1") {
2063
10
      ABIName = "elfv1";
2064
10
      A->claim();
2065
10
    } else if (V == "elfv2") {
2066
8
      ABIName = "elfv2";
2067
8
      A->claim();
2068
8
    } else 
if (2
V != "altivec"2
)
2069
      // The ppc64 linux abis are all "altivec" abis by default. Accept and ignore
2070
      // the option if given as we don't have backend support for any targets
2071
      // that don't use the altivec abi.
2072
0
      ABIName = A->getValue();
2073
42
  }
2074
595
  if (IEEELongDouble)
2075
4
    CmdArgs.push_back("-mabi=ieeelongdouble");
2076
595
  if (VecExtabi) {
2077
7
    if (!T.isOSAIX())
2078
0
      D.Diag(diag::err_drv_unsupported_opt_for_target)
2079
0
          << "-mabi=vec-extabi" << T.str();
2080
7
    CmdArgs.push_back("-mabi=vec-extabi");
2081
7
  }
2082
2083
595
  ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args);
2084
595
  if (FloatABI == ppc::FloatABI::Soft) {
2085
    // Floating point operations and argument passing are soft.
2086
9
    CmdArgs.push_back("-msoft-float");
2087
9
    CmdArgs.push_back("-mfloat-abi");
2088
9
    CmdArgs.push_back("soft");
2089
586
  } else {
2090
    // Floating point operations and argument passing are hard.
2091
586
    assert(FloatABI == ppc::FloatABI::Hard && "Invalid float abi!");
2092
586
    CmdArgs.push_back("-mfloat-abi");
2093
586
    CmdArgs.push_back("hard");
2094
586
  }
2095
2096
595
  if (ABIName) {
2097
271
    CmdArgs.push_back("-target-abi");
2098
271
    CmdArgs.push_back(ABIName);
2099
271
  }
2100
595
}
2101
2102
static void SetRISCVSmallDataLimit(const ToolChain &TC, const ArgList &Args,
2103
735
                                   ArgStringList &CmdArgs) {
2104
735
  const Driver &D = TC.getDriver();
2105
735
  const llvm::Triple &Triple = TC.getTriple();
2106
  // Default small data limitation is eight.
2107
735
  const char *SmallDataLimit = "8";
2108
  // Get small data limitation.
2109
735
  if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
2110
735
                      options::OPT_fPIC)) {
2111
    // Not support linker relaxation for PIC.
2112
4
    SmallDataLimit = "0";
2113
4
    if (Args.hasArg(options::OPT_G)) {
2114
0
      D.Diag(diag::warn_drv_unsupported_sdata);
2115
0
    }
2116
731
  } else if (Args.getLastArgValue(options::OPT_mcmodel_EQ)
2117
731
                 .equals_insensitive("large") &&
2118
731
             
(Triple.getArch() == llvm::Triple::riscv64)1
) {
2119
    // Not support linker relaxation for RV64 with large code model.
2120
1
    SmallDataLimit = "0";
2121
1
    if (Args.hasArg(options::OPT_G)) {
2122
0
      D.Diag(diag::warn_drv_unsupported_sdata);
2123
0
    }
2124
730
  } else if (Triple.isAndroid()) {
2125
    // GP relaxation is not supported on Android.
2126
12
    SmallDataLimit = "0";
2127
12
    if (Args.hasArg(options::OPT_G)) {
2128
1
      D.Diag(diag::warn_drv_unsupported_sdata);
2129
1
    }
2130
718
  } else if (Arg *A = Args.getLastArg(options::OPT_G)) {
2131
8
    SmallDataLimit = A->getValue();
2132
8
  }
2133
  // Forward the -msmall-data-limit= option.
2134
735
  CmdArgs.push_back("-msmall-data-limit");
2135
735
  CmdArgs.push_back(SmallDataLimit);
2136
735
}
2137
2138
void Clang::AddRISCVTargetArgs(const ArgList &Args,
2139
735
                               ArgStringList &CmdArgs) const {
2140
735
  const llvm::Triple &Triple = getToolChain().getTriple();
2141
735
  StringRef ABIName = riscv::getRISCVABI(Args, Triple);
2142
2143
735
  CmdArgs.push_back("-target-abi");
2144
735
  CmdArgs.push_back(ABIName.data());
2145
2146
735
  SetRISCVSmallDataLimit(getToolChain(), Args, CmdArgs);
2147
2148
735
  if (!Args.hasFlag(options::OPT_mimplicit_float,
2149
735
                    options::OPT_mno_implicit_float, true))
2150
2
    CmdArgs.push_back("-no-implicit-float");
2151
2152
735
  if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
2153
14
    CmdArgs.push_back("-tune-cpu");
2154
14
    if (strcmp(A->getValue(), "native") == 0)
2155
1
      CmdArgs.push_back(Args.MakeArgString(llvm::sys::getHostCPUName()));
2156
13
    else
2157
13
      CmdArgs.push_back(A->getValue());
2158
14
  }
2159
2160
  // Handle -mrvv-vector-bits=<bits>
2161
735
  if (Arg *A = Args.getLastArg(options::OPT_mrvv_vector_bits_EQ)) {
2162
15
    StringRef Val = A->getValue();
2163
15
    const Driver &D = getToolChain().getDriver();
2164
2165
    // Get minimum VLen from march.
2166
15
    unsigned MinVLen = 0;
2167
15
    StringRef Arch = riscv::getRISCVArch(Args, Triple);
2168
15
    auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
2169
15
        Arch, /*EnableExperimentalExtensions*/ true);
2170
15
    if (!ISAInfo) {
2171
      // Ignore parsing error.
2172
0
      consumeError(ISAInfo.takeError());
2173
15
    } else {
2174
15
      MinVLen = (*ISAInfo)->getMinVLen();
2175
15
    }
2176
2177
    // If the value is "zvl", use MinVLen from march. Otherwise, try to parse
2178
    // as integer as long as we have a MinVLen.
2179
15
    unsigned Bits = 0;
2180
15
    if (Val.equals("zvl") && 
MinVLen >= llvm::RISCV::RVVBitsPerBlock3
) {
2181
2
      Bits = MinVLen;
2182
13
    } else if (!Val.getAsInteger(10, Bits)) {
2183
      // Only accept power of 2 values beteen RVVBitsPerBlock and 65536 that
2184
      // at least MinVLen.
2185
9
      if (Bits < MinVLen || 
Bits < llvm::RISCV::RVVBitsPerBlock7
||
2186
9
          
Bits > 655367
||
!llvm::isPowerOf2_32(Bits)6
)
2187
3
        Bits = 0;
2188
9
    }
2189
2190
    // If we got a valid value try to use it.
2191
15
    if (Bits != 0) {
2192
8
      unsigned VScaleMin = Bits / llvm::RISCV::RVVBitsPerBlock;
2193
8
      CmdArgs.push_back(
2194
8
          Args.MakeArgString("-mvscale-max=" + llvm::Twine(VScaleMin)));
2195
8
      CmdArgs.push_back(
2196
8
          Args.MakeArgString("-mvscale-min=" + llvm::Twine(VScaleMin)));
2197
8
    } else 
if (7
!Val.equals("scalable")7
) {
2198
      // Handle the unsupported values passed to mrvv-vector-bits.
2199
5
      D.Diag(diag::err_drv_unsupported_option_argument)
2200
5
          << A->getSpelling() << Val;
2201
5
    }
2202
15
  }
2203
735
}
2204
2205
void Clang::AddSparcTargetArgs(const ArgList &Args,
2206
209
                               ArgStringList &CmdArgs) const {
2207
209
  sparc::FloatABI FloatABI =
2208
209
      sparc::getSparcFloatABI(getToolChain().getDriver(), Args);
2209
2210
209
  if (FloatABI == sparc::FloatABI::Soft) {
2211
    // Floating point operations and argument passing are soft.
2212
5
    CmdArgs.push_back("-msoft-float");
2213
5
    CmdArgs.push_back("-mfloat-abi");
2214
5
    CmdArgs.push_back("soft");
2215
204
  } else {
2216
    // Floating point operations and argument passing are hard.
2217
204
    assert(FloatABI == sparc::FloatABI::Hard && "Invalid float abi!");
2218
204
    CmdArgs.push_back("-mfloat-abi");
2219
204
    CmdArgs.push_back("hard");
2220
204
  }
2221
2222
209
  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)) {
2223
4
    StringRef Name = A->getValue();
2224
4
    std::string TuneCPU;
2225
4
    if (Name == "native")
2226
0
      TuneCPU = std::string(llvm::sys::getHostCPUName());
2227
4
    else
2228
4
      TuneCPU = std::string(Name);
2229
2230
4
    CmdArgs.push_back("-tune-cpu");
2231
4
    CmdArgs.push_back(Args.MakeArgString(TuneCPU));
2232
4
  }
2233
209
}
2234
2235
void Clang::AddSystemZTargetArgs(const ArgList &Args,
2236
98
                                 ArgStringList &CmdArgs) const {
2237
98
  if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
2238
0
    CmdArgs.push_back("-tune-cpu");
2239
0
    if (strcmp(A->getValue(), "native") == 0)
2240
0
      CmdArgs.push_back(Args.MakeArgString(llvm::sys::getHostCPUName()));
2241
0
    else
2242
0
      CmdArgs.push_back(A->getValue());
2243
0
  }
2244
2245
98
  bool HasBackchain =
2246
98
      Args.hasFlag(options::OPT_mbackchain, options::OPT_mno_backchain, false);
2247
98
  bool HasPackedStack = Args.hasFlag(options::OPT_mpacked_stack,
2248
98
                                     options::OPT_mno_packed_stack, false);
2249
98
  systemz::FloatABI FloatABI =
2250
98
      systemz::getSystemZFloatABI(getToolChain().getDriver(), Args);
2251
98
  bool HasSoftFloat = (FloatABI == systemz::FloatABI::Soft);
2252
98
  if (HasBackchain && 
HasPackedStack1
&&
!HasSoftFloat0
) {
2253
0
    const Driver &D = getToolChain().getDriver();
2254
0
    D.Diag(diag::err_drv_unsupported_opt)
2255
0
      << "-mpacked-stack -mbackchain -mhard-float";
2256
0
  }
2257
98
  if (HasBackchain)
2258
1
    CmdArgs.push_back("-mbackchain");
2259
98
  if (HasPackedStack)
2260
0
    CmdArgs.push_back("-mpacked-stack");
2261
98
  if (HasSoftFloat) {
2262
    // Floating point operations and argument passing are soft.
2263
1
    CmdArgs.push_back("-msoft-float");
2264
1
    CmdArgs.push_back("-mfloat-abi");
2265
1
    CmdArgs.push_back("soft");
2266
1
  }
2267
98
}
2268
2269
void Clang::AddX86TargetArgs(const ArgList &Args,
2270
40.2k
                             ArgStringList &CmdArgs) const {
2271
40.2k
  const Driver &D = getToolChain().getDriver();
2272
40.2k
  addX86AlignBranchArgs(D, Args, CmdArgs, /*IsLTO=*/false);
2273
2274
40.2k
  if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) ||
2275
40.2k
      
Args.hasArg(options::OPT_mkernel)40.2k
||
2276
40.2k
      
Args.hasArg(options::OPT_fapple_kext)40.2k
)
2277
20
    CmdArgs.push_back("-disable-red-zone");
2278
2279
40.2k
  if (!Args.hasFlag(options::OPT_mtls_direct_seg_refs,
2280
40.2k
                    options::OPT_mno_tls_direct_seg_refs, true))
2281
1
    CmdArgs.push_back("-mno-tls-direct-seg-refs");
2282
2283
  // Default to avoid implicit floating-point for kernel/kext code, but allow
2284
  // that to be overridden with -mno-soft-float.
2285
40.2k
  bool NoImplicitFloat = (Args.hasArg(options::OPT_mkernel) ||
2286
40.2k
                          
Args.hasArg(options::OPT_fapple_kext)40.2k
);
2287
40.2k
  if (Arg *A = Args.getLastArg(
2288
40.2k
          options::OPT_msoft_float, options::OPT_mno_soft_float,
2289
40.2k
          options::OPT_mimplicit_float, options::OPT_mno_implicit_float)) {
2290
6
    const Option &O = A->getOption();
2291
6
    NoImplicitFloat = (O.matches(options::OPT_mno_implicit_float) ||
2292
6
                       
O.matches(options::OPT_msoft_float)5
);
2293
6
  }
2294
40.2k
  if (NoImplicitFloat)
2295
21
    CmdArgs.push_back("-no-implicit-float");
2296
2297
40.2k
  if (Arg *A = Args.getLastArg(options::OPT_masm_EQ)) {
2298
3
    StringRef Value = A->getValue();
2299
3
    if (Value == "intel" || 
Value == "att"2
) {
2300
2
      CmdArgs.push_back("-mllvm");
2301
2
      CmdArgs.push_back(Args.MakeArgString("-x86-asm-syntax=" + Value));
2302
2
      CmdArgs.push_back(Args.MakeArgString("-inline-asm=" + Value));
2303
2
    } else {
2304
1
      D.Diag(diag::err_drv_unsupported_option_argument)
2305
1
          << A->getSpelling() << Value;
2306
1
    }
2307
40.2k
  } else if (D.IsCLMode()) {
2308
703
    CmdArgs.push_back("-mllvm");
2309
703
    CmdArgs.push_back("-x86-asm-syntax=intel");
2310
703
  }
2311
2312
40.2k
  if (Arg *A = Args.getLastArg(options::OPT_mskip_rax_setup,
2313
40.2k
                               options::OPT_mno_skip_rax_setup))
2314
2
    if (A->getOption().matches(options::OPT_mskip_rax_setup))
2315
1
      CmdArgs.push_back(Args.MakeArgString("-mskip-rax-setup"));
2316
2317
  // Set flags to support MCU ABI.
2318
40.2k
  if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu, false)) {
2319
8
    CmdArgs.push_back("-mfloat-abi");
2320
8
    CmdArgs.push_back("soft");
2321
8
    CmdArgs.push_back("-mstack-alignment=4");
2322
8
  }
2323
2324
  // Handle -mtune.
2325
2326
  // Default to "generic" unless -march is present or targetting the PS4/PS5.
2327
40.2k
  std::string TuneCPU;
2328
40.2k
  if (!Args.hasArg(clang::driver::options::OPT_march_EQ) &&
2329
40.2k
      
!getToolChain().getTriple().isPS()39.7k
)
2330
39.4k
    TuneCPU = "generic";
2331
2332
  // Override based on -mtune.
2333
40.2k
  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)) {
2334
10
    StringRef Name = A->getValue();
2335
2336
10
    if (Name == "native") {
2337
0
      Name = llvm::sys::getHostCPUName();
2338
0
      if (!Name.empty())
2339
0
        TuneCPU = std::string(Name);
2340
0
    } else
2341
10
      TuneCPU = std::string(Name);
2342
10
  }
2343
2344
40.2k
  if (!TuneCPU.empty()) {
2345
39.4k
    CmdArgs.push_back("-tune-cpu");
2346
39.4k
    CmdArgs.push_back(Args.MakeArgString(TuneCPU));
2347
39.4k
  }
2348
40.2k
}
2349
2350
void Clang::AddHexagonTargetArgs(const ArgList &Args,
2351
137
                                 ArgStringList &CmdArgs) const {
2352
137
  CmdArgs.push_back("-mqdsp6-compat");
2353
137
  CmdArgs.push_back("-Wreturn-type");
2354
2355
137
  if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
2356
1
    CmdArgs.push_back("-mllvm");
2357
1
    CmdArgs.push_back(
2358
1
        Args.MakeArgString("-hexagon-small-data-threshold=" + Twine(*G)));
2359
1
  }
2360
2361
137
  if (!Args.hasArg(options::OPT_fno_short_enums))
2362
137
    CmdArgs.push_back("-fshort-enums");
2363
137
  if (Args.getLastArg(options::OPT_mieee_rnd_near)) {
2364
0
    CmdArgs.push_back("-mllvm");
2365
0
    CmdArgs.push_back("-enable-hexagon-ieee-rnd-near");
2366
0
  }
2367
137
  CmdArgs.push_back("-mllvm");
2368
137
  CmdArgs.push_back("-machine-sink-split=0");
2369
137
}
2370
2371
void Clang::AddLanaiTargetArgs(const ArgList &Args,
2372
3
                               ArgStringList &CmdArgs) const {
2373
3
  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
2374
0
    StringRef CPUName = A->getValue();
2375
2376
0
    CmdArgs.push_back("-target-cpu");
2377
0
    CmdArgs.push_back(Args.MakeArgString(CPUName));
2378
0
  }
2379
3
  if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
2380
0
    StringRef Value = A->getValue();
2381
    // Only support mregparm=4 to support old usage. Report error for all other
2382
    // cases.
2383
0
    int Mregparm;
2384
0
    if (Value.getAsInteger(10, Mregparm)) {
2385
0
      if (Mregparm != 4) {
2386
0
        getToolChain().getDriver().Diag(
2387
0
            diag::err_drv_unsupported_option_argument)
2388
0
            << A->getSpelling() << Value;
2389
0
      }
2390
0
    }
2391
0
  }
2392
3
}
2393
2394
void Clang::AddWebAssemblyTargetArgs(const ArgList &Args,
2395
129
                                     ArgStringList &CmdArgs) const {
2396
  // Default to "hidden" visibility.
2397
129
  if (!Args.hasArg(options::OPT_fvisibility_EQ,
2398
129
                   options::OPT_fvisibility_ms_compat))
2399
127
    CmdArgs.push_back("-fvisibility=hidden");
2400
129
}
2401
2402
4
void Clang::AddVETargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
2403
  // Floating point operations and argument passing are hard.
2404
4
  CmdArgs.push_back("-mfloat-abi");
2405
4
  CmdArgs.push_back("hard");
2406
4
}
2407
2408
void Clang::DumpCompilationDatabase(Compilation &C, StringRef Filename,
2409
                                    StringRef Target, const InputInfo &Output,
2410
12
                                    const InputInfo &Input, const ArgList &Args) const {
2411
  // If this is a dry run, do not create the compilation database file.
2412
12
  if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH))
2413
0
    return;
2414
2415
12
  using llvm::yaml::escape;
2416
12
  const Driver &D = getToolChain().getDriver();
2417
2418
12
  if (!CompilationDatabase) {
2419
8
    std::error_code EC;
2420
8
    auto File = std::make_unique<llvm::raw_fd_ostream>(
2421
8
        Filename, EC,
2422
8
        llvm::sys::fs::OF_TextWithCRLF | llvm::sys::fs::OF_Append);
2423
8
    if (EC) {
2424
1
      D.Diag(clang::diag::err_drv_compilationdatabase) << Filename
2425
1
                                                       << EC.message();
2426
1
      return;
2427
1
    }
2428
7
    CompilationDatabase = std::move(File);
2429
7
  }
2430
11
  auto &CDB = *CompilationDatabase;
2431
11
  auto CWD = D.getVFS().getCurrentWorkingDirectory();
2432
11
  if (!CWD)
2433
0
    CWD = ".";
2434
11
  CDB << "{ \"directory\": \"" << escape(*CWD) << "\"";
2435
11
  CDB << ", \"file\": \"" << escape(Input.getFilename()) << "\"";
2436
11
  if (Output.isFilename())
2437
10
    CDB << ", \"output\": \"" << escape(Output.getFilename()) << "\"";
2438
11
  CDB << ", \"arguments\": [\"" << escape(D.ClangExecutable) << "\"";
2439
11
  SmallString<128> Buf;
2440
11
  Buf = "-x";
2441
11
  Buf += types::getTypeName(Input.getType());
2442
11
  CDB << ", \"" << escape(Buf) << "\"";
2443
11
  if (!D.SysRoot.empty() && 
!Args.hasArg(options::OPT__sysroot_EQ)2
) {
2444
0
    Buf = "--sysroot=";
2445
0
    Buf += D.SysRoot;
2446
0
    CDB << ", \"" << escape(Buf) << "\"";
2447
0
  }
2448
11
  CDB << ", \"" << escape(Input.getFilename()) << "\"";
2449
11
  if (Output.isFilename())
2450
10
    CDB << ", \"-o\", \"" << escape(Output.getFilename()) << "\"";
2451
104
  for (auto &A: Args) {
2452
104
    auto &O = A->getOption();
2453
    // Skip language selection, which is positional.
2454
104
    if (O.getID() == options::OPT_x)
2455
4
      continue;
2456
    // Skip writing dependency output and the compilation database itself.
2457
100
    if (O.getGroup().isValid() && 
O.getGroup().getID() == options::OPT_M_Group58
)
2458
12
      continue;
2459
88
    if (O.getID() == options::OPT_gen_cdb_fragment_path)
2460
4
      continue;
2461
    // Skip inputs.
2462
84
    if (O.getKind() == Option::InputClass)
2463
13
      continue;
2464
    // Skip output.
2465
71
    if (O.getID() == options::OPT_o)
2466
8
      continue;
2467
    // All other arguments are quoted and appended.
2468
63
    ArgStringList ASL;
2469
63
    A->render(Args, ASL);
2470
63
    for (auto &it: ASL)
2471
76
      CDB << ", \"" << escape(it) << "\"";
2472
63
  }
2473
11
  Buf = "--target=";
2474
11
  Buf += Target;
2475
11
  CDB << ", \"" << escape(Buf) << "\"]},\n";
2476
11
}
2477
2478
void Clang::DumpCompilationDatabaseFragmentToDir(
2479
    StringRef Dir, Compilation &C, StringRef Target, const InputInfo &Output,
2480
4
    const InputInfo &Input, const llvm::opt::ArgList &Args) const {
2481
  // If this is a dry run, do not create the compilation database file.
2482
4
  if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH))
2483
1
    return;
2484
2485
3
  if (CompilationDatabase)
2486
0
    DumpCompilationDatabase(C, "", Target, Output, Input, Args);
2487
2488
3
  SmallString<256> Path = Dir;
2489
3
  const auto &Driver = C.getDriver();
2490
3
  Driver.getVFS().makeAbsolute(Path);
2491
3
  auto Err = llvm::sys::fs::create_directory(Path, /*IgnoreExisting=*/true);
2492
3
  if (Err) {
2493
0
    Driver.Diag(diag::err_drv_compilationdatabase) << Dir << Err.message();
2494
0
    return;
2495
0
  }
2496
2497
3
  llvm::sys::path::append(
2498
3
      Path,
2499
3
      Twine(llvm::sys::path::filename(Input.getFilename())) + ".%%%%.json");
2500
3
  int FD;
2501
3
  SmallString<256> TempPath;
2502
3
  Err = llvm::sys::fs::createUniqueFile(Path, FD, TempPath,
2503
3
                                        llvm::sys::fs::OF_Text);
2504
3
  if (Err) {
2505
0
    Driver.Diag(diag::err_drv_compilationdatabase) << Path << Err.message();
2506
0
    return;
2507
0
  }
2508
3
  CompilationDatabase =
2509
3
      std::make_unique<llvm::raw_fd_ostream>(FD, /*shouldClose=*/true);
2510
3
  DumpCompilationDatabase(C, "", Target, Output, Input, Args);
2511
3
}
2512
2513
45
static bool CheckARMImplicitITArg(StringRef Value) {
2514
45
  return Value == "always" || 
Value == "never"24
||
Value == "arm"15
||
2515
45
         
Value == "thumb"10
;
2516
45
}
2517
2518
static void AddARMImplicitITArgs(const ArgList &Args, ArgStringList &CmdArgs,
2519
30
                                 StringRef Value) {
2520
30
  CmdArgs.push_back("-mllvm");
2521
30
  CmdArgs.push_back(Args.MakeArgString("-arm-implicit-it=" + Value));
2522
30
}
2523
2524
static void CollectArgsForIntegratedAssembler(Compilation &C,
2525
                                              const ArgList &Args,
2526
                                              ArgStringList &CmdArgs,
2527
11.7k
                                              const Driver &D) {
2528
11.7k
  if (UseRelaxAll(C, Args))
2529
11.1k
    CmdArgs.push_back("-mrelax-all");
2530
2531
  // Only default to -mincremental-linker-compatible if we think we are
2532
  // targeting the MSVC linker.
2533
11.7k
  bool DefaultIncrementalLinkerCompatible =
2534
11.7k
      C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
2535
11.7k
  if (Args.hasFlag(options::OPT_mincremental_linker_compatible,
2536
11.7k
                   options::OPT_mno_incremental_linker_compatible,
2537
11.7k
                   DefaultIncrementalLinkerCompatible))
2538
689
    CmdArgs.push_back("-mincremental-linker-compatible");
2539
2540
11.7k
  Args.AddLastArg(CmdArgs, options::OPT_femit_dwarf_unwind_EQ);
2541
2542
11.7k
  Args.addOptInFlag(CmdArgs, options::OPT_femit_compact_unwind_non_canonical,
2543
11.7k
                    options::OPT_fno_emit_compact_unwind_non_canonical);
2544
2545
  // If you add more args here, also add them to the block below that
2546
  // starts with "// If CollectArgsForIntegratedAssembler() isn't called below".
2547
2548
  // When passing -I arguments to the assembler we sometimes need to
2549
  // unconditionally take the next argument.  For example, when parsing
2550
  // '-Wa,-I -Wa,foo' we need to accept the -Wa,foo arg after seeing the
2551
  // -Wa,-I arg and when parsing '-Wa,-I,foo' we need to accept the 'foo'
2552
  // arg after parsing the '-I' arg.
2553
11.7k
  bool TakeNextArg = false;
2554
2555
11.7k
  bool UseRelaxRelocations = C.getDefaultToolChain().useRelaxRelocations();
2556
11.7k
  bool UseNoExecStack = false;
2557
11.7k
  const char *MipsTargetFeature = nullptr;
2558
11.7k
  StringRef ImplicitIt;
2559
11.7k
  for (const Arg *A :
2560
11.7k
       Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler,
2561
11.7k
                     options::OPT_mimplicit_it_EQ)) {
2562
179
    A->claim();
2563
2564
179
    if (A->getOption().getID() == options::OPT_mimplicit_it_EQ) {
2565
8
      switch (C.getDefaultToolChain().getArch()) {
2566
8
      case llvm::Triple::arm:
2567
8
      case llvm::Triple::armeb:
2568
8
      case llvm::Triple::thumb:
2569
8
      case llvm::Triple::thumbeb:
2570
        // Only store the value; the last value set takes effect.
2571
8
        ImplicitIt = A->getValue();
2572
8
        if (!CheckARMImplicitITArg(ImplicitIt))
2573
1
          D.Diag(diag::err_drv_unsupported_option_argument)
2574
1
              << A->getSpelling() << ImplicitIt;
2575
8
        continue;
2576
0
      default:
2577
0
        break;
2578
8
      }
2579
8
    }
2580
2581
194
    
for (StringRef Value : A->getValues())171
{
2582
194
      if (TakeNextArg) {
2583
7
        CmdArgs.push_back(Value.data());
2584
7
        TakeNextArg = false;
2585
7
        continue;
2586
7
      }
2587
2588
187
      if (C.getDefaultToolChain().getTriple().isOSBinFormatCOFF() &&
2589
187
          
Value == "-mbig-obj"2
)
2590
2
        continue; // LLVM handles bigobj automatically
2591
2592
185
      switch (C.getDefaultToolChain().getArch()) {
2593
63
      default:
2594
63
        break;
2595
63
      case llvm::Triple::wasm32:
2596
0
      case llvm::Triple::wasm64:
2597
0
        if (Value == "--no-type-check") {
2598
0
          CmdArgs.push_back("-mno-type-check");
2599
0
          continue;
2600
0
        }
2601
0
        break;
2602
0
      case llvm::Triple::thumb:
2603
0
      case llvm::Triple::thumbeb:
2604
90
      case llvm::Triple::arm:
2605
90
      case llvm::Triple::armeb:
2606
90
        if (Value.startswith("-mimplicit-it=")) {
2607
          // Only store the value; the last value set takes effect.
2608
37
          ImplicitIt = Value.split("=").second;
2609
37
          if (CheckARMImplicitITArg(ImplicitIt))
2610
33
            continue;
2611
37
        }
2612
57
        if (Value == "-mthumb")
2613
          // -mthumb has already been processed in ComputeLLVMTriple()
2614
          // recognize but skip over here.
2615
6
          continue;
2616
51
        break;
2617
51
      case llvm::Triple::mips:
2618
32
      case llvm::Triple::mipsel:
2619
32
      case llvm::Triple::mips64:
2620
32
      case llvm::Triple::mips64el:
2621
32
        if (Value == "--trap") {
2622
3
          CmdArgs.push_back("-target-feature");
2623
3
          CmdArgs.push_back("+use-tcc-in-div");
2624
3
          continue;
2625
3
        }
2626
29
        if (Value == "--break") {
2627
3
          CmdArgs.push_back("-target-feature");
2628
3
          CmdArgs.push_back("-use-tcc-in-div");
2629
3
          continue;
2630
3
        }
2631
26
        if (Value.startswith("-msoft-float")) {
2632
3
          CmdArgs.push_back("-target-feature");
2633
3
          CmdArgs.push_back("+soft-float");
2634
3
          continue;
2635
3
        }
2636
23
        if (Value.startswith("-mhard-float")) {
2637
3
          CmdArgs.push_back("-target-feature");
2638
3
          CmdArgs.push_back("-soft-float");
2639
3
          continue;
2640
3
        }
2641
2642
20
        MipsTargetFeature = llvm::StringSwitch<const char *>(Value)
2643
20
                                .Case("-mips1", "+mips1")
2644
20
                                .Case("-mips2", "+mips2")
2645
20
                                .Case("-mips3", "+mips3")
2646
20
                                .Case("-mips4", "+mips4")
2647
20
                                .Case("-mips5", "+mips5")
2648
20
                                .Case("-mips32", "+mips32")
2649
20
                                .Case("-mips32r2", "+mips32r2")
2650
20
                                .Case("-mips32r3", "+mips32r3")
2651
20
                                .Case("-mips32r5", "+mips32r5")
2652
20
                                .Case("-mips32r6", "+mips32r6")
2653
20
                                .Case("-mips64", "+mips64")
2654
20
                                .Case("-mips64r2", "+mips64r2")
2655
20
                                .Case("-mips64r3", "+mips64r3")
2656
20
                                .Case("-mips64r5", "+mips64r5")
2657
20
                                .Case("-mips64r6", "+mips64r6")
2658
20
                                .Default(nullptr);
2659
20
        if (MipsTargetFeature)
2660
20
          continue;
2661
185
      }
2662
2663
114
      if (Value == "-force_cpusubtype_ALL") {
2664
        // Do nothing, this is the default and we don't support anything else.
2665
114
      } else if (Value == "-L") {
2666
1
        CmdArgs.push_back("-msave-temp-labels");
2667
113
      } else if (Value == "--fatal-warnings") {
2668
4
        CmdArgs.push_back("-massembler-fatal-warnings");
2669
109
      } else if (Value == "--no-warn" || 
Value == "-W"107
) {
2670
3
        CmdArgs.push_back("-massembler-no-warn");
2671
106
      } else if (Value == "--noexecstack") {
2672
1
        UseNoExecStack = true;
2673
105
      } else if (Value.startswith("-compress-debug-sections") ||
2674
105
                 
Value.startswith("--compress-debug-sections")103
||
2675
105
                 
Value == "-nocompress-debug-sections"100
||
2676
105
                 
Value == "--nocompress-debug-sections"100
) {
2677
6
        CmdArgs.push_back(Value.data());
2678
99
      } else if (Value == "-mrelax-relocations=yes" ||
2679
99
                 
Value == "--mrelax-relocations=yes"95
) {
2680
4
        UseRelaxRelocations = true;
2681
95
      } else if (Value == "-mrelax-relocations=no" ||
2682
95
                 
Value == "--mrelax-relocations=no"91
) {
2683
6
        UseRelaxRelocations = false;
2684
89
      } else if (Value.startswith("-I")) {
2685
5
        CmdArgs.push_back(Value.data());
2686
        // We need to consume the next argument if the current arg is a plain
2687
        // -I. The next arg will be the include directory.
2688
5
        if (Value == "-I")
2689
3
          TakeNextArg = true;
2690
84
      } else if (Value.startswith("-gdwarf-")) {
2691
        // "-gdwarf-N" options are not cc1as options.
2692
3
        unsigned DwarfVersion = DwarfVersionNum(Value);
2693
3
        if (DwarfVersion == 0) { // Send it onward, and let cc1as complain.
2694
1
          CmdArgs.push_back(Value.data());
2695
2
        } else {
2696
2
          RenderDebugEnablingArgs(Args, CmdArgs,
2697
2
                                  llvm::codegenoptions::DebugInfoConstructor,
2698
2
                                  DwarfVersion, llvm::DebuggerKind::Default);
2699
2
        }
2700
81
      } else if (Value.startswith("-mcpu") || 
Value.startswith("-mfpu")64
||
2701
81
                 
Value.startswith("-mhwdiv")61
||
Value.startswith("-march")57
) {
2702
        // Do nothing, we'll validate it later.
2703
63
      } else 
if (18
Value == "-defsym"18
) {
2704
7
          if (A->getNumValues() != 2) {
2705
2
            D.Diag(diag::err_drv_defsym_invalid_format) << Value;
2706
2
            break;
2707
2
          }
2708
5
          const char *S = A->getValue(1);
2709
5
          auto Pair = StringRef(S).split('=');
2710
5
          auto Sym = Pair.first;
2711
5
          auto SVal = Pair.second;
2712
2713
5
          if (Sym.empty() || 
SVal.empty()4
) {
2714
2
            D.Diag(diag::err_drv_defsym_invalid_format) << S;
2715
2
            break;
2716
2
          }
2717
3
          int64_t IVal;
2718
3
          if (SVal.getAsInteger(0, IVal)) {
2719
1
            D.Diag(diag::err_drv_defsym_invalid_symval) << SVal;
2720
1
            break;
2721
1
          }
2722
2
          CmdArgs.push_back(Value.data());
2723
2
          TakeNextArg = true;
2724
11
      } else if (Value == "-fdebug-compilation-dir") {
2725
2
        CmdArgs.push_back("-fdebug-compilation-dir");
2726
2
        TakeNextArg = true;
2727
9
      } else if (Value.consume_front("-fdebug-compilation-dir=")) {
2728
        // The flag is a -Wa / -Xassembler argument and Options doesn't
2729
        // parse the argument, so this isn't automatically aliased to
2730
        // -fdebug-compilation-dir (without '=') here.
2731
2
        CmdArgs.push_back("-fdebug-compilation-dir");
2732
2
        CmdArgs.push_back(Value.data());
2733
7
      } else if (Value == "--version") {
2734
1
        D.PrintVersion(C, llvm::outs());
2735
6
      } else {
2736
6
        D.Diag(diag::err_drv_unsupported_option_argument)
2737
6
            << A->getSpelling() << Value;
2738
6
      }
2739
114
    }
2740
171
  }
2741
11.7k
  if (ImplicitIt.size())
2742
30
    AddARMImplicitITArgs(Args, CmdArgs, ImplicitIt);
2743
11.7k
  if (!UseRelaxRelocations)
2744
6
    CmdArgs.push_back("-mrelax-relocations=no");
2745
11.7k
  if (UseNoExecStack)
2746
1
    CmdArgs.push_back("-mnoexecstack");
2747
11.7k
  if (MipsTargetFeature != nullptr) {
2748
17
    CmdArgs.push_back("-target-feature");
2749
17
    CmdArgs.push_back(MipsTargetFeature);
2750
17
  }
2751
2752
  // forward -fembed-bitcode to assmebler
2753
11.7k
  if (C.getDriver().embedBitcodeEnabled() ||
2754
11.7k
      
C.getDriver().embedBitcodeMarkerOnly()11.7k
)
2755
16
    Args.AddLastArg(CmdArgs, options::OPT_fembed_bitcode_EQ);
2756
2757
11.7k
  if (const char *AsSecureLogFile = getenv("AS_SECURE_LOG_FILE")) {
2758
1
    CmdArgs.push_back("-as-secure-log-file");
2759
1
    CmdArgs.push_back(Args.MakeArgString(AsSecureLogFile));
2760
1
  }
2761
11.7k
}
2762
2763
static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
2764
                                       bool OFastEnabled, const ArgList &Args,
2765
                                       ArgStringList &CmdArgs,
2766
47.7k
                                       const JobAction &JA) {
2767
  // Handle various floating point optimization flags, mapping them to the
2768
  // appropriate LLVM code generation flags. This is complicated by several
2769
  // "umbrella" flags, so we do this by stepping through the flags incrementally
2770
  // adjusting what we think is enabled/disabled, then at the end setting the
2771
  // LLVM flags based on the final state.
2772
47.7k
  bool HonorINFs = true;
2773
47.7k
  bool HonorNaNs = true;
2774
47.7k
  bool ApproxFunc = false;
2775
  // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes.
2776
47.7k
  bool MathErrno = TC.IsMathErrnoDefault();
2777
47.7k
  bool AssociativeMath = false;
2778
47.7k
  bool ReciprocalMath = false;
2779
47.7k
  bool SignedZeros = true;
2780
47.7k
  bool TrappingMath = false; // Implemented via -ffp-exception-behavior
2781
47.7k
  bool TrappingMathPresent = false; // Is trapping-math in args, and not
2782
                                    // overriden by ffp-exception-behavior?
2783
47.7k
  bool RoundingFPMath = false;
2784
47.7k
  bool RoundingMathPresent = false; // Is rounding-math in args?
2785
  // -ffp-model values: strict, fast, precise
2786
47.7k
  StringRef FPModel = "";
2787
  // -ffp-exception-behavior options: strict, maytrap, ignore
2788
47.7k
  StringRef FPExceptionBehavior = "";
2789
  // -ffp-eval-method options: double, extended, source
2790
47.7k
  StringRef FPEvalMethod = "";
2791
47.7k
  const llvm::DenormalMode DefaultDenormalFPMath =
2792
47.7k
      TC.getDefaultDenormalModeForType(Args, JA);
2793
47.7k
  const llvm::DenormalMode DefaultDenormalFP32Math =
2794
47.7k
      TC.getDefaultDenormalModeForType(Args, JA, &llvm::APFloat::IEEEsingle());
2795
2796
47.7k
  llvm::DenormalMode DenormalFPMath = DefaultDenormalFPMath;
2797
47.7k
  llvm::DenormalMode DenormalFP32Math = DefaultDenormalFP32Math;
2798
  // CUDA and HIP don't rely on the frontend to pass an ffp-contract option.
2799
  // If one wasn't given by the user, don't pass it here.
2800
47.7k
  StringRef FPContract;
2801
47.7k
  StringRef LastSeenFfpContractOption;
2802
47.7k
  bool SeenUnsafeMathModeOption = false;
2803
47.7k
  if (!JA.isDeviceOffloading(Action::OFK_Cuda) &&
2804
47.7k
      
!JA.isOffloading(Action::OFK_HIP)47.7k
)
2805
46.9k
    FPContract = "on";
2806
47.7k
  bool StrictFPModel = false;
2807
47.7k
  StringRef Float16ExcessPrecision = "";
2808
47.7k
  StringRef BFloat16ExcessPrecision = "";
2809
2810
47.7k
  if (const Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
2811
0
    CmdArgs.push_back("-mlimit-float-precision");
2812
0
    CmdArgs.push_back(A->getValue());
2813
0
  }
2814
2815
776k
  for (const Arg *A : Args) {
2816
776k
    auto optID = A->getOption().getID();
2817
776k
    bool PreciseFPModel = false;
2818
776k
    switch (optID) {
2819
776k
    default:
2820
776k
      break;
2821
776k
    case options::OPT_ffp_model_EQ: {
2822
      // If -ffp-model= is seen, reset to fno-fast-math
2823
47
      HonorINFs = true;
2824
47
      HonorNaNs = true;
2825
47
      ApproxFunc = false;
2826
      // Turning *off* -ffast-math restores the toolchain default.
2827
47
      MathErrno = TC.IsMathErrnoDefault();
2828
47
      AssociativeMath = false;
2829
47
      ReciprocalMath = false;
2830
47
      SignedZeros = true;
2831
      // -fno_fast_math restores default denormal and fpcontract handling
2832
47
      FPContract = "on";
2833
47
      DenormalFPMath = llvm::DenormalMode::getIEEE();
2834
2835
      // FIXME: The target may have picked a non-IEEE default mode here based on
2836
      // -cl-denorms-are-zero. Should the target consider -fp-model interaction?
2837
47
      DenormalFP32Math = llvm::DenormalMode::getIEEE();
2838
2839
47
      StringRef Val = A->getValue();
2840
47
      if (OFastEnabled && 
!Val.equals("fast")3
) {
2841
          // Only -ffp-model=fast is compatible with OFast, ignore.
2842
3
        D.Diag(clang::diag::warn_drv_overriding_option)
2843
3
            << Args.MakeArgString("-ffp-model=" + Val) << "-Ofast";
2844
3
        break;
2845
3
      }
2846
44
      StrictFPModel = false;
2847
44
      PreciseFPModel = true;
2848
      // ffp-model= is a Driver option, it is entirely rewritten into more
2849
      // granular options before being passed into cc1.
2850
      // Use the gcc option in the switch below.
2851
44
      if (!FPModel.empty() && 
!FPModel.equals(Val)2
)
2852
2
        D.Diag(clang::diag::warn_drv_overriding_option)
2853
2
            << Args.MakeArgString("-ffp-model=" + FPModel)
2854
2
            << Args.MakeArgString("-ffp-model=" + Val);
2855
44
      if (Val.equals("fast")) {
2856
9
        optID = options::OPT_ffast_math;
2857
9
        FPModel = Val;
2858
9
        FPContract = "fast";
2859
35
      } else if (Val.equals("precise")) {
2860
8
        optID = options::OPT_ffp_contract;
2861
8
        FPModel = Val;
2862
8
        FPContract = "on";
2863
8
        PreciseFPModel = true;
2864
27
      } else if (Val.equals("strict")) {
2865
26
        StrictFPModel = true;
2866
26
        optID = options::OPT_frounding_math;
2867
26
        FPExceptionBehavior = "strict";
2868
26
        FPModel = Val;
2869
26
        FPContract = "off";
2870
26
        TrappingMath = true;
2871
26
      } else
2872
1
        D.Diag(diag::err_drv_unsupported_option_argument)
2873
1
            << A->getSpelling() << Val;
2874
44
      break;
2875
47
      }
2876
776k
    }
2877
2878
776k
    switch (optID) {
2879
    // If this isn't an FP option skip the claim below
2880
776k
    default: continue;
2881
2882
    // Options controlling individual features
2883
776k
    
case options::OPT_fhonor_infinities: HonorINFs = true; break3
;
2884
7
    case options::OPT_fno_honor_infinities: HonorINFs = false;        break;
2885
3
    case options::OPT_fhonor_nans:          HonorNaNs = true;         break;
2886
6
    case options::OPT_fno_honor_nans:       HonorNaNs = false;        break;
2887
11
    case options::OPT_fapprox_func:         ApproxFunc = true;        break;
2888
2
    case options::OPT_fno_approx_func:      ApproxFunc = false;       break;
2889
8
    case options::OPT_fmath_errno:          MathErrno = true;         break;
2890
15
    case options::OPT_fno_math_errno:       MathErrno = false;        break;
2891
11
    case options::OPT_fassociative_math:    AssociativeMath = true;   break;
2892
4
    case options::OPT_fno_associative_math: AssociativeMath = false;  break;
2893
14
    case options::OPT_freciprocal_math:     ReciprocalMath = true;    break;
2894
3
    case options::OPT_fno_reciprocal_math:  ReciprocalMath = false;   break;
2895
3
    case options::OPT_fsigned_zeros:        SignedZeros = true;       break;
2896
14
    case options::OPT_fno_signed_zeros:     SignedZeros = false;      break;
2897
4
    case options::OPT_ftrapping_math:
2898
4
      if (!TrappingMathPresent && 
!FPExceptionBehavior.empty()3
&&
2899
4
          
!FPExceptionBehavior.equals("strict")0
)
2900
        // Warn that previous value of option is overridden.
2901
0
        D.Diag(clang::diag::warn_drv_overriding_option)
2902
0
            << Args.MakeArgString("-ffp-exception-behavior=" +
2903
0
                                  FPExceptionBehavior)
2904
0
            << "-ftrapping-math";
2905
4
      TrappingMath = true;
2906
4
      TrappingMathPresent = true;
2907
4
      FPExceptionBehavior = "strict";
2908
4
      break;
2909
11
    case options::OPT_fno_trapping_math:
2910
11
      if (!TrappingMathPresent && !FPExceptionBehavior.empty() &&
2911
11
          
!FPExceptionBehavior.equals("ignore")1
)
2912
        // Warn that previous value of option is overridden.
2913
1
        D.Diag(clang::diag::warn_drv_overriding_option)
2914
1
            << Args.MakeArgString("-ffp-exception-behavior=" +
2915
1
                                  FPExceptionBehavior)
2916
1
            << "-fno-trapping-math";
2917
11
      TrappingMath = false;
2918
11
      TrappingMathPresent = true;
2919
11
      FPExceptionBehavior = "ignore";
2920
11
      break;
2921
2922
29
    case options::OPT_frounding_math:
2923
29
      RoundingFPMath = true;
2924
29
      RoundingMathPresent = true;
2925
29
      break;
2926
2927
4
    case options::OPT_fno_rounding_math:
2928
4
      RoundingFPMath = false;
2929
4
      RoundingMathPresent = false;
2930
4
      break;
2931
2932
11
    case options::OPT_fdenormal_fp_math_EQ:
2933
11
      DenormalFPMath = llvm::parseDenormalFPAttribute(A->getValue());
2934
11
      DenormalFP32Math = DenormalFPMath;
2935
11
      if (!DenormalFPMath.isValid()) {
2936
4
        D.Diag(diag::err_drv_invalid_value)
2937
4
            << A->getAsString(Args) << A->getValue();
2938
4
      }
2939
11
      break;
2940
2941
0
    case options::OPT_fdenormal_fp_math_f32_EQ:
2942
0
      DenormalFP32Math = llvm::parseDenormalFPAttribute(A->getValue());
2943
0
      if (!DenormalFP32Math.isValid()) {
2944
0
        D.Diag(diag::err_drv_invalid_value)
2945
0
            << A->getAsString(Args) << A->getValue();
2946
0
      }
2947
0
      break;
2948
2949
    // Validate and pass through -ffp-contract option.
2950
105
    case options::OPT_ffp_contract: {
2951
105
      StringRef Val = A->getValue();
2952
105
      if (PreciseFPModel) {
2953
        // -ffp-model=precise enables ffp-contract=on.
2954
        // -ffp-model=precise sets PreciseFPModel to on and Val to
2955
        // "precise". FPContract is set.
2956
8
        ;
2957
97
      } else if (Val.equals("fast") || 
Val.equals("on")64
||
Val.equals("off")32
||
2958
97
                 
Val.equals("fast-honor-pragmas")1
) {
2959
97
        FPContract = Val;
2960
97
        LastSeenFfpContractOption = Val;
2961
97
      } else
2962
0
        D.Diag(diag::err_drv_unsupported_option_argument)
2963
0
            << A->getSpelling() << Val;
2964
105
      break;
2965
0
    }
2966
2967
    // Validate and pass through -ffp-model option.
2968
4
    case options::OPT_ffp_model_EQ:
2969
      // This should only occur in the error case
2970
      // since the optID has been replaced by a more granular
2971
      // floating point option.
2972
4
      break;
2973
2974
    // Validate and pass through -ffp-exception-behavior option.
2975
10
    case options::OPT_ffp_exception_behavior_EQ: {
2976
10
      StringRef Val = A->getValue();
2977
10
      if (!TrappingMathPresent && 
!FPExceptionBehavior.empty()9
&&
2978
10
          
!FPExceptionBehavior.equals(Val)0
)
2979
        // Warn that previous value of option is overridden.
2980
0
        D.Diag(clang::diag::warn_drv_overriding_option)
2981
0
            << Args.MakeArgString("-ffp-exception-behavior=" +
2982
0
                                  FPExceptionBehavior)
2983
0
            << Args.MakeArgString("-ffp-exception-behavior=" + Val);
2984
10
      TrappingMath = TrappingMathPresent = false;
2985
10
      if (Val.equals("ignore") || 
Val.equals("maytrap")7
)
2986
5
        FPExceptionBehavior = Val;
2987
5
      else if (Val.equals("strict")) {
2988
4
        FPExceptionBehavior = Val;
2989
4
        TrappingMath = TrappingMathPresent = true;
2990
4
      } else
2991
1
        D.Diag(diag::err_drv_unsupported_option_argument)
2992
1
            << A->getSpelling() << Val;
2993
10
      break;
2994
0
    }
2995
2996
    // Validate and pass through -ffp-eval-method option.
2997
5
    case options::OPT_ffp_eval_method_EQ: {
2998
5
      StringRef Val = A->getValue();
2999
5
      if (Val.equals("double") || Val.equals("extended") ||
3000
5
          Val.equals("source"))
3001
5
        FPEvalMethod = Val;
3002
0
      else
3003
0
        D.Diag(diag::err_drv_unsupported_option_argument)
3004
0
            << A->getSpelling() << Val;
3005
5
      break;
3006
0
    }
3007
3008
26
    case options::OPT_fexcess_precision_EQ: {
3009
26
      StringRef Val = A->getValue();
3010
26
      const llvm::Triple::ArchType Arch = TC.getArch();
3011
26
      if (Arch == llvm::Triple::x86 || 
Arch == llvm::Triple::x86_6418
) {
3012
18
        if (Val.equals("standard") || 
Val.equals("fast")14
)
3013
8
          Float16ExcessPrecision = Val;
3014
        // To make it GCC compatible, allow the value of "16" which
3015
        // means disable excess precision, the same meaning than clang's
3016
        // equivalent value "none".
3017
10
        else if (Val.equals("16"))
3018
4
          Float16ExcessPrecision = "none";
3019
6
        else
3020
6
          D.Diag(diag::err_drv_unsupported_option_argument)
3021
6
              << A->getSpelling() << Val;
3022
18
      } else {
3023
8
        if (!(Val.equals("standard") || 
Val.equals("fast")6
))
3024
4
          D.Diag(diag::err_drv_unsupported_option_argument)
3025
4
              << A->getSpelling() << Val;
3026
8
      }
3027
26
      BFloat16ExcessPrecision = Float16ExcessPrecision;
3028
26
      break;
3029
0
    }
3030
10
    case options::OPT_ffinite_math_only:
3031
10
      HonorINFs = false;
3032
10
      HonorNaNs = false;
3033
10
      break;
3034
6
    case options::OPT_fno_finite_math_only:
3035
6
      HonorINFs = true;
3036
6
      HonorNaNs = true;
3037
6
      break;
3038
3039
37
    case options::OPT_funsafe_math_optimizations:
3040
37
      AssociativeMath = true;
3041
37
      ReciprocalMath = true;
3042
37
      SignedZeros = false;
3043
37
      ApproxFunc = true;
3044
37
      TrappingMath = false;
3045
37
      FPExceptionBehavior = "";
3046
37
      FPContract = "fast";
3047
37
      SeenUnsafeMathModeOption = true;
3048
37
      break;
3049
28
    case options::OPT_fno_unsafe_math_optimizations:
3050
28
      AssociativeMath = false;
3051
28
      ReciprocalMath = false;
3052
28
      SignedZeros = true;
3053
28
      ApproxFunc = false;
3054
28
      TrappingMath = true;
3055
28
      FPExceptionBehavior = "strict";
3056
3057
      // The target may have opted to flush by default, so force IEEE.
3058
28
      DenormalFPMath = llvm::DenormalMode::getIEEE();
3059
28
      DenormalFP32Math = llvm::DenormalMode::getIEEE();
3060
28
      if (!JA.isDeviceOffloading(Action::OFK_Cuda) &&
3061
28
          !JA.isOffloading(Action::OFK_HIP)) {
3062
28
        if (LastSeenFfpContractOption != "") {
3063
13
          FPContract = LastSeenFfpContractOption;
3064
15
        } else if (SeenUnsafeMathModeOption)
3065
5
          FPContract = "on";
3066
28
      }
3067
28
      break;
3068
3069
27
    case options::OPT_Ofast:
3070
      // If -Ofast is the optimization level, then -ffast-math should be enabled
3071
27
      if (!OFastEnabled)
3072
2
        continue;
3073
27
      
[[fallthrough]];25
3074
131
    case options::OPT_ffast_math:
3075
131
      HonorINFs = false;
3076
131
      HonorNaNs = false;
3077
131
      MathErrno = false;
3078
131
      AssociativeMath = true;
3079
131
      ReciprocalMath = true;
3080
131
      ApproxFunc = true;
3081
131
      SignedZeros = false;
3082
131
      TrappingMath = false;
3083
131
      RoundingFPMath = false;
3084
131
      FPExceptionBehavior = "";
3085
      // If fast-math is set then set the fp-contract mode to fast.
3086
131
      FPContract = "fast";
3087
131
      SeenUnsafeMathModeOption = true;
3088
131
      break;
3089
63
    case options::OPT_fno_fast_math:
3090
63
      HonorINFs = true;
3091
63
      HonorNaNs = true;
3092
      // Turning on -ffast-math (with either flag) removes the need for
3093
      // MathErrno. However, turning *off* -ffast-math merely restores the
3094
      // toolchain default (which may be false).
3095
63
      MathErrno = TC.IsMathErrnoDefault();
3096
63
      AssociativeMath = false;
3097
63
      ReciprocalMath = false;
3098
63
      ApproxFunc = false;
3099
63
      SignedZeros = true;
3100
      // -fno_fast_math restores default denormal and fpcontract handling
3101
63
      DenormalFPMath = DefaultDenormalFPMath;
3102
63
      DenormalFP32Math = llvm::DenormalMode::getIEEE();
3103
63
      if (!JA.isDeviceOffloading(Action::OFK_Cuda) &&
3104
63
          !JA.isOffloading(Action::OFK_HIP)) {
3105
60
        if (LastSeenFfpContractOption != "") {
3106
16
          FPContract = LastSeenFfpContractOption;
3107
44
        } else if (SeenUnsafeMathModeOption)
3108
7
          FPContract = "on";
3109
60
      }
3110
63
      break;
3111
776k
    }
3112
588
    if (StrictFPModel) {
3113
      // If -ffp-model=strict has been specified on command line but
3114
      // subsequent options conflict then emit warning diagnostic.
3115
44
      if (HonorINFs && 
HonorNaNs39
&&
!AssociativeMath38
&&
!ReciprocalMath36
&&
3116
44
          
SignedZeros35
&&
TrappingMath34
&&
RoundingFPMath33
&&
!ApproxFunc32
&&
3117
44
          
DenormalFPMath == llvm::DenormalMode::getIEEE()31
&&
3118
44
          
DenormalFP32Math == llvm::DenormalMode::getIEEE()30
&&
3119
44
          
FPContract.equals("off")30
)
3120
        // OK: Current Arg doesn't conflict with -ffp-model=strict
3121
27
        ;
3122
17
      else {
3123
17
        StrictFPModel = false;
3124
17
        FPModel = "";
3125
17
        auto RHS = (A->getNumValues() == 0)
3126
17
                       ? 
A->getSpelling()13
3127
17
                       : 
Args.MakeArgString(A->getSpelling() + A->getValue())4
;
3128
17
        if (RHS != "-ffp-model=strict")
3129
17
          D.Diag(clang::diag::warn_drv_overriding_option)
3130
17
              << "-ffp-model=strict" << RHS;
3131
17
      }
3132
44
    }
3133
3134
    // If we handled this option claim it
3135
588
    A->claim();
3136
588
  }
3137
3138
47.7k
  if (!HonorINFs)
3139
112
    CmdArgs.push_back("-menable-no-infs");
3140
3141
47.7k
  if (!HonorNaNs)
3142
111
    CmdArgs.push_back("-menable-no-nans");
3143
3144
47.7k
  if (ApproxFunc)
3145
139
    CmdArgs.push_back("-fapprox-func");
3146
3147
47.7k
  if (MathErrno)
3148
28.0k
    CmdArgs.push_back("-fmath-errno");
3149
3150
47.7k
 if (AssociativeMath && 
ReciprocalMath136
&&
!SignedZeros132
&&
ApproxFunc129
&&
3151
47.7k
     
!TrappingMath127
)
3152
124
    CmdArgs.push_back("-funsafe-math-optimizations");
3153
3154
47.7k
  if (!SignedZeros)
3155
140
    CmdArgs.push_back("-fno-signed-zeros");
3156
3157
47.7k
  if (AssociativeMath && 
!SignedZeros136
&&
!TrappingMath132
)
3158
128
    CmdArgs.push_back("-mreassociate");
3159
3160
47.7k
  if (ReciprocalMath)
3161
139
    CmdArgs.push_back("-freciprocal-math");
3162
3163
47.7k
  if (TrappingMath) {
3164
    // FP Exception Behavior is also set to strict
3165
50
    assert(FPExceptionBehavior.equals("strict"));
3166
50
  }
3167
3168
  // The default is IEEE.
3169
47.7k
  if (DenormalFPMath != llvm::DenormalMode::getIEEE()) {
3170
300
    llvm::SmallString<64> DenormFlag;
3171
300
    llvm::raw_svector_ostream ArgStr(DenormFlag);
3172
300
    ArgStr << "-fdenormal-fp-math=" << DenormalFPMath;
3173
300
    CmdArgs.push_back(Args.MakeArgString(ArgStr.str()));
3174
300
  }
3175
3176
  // Add f32 specific denormal mode flag if it's different.
3177
47.7k
  if (DenormalFP32Math != DenormalFPMath) {
3178
123
    llvm::SmallString<64> DenormFlag;
3179
123
    llvm::raw_svector_ostream ArgStr(DenormFlag);
3180
123
    ArgStr << "-fdenormal-fp-math-f32=" << DenormalFP32Math;
3181
123
    CmdArgs.push_back(Args.MakeArgString(ArgStr.str()));
3182
123
  }
3183
3184
47.7k
  if (!FPContract.empty())
3185
46.9k
    CmdArgs.push_back(Args.MakeArgString("-ffp-contract=" + FPContract));
3186
3187
47.7k
  if (!RoundingFPMath)
3188
47.7k
    CmdArgs.push_back(Args.MakeArgString("-fno-rounding-math"));
3189
3190
47.7k
  if (RoundingFPMath && 
RoundingMathPresent23
)
3191
23
    CmdArgs.push_back(Args.MakeArgString("-frounding-math"));
3192
3193
47.7k
  if (!FPExceptionBehavior.empty())
3194
65
    CmdArgs.push_back(Args.MakeArgString("-ffp-exception-behavior=" +
3195
65
                      FPExceptionBehavior));
3196
3197
47.7k
  if (!FPEvalMethod.empty())
3198
5
    CmdArgs.push_back(Args.MakeArgString("-ffp-eval-method=" + FPEvalMethod));
3199
3200
47.7k
  if (!Float16ExcessPrecision.empty())
3201
12
    CmdArgs.push_back(Args.MakeArgString("-ffloat16-excess-precision=" +
3202
12
                                         Float16ExcessPrecision));
3203
47.7k
  if (!BFloat16ExcessPrecision.empty())
3204
12
    CmdArgs.push_back(Args.MakeArgString("-fbfloat16-excess-precision=" +
3205
12
                                         BFloat16ExcessPrecision));
3206
3207
47.7k
  ParseMRecip(D, Args, CmdArgs);
3208
3209
  // -ffast-math enables the __FAST_MATH__ preprocessor macro, but check for the
3210
  // individual features enabled by -ffast-math instead of the option itself as
3211
  // that's consistent with gcc's behaviour.
3212
47.7k
  if (!HonorINFs && 
!HonorNaNs112
&&
!MathErrno106
&&
AssociativeMath103
&&
ApproxFunc94
&&
3213
47.7k
      
ReciprocalMath93
&&
!SignedZeros92
&&
!TrappingMath91
&&
!RoundingFPMath89
) {
3214
89
    CmdArgs.push_back("-ffast-math");
3215
89
    if (FPModel.equals("fast")) {
3216
7
      if (FPContract.equals("fast"))
3217
        // All set, do nothing.
3218
5
        ;
3219
2
      else if (FPContract.empty())
3220
        // Enable -ffp-contract=fast
3221
0
        CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast"));
3222
2
      else
3223
2
        D.Diag(clang::diag::warn_drv_overriding_option)
3224
2
            << "-ffp-model=fast"
3225
2
            << Args.MakeArgString("-ffp-contract=" + FPContract);
3226
7
    }
3227
89
  }
3228
3229
  // Handle __FINITE_MATH_ONLY__ similarly.
3230
47.7k
  if (!HonorINFs && 
!HonorNaNs112
)
3231
106
    CmdArgs.push_back("-ffinite-math-only");
3232
3233
47.7k
  if (const Arg *A = Args.getLastArg(options::OPT_mfpmath_EQ)) {
3234
1
    CmdArgs.push_back("-mfpmath");
3235
1
    CmdArgs.push_back(A->getValue());
3236
1
  }
3237
3238
  // Disable a codegen optimization for floating-point casts.
3239
47.7k
  if (Args.hasFlag(options::OPT_fno_strict_float_cast_overflow,
3240
47.7k
                   options::OPT_fstrict_float_cast_overflow, false))
3241
1
    CmdArgs.push_back("-fno-strict-float-cast-overflow");
3242
47.7k
}
3243
3244
static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs,
3245
                                  const llvm::Triple &Triple,
3246
56
                                  const InputInfo &Input) {
3247
  // Add default argument set.
3248
56
  if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
3249
56
    CmdArgs.push_back("-analyzer-checker=core");
3250
56
    CmdArgs.push_back("-analyzer-checker=apiModeling");
3251
3252
56
    if (!Triple.isWindowsMSVCEnvironment()) {
3253
53
      CmdArgs.push_back("-analyzer-checker=unix");
3254
53
    } else {
3255
      // Enable "unix" checkers that also work on Windows.
3256
3
      CmdArgs.push_back("-analyzer-checker=unix.API");
3257
3
      CmdArgs.push_back("-analyzer-checker=unix.Malloc");
3258
3
      CmdArgs.push_back("-analyzer-checker=unix.MallocSizeof");
3259
3
      CmdArgs.push_back("-analyzer-checker=unix.MismatchedDeallocator");
3260
3
      CmdArgs.push_back("-analyzer-checker=unix.cstring.BadSizeArg");
3261
3
      CmdArgs.push_back("-analyzer-checker=unix.cstring.NullArg");
3262
3
    }
3263
3264
    // Disable some unix checkers for PS4/PS5.
3265
56
    if (Triple.isPS()) {
3266
6
      CmdArgs.push_back("-analyzer-disable-checker=unix.API");
3267
6
      CmdArgs.push_back("-analyzer-disable-checker=unix.Vfork");
3268
6
    }
3269
3270
56
    if (Triple.isOSDarwin()) {
3271
44
      CmdArgs.push_back("-analyzer-checker=osx");
3272
44
      CmdArgs.push_back(
3273
44
          "-analyzer-checker=security.insecureAPI.decodeValueOfObjCType");
3274
44
    }
3275
12
    else if (Triple.isOSFuchsia())
3276
0
      CmdArgs.push_back("-analyzer-checker=fuchsia");
3277
3278
56
    CmdArgs.push_back("-analyzer-checker=deadcode");
3279
3280
56
    if (types::isCXX(Input.getType()))
3281
21
      CmdArgs.push_back("-analyzer-checker=cplusplus");
3282
3283
56
    if (!Triple.isPS()) {
3284
50
      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.UncheckedReturn");
3285
50
      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.getpw");
3286
50
      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.gets");
3287
50
      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mktemp");
3288
50
      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mkstemp");
3289
50
      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.vfork");
3290
50
    }
3291
3292
    // Default nullability checks.
3293
56
    CmdArgs.push_back("-analyzer-checker=nullability.NullPassedToNonnull");
3294
56
    CmdArgs.push_back("-analyzer-checker=nullability.NullReturnedFromNonnull");
3295
56
  }
3296
3297
  // Set the output format. The default is plist, for (lame) historical reasons.
3298
56
  CmdArgs.push_back("-analyzer-output");
3299
56
  if (Arg *A = Args.getLastArg(options::OPT__analyzer_output))
3300
0
    CmdArgs.push_back(A->getValue());
3301
56
  else
3302
56
    CmdArgs.push_back("plist");
3303
3304
  // Disable the presentation of standard compiler warnings when using
3305
  // --analyze.  We only want to show static analyzer diagnostics or frontend
3306
  // errors.
3307
56
  CmdArgs.push_back("-w");
3308
3309
  // Add -Xanalyzer arguments when running as analyzer.
3310
56
  Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
3311
56
}
3312
3313
3
static bool isValidSymbolName(StringRef S) {
3314
3
  if (S.empty())
3315
1
    return false;
3316
3317
2
  if (std::isdigit(S[0]))
3318
1
    return false;
3319
3320
3
  
return llvm::all_of(S, [](char C) 1
{ return std::isalnum(C) ||
C == '_'0
; });
3321
2
}
3322
3323
static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
3324
                             const ArgList &Args, ArgStringList &CmdArgs,
3325
47.7k
                             bool KernelOrKext) {
3326
47.7k
  const llvm::Triple &EffectiveTriple = TC.getEffectiveTriple();
3327
3328
  // NVPTX doesn't support stack protectors; from the compiler's perspective, it
3329
  // doesn't even have a stack!
3330
47.7k
  if (EffectiveTriple.isNVPTX())
3331
63
    return;
3332
3333
  // -stack-protector=0 is default.
3334
47.6k
  LangOptions::StackProtectorMode StackProtectorLevel = LangOptions::SSPOff;
3335
47.6k
  LangOptions::StackProtectorMode DefaultStackProtectorLevel =
3336
47.6k
      TC.GetDefaultStackProtectorLevel(KernelOrKext);
3337
3338
47.6k
  if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
3339
47.6k
                               options::OPT_fstack_protector_all,
3340
47.6k
                               options::OPT_fstack_protector_strong,
3341
47.6k
                               options::OPT_fstack_protector)) {
3342
15
    if (A->getOption().matches(options::OPT_fstack_protector))
3343
9
      StackProtectorLevel =
3344
9
          std::max<>(LangOptions::SSPOn, DefaultStackProtectorLevel);
3345
6
    else if (A->getOption().matches(options::OPT_fstack_protector_strong))
3346
2
      StackProtectorLevel = LangOptions::SSPStrong;
3347
4
    else if (A->getOption().matches(options::OPT_fstack_protector_all))
3348
3
      StackProtectorLevel = LangOptions::SSPReq;
3349
3350
15
    if (EffectiveTriple.isBPF() && 
StackProtectorLevel != LangOptions::SSPOff0
) {
3351
0
      D.Diag(diag::warn_drv_unsupported_option_for_target)
3352
0
          << A->getSpelling() << EffectiveTriple.getTriple();
3353
0
      StackProtectorLevel = DefaultStackProtectorLevel;
3354
0
    }
3355
47.6k
  } else {
3356
47.6k
    StackProtectorLevel = DefaultStackProtectorLevel;
3357
47.6k
  }
3358
3359
47.6k
  if (StackProtectorLevel) {
3360
18.2k
    CmdArgs.push_back("-stack-protector");
3361
18.2k
    CmdArgs.push_back(Args.MakeArgString(Twine(StackProtectorLevel)));
3362
18.2k
  }
3363
3364
  // --param ssp-buffer-size=
3365
47.6k
  for (const Arg *A : Args.filtered(options::OPT__param)) {
3366
5
    StringRef Str(A->getValue());
3367
5
    if (Str.startswith("ssp-buffer-size=")) {
3368
2
      if (StackProtectorLevel) {
3369
2
        CmdArgs.push_back("-stack-protector-buffer-size");
3370
        // FIXME: Verify the argument is a valid integer.
3371
2
        CmdArgs.push_back(Args.MakeArgString(Str.drop_front(16)));
3372
2
      }
3373
2
      A->claim();
3374
2
    }
3375
5
  }
3376
3377
47.6k
  const std::string &TripleStr = EffectiveTriple.getTriple();
3378
47.6k
  if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
3379
11
    StringRef Value = A->getValue();
3380
11
    if (!EffectiveTriple.isX86() && 
!EffectiveTriple.isAArch64()8
&&
3381
11
        
!EffectiveTriple.isARM()5
&&
!EffectiveTriple.isThumb()2
)
3382
1
      D.Diag(diag::err_drv_unsupported_opt_for_target)
3383
1
          << A->getAsString(Args) << TripleStr;
3384
11
    if ((EffectiveTriple.isX86() || 
EffectiveTriple.isARM()8
||
3385
11
         
EffectiveTriple.isThumb()5
) &&
3386
11
        
Value != "tls"7
&&
Value != "global"3
) {
3387
2
      D.Diag(diag::err_drv_invalid_value_with_suggestion)
3388
2
          << A->getOption().getName() << Value << "tls global";
3389
2
      return;
3390
2
    }
3391
9
    if ((EffectiveTriple.isARM() || 
EffectiveTriple.isThumb()7
) &&
3392
9
        
Value == "tls"3
) {
3393
3
      if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
3394
1
        D.Diag(diag::err_drv_ssp_missing_offset_argument)
3395
1
            << A->getAsString(Args);
3396
1
        return;
3397
1
      }
3398
      // Check whether the target subarch supports the hardware TLS register
3399
2
      if (!arm::isHardTPSupported(EffectiveTriple)) {
3400
1
        D.Diag(diag::err_target_unsupported_tp_hard)
3401
1
            << EffectiveTriple.getArchName();
3402
1
        return;
3403
1
      }
3404
      // Check whether the user asked for something other than -mtp=cp15
3405
1
      if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
3406
1
        StringRef Value = A->getValue();
3407
1
        if (Value != "cp15") {
3408
1
          D.Diag(diag::err_drv_argument_not_allowed_with)
3409
1
              << A->getAsString(Args) << "-mstack-protector-guard=tls";
3410
1
          return;
3411
1
        }
3412
1
      }
3413
0
      CmdArgs.push_back("-target-feature");
3414
0
      CmdArgs.push_back("+read-tp-tpidruro");
3415
0
    }
3416
6
    if (EffectiveTriple.isAArch64() && 
Value != "sysreg"3
&&
Value != "global"1
) {
3417
1
      D.Diag(diag::err_drv_invalid_value_with_suggestion)
3418
1
          << A->getOption().getName() << Value << "sysreg global";
3419
1
      return;
3420
1
    }
3421
5
    A->render(Args, CmdArgs);
3422
5
  }
3423
3424
47.6k
  if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) {
3425
5
    StringRef Value = A->getValue();
3426
5
    if (!EffectiveTriple.isX86() && 
!EffectiveTriple.isAArch64()4
&&
3427
5
        
!EffectiveTriple.isARM()2
&&
!EffectiveTriple.isThumb()1
)
3428
1
      D.Diag(diag::err_drv_unsupported_opt_for_target)
3429
1
          << A->getAsString(Args) << TripleStr;
3430
5
    int Offset;
3431
5
    if (Value.getAsInteger(10, Offset)) {
3432
0
      D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
3433
0
      return;
3434
0
    }
3435
5
    if ((EffectiveTriple.isARM() || 
EffectiveTriple.isThumb()4
) &&
3436
5
        
(1
Offset < 01
||
Offset > 0xfffff1
)) {
3437
1
      D.Diag(diag::err_drv_invalid_int_value)
3438
1
          << A->getOption().getName() << Value;
3439
1
      return;
3440
1
    }
3441
4
    A->render(Args, CmdArgs);
3442
4
  }
3443
3444
47.6k
  if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
3445
7
    StringRef Value = A->getValue();
3446
7
    if (!EffectiveTriple.isX86() && 
!EffectiveTriple.isAArch64()3
)
3447
1
      D.Diag(diag::err_drv_unsupported_opt_for_target)
3448
1
          << A->getAsString(Args) << TripleStr;
3449
7
    if (EffectiveTriple.isX86() && 
(4
Value != "fs"4
&&
Value != "gs"3
)) {
3450
2
      D.Diag(diag::err_drv_invalid_value_with_suggestion)
3451
2
          << A->getOption().getName() << Value << "fs gs";
3452
2
      return;
3453
2
    }
3454
5
    if (EffectiveTriple.isAArch64() && 
Value != "sp_el0"2
) {
3455
1
      D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
3456
1
      return;
3457
1
    }
3458
4
    A->render(Args, CmdArgs);
3459
4
  }
3460
3461
47.6k
  if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_symbol_EQ)) {
3462
3
    StringRef Value = A->getValue();
3463
3
    if (!isValidSymbolName(Value)) {
3464
2
      D.Diag(diag::err_drv_argument_only_allowed_with)
3465
2
          << A->getOption().getName() << "legal symbol name";
3466
2
      return;
3467
2
    }
3468
1
    A->render(Args, CmdArgs);
3469
1
  }
3470
47.6k
}
3471
3472
static void RenderSCPOptions(const ToolChain &TC, const ArgList &Args,
3473
47.7k
                             ArgStringList &CmdArgs) {
3474
47.7k
  const llvm::Triple &EffectiveTriple = TC.getEffectiveTriple();
3475
3476
47.7k
  if (!EffectiveTriple.isOSFreeBSD() && 
!EffectiveTriple.isOSLinux()47.6k
)
3477
42.7k
    return;
3478
3479
4.98k
  if (!EffectiveTriple.isX86() && 
!EffectiveTriple.isSystemZ()2.11k
&&
3480
4.98k
      
!EffectiveTriple.isPPC64()2.07k
)
3481
1.85k
    return;
3482
3483
3.13k
  Args.addOptInFlag(CmdArgs, options::OPT_fstack_clash_protection,
3484
3.13k
                    options::OPT_fno_stack_clash_protection);
3485
3.13k
}
3486
3487
static void RenderTrivialAutoVarInitOptions(const Driver &D,
3488
                                            const ToolChain &TC,
3489
                                            const ArgList &Args,
3490
47.7k
                                            ArgStringList &CmdArgs) {
3491
47.7k
  auto DefaultTrivialAutoVarInit = TC.GetDefaultTrivialAutoVarInit();
3492
47.7k
  StringRef TrivialAutoVarInit = "";
3493
3494
776k
  for (const Arg *A : Args) {
3495
776k
    switch (A->getOption().getID()) {
3496
776k
    default:
3497
776k
      continue;
3498
776k
    case options::OPT_ftrivial_auto_var_init: {
3499
7
      A->claim();
3500
7
      StringRef Val = A->getValue();
3501
7
      if (Val == "uninitialized" || 
Val == "zero"6
||
Val == "pattern"3
)
3502
7
        TrivialAutoVarInit = Val;
3503
0
      else
3504
0
        D.Diag(diag::err_drv_unsupported_option_argument)
3505
0
            << A->getSpelling() << Val;
3506
7
      break;
3507
0
    }
3508
776k
    }
3509
776k
  }
3510
3511
47.7k
  if (TrivialAutoVarInit.empty())
3512
47.7k
    switch (DefaultTrivialAutoVarInit) {
3513
47.7k
    case LangOptions::TrivialAutoVarInitKind::Uninitialized:
3514
47.7k
      break;
3515
0
    case LangOptions::TrivialAutoVarInitKind::Pattern:
3516
0
      TrivialAutoVarInit = "pattern";
3517
0
      break;
3518
0
    case LangOptions::TrivialAutoVarInitKind::Zero:
3519
0
      TrivialAutoVarInit = "zero";
3520
0
      break;
3521
47.7k
    }
3522
3523
47.7k
  if (!TrivialAutoVarInit.empty()) {
3524
7
    CmdArgs.push_back(
3525
7
        Args.MakeArgString("-ftrivial-auto-var-init=" + TrivialAutoVarInit));
3526
7
  }
3527
3528
47.7k
  if (Arg *A =
3529
47.7k
          Args.getLastArg(options::OPT_ftrivial_auto_var_init_stop_after)) {
3530
5
    if (!Args.hasArg(options::OPT_ftrivial_auto_var_init) ||
3531
5
        StringRef(
3532
4
            Args.getLastArg(options::OPT_ftrivial_auto_var_init)->getValue()) ==
3533
4
            "uninitialized")
3534
1
      D.Diag(diag::err_drv_trivial_auto_var_init_stop_after_missing_dependency);
3535
5
    A->claim();
3536
5
    StringRef Val = A->getValue();
3537
5
    if (std::stoi(Val.str()) <= 0)
3538
3
      D.Diag(diag::err_drv_trivial_auto_var_init_stop_after_invalid_value);
3539
5
    CmdArgs.push_back(
3540
5
        Args.MakeArgString("-ftrivial-auto-var-init-stop-after=" + Val));
3541
5
  }
3542
47.7k
}
3543
3544
static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs,
3545
47.7k
                                types::ID InputType) {
3546
  // cl-denorms-are-zero is not forwarded. It is translated into a generic flag
3547
  // for denormal flushing handling based on the target.
3548
47.7k
  const unsigned ForwardedArguments[] = {
3549
47.7k
      options::OPT_cl_opt_disable,
3550
47.7k
      options::OPT_cl_strict_aliasing,
3551
47.7k
      options::OPT_cl_single_precision_constant,
3552
47.7k
      options::OPT_cl_finite_math_only,
3553
47.7k
      options::OPT_cl_kernel_arg_info,
3554
47.7k
      options::OPT_cl_unsafe_math_optimizations,
3555
47.7k
      options::OPT_cl_fast_relaxed_math,
3556
47.7k
      options::OPT_cl_mad_enable,
3557
47.7k
      options::OPT_cl_no_signed_zeros,
3558
47.7k
      options::OPT_cl_fp32_correctly_rounded_divide_sqrt,
3559
47.7k
      options::OPT_cl_uniform_work_group_size
3560
47.7k
  };
3561
3562
47.7k
  if (Arg *A = Args.getLastArg(options::OPT_cl_std_EQ)) {
3563
17
    std::string CLStdStr = std::string("-cl-std=") + A->getValue();
3564
17
    CmdArgs.push_back(Args.MakeArgString(CLStdStr));
3565
47.7k
  } else if (Arg *A = Args.getLastArg(options::OPT_cl_ext_EQ)) {
3566
1
    std::string CLExtStr = std::string("-cl-ext=") + A->getValue();
3567
1
    CmdArgs.push_back(Args.MakeArgString(CLExtStr));
3568
1
  }
3569
3570
47.7k
  for (const auto &Arg : ForwardedArguments)
3571
525k
    if (const auto *A = Args.getLastArg(Arg))
3572
15
      CmdArgs.push_back(Args.MakeArgString(A->getOption().getPrefixedName()));
3573
3574
  // Only add the default headers if we are compiling OpenCL sources.
3575
47.7k
  if ((types::isOpenCL(InputType) ||
3576
47.7k
       
(47.4k
Args.hasArg(options::OPT_cl_std_EQ)47.4k
&&
types::isSrcFile(InputType)0
)) &&
3577
47.7k
      
!Args.hasArg(options::OPT_cl_no_stdinc)325
) {
3578
322
    CmdArgs.push_back("-finclude-default-header");
3579
322
    CmdArgs.push_back("-fdeclare-opencl-builtins");
3580
322
  }
3581
47.7k
}
3582
3583
static void RenderHLSLOptions(const ArgList &Args, ArgStringList &CmdArgs,
3584
47.7k
                              types::ID InputType) {
3585
47.7k
  const unsigned ForwardedArguments[] = {options::OPT_dxil_validator_version,
3586
47.7k
                                         options::OPT_D,
3587
47.7k
                                         options::OPT_I,
3588
47.7k
                                         options::OPT_S,
3589
47.7k
                                         options::OPT_O,
3590
47.7k
                                         options::OPT_emit_llvm,
3591
47.7k
                                         options::OPT_emit_obj,
3592
47.7k
                                         options::OPT_disable_llvm_passes,
3593
47.7k
                                         options::OPT_fnative_half_type,
3594
47.7k
                                         options::OPT_hlsl_entrypoint};
3595
47.7k
  if (!types::isHLSL(InputType))
3596
47.6k
    return;
3597
62
  for (const auto &Arg : ForwardedArguments)
3598
620
    if (const auto *A = Args.getLastArg(Arg))
3599
176
      A->renderAsInput(Args, CmdArgs);
3600
  // Add the default headers if dxc_no_stdinc is not set.
3601
62
  if (!Args.hasArg(options::OPT_dxc_no_stdinc) &&
3602
62
      
!Args.hasArg(options::OPT_nostdinc)61
)
3603
60
    CmdArgs.push_back("-finclude-default-header");
3604
62
}
3605
3606
static void RenderARCMigrateToolOptions(const Driver &D, const ArgList &Args,
3607
47.7k
                                        ArgStringList &CmdArgs) {
3608
47.7k
  bool ARCMTEnabled = false;
3609
47.7k
  if (!Args.hasArg(options::OPT_fno_objc_arc, options::OPT_fobjc_arc)) {
3610
46.5k
    if (const Arg *A = Args.getLastArg(options::OPT_ccc_arcmt_check,
3611
46.5k
                                       options::OPT_ccc_arcmt_modify,
3612
46.5k
                                       options::OPT_ccc_arcmt_migrate)) {
3613
2
      ARCMTEnabled = true;
3614
2
      switch (A->getOption().getID()) {
3615
0
      default: llvm_unreachable("missed a case");
3616
1
      case options::OPT_ccc_arcmt_check:
3617
1
        CmdArgs.push_back("-arcmt-action=check");
3618
1
        break;
3619
0
      case options::OPT_ccc_arcmt_modify:
3620
0
        CmdArgs.push_back("-arcmt-action=modify");
3621
0
        break;
3622
1
      case options::OPT_ccc_arcmt_migrate:
3623
1
        CmdArgs.push_back("-arcmt-action=migrate");
3624
1
        CmdArgs.push_back("-mt-migrate-directory");
3625
1
        CmdArgs.push_back(A->getValue());
3626
3627
1
        Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_report_output);
3628
1
        Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_emit_arc_errors);
3629
1
        break;
3630
2
      }
3631
2
    }
3632
46.5k
  } else {
3633
1.18k
    Args.ClaimAllArgs(options::OPT_ccc_arcmt_check);
3634
1.18k
    Args.ClaimAllArgs(options::OPT_ccc_arcmt_modify);
3635
1.18k
    Args.ClaimAllArgs(options::OPT_ccc_arcmt_migrate);
3636
1.18k
  }
3637
3638
47.7k
  if (const Arg *A = Args.getLastArg(options::OPT_ccc_objcmt_migrate)) {
3639
1
    if (ARCMTEnabled)
3640
0
      D.Diag(diag::err_drv_argument_not_allowed_with)
3641
0
          << A->getAsString(Args) << "-ccc-arcmt-migrate";
3642
3643
1
    CmdArgs.push_back("-mt-migrate-directory");
3644
1
    CmdArgs.push_back(A->getValue());
3645
3646
1
    if (!Args.hasArg(options::OPT_objcmt_migrate_literals,
3647
1
                     options::OPT_objcmt_migrate_subscripting,
3648
1
                     options::OPT_objcmt_migrate_property)) {
3649
      // None specified, means enable them all.
3650
1
      CmdArgs.push_back("-objcmt-migrate-literals");
3651
1
      CmdArgs.push_back("-objcmt-migrate-subscripting");
3652
1
      CmdArgs.push_back("-objcmt-migrate-property");
3653
1
    } else {
3654
0
      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
3655
0
      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
3656
0
      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
3657
0
    }
3658
47.7k
  } else {
3659
47.7k
    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
3660
47.7k
    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
3661
47.7k
    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
3662
47.7k
    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_all);
3663
47.7k
    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readonly_property);
3664
47.7k
    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readwrite_property);
3665
47.7k
    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property_dot_syntax);
3666
47.7k
    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_annotation);
3667
47.7k
    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_instancetype);
3668
47.7k
    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_nsmacros);
3669
47.7k
    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_protocol_conformance);
3670
47.7k
    Args.AddLastArg(CmdArgs, options::OPT_objcmt_atomic_property);
3671
47.7k
    Args.AddLastArg(CmdArgs, options::OPT_objcmt_returns_innerpointer_property);
3672
47.7k
    Args.AddLastArg(CmdArgs, options::OPT_objcmt_ns_nonatomic_iosonly);
3673
47.7k
    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_designated_init);
3674
47.7k
    Args.AddLastArg(CmdArgs, options::OPT_objcmt_allowlist_dir_path);
3675
47.7k
  }
3676
47.7k
}
3677
3678
static void RenderBuiltinOptions(const ToolChain &TC, const llvm::Triple &T,
3679
47.7k
                                 const ArgList &Args, ArgStringList &CmdArgs) {
3680
  // -fbuiltin is default unless -mkernel is used.
3681
47.7k
  bool UseBuiltins =
3682
47.7k
      Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin,
3683
47.7k
                   !Args.hasArg(options::OPT_mkernel));
3684
47.7k
  if (!UseBuiltins)
3685
24
    CmdArgs.push_back("-fno-builtin");
3686
3687
  // -ffreestanding implies -fno-builtin.
3688
47.7k
  if (Args.hasArg(options::OPT_ffreestanding))
3689
46
    UseBuiltins = false;
3690
3691
  // Process the -fno-builtin-* options.
3692
47.7k
  for (const Arg *A : Args.filtered(options::OPT_fno_builtin_)) {
3693
3
    A->claim();
3694
3695
    // If -fno-builtin is specified, then there's no need to pass the option to
3696
    // the frontend.
3697
3
    if (UseBuiltins)
3698
0
      A->render(Args, CmdArgs);
3699
3
  }
3700
3701
  // le32-specific flags:
3702
  //  -fno-math-builtin: clang should not convert math builtins to intrinsics
3703
  //                     by default.
3704
47.7k
  if (TC.getArch() == llvm::Triple::le32)
3705
0
    CmdArgs.push_back("-fno-math-builtin");
3706
47.7k
}
3707
3708
4.08k
bool Driver::getDefaultModuleCachePath(SmallVectorImpl<char> &Result) {
3709
4.08k
  if (const char *Str = std::getenv("CLANG_MODULE_CACHE_PATH")) {
3710
2
    Twine Path{Str};
3711
2
    Path.toVector(Result);
3712
2
    return Path.getSingleStringRef() != "";
3713
2
  }
3714
4.08k
  
if (4.08k
llvm::sys::path::cache_directory(Result)4.08k
) {
3715
4.08k
    llvm::sys::path::append(Result, "clang");
3716
4.08k
    llvm::sys::path::append(Result, "ModuleCache");
3717
4.08k
    return true;
3718
4.08k
  }
3719
18.4E
  return false;
3720
4.08k
}
3721
3722
static bool RenderModulesOptions(Compilation &C, const Driver &D,
3723
                                 const ArgList &Args, const InputInfo &Input,
3724
                                 const InputInfo &Output, const Arg *Std,
3725
47.7k
                                 ArgStringList &CmdArgs) {
3726
47.7k
  bool IsCXX = types::isCXX(Input.getType());
3727
  // FIXME: Find a better way to determine whether the input has standard c++
3728
  // modules support by default.
3729
47.7k
  bool HaveStdCXXModules =
3730
47.7k
      IsCXX && 
Std31.4k
&&
3731
47.7k
      
(25.8k
Std->containsValue("c++2a")25.8k
||
Std->containsValue("gnu++2a")25.8k
||
3732
25.8k
       
Std->containsValue("c++20")25.8k
||
Std->containsValue("gnu++20")22.6k
||
3733
25.8k
       
Std->containsValue("c++2b")22.6k
||
Std->containsValue("gnu++2b")22.6k
||
3734
25.8k
       
Std->containsValue("c++23")22.6k
||
Std->containsValue("gnu++23")22.6k
||
3735
25.8k
       
Std->containsValue("c++2c")22.6k
||
Std->containsValue("gnu++2c")22.6k
||
3736
25.8k
       
Std->containsValue("c++26")22.6k
||
Std->containsValue("gnu++26")22.6k
||
3737
25.8k
       
Std->containsValue("c++latest")22.6k
||
Std->containsValue("gnu++latest")22.6k
);
3738
47.7k
  bool HaveModules = HaveStdCXXModules;
3739
3740
  // -fmodules enables the use of precompiled modules (off by default).
3741
  // Users can pass -fno-cxx-modules to turn off modules support for
3742
  // C++/Objective-C++ programs.
3743
47.7k
  bool HaveClangModules = false;
3744
47.7k
  if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) {
3745
1.43k
    bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules,
3746
1.43k
                                     options::OPT_fno_cxx_modules, true);
3747
1.43k
    if (AllowedInCXX || 
!IsCXX1
) {
3748
1.43k
      CmdArgs.push_back("-fmodules");
3749
1.43k
      HaveClangModules = true;
3750
1.43k
    }
3751
1.43k
  }
3752
3753
47.7k
  HaveModules |= HaveClangModules;
3754
3755
  // -fmodule-maps enables implicit reading of module map files. By default,
3756
  // this is enabled if we are using Clang's flavor of precompiled modules.
3757
47.7k
  if (Args.hasFlag(options::OPT_fimplicit_module_maps,
3758
47.7k
                   options::OPT_fno_implicit_module_maps, HaveClangModules))
3759
1.43k
    CmdArgs.push_back("-fimplicit-module-maps");
3760
3761
  // -fmodules-decluse checks that modules used are declared so (off by default)
3762
47.7k
  Args.addOptInFlag(CmdArgs, options::OPT_fmodules_decluse,
3763
47.7k
                    options::OPT_fno_modules_decluse);
3764
3765
  // -fmodules-strict-decluse is like -fmodule-decluse, but also checks that
3766
  // all #included headers are part of modules.
3767
47.7k
  if (Args.hasFlag(options::OPT_fmodules_strict_decluse,
3768
47.7k
                   options::OPT_fno_modules_strict_decluse, false))
3769
0
    CmdArgs.push_back("-fmodules-strict-decluse");
3770
3771
  // -fno-implicit-modules turns off implicitly compiling modules on demand.
3772
47.7k
  bool ImplicitModules = false;
3773
47.7k
  if (!Args.hasFlag(options::OPT_fimplicit_modules,
3774
47.7k
                    options::OPT_fno_implicit_modules, HaveClangModules)) {
3775
46.3k
    if (HaveModules)
3776
3.25k
      CmdArgs.push_back("-fno-implicit-modules");
3777
46.3k
  } else 
if (1.43k
HaveModules1.43k
) {
3778
1.43k
    ImplicitModules = true;
3779
    // -fmodule-cache-path specifies where our implicitly-built module files
3780
    // should be written.
3781
1.43k
    SmallString<128> Path;
3782
1.43k
    if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path))
3783
1.39k
      Path = A->getValue();
3784
3785
1.43k
    bool HasPath = true;
3786
1.43k
    if (C.isForDiagnostics()) {
3787
      // When generating crash reports, we want to emit the modules along with
3788
      // the reproduction sources, so we ignore any provided module path.
3789
14
      Path = Output.getFilename();
3790
14
      llvm::sys::path::replace_extension(Path, ".cache");
3791
14
      llvm::sys::path::append(Path, "modules");
3792
1.41k
    } else if (Path.empty()) {
3793
      // No module path was provided: use the default.
3794
32
      HasPath = Driver::getDefaultModuleCachePath(Path);
3795
32
    }
3796
3797
    // `HasPath` will only be false if getDefaultModuleCachePath() fails.
3798
    // That being said, that failure is unlikely and not caching is harmless.
3799
1.43k
    if (HasPath) {
3800
1.43k
      const char Arg[] = "-fmodules-cache-path=";
3801
1.43k
      Path.insert(Path.begin(), Arg, Arg + strlen(Arg));
3802
1.43k
      CmdArgs.push_back(Args.MakeArgString(Path));
3803
1.43k
    }
3804
1.43k
  }
3805
3806
47.7k
  if (HaveModules) {
3807
4.68k
    if (Args.hasFlag(options::OPT_fprebuilt_implicit_modules,
3808
4.68k
                     options::OPT_fno_prebuilt_implicit_modules, false))
3809
0
      CmdArgs.push_back("-fprebuilt-implicit-modules");
3810
4.68k
    if (Args.hasFlag(options::OPT_fmodules_validate_input_files_content,
3811
4.68k
                     options::OPT_fno_modules_validate_input_files_content,
3812
4.68k
                     false))
3813
1
      CmdArgs.push_back("-fvalidate-ast-input-files-content");
3814
4.68k
  }
3815
3816
  // -fmodule-name specifies the module that is currently being built (or
3817
  // used for header checking by -fmodule-maps).
3818
47.7k
  Args.AddLastArg(CmdArgs, options::OPT_fmodule_name_EQ);
3819
3820
  // -fmodule-map-file can be used to specify files containing module
3821
  // definitions.
3822
47.7k
  Args.AddAllArgs(CmdArgs, options::OPT_fmodule_map_file);
3823
3824
  // -fbuiltin-module-map can be used to load the clang
3825
  // builtin headers modulemap file.
3826
47.7k
  if (Args.hasArg(options::OPT_fbuiltin_module_map)) {
3827
1
    SmallString<128> BuiltinModuleMap(D.ResourceDir);
3828
1
    llvm::sys::path::append(BuiltinModuleMap, "include");
3829
1
    llvm::sys::path::append(BuiltinModuleMap, "module.modulemap");
3830
1
    if (llvm::sys::fs::exists(BuiltinModuleMap))
3831
1
      CmdArgs.push_back(
3832
1
          Args.MakeArgString("-fmodule-map-file=" + BuiltinModuleMap));
3833
1
  }
3834
3835
  // The -fmodule-file=<name>=<file> form specifies the mapping of module
3836
  // names to precompiled module files (the module is loaded only if used).
3837
  // The -fmodule-file=<file> form can be used to unconditionally load
3838
  // precompiled module files (whether used or not).
3839
47.7k
  if (HaveModules || 
Input.getType() == clang::driver::types::TY_ModuleFile43.0k
) {
3840
4.70k
    Args.AddAllArgs(CmdArgs, options::OPT_fmodule_file);
3841
3842
    // -fprebuilt-module-path specifies where to load the prebuilt module files.
3843
4.70k
    for (const Arg *A : Args.filtered(options::OPT_fprebuilt_module_path)) {
3844
32
      CmdArgs.push_back(Args.MakeArgString(
3845
32
          std::string("-fprebuilt-module-path=") + A->getValue()));
3846
32
      A->claim();
3847
32
    }
3848
4.70k
  } else
3849
43.0k
    Args.ClaimAllArgs(options::OPT_fmodule_file);
3850
3851
  // When building modules and generating crashdumps, we need to dump a module
3852
  // dependency VFS alongside the output.
3853
47.7k
  if (HaveClangModules && 
C.isForDiagnostics()1.43k
) {
3854
14
    SmallString<128> VFSDir(Output.getFilename());
3855
14
    llvm::sys::path::replace_extension(VFSDir, ".cache");
3856
    // Add the cache directory as a temp so the crash diagnostics pick it up.
3857
14
    C.addTempFile(Args.MakeArgString(VFSDir));
3858
3859
14
    llvm::sys::path::append(VFSDir, "vfs");
3860
14
    CmdArgs.push_back("-module-dependency-dir");
3861
14
    CmdArgs.push_back(Args.MakeArgString(VFSDir));
3862
14
  }
3863
3864
47.7k
  if (HaveClangModules)
3865
1.43k
    Args.AddLastArg(CmdArgs, options::OPT_fmodules_user_build_path);
3866
3867
  // Pass through all -fmodules-ignore-macro arguments.
3868
47.7k
  Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro);
3869
47.7k
  Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval);
3870
47.7k
  Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after);
3871
3872
47.7k
  if (HaveClangModules) {
3873
1.43k
    Args.AddLastArg(CmdArgs, options::OPT_fbuild_session_timestamp);
3874
3875
1.43k
    if (Arg *A = Args.getLastArg(options::OPT_fbuild_session_file)) {
3876
5
      if (Args.hasArg(options::OPT_fbuild_session_timestamp))
3877
1
        D.Diag(diag::err_drv_argument_not_allowed_with)
3878
1
            << A->getAsString(Args) << "-fbuild-session-timestamp";
3879
3880
5
      llvm::sys::fs::file_status Status;
3881
5
      if (llvm::sys::fs::status(A->getValue(), Status))
3882
1
        D.Diag(diag::err_drv_no_such_file) << A->getValue();
3883
5
      CmdArgs.push_back(Args.MakeArgString(
3884
5
          "-fbuild-session-timestamp=" +
3885
5
          Twine((uint64_t)std::chrono::duration_cast<std::chrono::seconds>(
3886
5
                    Status.getLastModificationTime().time_since_epoch())
3887
5
                    .count())));
3888
5
    }
3889
3890
1.43k
    if (Args.getLastArg(
3891
1.43k
            options::OPT_fmodules_validate_once_per_build_session)) {
3892
4
      if (!Args.getLastArg(options::OPT_fbuild_session_timestamp,
3893
4
                           options::OPT_fbuild_session_file))
3894
1
        D.Diag(diag::err_drv_modules_validate_once_requires_timestamp);
3895
3896
4
      Args.AddLastArg(CmdArgs,
3897
4
                      options::OPT_fmodules_validate_once_per_build_session);
3898
4
    }
3899
3900
1.43k
    if (Args.hasFlag(options::OPT_fmodules_validate_system_headers,
3901
1.43k
                     options::OPT_fno_modules_validate_system_headers,
3902
1.43k
                     ImplicitModules))
3903
1.42k
      CmdArgs.push_back("-fmodules-validate-system-headers");
3904
3905
1.43k
    Args.AddLastArg(CmdArgs,
3906
1.43k
                    options::OPT_fmodules_disable_diagnostic_validation);
3907
46.3k
  } else {
3908
46.3k
    Args.ClaimAllArgs(options::OPT_fbuild_session_timestamp);
3909
46.3k
    Args.ClaimAllArgs(options::OPT_fbuild_session_file);
3910
46.3k
    Args.ClaimAllArgs(options::OPT_fmodules_validate_once_per_build_session);
3911
46.3k
    Args.ClaimAllArgs(options::OPT_fmodules_validate_system_headers);
3912
46.3k
    Args.ClaimAllArgs(options::OPT_fno_modules_validate_system_headers);
3913
46.3k
    Args.ClaimAllArgs(options::OPT_fmodules_disable_diagnostic_validation);
3914
46.3k
  }
3915
3916
  // Claim `-fmodule-output` and `-fmodule-output=` to avoid unused warnings.
3917
47.7k
  Args.ClaimAllArgs(options::OPT_fmodule_output);
3918
47.7k
  Args.ClaimAllArgs(options::OPT_fmodule_output_EQ);
3919
3920
47.7k
  return HaveModules;
3921
47.7k
}
3922
3923
static void RenderCharacterOptions(const ArgList &Args, const llvm::Triple &T,
3924
47.7k
                                   ArgStringList &CmdArgs) {
3925
  // -fsigned-char is default.
3926
47.7k
  if (const Arg *A = Args.getLastArg(options::OPT_fsigned_char,
3927
47.7k
                                     options::OPT_fno_signed_char,
3928
47.7k
                                     options::OPT_funsigned_char,
3929
47.7k
                                     options::OPT_fno_unsigned_char)) {
3930
10
    if (A->getOption().matches(options::OPT_funsigned_char) ||
3931
10
        
A->getOption().matches(options::OPT_fno_signed_char)6
) {
3932
6
      CmdArgs.push_back("-fno-signed-char");
3933
6
    }
3934
47.7k
  } else if (!isSignedCharDefault(T)) {
3935
5.03k
    CmdArgs.push_back("-fno-signed-char");
3936
5.03k
  }
3937
3938
  // The default depends on the language standard.
3939
47.7k
  Args.AddLastArg(CmdArgs, options::OPT_fchar8__t, options::OPT_fno_char8__t);
3940
3941
47.7k
  if (const Arg *A = Args.getLastArg(options::OPT_fshort_wchar,
3942
47.7k
                                     options::OPT_fno_short_wchar)) {
3943
26
    if (A->getOption().matches(options::OPT_fshort_wchar)) {
3944
4
      CmdArgs.push_back("-fwchar-type=short");
3945
4
      CmdArgs.push_back("-fno-signed-wchar");
3946
22
    } else {
3947
22
      bool IsARM = T.isARM() || 
T.isThumb()9
||
T.isAArch64()9
;
3948
22
      CmdArgs.push_back("-fwchar-type=int");
3949
22
      if (T.isOSzOS() ||
3950
22
          (IsARM && 
!(20
T.isOSWindows()20
||
T.isOSNetBSD()18
||
T.isOSOpenBSD()12
)))
3951
6
        CmdArgs.push_back("-fno-signed-wchar");
3952
16
      else
3953
16
        CmdArgs.push_back("-fsigned-wchar");
3954
22
    }
3955
47.7k
  } else if (T.isOSzOS())
3956
37
    CmdArgs.push_back("-fno-signed-wchar");
3957
47.7k
}
3958
3959
static void RenderObjCOptions(const ToolChain &TC, const Driver &D,
3960
                              const llvm::Triple &T, const ArgList &Args,
3961
                              ObjCRuntime &Runtime, bool InferCovariantReturns,
3962
47.7k
                              const InputInfo &Input, ArgStringList &CmdArgs) {
3963
47.7k
  const llvm::Triple::ArchType Arch = TC.getArch();
3964
3965
  // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and legacy
3966
  // is the default. Except for deployment target of 10.5, next runtime is
3967
  // always legacy dispatch and -fno-objc-legacy-dispatch gets ignored silently.
3968
47.7k
  if (Runtime.isNonFragile()) {
3969
19.3k
    if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch,
3970
19.3k
                      options::OPT_fno_objc_legacy_dispatch,
3971
19.3k
                      Runtime.isLegacyDispatchDefaultForArch(Arch))) {
3972
35
      if (TC.UseObjCMixedDispatch())
3973
2
        CmdArgs.push_back("-fobjc-dispatch-method=mixed");
3974
33
      else
3975
33
        CmdArgs.push_back("-fobjc-dispatch-method=non-legacy");
3976
35
    }
3977
19.3k
  }
3978
3979
  // When ObjectiveC legacy runtime is in effect on MacOSX, turn on the option
3980
  // to do Array/Dictionary subscripting by default.
3981
47.7k
  if (Arch == llvm::Triple::x86 && 
T.isMacOSX()11.2k
&&
3982
47.7k
      
Runtime.getKind() == ObjCRuntime::FragileMacOSX116
&&
Runtime.isNeXTFamily()102
)
3983
102
    CmdArgs.push_back("-fobjc-subscripting-legacy-runtime");
3984
3985
  // Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc.
3986
  // NOTE: This logic is duplicated in ToolChains.cpp.
3987
47.7k
  if (isObjCAutoRefCount(Args)) {
3988
1.17k
    TC.CheckObjCARC();
3989
3990
1.17k
    CmdArgs.push_back("-fobjc-arc");
3991
3992
    // FIXME: It seems like this entire block, and several around it should be
3993
    // wrapped in isObjC, but for now we just use it here as this is where it
3994
    // was being used previously.
3995
1.17k
    if (types::isCXX(Input.getType()) && 
types::isObjC(Input.getType())1.14k
) {
3996
1.14k
      if (TC.GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
3997
1.04k
        CmdArgs.push_back("-fobjc-arc-cxxlib=libc++");
3998
103
      else
3999
103
        CmdArgs.push_back("-fobjc-arc-cxxlib=libstdc++");
4000
1.14k
    }
4001
4002
    // Allow the user to enable full exceptions code emission.
4003
    // We default off for Objective-C, on for Objective-C++.
4004
1.17k
    if (Args.hasFlag(options::OPT_fobjc_arc_exceptions,
4005
1.17k
                     options::OPT_fno_objc_arc_exceptions,
4006
1.17k
                     /*Default=*/types::isCXX(Input.getType())))
4007
1.14k
      CmdArgs.push_back("-fobjc-arc-exceptions");
4008
1.17k
  }
4009
4010
  // Silence warning for full exception code emission options when explicitly
4011
  // set to use no ARC.
4012
47.7k
  if (Args.hasArg(options::OPT_fno_objc_arc)) {
4013
11
    Args.ClaimAllArgs(options::OPT_fobjc_arc_exceptions);
4014
11
    Args.ClaimAllArgs(options::OPT_fno_objc_arc_exceptions);
4015
11
  }
4016
4017
  // Allow the user to control whether messages can be converted to runtime
4018
  // functions.
4019
47.7k
  if (types::isObjC(Input.getType())) {
4020
3.03k
    auto *Arg = Args.getLastArg(
4021
3.03k
        options::OPT_fobjc_convert_messages_to_runtime_calls,
4022
3.03k
        options::OPT_fno_objc_convert_messages_to_runtime_calls);
4023
3.03k
    if (Arg &&
4024
3.03k
        Arg->getOption().matches(
4025
2
            options::OPT_fno_objc_convert_messages_to_runtime_calls))
4026
1
      CmdArgs.push_back("-fno-objc-convert-messages-to-runtime-calls");
4027
3.03k
  }
4028
4029
  // -fobjc-infer-related-result-type is the default, except in the Objective-C
4030
  // rewriter.
4031
47.7k
  if (InferCovariantReturns)
4032
8
    CmdArgs.push_back("-fno-objc-infer-related-result-type");
4033
4034
  // Pass down -fobjc-weak or -fno-objc-weak if present.
4035
47.7k
  if (types::isObjC(Input.getType())) {
4036
3.03k
    auto WeakArg =
4037
3.03k
        Args.getLastArg(options::OPT_fobjc_weak, options::OPT_fno_objc_weak);
4038
3.03k
    if (!WeakArg) {
4039
      // nothing to do
4040
3.01k
    } else 
if (12
!Runtime.allowsWeak()12
) {
4041
4
      if (WeakArg->getOption().matches(options::OPT_fobjc_weak))
4042
4
        D.Diag(diag::err_objc_weak_unsupported);
4043
8
    } else {
4044
8
      WeakArg->render(Args, CmdArgs);
4045
8
    }
4046
3.03k
  }
4047
4048
47.7k
  if (Args.hasArg(options::OPT_fobjc_disable_direct_methods_for_testing))
4049
1
    CmdArgs.push_back("-fobjc-disable-direct-methods-for-testing");
4050
47.7k
}
4051
4052
static void RenderDiagnosticsOptions(const Driver &D, const ArgList &Args,
4053
47.7k
                                     ArgStringList &CmdArgs) {
4054
47.7k
  bool CaretDefault = true;
4055
47.7k
  bool ColumnDefault = true;
4056
4057
47.7k
  if (const Arg *A = Args.getLastArg(options::OPT__SLASH_diagnostics_classic,
4058
47.7k
                                     options::OPT__SLASH_diagnostics_column,
4059
47.7k
                                     options::OPT__SLASH_diagnostics_caret)) {
4060
5
    switch (A->getOption().getID()) {
4061
2
    case options::OPT__SLASH_diagnostics_caret:
4062
2
      CaretDefault = true;
4063
2
      ColumnDefault = true;
4064
2
      break;
4065
1
    case options::OPT__SLASH_diagnostics_column:
4066
1
      CaretDefault = false;
4067
1
      ColumnDefault = true;
4068
1
      break;
4069
2
    case options::OPT__SLASH_diagnostics_classic:
4070
2
      CaretDefault = false;
4071
2
      ColumnDefault = false;
4072
2
      break;
4073
5
    }
4074
5
  }
4075
4076
  // -fcaret-diagnostics is default.
4077
47.7k
  if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
4078
47.7k
                    options::OPT_fno_caret_diagnostics, CaretDefault))
4079
3
    CmdArgs.push_back("-fno-caret-diagnostics");
4080
4081
47.7k
  Args.addOptOutFlag(CmdArgs, options::OPT_fdiagnostics_fixit_info,
4082
47.7k
                     options::OPT_fno_diagnostics_fixit_info);
4083
47.7k
  Args.addOptOutFlag(CmdArgs, options::OPT_fdiagnostics_show_option,
4084
47.7k
                     options::OPT_fno_diagnostics_show_option);
4085
4086
47.7k
  if (const Arg *A =
4087
47.7k
          Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) {
4088
0
    CmdArgs.push_back("-fdiagnostics-show-category");
4089
0
    CmdArgs.push_back(A->getValue());
4090
0
  }
4091
4092
47.7k
  Args.addOptInFlag(CmdArgs, options::OPT_fdiagnostics_show_hotness,
4093
47.7k
                    options::OPT_fno_diagnostics_show_hotness);
4094
4095
47.7k
  if (const Arg *A =
4096
47.7k
          Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) {
4097
6
    std::string Opt =
4098
6
        std::string("-fdiagnostics-hotness-threshold=") + A->getValue();
4099
6
    CmdArgs.push_back(Args.MakeArgString(Opt));
4100
6
  }
4101
4102
47.7k
  if (const Arg *A =
4103
47.7k
          Args.getLastArg(options::OPT_fdiagnostics_misexpect_tolerance_EQ)) {
4104
1
    std::string Opt =
4105
1
        std::string("-fdiagnostics-misexpect-tolerance=") + A->getValue();
4106
1
    CmdArgs.push_back(Args.MakeArgString(Opt));
4107
1
  }
4108
4109
47.7k
  if (const Arg *A = Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) {
4110
19
    CmdArgs.push_back("-fdiagnostics-format");
4111
19
    CmdArgs.push_back(A->getValue());
4112
19
    if (StringRef(A->getValue()) == "sarif" ||
4113
19
        
StringRef(A->getValue()) == "SARIF"17
)
4114
3
      D.Diag(diag::warn_drv_sarif_format_unstable);
4115
19
  }
4116
4117
47.7k
  if (const Arg *A = Args.getLastArg(
4118
47.7k
          options::OPT_fdiagnostics_show_note_include_stack,
4119
47.7k
          options::OPT_fno_diagnostics_show_note_include_stack)) {
4120
0
    const Option &O = A->getOption();
4121
0
    if (O.matches(options::OPT_fdiagnostics_show_note_include_stack))
4122
0
      CmdArgs.push_back("-fdiagnostics-show-note-include-stack");
4123
0
    else
4124
0
      CmdArgs.push_back("-fno-diagnostics-show-note-include-stack");
4125
0
  }
4126
4127
  // Color diagnostics are parsed by the driver directly from argv and later
4128
  // re-parsed to construct this job; claim any possible color diagnostic here
4129
  // to avoid warn_drv_unused_argument and diagnose bad
4130
  // OPT_fdiagnostics_color_EQ values.
4131
47.7k
  Args.getLastArg(options::OPT_fcolor_diagnostics,
4132
47.7k
                  options::OPT_fno_color_diagnostics);
4133
47.7k
  if (const Arg *A = Args.getLastArg(options::OPT_fdiagnostics_color_EQ)) {
4134
9
    StringRef Value(A->getValue());
4135
9
    if (Value != "always" && 
Value != "never"6
&&
Value != "auto"4
)
4136
1
      D.Diag(diag::err_drv_invalid_argument_to_option)
4137
1
          << Value << A->getOption().getName();
4138
9
  }
4139
4140
47.7k
  if (D.getDiags().getDiagnosticOptions().ShowColors)
4141
12
    CmdArgs.push_back("-fcolor-diagnostics");
4142
4143
47.7k
  if (Args.hasArg(options::OPT_fansi_escape_codes))
4144
1
    CmdArgs.push_back("-fansi-escape-codes");
4145
4146
47.7k
  Args.addOptOutFlag(CmdArgs, options::OPT_fshow_source_location,
4147
47.7k
                     options::OPT_fno_show_source_location);
4148
4149
47.7k
  Args.addOptOutFlag(CmdArgs, options::OPT_fdiagnostics_show_line_numbers,
4150
47.7k
                     options::OPT_fno_diagnostics_show_line_numbers);
4151
4152
47.7k
  if (Args.hasArg(options::OPT_fdiagnostics_absolute_paths))
4153
0
    CmdArgs.push_back("-fdiagnostics-absolute-paths");
4154
4155
47.7k
  if (!Args.hasFlag(options::OPT_fshow_column, options::OPT_fno_show_column,
4156
47.7k
                    ColumnDefault))
4157
4
    CmdArgs.push_back("-fno-show-column");
4158
4159
47.7k
  Args.addOptOutFlag(CmdArgs, options::OPT_fspell_checking,
4160
47.7k
                     options::OPT_fno_spell_checking);
4161
47.7k
}
4162
4163
DwarfFissionKind tools::getDebugFissionKind(const Driver &D,
4164
4.67k
                                            const ArgList &Args, Arg *&Arg) {
4165
4.67k
  Arg = Args.getLastArg(options::OPT_gsplit_dwarf, options::OPT_gsplit_dwarf_EQ,
4166
4.67k
                        options::OPT_gno_split_dwarf);
4167
4.67k
  if (!Arg || 
Arg->getOption().matches(options::OPT_gno_split_dwarf)62
)
4168
4.61k
    return DwarfFissionKind::None;
4169
4170
60
  if (Arg->getOption().matches(options::OPT_gsplit_dwarf))
4171
46
    return DwarfFissionKind::Split;
4172
4173
14
  StringRef Value = Arg->getValue();
4174
14
  if (Value == "split")
4175
5
    return DwarfFissionKind::Split;
4176
9
  if (Value == "single")
4177
9
    return DwarfFissionKind::Single;
4178
4179
0
  D.Diag(diag::err_drv_unsupported_option_argument)
4180
0
      << Arg->getSpelling() << Arg->getValue();
4181
0
  return DwarfFissionKind::None;
4182
9
}
4183
4184
static void renderDwarfFormat(const Driver &D, const llvm::Triple &T,
4185
                              const ArgList &Args, ArgStringList &CmdArgs,
4186
48.2k
                              unsigned DwarfVersion) {
4187
48.2k
  auto *DwarfFormatArg =
4188
48.2k
      Args.getLastArg(options::OPT_gdwarf64, options::OPT_gdwarf32);
4189
48.2k
  if (!DwarfFormatArg)
4190
48.2k
    return;
4191
4192
15
  if (DwarfFormatArg->getOption().matches(options::OPT_gdwarf64)) {
4193
14
    if (DwarfVersion < 3)
4194
2
      D.Diag(diag::err_drv_argument_only_allowed_with)
4195
2
          << DwarfFormatArg->getAsString(Args) << "DWARFv3 or greater";
4196
12
    else if (!T.isArch64Bit())
4197
2
      D.Diag(diag::err_drv_argument_only_allowed_with)
4198
2
          << DwarfFormatArg->getAsString(Args) << "64 bit architecture";
4199
10
    else if (!T.isOSBinFormatELF())
4200
2
      D.Diag(diag::err_drv_argument_only_allowed_with)
4201
2
          << DwarfFormatArg->getAsString(Args) << "ELF platforms";
4202
14
  }
4203
4204
15
  DwarfFormatArg->render(Args, CmdArgs);
4205
15
}
4206
4207
static void
4208
renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T,
4209
                   const ArgList &Args, bool IRInput, ArgStringList &CmdArgs,
4210
                   const InputInfo &Output,
4211
                   llvm::codegenoptions::DebugInfoKind &DebugInfoKind,
4212
47.7k
                   DwarfFissionKind &DwarfFission) {
4213
47.7k
  if (Args.hasFlag(options::OPT_fdebug_info_for_profiling,
4214
47.7k
                   options::OPT_fno_debug_info_for_profiling, false) &&
4215
47.7k
      checkDebugInfoOption(
4216
2
          Args.getLastArg(options::OPT_fdebug_info_for_profiling), Args, D, TC))
4217
2
    CmdArgs.push_back("-fdebug-info-for-profiling");
4218
4219
  // The 'g' groups options involve a somewhat intricate sequence of decisions
4220
  // about what to pass from the driver to the frontend, but by the time they
4221
  // reach cc1 they've been factored into three well-defined orthogonal choices:
4222
  //  * what level of debug info to generate
4223
  //  * what dwarf version to write
4224
  //  * what debugger tuning to use
4225
  // This avoids having to monkey around further in cc1 other than to disable
4226
  // codeview if not running in a Windows environment. Perhaps even that
4227
  // decision should be made in the driver as well though.
4228
47.7k
  llvm::DebuggerKind DebuggerTuning = TC.getDefaultDebuggerTuning();
4229
4230
47.7k
  bool SplitDWARFInlining =
4231
47.7k
      Args.hasFlag(options::OPT_fsplit_dwarf_inlining,
4232
47.7k
                   options::OPT_fno_split_dwarf_inlining, false);
4233
4234
  // Normally -gsplit-dwarf is only useful with -gN. For IR input, Clang does
4235
  // object file generation and no IR generation, -gN should not be needed. So
4236
  // allow -gsplit-dwarf with either -gN or IR input.
4237
47.7k
  if (IRInput || 
Args.hasArg(options::OPT_g_Group)47.6k
) {
4238
3.50k
    Arg *SplitDWARFArg;
4239
3.50k
    DwarfFission = getDebugFissionKind(D, Args, SplitDWARFArg);
4240
3.50k
    if (DwarfFission != DwarfFissionKind::None &&
4241
3.50k
        
!checkDebugInfoOption(SplitDWARFArg, Args, D, TC)53
) {
4242
0
      DwarfFission = DwarfFissionKind::None;
4243
0
      SplitDWARFInlining = false;
4244
0
    }
4245
3.50k
  }
4246
47.7k
  if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) {
4247
3.37k
    DebugInfoKind = llvm::codegenoptions::DebugInfoConstructor;
4248
4249
    // If the last option explicitly specified a debug-info level, use it.
4250
3.37k
    if (checkDebugInfoOption(A, Args, D, TC) &&
4251
3.37k
        A->getOption().matches(options::OPT_gN_Group)) {
4252
132
      DebugInfoKind = debugLevelToInfoKind(*A);
4253
      // For -g0 or -gline-tables-only, drop -gsplit-dwarf. This gets a bit more
4254
      // complicated if you've disabled inline info in the skeleton CUs
4255
      // (SplitDWARFInlining) - then there's value in composing split-dwarf and
4256
      // line-tables-only, so let those compose naturally in that case.
4257
132
      if (DebugInfoKind == llvm::codegenoptions::NoDebugInfo ||
4258
132
          
DebugInfoKind == llvm::codegenoptions::DebugDirectivesOnly102
||
4259
132
          
(96
DebugInfoKind == llvm::codegenoptions::DebugLineTablesOnly96
&&
4260
96
           
SplitDWARFInlining22
))
4261
37
        DwarfFission = DwarfFissionKind::None;
4262
132
    }
4263
3.37k
  }
4264
4265
  // If a debugger tuning argument appeared, remember it.
4266
47.7k
  bool HasDebuggerTuning = false;
4267
47.7k
  if (const Arg *A =
4268
47.7k
          Args.getLastArg(options::OPT_gTune_Group, options::OPT_ggdbN_Group)) {
4269
123
    HasDebuggerTuning = true;
4270
123
    if (checkDebugInfoOption(A, Args, D, TC)) {
4271
123
      if (A->getOption().matches(options::OPT_glldb))
4272
65
        DebuggerTuning = llvm::DebuggerKind::LLDB;
4273
58
      else if (A->getOption().matches(options::OPT_gsce))
4274
3
        DebuggerTuning = llvm::DebuggerKind::SCE;
4275
55
      else if (A->getOption().matches(options::OPT_gdbx))
4276
5
        DebuggerTuning = llvm::DebuggerKind::DBX;
4277
50
      else
4278
50
        DebuggerTuning = llvm::DebuggerKind::GDB;
4279
123
    }
4280
123
  }
4281
4282
  // If a -gdwarf argument appeared, remember it.
4283
47.7k
  bool EmitDwarf = false;
4284
47.7k
  if (const Arg *A = getDwarfNArg(Args))
4285
52
    EmitDwarf = checkDebugInfoOption(A, Args, D, TC);
4286
4287
47.7k
  bool EmitCodeView = false;
4288
47.7k
  if (const Arg *A = Args.getLastArg(options::OPT_gcodeview))
4289
19
    EmitCodeView = checkDebugInfoOption(A, Args, D, TC);
4290
4291
  // If the user asked for debug info but did not explicitly specify -gcodeview
4292
  // or -gdwarf, ask the toolchain for the default format.
4293
47.7k
  if (!EmitCodeView && 
!EmitDwarf47.7k
&&
4294
47.7k
      
DebugInfoKind != llvm::codegenoptions::NoDebugInfo47.6k
) {
4295
3.27k
    switch (TC.getDefaultDebugFormat()) {
4296
51
    case llvm::codegenoptions::DIF_CodeView:
4297
51
      EmitCodeView = true;
4298
51
      break;
4299
3.22k
    case llvm::codegenoptions::DIF_DWARF:
4300
3.22k
      EmitDwarf = true;
4301
3.22k
      break;
4302
3.27k
    }
4303
3.27k
  }
4304
4305
47.7k
  unsigned RequestedDWARFVersion = 0; // DWARF version requested by the user
4306
47.7k
  unsigned EffectiveDWARFVersion = 0; // DWARF version TC can generate. It may
4307
                                      // be lower than what the user wanted.
4308
47.7k
  if (EmitDwarf) {
4309
3.28k
    RequestedDWARFVersion = getDwarfVersion(TC, Args);
4310
    // Clamp effective DWARF version to the max supported by the toolchain.
4311
3.28k
    EffectiveDWARFVersion =
4312
3.28k
        std::min(RequestedDWARFVersion, TC.getMaxDwarfVersion());
4313
44.4k
  } else {
4314
44.4k
    Args.ClaimAllArgs(options::OPT_fdebug_default_version);
4315
44.4k
  }
4316
4317
  // -gline-directives-only supported only for the DWARF debug info.
4318
47.7k
  if (RequestedDWARFVersion == 0 &&
4319
47.7k
      
DebugInfoKind == llvm::codegenoptions::DebugDirectivesOnly44.4k
)
4320
0
    DebugInfoKind = llvm::codegenoptions::NoDebugInfo;
4321
4322
  // strict DWARF is set to false by default. But for DBX, we need it to be set
4323
  // as true by default.
4324
47.7k
  if (const Arg *A = Args.getLastArg(options::OPT_gstrict_dwarf))
4325
2
    (void)checkDebugInfoOption(A, Args, D, TC);
4326
47.7k
  if (Args.hasFlag(options::OPT_gstrict_dwarf, options::OPT_gno_strict_dwarf,
4327
47.7k
                   DebuggerTuning == llvm::DebuggerKind::DBX))
4328
236
    CmdArgs.push_back("-gstrict-dwarf");
4329
4330
  // And we handle flag -grecord-gcc-switches later with DWARFDebugFlags.
4331
47.7k
  Args.ClaimAllArgs(options::OPT_g_flags_Group);
4332
4333
  // Column info is included by default for everything except SCE and
4334
  // CodeView. Clang doesn't track end columns, just starting columns, which,
4335
  // in theory, is fine for CodeView (and PDB).  In practice, however, the
4336
  // Microsoft debuggers don't handle missing end columns well, and the AIX
4337
  // debugger DBX also doesn't handle the columns well, so it's better not to
4338
  // include any column info.
4339
47.7k
  if (const Arg *A = Args.getLastArg(options::OPT_gcolumn_info))
4340
16
    (void)checkDebugInfoOption(A, Args, D, TC);
4341
47.7k
  if (!Args.hasFlag(options::OPT_gcolumn_info, options::OPT_gno_column_info,
4342
47.7k
                    !EmitCodeView &&
4343
47.7k
                        
(47.6k
DebuggerTuning != llvm::DebuggerKind::SCE47.6k
&&
4344
47.6k
                         
DebuggerTuning != llvm::DebuggerKind::DBX47.3k
)))
4345
591
    CmdArgs.push_back("-gno-column-info");
4346
4347
  // FIXME: Move backend command line options to the module.
4348
47.7k
  if (Args.hasFlag(options::OPT_gmodules, options::OPT_gno_modules, false)) {
4349
    // If -gline-tables-only or -gline-directives-only is the last option it
4350
    // wins.
4351
64
    if (checkDebugInfoOption(Args.getLastArg(options::OPT_gmodules), Args, D,
4352
64
                             TC)) {
4353
64
      if (DebugInfoKind != llvm::codegenoptions::DebugLineTablesOnly &&
4354
64
          
DebugInfoKind != llvm::codegenoptions::DebugDirectivesOnly63
) {
4355
62
        DebugInfoKind = llvm::codegenoptions::DebugInfoConstructor;
4356
62
        CmdArgs.push_back("-dwarf-ext-refs");
4357
62
        CmdArgs.push_back("-fmodule-format=obj");
4358
62
      }
4359
64
    }
4360
64
  }
4361
4362
47.7k
  if (T.isOSBinFormatELF() && 
SplitDWARFInlining20.6k
)
4363
4
    CmdArgs.push_back("-fsplit-dwarf-inlining");
4364
4365
  // After we've dealt with all combinations of things that could
4366
  // make DebugInfoKind be other than None or DebugLineTablesOnly,
4367
  // figure out if we need to "upgrade" it to standalone debug info.
4368
  // We parse these two '-f' options whether or not they will be used,
4369
  // to claim them even if you wrote "-fstandalone-debug -gline-tables-only"
4370
47.7k
  bool NeedFullDebug = Args.hasFlag(
4371
47.7k
      options::OPT_fstandalone_debug, options::OPT_fno_standalone_debug,
4372
47.7k
      DebuggerTuning == llvm::DebuggerKind::LLDB ||
4373
47.7k
          
TC.GetDefaultStandaloneDebug()30.0k
);
4374
47.7k
  if (const Arg *A = Args.getLastArg(options::OPT_fstandalone_debug))
4375
2.74k
    (void)checkDebugInfoOption(A, Args, D, TC);
4376
4377
47.7k
  if (DebugInfoKind == llvm::codegenoptions::LimitedDebugInfo ||
4378
47.7k
      DebugInfoKind == llvm::codegenoptions::DebugInfoConstructor) {
4379
3.31k
    if (Args.hasFlag(options::OPT_fno_eliminate_unused_debug_types,
4380
3.31k
                     options::OPT_feliminate_unused_debug_types, false))
4381
1
      DebugInfoKind = llvm::codegenoptions::UnusedTypeInfo;
4382
3.31k
    else if (NeedFullDebug)
4383
2.99k
      DebugInfoKind = llvm::codegenoptions::FullDebugInfo;
4384
3.31k
  }
4385
4386
47.7k
  if (Args.hasFlag(options::OPT_gembed_source, options::OPT_gno_embed_source,
4387
47.7k
                   false)) {
4388
    // Source embedding is a vendor extension to DWARF v5. By now we have
4389
    // checked if a DWARF version was stated explicitly, and have otherwise
4390
    // fallen back to the target default, so if this is still not at least 5
4391
    // we emit an error.
4392
2
    const Arg *A = Args.getLastArg(options::OPT_gembed_source);
4393
2
    if (RequestedDWARFVersion < 5)
4394
1
      D.Diag(diag::err_drv_argument_only_allowed_with)
4395
1
          << A->getAsString(Args) << "-gdwarf-5";
4396
1
    else if (EffectiveDWARFVersion < 5)
4397
      // The toolchain has reduced allowed dwarf version, so we can't enable
4398
      // -gembed-source.
4399
0
      D.Diag(diag::warn_drv_dwarf_version_limited_by_target)
4400
0
          << A->getAsString(Args) << TC.getTripleString() << 5
4401
0
          << EffectiveDWARFVersion;
4402
1
    else if (checkDebugInfoOption(A, Args, D, TC))
4403
1
      CmdArgs.push_back("-gembed-source");
4404
2
  }
4405
4406
47.7k
  if (EmitCodeView) {
4407
70
    CmdArgs.push_back("-gcodeview");
4408
4409
70
    Args.addOptInFlag(CmdArgs, options::OPT_gcodeview_ghash,
4410
70
                      options::OPT_gno_codeview_ghash);
4411
4412
70
    Args.addOptOutFlag(CmdArgs, options::OPT_gcodeview_command_line,
4413
70
                       options::OPT_gno_codeview_command_line);
4414
70
  }
4415
4416
47.7k
  Args.addOptOutFlag(CmdArgs, options::OPT_ginline_line_tables,
4417
47.7k
                     options::OPT_gno_inline_line_tables);
4418
4419
  // When emitting remarks, we need at least debug lines in the output.
4420
47.7k
  if (willEmitRemarks(Args) &&
4421
47.7k
      
DebugInfoKind <= llvm::codegenoptions::DebugDirectivesOnly38
)
4422
37
    DebugInfoKind = llvm::codegenoptions::DebugLineTablesOnly;
4423
4424
  // Adjust the debug info kind for the given toolchain.
4425
47.7k
  TC.adjustDebugInfoKind(DebugInfoKind, Args);
4426
4427
  // On AIX, the debugger tuning option can be omitted if it is not explicitly
4428
  // set.
4429
47.7k
  RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, EffectiveDWARFVersion,
4430
47.7k
                          T.isOSAIX() && 
!HasDebuggerTuning241
4431
47.7k
                              ? 
llvm::DebuggerKind::Default233
4432
47.7k
                              : 
DebuggerTuning47.5k
);
4433
4434
  // -fdebug-macro turns on macro debug info generation.
4435
47.7k
  if (Args.hasFlag(options::OPT_fdebug_macro, options::OPT_fno_debug_macro,
4436
47.7k
                   false))
4437
1
    if (checkDebugInfoOption(Args.getLastArg(options::OPT_fdebug_macro), Args,
4438
1
                             D, TC))
4439
1
      CmdArgs.push_back("-debug-info-macro");
4440
4441
  // -ggnu-pubnames turns on gnu style pubnames in the backend.
4442
47.7k
  const auto *PubnamesArg =
4443
47.7k
      Args.getLastArg(options::OPT_ggnu_pubnames, options::OPT_gno_gnu_pubnames,
4444
47.7k
                      options::OPT_gpubnames, options::OPT_gno_pubnames);
4445
47.7k
  if (DwarfFission != DwarfFissionKind::None ||
4446
47.7k
      
(47.7k
PubnamesArg47.7k
&&
checkDebugInfoOption(PubnamesArg, Args, D, TC)7
))
4447
54
    if (!PubnamesArg ||
4448
54
        
(10
!PubnamesArg->getOption().matches(options::OPT_gno_gnu_pubnames)10
&&
4449
10
         
!PubnamesArg->getOption().matches(options::OPT_gno_pubnames)7
))
4450
46
      CmdArgs.push_back(PubnamesArg && PubnamesArg->getOption().matches(
4451
2
                                           options::OPT_gpubnames)
4452
46
                            ? 
"-gpubnames"1
4453
46
                            : 
"-ggnu-pubnames"45
);
4454
47.7k
  const auto *SimpleTemplateNamesArg =
4455
47.7k
      Args.getLastArg(options::OPT_gsimple_template_names,
4456
47.7k
                      options::OPT_gno_simple_template_names);
4457
47.7k
  bool ForwardTemplateParams = DebuggerTuning == llvm::DebuggerKind::SCE;
4458
47.7k
  if (SimpleTemplateNamesArg &&
4459
47.7k
      
checkDebugInfoOption(SimpleTemplateNamesArg, Args, D, TC)23
) {
4460
23
    const auto &Opt = SimpleTemplateNamesArg->getOption();
4461
23
    if (Opt.matches(options::OPT_gsimple_template_names)) {
4462
13
      ForwardTemplateParams = true;
4463
13
      CmdArgs.push_back("-gsimple-template-names=simple");
4464
13
    }
4465
23
  }
4466
4467
47.7k
  if (const Arg *A = Args.getLastArg(options::OPT_gsrc_hash_EQ)) {
4468
3
    StringRef v = A->getValue();
4469
3
    CmdArgs.push_back(Args.MakeArgString("-gsrc-hash=" + v));
4470
3
  }
4471
4472
47.7k
  Args.addOptInFlag(CmdArgs, options::OPT_fdebug_ranges_base_address,
4473
47.7k
                    options::OPT_fno_debug_ranges_base_address);
4474
4475
  // -gdwarf-aranges turns on the emission of the aranges section in the
4476
  // backend.
4477
  // Always enabled for SCE tuning.
4478
47.7k
  bool NeedAranges = DebuggerTuning == llvm::DebuggerKind::SCE;
4479
47.7k
  if (const Arg *A = Args.getLastArg(options::OPT_gdwarf_aranges))
4480
1
    NeedAranges = checkDebugInfoOption(A, Args, D, TC) || 
NeedAranges0
;
4481
47.7k
  if (NeedAranges) {
4482
287
    CmdArgs.push_back("-mllvm");
4483
287
    CmdArgs.push_back("-generate-arange-section");
4484
287
  }
4485
4486
47.7k
  Args.addOptInFlag(CmdArgs, options::OPT_fforce_dwarf_frame,
4487
47.7k
                    options::OPT_fno_force_dwarf_frame);
4488
4489
47.7k
  if (Args.hasFlag(options::OPT_fdebug_types_section,
4490
47.7k
                   options::OPT_fno_debug_types_section, false)) {
4491
4
    if (!(T.isOSBinFormatELF() || 
T.isOSBinFormatWasm()2
)) {
4492
1
      D.Diag(diag::err_drv_unsupported_opt_for_target)
4493
1
          << Args.getLastArg(options::OPT_fdebug_types_section)
4494
1
                 ->getAsString(Args)
4495
1
          << T.getTriple();
4496
3
    } else if (checkDebugInfoOption(
4497
3
                   Args.getLastArg(options::OPT_fdebug_types_section), Args, D,
4498
3
                   TC)) {
4499
3
      CmdArgs.push_back("-mllvm");
4500
3
      CmdArgs.push_back("-generate-type-units");
4501
3
    }
4502
4
  }
4503
4504
  // To avoid join/split of directory+filename, the integrated assembler prefers
4505
  // the directory form of .file on all DWARF versions. GNU as doesn't allow the
4506
  // form before DWARF v5.
4507
47.7k
  if (!Args.hasFlag(options::OPT_fdwarf_directory_asm,
4508
47.7k
                    options::OPT_fno_dwarf_directory_asm,
4509
47.7k
                    TC.useIntegratedAs() || 
EffectiveDWARFVersion >= 5390
))
4510
386
    CmdArgs.push_back("-fno-dwarf-directory-asm");
4511
4512
  // Decide how to render forward declarations of template instantiations.
4513
  // SCE wants full descriptions, others just get them in the name.
4514
47.7k
  if (ForwardTemplateParams)
4515
299
    CmdArgs.push_back("-debug-forward-template-params");
4516
4517
  // Do we need to explicitly import anonymous namespaces into the parent
4518
  // scope?
4519
47.7k
  if (DebuggerTuning == llvm::DebuggerKind::SCE)
4520
286
    CmdArgs.push_back("-dwarf-explicit-import");
4521
4522
47.7k
  renderDwarfFormat(D, T, Args, CmdArgs, EffectiveDWARFVersion);
4523
47.7k
  RenderDebugInfoCompressionArgs(Args, CmdArgs, D, TC);
4524
4525
  // This controls whether or not we perform JustMyCode instrumentation.
4526
47.7k
  if (Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false)) {
4527
13
    if (TC.getTriple().isOSBinFormatELF() || 
D.IsCLMode()5
) {
4528
11
      if (DebugInfoKind >= llvm::codegenoptions::DebugInfoConstructor)
4529
3
        CmdArgs.push_back("-fjmc");
4530
8
      else if (D.IsCLMode())
4531
2
        D.Diag(clang::diag::warn_drv_jmc_requires_debuginfo) << "/JMC"
4532
2
                                                             << "'/Zi', '/Z7'";
4533
6
      else
4534
6
        D.Diag(clang::diag::warn_drv_jmc_requires_debuginfo) << "-fjmc"
4535
6
                                                             << "-g";
4536
11
    } else {
4537
2
      D.Diag(clang::diag::warn_drv_fjmc_for_elf_only);
4538
2
    }
4539
13
  }
4540
4541
  // Add in -fdebug-compilation-dir if necessary.
4542
47.7k
  const char *DebugCompilationDir =
4543
47.7k
      addDebugCompDirArg(Args, CmdArgs, D.getVFS());
4544
4545
47.7k
  addDebugPrefixMapArg(D, TC, Args, CmdArgs);
4546
4547
  // Add the output path to the object file for CodeView debug infos.
4548
47.7k
  if (EmitCodeView && 
Output.isFilename()70
)
4549
69
    addDebugObjectName(Args, CmdArgs, DebugCompilationDir,
4550
69
                       Output.getFilename());
4551
47.7k
}
4552
4553
static void ProcessVSRuntimeLibrary(const ArgList &Args,
4554
726
                                    ArgStringList &CmdArgs) {
4555
726
  unsigned RTOptionID = options::OPT__SLASH_MT;
4556
4557
726
  if (Args.hasArg(options::OPT__SLASH_LDd))
4558
    // The /LDd option implies /MTd. The dependent lib part can be overridden,
4559
    // but defining _DEBUG is sticky.
4560
24
    RTOptionID = options::OPT__SLASH_MTd;
4561
4562
726
  if (Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group))
4563
30
    RTOptionID = A->getOption().getID();
4564
4565
726
  if (Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
4566
5
    RTOptionID = llvm::StringSwitch<unsigned>(A->getValue())
4567
5
                     .Case("static", options::OPT__SLASH_MT)
4568
5
                     .Case("static_dbg", options::OPT__SLASH_MTd)
4569
5
                     .Case("dll", options::OPT__SLASH_MD)
4570
5
                     .Case("dll_dbg", options::OPT__SLASH_MDd)
4571
5
                     .Default(options::OPT__SLASH_MT);
4572
5
  }
4573
4574
726
  StringRef FlagForCRT;
4575
726
  switch (RTOptionID) {
4576
10
  case options::OPT__SLASH_MD:
4577
10
    if (Args.hasArg(options::OPT__SLASH_LDd))
4578
2
      CmdArgs.push_back("-D_DEBUG");
4579
10
    CmdArgs.push_back("-D_MT");
4580
10
    CmdArgs.push_back("-D_DLL");
4581
10
    FlagForCRT = "--dependent-lib=msvcrt";
4582
10
    break;
4583
8
  case options::OPT__SLASH_MDd:
4584
8
    CmdArgs.push_back("-D_DEBUG");
4585
8
    CmdArgs.push_back("-D_MT");
4586
8
    CmdArgs.push_back("-D_DLL");
4587
8
    FlagForCRT = "--dependent-lib=msvcrtd";
4588
8
    break;
4589
680
  case options::OPT__SLASH_MT:
4590
680
    if (Args.hasArg(options::OPT__SLASH_LDd))
4591
2
      CmdArgs.push_back("-D_DEBUG");
4592
680
    CmdArgs.push_back("-D_MT");
4593
680
    CmdArgs.push_back("-flto-visibility-public-std");
4594
680
    FlagForCRT = "--dependent-lib=libcmt";
4595
680
    break;
4596
24
  case options::OPT__SLASH_MTd:
4597
24
    CmdArgs.push_back("-D_DEBUG");
4598
24
    CmdArgs.push_back("-D_MT");
4599
24
    CmdArgs.push_back("-flto-visibility-public-std");
4600
24
    FlagForCRT = "--dependent-lib=libcmtd";
4601
24
    break;
4602
0
  default:
4603
0
    llvm_unreachable("Unexpected option ID.");
4604
726
  }
4605
4606
723
  if (Args.hasArg(options::OPT_fms_omit_default_lib)) {
4607
4
    CmdArgs.push_back("-D_VC_NODEFAULTLIB");
4608
719
  } else {
4609
719
    CmdArgs.push_back(FlagForCRT.data());
4610
4611
    // This provides POSIX compatibility (maps 'open' to '_open'), which most
4612
    // users want.  The /Za flag to cl.exe turns this off, but it's not
4613
    // implemented in clang.
4614
719
    CmdArgs.push_back("--dependent-lib=oldnames");
4615
719
  }
4616
723
}
4617
4618
void Clang::ConstructJob(Compilation &C, const JobAction &JA,
4619
                         const InputInfo &Output, const InputInfoList &Inputs,
4620
47.7k
                         const ArgList &Args, const char *LinkingOutput) const {
4621
47.7k
  const auto &TC = getToolChain();
4622
47.7k
  const llvm::Triple &RawTriple = TC.getTriple();
4623
47.7k
  const llvm::Triple &Triple = TC.getEffectiveTriple();
4624
47.7k
  const std::string &TripleStr = Triple.getTriple();
4625
4626
47.7k
  bool KernelOrKext =
4627
47.7k
      Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
4628
47.7k
  const Driver &D = TC.getDriver();
4629
47.7k
  ArgStringList CmdArgs;
4630
4631
47.7k
  assert(Inputs.size() >= 1 && "Must have at least one input.");
4632
  // CUDA/HIP compilation may have multiple inputs (source file + results of
4633
  // device-side compilations). OpenMP device jobs also take the host IR as a
4634
  // second input. Module precompilation accepts a list of header files to
4635
  // include as part of the module. API extraction accepts a list of header
4636
  // files whose API information is emitted in the output. All other jobs are
4637
  // expected to have exactly one input.
4638
47.7k
  bool IsCuda = JA.isOffloading(Action::OFK_Cuda);
4639
47.7k
  bool IsCudaDevice = JA.isDeviceOffloading(Action::OFK_Cuda);
4640
47.7k
  bool IsHIP = JA.isOffloading(Action::OFK_HIP);
4641
47.7k
  bool IsHIPDevice = JA.isDeviceOffloading(Action::OFK_HIP);
4642
47.7k
  bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP);
4643
47.7k
  bool IsExtractAPI = isa<ExtractAPIJobAction>(JA);
4644
47.7k
  bool IsDeviceOffloadAction = !(JA.isDeviceOffloading(Action::OFK_None) ||
4645
47.7k
                                 
JA.isDeviceOffloading(Action::OFK_Host)519
);
4646
47.7k
  bool IsHostOffloadingAction =
4647
47.7k
      JA.isHostOffloading(Action::OFK_OpenMP) ||
4648
47.7k
      
(47.7k
JA.isHostOffloading(C.getActiveOffloadKinds())47.7k
&&
4649
47.7k
       Args.hasFlag(options::OPT_offload_new_driver,
4650
338
                    options::OPT_no_offload_new_driver, false));
4651
4652
47.7k
  bool IsRDCMode =
4653
47.7k
      Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false);
4654
47.7k
  bool IsUsingLTO = D.isUsingLTO(IsDeviceOffloadAction);
4655
47.7k
  auto LTOMode = D.getLTOMode(IsDeviceOffloadAction);
4656
4657
  // Extract API doesn't have a main input file, so invent a fake one as a
4658
  // placeholder.
4659
47.7k
  InputInfo ExtractAPIPlaceholderInput(Inputs[0].getType(), "extract-api",
4660
47.7k
                                       "extract-api");
4661
4662
47.7k
  const InputInfo &Input =
4663
47.7k
      IsExtractAPI ? 
ExtractAPIPlaceholderInput20
:
Inputs[0]47.7k
;
4664
4665
47.7k
  InputInfoList ExtractAPIInputs;
4666
47.7k
  InputInfoList HostOffloadingInputs;
4667
47.7k
  const InputInfo *CudaDeviceInput = nullptr;
4668
47.7k
  const InputInfo *OpenMPDeviceInput = nullptr;
4669
48.0k
  for (const InputInfo &I : Inputs) {
4670
48.0k
    if (&I == &Input || 
I.getType() == types::TY_Nothing262
) {
4671
      // This is the primary input or contains nothing.
4672
47.7k
    } else 
if (259
IsExtractAPI259
) {
4673
24
      auto ExpectedInputType = ExtractAPIPlaceholderInput.getType();
4674
24
      if (I.getType() != ExpectedInputType) {
4675
1
        D.Diag(diag::err_drv_extract_api_wrong_kind)
4676
1
            << I.getFilename() << types::getTypeName(I.getType())
4677
1
            << types::getTypeName(ExpectedInputType);
4678
1
      }
4679
24
      ExtractAPIInputs.push_back(I);
4680
235
    } else if (IsHostOffloadingAction) {
4681
10
      HostOffloadingInputs.push_back(I);
4682
225
    } else if ((IsCuda || 
IsHIP186
) &&
!CudaDeviceInput217
) {
4683
217
      CudaDeviceInput = &I;
4684
217
    } else 
if (8
IsOpenMPDevice8
&&
!OpenMPDeviceInput9
) {
4685
9
      OpenMPDeviceInput = &I;
4686
18.4E
    } else {
4687
18.4E
      llvm_unreachable("unexpectedly given multiple inputs");
4688
18.4E
    }
4689
48.0k
  }
4690
4691
47.7k
  const llvm::Triple *AuxTriple =
4692
47.7k
      (IsCuda || 
IsHIP47.6k
) ?
TC.getAuxTriple()848
:
nullptr46.9k
;
4693
47.7k
  bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment();
4694
47.7k
  bool IsIAMCU = RawTriple.isOSIAMCU();
4695
4696
  // Adjust IsWindowsXYZ for CUDA/HIP compilations.  Even when compiling in
4697
  // device mode (i.e., getToolchain().getTriple() is NVPTX/AMDGCN, not
4698
  // Windows), we need to pass Windows-specific flags to cc1.
4699
47.7k
  if (IsCuda || 
IsHIP47.6k
)
4700
848
    IsWindowsMSVC |= AuxTriple && 
AuxTriple->isWindowsMSVCEnvironment()510
;
4701
4702
  // C++ is not supported for IAMCU.
4703
47.7k
  if (IsIAMCU && 
types::isCXX(Input.getType())9
)
4704
1
    D.Diag(diag::err_drv_clang_unsupported) << "C++ for IAMCU";
4705
4706
  // Invoke ourselves in -cc1 mode.
4707
  //
4708
  // FIXME: Implement custom jobs for internal actions.
4709
47.7k
  CmdArgs.push_back("-cc1");
4710
4711
  // Add the "effective" target triple.
4712
47.7k
  CmdArgs.push_back("-triple");
4713
47.7k
  CmdArgs.push_back(Args.MakeArgString(TripleStr));
4714
4715
47.7k
  if (const Arg *MJ = Args.getLastArg(options::OPT_MJ)) {
4716
9
    DumpCompilationDatabase(C, MJ->getValue(), TripleStr, Output, Input, Args);
4717
9
    Args.ClaimAllArgs(options::OPT_MJ);
4718
47.7k
  } else if (const Arg *GenCDBFragment =
4719
47.7k
                 Args.getLastArg(options::OPT_gen_cdb_fragment_path)) {
4720
4
    DumpCompilationDatabaseFragmentToDir(GenCDBFragment->getValue(), C,
4721
4
                                         TripleStr, Output, Input, Args);
4722
4
    Args.ClaimAllArgs(options::OPT_gen_cdb_fragment_path);
4723
4
  }
4724
4725
47.7k
  if (IsCuda || 
IsHIP47.6k
) {
4726
    // We have to pass the triple of the host if compiling for a CUDA/HIP device
4727
    // and vice-versa.
4728
848
    std::string NormalizedTriple;
4729
848
    if (JA.isDeviceOffloading(Action::OFK_Cuda) ||
4730
848
        
JA.isDeviceOffloading(Action::OFK_HIP)775
)
4731
510
      NormalizedTriple = C.getSingleOffloadToolChain<Action::OFK_Host>()
4732
510
                             ->getTriple()
4733
510
                             .normalize();
4734
338
    else {
4735
      // Host-side compilation.
4736
338
      NormalizedTriple =
4737
338
          (IsCuda ? 
C.getSingleOffloadToolChain<Action::OFK_Cuda>()70
4738
338
                  : 
C.getSingleOffloadToolChain<Action::OFK_HIP>()268
)
4739
338
              ->getTriple()
4740
338
              .normalize();
4741
338
      if (IsCuda) {
4742
        // We need to figure out which CUDA version we're compiling for, as that
4743
        // determines how we load and launch GPU kernels.
4744
70
        auto *CTC = static_cast<const toolchains::CudaToolChain *>(
4745
70
            C.getSingleOffloadToolChain<Action::OFK_Cuda>());
4746
70
        assert(CTC && "Expected valid CUDA Toolchain.");
4747
70
        if (CTC && CTC->CudaInstallation.version() != CudaVersion::UNKNOWN)
4748
19
          CmdArgs.push_back(Args.MakeArgString(
4749
19
              Twine("-target-sdk-version=") +
4750
19
              CudaVersionToString(CTC->CudaInstallation.version())));
4751
        // Unsized function arguments used for variadics were introduced in
4752
        // CUDA-9.0. We still do not support generating code that actually uses
4753
        // variadic arguments yet, but we do need to allow parsing them as
4754
        // recent CUDA headers rely on that.
4755
        // https://github.com/llvm/llvm-project/issues/58410
4756
70
        if (CTC->CudaInstallation.version() >= CudaVersion::CUDA_90)
4757
0
          CmdArgs.push_back("-fcuda-allow-variadic-functions");
4758
70
      }
4759
338
    }
4760
848
    CmdArgs.push_back("-aux-triple");
4761
848
    CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
4762
4763
848
    if (JA.isDeviceOffloading(Action::OFK_HIP) &&
4764
848
        
getToolChain().getTriple().isAMDGPU()437
) {
4765
      // Device side compilation printf
4766
427
      if (Args.getLastArg(options::OPT_mprintf_kind_EQ)) {
4767
6
        CmdArgs.push_back(Args.MakeArgString(
4768
6
            "-mprintf-kind=" +
4769
6
            Args.getLastArgValue(options::OPT_mprintf_kind_EQ)));
4770
        // Force compiler error on invalid conversion specifiers
4771
6
        CmdArgs.push_back(
4772
6
            Args.MakeArgString("-Werror=format-invalid-specifier"));
4773
6
      }
4774
427
    }
4775
848
  }
4776
4777
  // Unconditionally claim the printf option now to avoid unused diagnostic.
4778
47.7k
  if (const Arg *PF = Args.getLastArg(options::OPT_mprintf_kind_EQ))
4779
12
    PF->claim();
4780
4781
47.7k
  if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false)) {
4782
14
    CmdArgs.push_back("-fsycl-is-device");
4783
4784
14
    if (Arg *A = Args.getLastArg(options::OPT_sycl_std_EQ)) {
4785
6
      A->render(Args, CmdArgs);
4786
8
    } else {
4787
      // Ensure the default version in SYCL mode is 2020.
4788
8
      CmdArgs.push_back("-sycl-std=2020");
4789
8
    }
4790
14
  }
4791
4792
47.7k
  if (IsOpenMPDevice) {
4793
    // We have to pass the triple of the host if compiling for an OpenMP device.
4794
9
    std::string NormalizedTriple =
4795
9
        C.getSingleOffloadToolChain<Action::OFK_Host>()
4796
9
            ->getTriple()
4797
9
            .normalize();
4798
9
    CmdArgs.push_back("-aux-triple");
4799
9
    CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
4800
9
  }
4801
4802
47.7k
  if (Triple.isOSWindows() && 
(8.76k
Triple.getArch() == llvm::Triple::arm8.76k
||
4803
8.76k
                               Triple.getArch() == llvm::Triple::thumb)) {
4804
92
    unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 
40
: 6;
4805
92
    unsigned Version = 0;
4806
92
    bool Failure =
4807
92
        Triple.getArchName().substr(Offset).consumeInteger(10, Version);
4808
92
    if (Failure || Version < 7)
4809
3
      D.Diag(diag::err_target_unsupported_arch) << Triple.getArchName()
4810
3
                                                << TripleStr;
4811
92
  }
4812
4813
  // Push all default warning arguments that are specific to
4814
  // the given target.  These come before user provided warning options
4815
  // are provided.
4816
47.7k
  TC.addClangWarningOptions(CmdArgs);
4817
4818
  // FIXME: Subclass ToolChain for SPIR and move this to addClangWarningOptions.
4819
47.7k
  if (Triple.isSPIR() || 
Triple.isSPIRV()47.7k
)
4820
49
    CmdArgs.push_back("-Wspir-compat");
4821
4822
  // Select the appropriate action.
4823
47.7k
  RewriteKind rewriteKind = RK_None;
4824
4825
47.7k
  bool UnifiedLTO = false;
4826
47.7k
  if (IsUsingLTO) {
4827
294
    UnifiedLTO = Args.hasFlag(options::OPT_funified_lto,
4828
294
                              options::OPT_fno_unified_lto, Triple.isPS());
4829
294
    if (UnifiedLTO)
4830
29
      CmdArgs.push_back("-funified-lto");
4831
294
  }
4832
4833
  // If CollectArgsForIntegratedAssembler() isn't called below, claim the args
4834
  // it claims when not running an assembler. Otherwise, clang would emit
4835
  // "argument unused" warnings for assembler flags when e.g. adding "-E" to
4836
  // flags while debugging something. That'd be somewhat inconvenient, and it's
4837
  // also inconsistent with most other flags -- we don't warn on
4838
  // -ffunction-sections not being used in -E mode either for example, even
4839
  // though it's not really used either.
4840
47.7k
  if (!isa<AssembleJobAction>(JA)) {
4841
    // The args claimed here should match the args used in
4842
    // CollectArgsForIntegratedAssembler().
4843
36.5k
    if (TC.useIntegratedAs()) {
4844
36.1k
      Args.ClaimAllArgs(options::OPT_mrelax_all);
4845
36.1k
      Args.ClaimAllArgs(options::OPT_mno_relax_all);
4846
36.1k
      Args.ClaimAllArgs(options::OPT_mincremental_linker_compatible);
4847
36.1k
      Args.ClaimAllArgs(options::OPT_mno_incremental_linker_compatible);
4848
36.1k
      switch (C.getDefaultToolChain().getArch()) {
4849
570
      case llvm::Triple::arm:
4850
571
      case llvm::Triple::armeb:
4851
587
      case llvm::Triple::thumb:
4852
588
      case llvm::Triple::thumbeb:
4853
588
        Args.ClaimAllArgs(options::OPT_mimplicit_it_EQ);
4854
588
        break;
4855
35.5k
      default:
4856
35.5k
        break;
4857
36.1k
      }
4858
36.1k
    }
4859
36.5k
    Args.ClaimAllArgs(options::OPT_Wa_COMMA);
4860
36.5k
    Args.ClaimAllArgs(options::OPT_Xassembler);
4861
36.5k
    Args.ClaimAllArgs(options::OPT_femit_dwarf_unwind_EQ);
4862
36.5k
  }
4863
4864
47.7k
  if (isa<AnalyzeJobAction>(JA)) {
4865
56
    assert(JA.getType() == types::TY_Plist && "Invalid output type.");
4866
56
    CmdArgs.push_back("-analyze");
4867
47.7k
  } else if (isa<MigrateJobAction>(JA)) {
4868
0
    CmdArgs.push_back("-migrate");
4869
47.7k
  } else if (isa<PreprocessJobAction>(JA)) {
4870
2.03k
    if (Output.getType() == types::TY_Dependencies)
4871
14
      CmdArgs.push_back("-Eonly");
4872
2.02k
    else {
4873
2.02k
      CmdArgs.push_back("-E");
4874
2.02k
      if (Args.hasArg(options::OPT_rewrite_objc) &&
4875
2.02k
          
!Args.hasArg(options::OPT_g_Group)5
)
4876
4
        CmdArgs.push_back("-P");
4877
2.02k
      else if (JA.getType() == types::TY_PP_CXXHeaderUnit)
4878
1
        CmdArgs.push_back("-fdirectives-only");
4879
2.02k
    }
4880
45.6k
  } else if (isa<AssembleJobAction>(JA)) {
4881
11.2k
    CmdArgs.push_back("-emit-obj");
4882
4883
11.2k
    CollectArgsForIntegratedAssembler(C, Args, CmdArgs, D);
4884
4885
    // Also ignore explicit -force_cpusubtype_ALL option.
4886
11.2k
    (void)Args.hasArg(options::OPT_force__cpusubtype__ALL);
4887
34.4k
  } else if (isa<PrecompileJobAction>(JA)) {
4888
120
    if (JA.getType() == types::TY_Nothing)
4889
37
      CmdArgs.push_back("-fsyntax-only");
4890
83
    else if (JA.getType() == types::TY_ModuleFile)
4891
27
      CmdArgs.push_back("-emit-module-interface");
4892
56
    else if (JA.getType() == types::TY_HeaderUnit)
4893
9
      CmdArgs.push_back("-emit-header-unit");
4894
47
    else
4895
47
      CmdArgs.push_back("-emit-pch");
4896
34.3k
  } else if (isa<VerifyPCHJobAction>(JA)) {
4897
2
    CmdArgs.push_back("-verify-pch");
4898
34.3k
  } else if (isa<ExtractAPIJobAction>(JA)) {
4899
20
    assert(JA.getType() == types::TY_API_INFO &&
4900
20
           "Extract API actions must generate a API information.");
4901
20
    CmdArgs.push_back("-extract-api");
4902
20
    if (Arg *ProductNameArg = Args.getLastArg(options::OPT_product_name_EQ))
4903
7
      ProductNameArg->render(Args, CmdArgs);
4904
20
    if (Arg *ExtractAPIIgnoresFileArg =
4905
20
            Args.getLastArg(options::OPT_extract_api_ignores_EQ))
4906
1
      ExtractAPIIgnoresFileArg->render(Args, CmdArgs);
4907
34.3k
  } else {
4908
34.3k
    assert((isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) &&
4909
34.3k
           "Invalid action for clang tool.");
4910
34.3k
    if (JA.getType() == types::TY_Nothing) {
4911
31.7k
      CmdArgs.push_back("-fsyntax-only");
4912
31.7k
    } else 
if (2.59k
JA.getType() == types::TY_LLVM_IR2.59k
||
4913
2.59k
               
JA.getType() == types::TY_LTO_IR1.92k
) {
4914
713
      CmdArgs.push_back("-emit-llvm");
4915
1.88k
    } else if (JA.getType() == types::TY_LLVM_BC ||
4916
1.88k
               
JA.getType() == types::TY_LTO_BC1.61k
) {
4917
      // Emit textual llvm IR for AMDGPU offloading for -emit-llvm -S
4918
500
      if (Triple.isAMDGCN() && 
IsOpenMPDevice141
&&
Args.hasArg(options::OPT_S)9
&&
4919
500
          
Args.hasArg(options::OPT_emit_llvm)1
) {
4920
1
        CmdArgs.push_back("-emit-llvm");
4921
499
      } else {
4922
499
        CmdArgs.push_back("-emit-llvm-bc");
4923
499
      }
4924
1.38k
    } else if (JA.getType() == types::TY_IFS ||
4925
1.38k
               
JA.getType() == types::TY_IFS_CPP1.37k
) {
4926
26
      StringRef ArgStr =
4927
26
          Args.hasArg(options::OPT_interface_stub_version_EQ)
4928
26
              ? 
Args.getLastArgValue(options::OPT_interface_stub_version_EQ)8
4929
26
              : 
"ifs-v1"18
;
4930
26
      CmdArgs.push_back("-emit-interface-stubs");
4931
26
      CmdArgs.push_back(
4932
26
          Args.MakeArgString(Twine("-interface-stub-version=") + ArgStr.str()));
4933
1.35k
    } else if (JA.getType() == types::TY_PP_Asm) {
4934
1.32k
      CmdArgs.push_back("-S");
4935
1.32k
    } else 
if (31
JA.getType() == types::TY_AST31
) {
4936
15
      CmdArgs.push_back("-emit-pch");
4937
16
    } else if (JA.getType() == types::TY_ModuleFile) {
4938
2
      CmdArgs.push_back("-module-file-info");
4939
14
    } else if (JA.getType() == types::TY_RewrittenObjC) {
4940
5
      CmdArgs.push_back("-rewrite-objc");
4941
5
      rewriteKind = RK_NonFragile;
4942
9
    } else if (JA.getType() == types::TY_RewrittenLegacyObjC) {
4943
3
      CmdArgs.push_back("-rewrite-objc");
4944
3
      rewriteKind = RK_Fragile;
4945
6
    } else {
4946
6
      assert(JA.getType() == types::TY_PP_Asm && "Unexpected output type!");
4947
6
    }
4948
4949
    // Preserve use-list order by default when emitting bitcode, so that
4950
    // loading the bitcode up in 'opt' or 'llc' and running passes gives the
4951
    // same result as running passes here.  For LTO, we don't need to preserve
4952
    // the use-list order, since serialization to bitcode is part of the flow.
4953
34.3k
    if (JA.getType() == types::TY_LLVM_BC)
4954
264
      CmdArgs.push_back("-emit-llvm-uselists");
4955
4956
34.3k
    if (IsUsingLTO) {
4957
288
      if (IsDeviceOffloadAction && 
!JA.isDeviceOffloading(Action::OFK_OpenMP)2
&&
4958
288
          !Args.hasFlag(options::OPT_offload_new_driver,
4959
2
                        options::OPT_no_offload_new_driver, false) &&
4960
288
          
!Triple.isAMDGPU()2
) {
4961
0
        D.Diag(diag::err_drv_unsupported_opt_for_target)
4962
0
            << Args.getLastArg(options::OPT_foffload_lto,
4963
0
                               options::OPT_foffload_lto_EQ)
4964
0
                   ->getAsString(Args)
4965
0
            << Triple.getTriple();
4966
288
      } else if (Triple.isNVPTX() && 
!IsRDCMode0
&&
4967
288
                 
JA.isDeviceOffloading(Action::OFK_Cuda)0
) {
4968
0
        D.Diag(diag::err_drv_unsupported_opt_for_language_mode)
4969
0
            << Args.getLastArg(options::OPT_foffload_lto,
4970
0
                               options::OPT_foffload_lto_EQ)
4971
0
                   ->getAsString(Args)
4972
0
            << "-fno-gpu-rdc";
4973
288
      } else {
4974
288
        assert(LTOMode == LTOK_Full || LTOMode == LTOK_Thin);
4975
288
        CmdArgs.push_back(Args.MakeArgString(
4976
288
            Twine("-flto=") + (LTOMode == LTOK_Thin ? 
"thin"76
:
"full"212
)));
4977
        // PS4 uses the legacy LTO API, which does not support some of the
4978
        // features enabled by -flto-unit.
4979
288
        if (!RawTriple.isPS4() ||
4980
288
            
(D.getLTOMode() == LTOK_Full)16
||
!UnifiedLTO8
)
4981
281
          CmdArgs.push_back("-flto-unit");
4982
288
      }
4983
288
    }
4984
34.3k
  }
4985
4986
47.7k
  Args.AddLastArg(CmdArgs, options::OPT_dumpdir);
4987
4988
47.7k
  if (const Arg *A = Args.getLastArg(options::OPT_fthinlto_index_EQ)) {
4989
30
    if (!types::isLLVMIR(Input.getType()))
4990
1
      D.Diag(diag::err_drv_arg_requires_bitcode_input) << A->getAsString(Args);
4991
30
    Args.AddLastArg(CmdArgs, options::OPT_fthinlto_index_EQ);
4992
30
  }
4993
4994
47.7k
  if (Args.getLastArg(options::OPT_fthin_link_bitcode_EQ))
4995
1
    Args.AddLastArg(CmdArgs, options::OPT_fthin_link_bitcode_EQ);
4996
4997
47.7k
  if (Args.getLastArg(options::OPT_save_temps_EQ))
4998
255
    Args.AddLastArg(CmdArgs, options::OPT_save_temps_EQ);
4999
5000
47.7k
  auto *MemProfArg = Args.getLastArg(options::OPT_fmemory_profile,
5001
47.7k
                                     options::OPT_fmemory_profile_EQ,
5002
47.7k
                                     options::OPT_fno_memory_profile);
5003
47.7k
  if (MemProfArg &&
5004
47.7k
      
!MemProfArg->getOption().matches(options::OPT_fno_memory_profile)7
)
5005
5
    MemProfArg->render(Args, CmdArgs);
5006
5007
47.7k
  if (auto *MemProfUseArg =
5008
47.7k
          Args.getLastArg(options::OPT_fmemory_profile_use_EQ)) {
5009
3
    if (MemProfArg)
5010
1
      D.Diag(diag::err_drv_argument_not_allowed_with)
5011
1
          << MemProfUseArg->getAsString(Args) << MemProfArg->getAsString(Args);
5012
3
    if (auto *PGOInstrArg = Args.getLastArg(options::OPT_fprofile_generate,
5013
3
                                            options::OPT_fprofile_generate_EQ))
5014
1
      D.Diag(diag::err_drv_argument_not_allowed_with)
5015
1
          << MemProfUseArg->getAsString(Args) << PGOInstrArg->getAsString(Args);
5016
3
    MemProfUseArg->render(Args, CmdArgs);
5017
3
  }
5018
5019
  // Embed-bitcode option.
5020
  // Only white-listed flags below are allowed to be embedded.
5021
47.7k
  if (C.getDriver().embedBitcodeInObject() && 
!IsUsingLTO32
&&
5022
47.7k
      
(27
isa<BackendJobAction>(JA)27
||
isa<AssembleJobAction>(JA)26
)) {
5023
    // Add flags implied by -fembed-bitcode.
5024
12
    Args.AddLastArg(CmdArgs, options::OPT_fembed_bitcode_EQ);
5025
    // Disable all llvm IR level optimizations.
5026
12
    CmdArgs.push_back("-disable-llvm-passes");
5027
5028
    // Render target options.
5029
12
    TC.addClangTargetOptions(Args, CmdArgs, JA.getOffloadingDeviceKind());
5030
5031
    // reject options that shouldn't be supported in bitcode
5032
    // also reject kernel/kext
5033
12
    static const constexpr unsigned kBitcodeOptionIgnorelist[] = {
5034
12
        options::OPT_mkernel,
5035
12
        options::OPT_fapple_kext,
5036
12
        options::OPT_ffunction_sections,
5037
12
        options::OPT_fno_function_sections,
5038
12
        options::OPT_fdata_sections,
5039
12
        options::OPT_fno_data_sections,
5040
12
        options::OPT_fbasic_block_sections_EQ,
5041
12