Coverage Report

Created: 2021-01-19 06:58

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChain.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- ToolChain.cpp - Collections of tools for one platform --------------===//
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/Driver/ToolChain.h"
10
#include "InputInfo.h"
11
#include "ToolChains/Arch/ARM.h"
12
#include "ToolChains/Clang.h"
13
#include "ToolChains/InterfaceStubs.h"
14
#include "ToolChains/Flang.h"
15
#include "clang/Basic/ObjCRuntime.h"
16
#include "clang/Basic/Sanitizers.h"
17
#include "clang/Config/config.h"
18
#include "clang/Driver/Action.h"
19
#include "clang/Driver/Driver.h"
20
#include "clang/Driver/DriverDiagnostic.h"
21
#include "clang/Driver/Job.h"
22
#include "clang/Driver/Options.h"
23
#include "clang/Driver/SanitizerArgs.h"
24
#include "clang/Driver/XRayArgs.h"
25
#include "llvm/ADT/STLExtras.h"
26
#include "llvm/ADT/SmallString.h"
27
#include "llvm/ADT/StringRef.h"
28
#include "llvm/ADT/Triple.h"
29
#include "llvm/ADT/Twine.h"
30
#include "llvm/Config/llvm-config.h"
31
#include "llvm/MC/MCTargetOptions.h"
32
#include "llvm/Option/Arg.h"
33
#include "llvm/Option/ArgList.h"
34
#include "llvm/Option/OptTable.h"
35
#include "llvm/Option/Option.h"
36
#include "llvm/Support/ErrorHandling.h"
37
#include "llvm/Support/FileSystem.h"
38
#include "llvm/Support/Path.h"
39
#include "llvm/Support/TargetParser.h"
40
#include "llvm/Support/TargetRegistry.h"
41
#include "llvm/Support/VersionTuple.h"
42
#include "llvm/Support/VirtualFileSystem.h"
43
#include <cassert>
44
#include <cstddef>
45
#include <cstring>
46
#include <string>
47
48
using namespace clang;
49
using namespace driver;
50
using namespace tools;
51
using namespace llvm;
52
using namespace llvm::opt;
53
54
48.8k
static llvm::opt::Arg *GetRTTIArgument(const ArgList &Args) {
55
48.8k
  return Args.getLastArg(options::OPT_mkernel, options::OPT_fapple_kext,
56
48.8k
                         options::OPT_fno_rtti, options::OPT_frtti);
57
48.8k
}
58
59
static ToolChain::RTTIMode CalculateRTTIMode(const ArgList &Args,
60
                                             const llvm::Triple &Triple,
61
48.8k
                                             const Arg *CachedRTTIArg) {
62
  // Explicit rtti/no-rtti args
63
48.8k
  if (CachedRTTIArg) {
64
21.2k
    if (CachedRTTIArg->getOption().matches(options::OPT_frtti))
65
21.1k
      return ToolChain::RM_Enabled;
66
70
    else
67
70
      return ToolChain::RM_Disabled;
68
27.6k
  }
69
70
  // -frtti is default, except for the PS4 CPU.
71
27.6k
  return (Triple.isPS4CPU()) ? 
ToolChain::RM_Disabled137
:
ToolChain::RM_Enabled27.4k
;
72
27.6k
}
73
74
ToolChain::ToolChain(const Driver &D, const llvm::Triple &T,
75
                     const ArgList &Args)
76
    : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)),
77
48.8k
      CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)) {
78
48.8k
  if (D.CCCIsCXX()) {
79
6.52k
    if (auto CXXStdlibPath = getCXXStdlibPath())
80
9
      getFilePaths().push_back(*CXXStdlibPath);
81
6.52k
  }
82
83
48.8k
  if (auto RuntimePath = getRuntimePath())
84
35
    getLibraryPaths().push_back(*RuntimePath);
85
86
48.8k
  std::string CandidateLibPath = getArchSpecificLibPath();
87
48.8k
  if (getVFS().exists(CandidateLibPath))
88
28
    getFilePaths().push_back(CandidateLibPath);
89
48.8k
}
90
91
91
void ToolChain::setTripleEnvironment(llvm::Triple::EnvironmentType Env) {
92
91
  Triple.setEnvironment(Env);
93
91
  if (EffectiveTriple != llvm::Triple())
94
0
    EffectiveTriple.setEnvironment(Env);
95
91
}
96
97
48.8k
ToolChain::~ToolChain() = default;
98
99
221k
llvm::vfs::FileSystem &ToolChain::getVFS() const {
100
221k
  return getDriver().getVFS();
101
221k
}
102
103
213k
bool ToolChain::useIntegratedAs() const {
104
213k
  return Args.hasFlag(options::OPT_fintegrated_as,
105
213k
                      options::OPT_fno_integrated_as,
106
213k
                      IsIntegratedAssemblerDefault());
107
213k
}
108
109
10.0k
bool ToolChain::useRelaxRelocations() const {
110
10.0k
  return ENABLE_X86_RELAX_RELOCATIONS;
111
10.0k
}
112
113
7.94k
bool ToolChain::isNoExecStackDefault() const {
114
7.94k
    return false;
115
7.94k
}
116
117
118k
const SanitizerArgs& ToolChain::getSanitizerArgs() const {
118
118k
  if (!SanitizerArguments.get())
119
46.9k
    SanitizerArguments.reset(new SanitizerArgs(*this, Args));
120
118k
  return *SanitizerArguments.get();
121
118k
}
122
123
49.8k
const XRayArgs& ToolChain::getXRayArgs() const {
124
49.8k
  if (!XRayArguments.get())
125
46.7k
    XRayArguments.reset(new XRayArgs(*this, Args));
126
49.8k
  return *XRayArguments.get();
127
49.8k
}
128
129
namespace {
130
131
struct DriverSuffix {
132
  const char *Suffix;
133
  const char *ModeFlag;
134
};
135
136
} // namespace
137
138
131k
static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) {
139
  // A list of known driver suffixes. Suffixes are compared against the
140
  // program name in order. If there is a match, the frontend type is updated as
141
  // necessary by applying the ModeFlag.
142
131k
  static const DriverSuffix DriverSuffixes[] = {
143
131k
      {"clang", nullptr},
144
131k
      {"clang++", "--driver-mode=g++"},
145
131k
      {"clang-c++", "--driver-mode=g++"},
146
131k
      {"clang-cc", nullptr},
147
131k
      {"clang-cpp", "--driver-mode=cpp"},
148
131k
      {"clang-g++", "--driver-mode=g++"},
149
131k
      {"clang-gcc", nullptr},
150
131k
      {"clang-cl", "--driver-mode=cl"},
151
131k
      {"cc", nullptr},
152
131k
      {"cpp", "--driver-mode=cpp"},
153
131k
      {"cl", "--driver-mode=cl"},
154
131k
      {"++", "--driver-mode=g++"},
155
131k
      {"flang", "--driver-mode=flang"},
156
131k
  };
157
158
822k
  for (size_t i = 0; i < llvm::array_lengthof(DriverSuffixes); 
++i690k
) {
159
768k
    StringRef Suffix(DriverSuffixes[i].Suffix);
160
768k
    if (ProgName.endswith(Suffix)) {
161
77.9k
      Pos = ProgName.size() - Suffix.size();
162
77.9k
      return &DriverSuffixes[i];
163
77.9k
    }
164
768k
  }
165
53.1k
  return nullptr;
166
131k
}
167
168
/// Normalize the program name from argv[0] by stripping the file extension if
169
/// present and lower-casing the string on Windows.
170
80.2k
static std::string normalizeProgramName(llvm::StringRef Argv0) {
171
80.2k
  std::string ProgName = std::string(llvm::sys::path::stem(Argv0));
172
#ifdef _WIN32
173
  // Transform to lowercase for case insensitive file systems.
174
  std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(), ::tolower);
175
#endif
176
80.2k
  return ProgName;
177
80.2k
}
178
179
80.2k
static const DriverSuffix *parseDriverSuffix(StringRef ProgName, size_t &Pos) {
180
  // Try to infer frontend type and default target from the program name by
181
  // comparing it against DriverSuffixes in order.
182
183
  // If there is a match, the function tries to identify a target as prefix.
184
  // E.g. "x86_64-linux-clang" as interpreted as suffix "clang" with target
185
  // prefix "x86_64-linux". If such a target prefix is found, it may be
186
  // added via -target as implicit first argument.
187
80.2k
  const DriverSuffix *DS = FindDriverSuffix(ProgName, Pos);
188
189
80.2k
  if (!DS) {
190
    // Try again after stripping any trailing version number:
191
    // clang++3.5 -> clang++
192
25.3k
    ProgName = ProgName.rtrim("0123456789.");
193
25.3k
    DS = FindDriverSuffix(ProgName, Pos);
194
25.3k
  }
195
196
80.2k
  if (!DS) {
197
    // Try again after stripping trailing -component.
198
    // clang++-tot -> clang++
199
25.3k
    ProgName = ProgName.slice(0, ProgName.rfind('-'));
200
25.3k
    DS = FindDriverSuffix(ProgName, Pos);
201
25.3k
  }
202
80.2k
  return DS;
203
80.2k
}
204
205
ParsedClangName
206
80.2k
ToolChain::getTargetAndModeFromProgramName(StringRef PN) {
207
80.2k
  std::string ProgName = normalizeProgramName(PN);
208
80.2k
  size_t SuffixPos;
209
80.2k
  const DriverSuffix *DS = parseDriverSuffix(ProgName, SuffixPos);
210
80.2k
  if (!DS)
211
2.35k
    return {};
212
77.9k
  size_t SuffixEnd = SuffixPos + strlen(DS->Suffix);
213
214
77.9k
  size_t LastComponent = ProgName.rfind('-', SuffixPos);
215
77.9k
  if (LastComponent == std::string::npos)
216
77.9k
    return ParsedClangName(ProgName.substr(0, SuffixEnd), DS->ModeFlag);
217
34
  std::string ModeSuffix = ProgName.substr(LastComponent + 1,
218
34
                                           SuffixEnd - LastComponent - 1);
219
220
  // Infer target from the prefix.
221
34
  StringRef Prefix(ProgName);
222
34
  Prefix = Prefix.slice(0, LastComponent);
223
34
  std::string IgnoredError;
224
34
  bool IsRegistered =
225
34
      llvm::TargetRegistry::lookupTarget(std::string(Prefix), IgnoredError);
226
34
  return ParsedClangName{std::string(Prefix), ModeSuffix, DS->ModeFlag,
227
34
                         IsRegistered};
228
34
}
229
230
24.7k
StringRef ToolChain::getDefaultUniversalArchName() const {
231
  // In universal driver terms, the arch name accepted by -arch isn't exactly
232
  // the same as the ones that appear in the triple. Roughly speaking, this is
233
  // an inverse of the darwin::getArchTypeForDarwinArchName() function.
234
24.7k
  switch (Triple.getArch()) {
235
90
  case llvm::Triple::aarch64: {
236
90
    if (getTriple().isArm64e())
237
3
      return "arm64e";
238
87
    return "arm64";
239
87
  }
240
4
  case llvm::Triple::aarch64_32:
241
4
    return "arm64_32";
242
0
  case llvm::Triple::ppc:
243
0
    return "ppc";
244
0
  case llvm::Triple::ppcle:
245
0
    return "ppcle";
246
0
  case llvm::Triple::ppc64:
247
0
    return "ppc64";
248
0
  case llvm::Triple::ppc64le:
249
0
    return "ppc64le";
250
24.6k
  default:
251
24.6k
    return Triple.getArchName();
252
24.7k
  }
253
24.7k
}
254
255
463
std::string ToolChain::getInputFilename(const InputInfo &Input) const {
256
463
  return Input.getFilename();
257
463
}
258
259
1.13k
bool ToolChain::IsUnwindTablesDefault(const ArgList &Args) const {
260
1.13k
  return false;
261
1.13k
}
262
263
44.6k
Tool *ToolChain::getClang() const {
264
44.6k
  if (!Clang)
265
43.9k
    Clang.reset(new tools::Clang(*this));
266
44.6k
  return Clang.get();
267
44.6k
}
268
269
17
Tool *ToolChain::getFlang() const {
270
17
  if (!Flang)
271
16
    Flang.reset(new tools::Flang(*this));
272
17
  return Flang.get();
273
17
}
274
275
0
Tool *ToolChain::buildAssembler() const {
276
0
  return new tools::ClangAs(*this);
277
0
}
278
279
0
Tool *ToolChain::buildLinker() const {
280
0
  llvm_unreachable("Linking is not supported by this toolchain");
281
0
}
282
283
0
Tool *ToolChain::buildStaticLibTool() const {
284
0
  llvm_unreachable("Creating static lib is not supported by this toolchain");
285
0
}
286
287
813
Tool *ToolChain::getAssemble() const {
288
813
  if (!Assemble)
289
789
    Assemble.reset(buildAssembler());
290
813
  return Assemble.get();
291
813
}
292
293
383
Tool *ToolChain::getClangAs() const {
294
383
  if (!Assemble)
295
367
    Assemble.reset(new tools::ClangAs(*this));
296
383
  return Assemble.get();
297
383
}
298
299
7.26k
Tool *ToolChain::getLink() const {
300
7.26k
  if (!Link)
301
7.09k
    Link.reset(buildLinker());
302
7.26k
  return Link.get();
303
7.26k
}
304
305
7
Tool *ToolChain::getStaticLibTool() const {
306
7
  if (!StaticLibTool)
307
7
    StaticLibTool.reset(buildStaticLibTool());
308
7
  return StaticLibTool.get();
309
7
}
310
311
23
Tool *ToolChain::getIfsMerge() const {
312
23
  if (!IfsMerge)
313
21
    IfsMerge.reset(new tools::ifstool::Merger(*this));
314
23
  return IfsMerge.get();
315
23
}
316
317
64
Tool *ToolChain::getOffloadBundler() const {
318
64
  if (!OffloadBundler)
319
48
    OffloadBundler.reset(new tools::OffloadBundler(*this));
320
64
  return OffloadBundler.get();
321
64
}
322
323
65
Tool *ToolChain::getOffloadWrapper() const {
324
65
  if (!OffloadWrapper)
325
65
    OffloadWrapper.reset(new tools::OffloadWrapper(*this));
326
65
  return OffloadWrapper.get();
327
65
}
328
329
8.28k
Tool *ToolChain::getTool(Action::ActionClass AC) const {
330
8.28k
  switch (AC) {
331
813
  case Action::AssembleJobClass:
332
813
    return getAssemble();
333
334
23
  case Action::IfsMergeJobClass:
335
23
    return getIfsMerge();
336
337
7.26k
  case Action::LinkJobClass:
338
7.26k
    return getLink();
339
340
7
  case Action::StaticLibJobClass:
341
7
    return getStaticLibTool();
342
343
0
  case Action::InputClass:
344
0
  case Action::BindArchClass:
345
0
  case Action::OffloadClass:
346
0
  case Action::LipoJobClass:
347
0
  case Action::DsymutilJobClass:
348
0
  case Action::VerifyDebugInfoJobClass:
349
0
    llvm_unreachable("Invalid tool kind.");
350
351
0
  case Action::CompileJobClass:
352
0
  case Action::PrecompileJobClass:
353
2
  case Action::HeaderModulePrecompileJobClass:
354
2
  case Action::PreprocessJobClass:
355
43
  case Action::AnalyzeJobClass:
356
43
  case Action::MigrateJobClass:
357
45
  case Action::VerifyPCHJobClass:
358
45
  case Action::BackendJobClass:
359
45
    return getClang();
360
361
19
  case Action::OffloadBundlingJobClass:
362
64
  case Action::OffloadUnbundlingJobClass:
363
64
    return getOffloadBundler();
364
365
65
  case Action::OffloadWrapperJobClass:
366
65
    return getOffloadWrapper();
367
0
  }
368
369
0
  llvm_unreachable("Invalid tool kind.");
370
0
}
371
372
static StringRef getArchNameForCompilerRTLib(const ToolChain &TC,
373
947
                                             const ArgList &Args) {
374
947
  const llvm::Triple &Triple = TC.getTriple();
375
947
  bool IsWindows = Triple.isOSWindows();
376
377
947
  if (TC.getArch() == llvm::Triple::arm || 
TC.getArch() == llvm::Triple::armeb884
)
378
67
    return (arm::getARMFloatABI(TC, Args) == arm::FloatABI::Hard && 
!IsWindows24
)
379
12
               ? "armhf"
380
55
               : "arm";
381
382
  // For historic reasons, Android library is using i686 instead of i386.
383
880
  if (TC.getArch() == llvm::Triple::x86 && 
Triple.isAndroid()127
)
384
1
    return "i686";
385
386
879
  return llvm::Triple::getArchTypeName(TC.getArch());
387
879
}
388
389
59.1k
StringRef ToolChain::getOSLibName() const {
390
59.1k
  switch (Triple.getOS()) {
391
567
  case llvm::Triple::FreeBSD:
392
567
    return "freebsd";
393
997
  case llvm::Triple::NetBSD:
394
997
    return "netbsd";
395
207
  case llvm::Triple::OpenBSD:
396
207
    return "openbsd";
397
191
  case llvm::Triple::Solaris:
398
191
    return "sunos";
399
201
  case llvm::Triple::AIX:
400
201
    return "aix";
401
56.9k
  default:
402
56.9k
    return getOS();
403
59.1k
  }
404
59.1k
}
405
406
10.7k
std::string ToolChain::getCompilerRTPath() const {
407
10.7k
  SmallString<128> Path(getDriver().ResourceDir);
408
10.7k
  if (Triple.isOSUnknown()) {
409
514
    llvm::sys::path::append(Path, "lib");
410
10.2k
  } else {
411
10.2k
    llvm::sys::path::append(Path, "lib", getOSLibName());
412
10.2k
  }
413
10.7k
  return std::string(Path.str());
414
10.7k
}
415
416
std::string ToolChain::getCompilerRTBasename(const ArgList &Args,
417
                                             StringRef Component, FileType Type,
418
1.92k
                                             bool AddArch) const {
419
1.92k
  const llvm::Triple &TT = getTriple();
420
1.92k
  bool IsITANMSVCWindows =
421
1.92k
      TT.isWindowsMSVCEnvironment() || 
TT.isWindowsItaniumEnvironment()1.78k
;
422
423
1.92k
  const char *Prefix =
424
1.92k
      IsITANMSVCWindows || 
Type == ToolChain::FT_Object1.75k
?
""233
:
"lib"1.69k
;
425
1.92k
  const char *Suffix;
426
1.92k
  switch (Type) {
427
60
  case ToolChain::FT_Object:
428
60
    Suffix = IsITANMSVCWindows ? 
".obj"0
: ".o";
429
60
    break;
430
1.78k
  case ToolChain::FT_Static:
431
1.61k
    Suffix = IsITANMSVCWindows ? 
".lib"173
: ".a";
432
1.78k
    break;
433
78
  case ToolChain::FT_Shared:
434
78
    Suffix = Triple.isOSWindows()
435
4
                 ? (Triple.isWindowsGNUEnvironment() ? ".dll.a" : 
".lib"0
)
436
74
                 : ".so";
437
78
    break;
438
1.92k
  }
439
440
1.92k
  std::string ArchAndEnv;
441
1.92k
  if (AddArch) {
442
947
    StringRef Arch = getArchNameForCompilerRTLib(*this, Args);
443
918
    const char *Env = TT.isAndroid() ? 
"-android"29
: "";
444
947
    ArchAndEnv = ("-" + Arch + Env).str();
445
947
  }
446
1.92k
  return (Prefix + Twine("clang_rt.") + Component + ArchAndEnv + Suffix).str();
447
1.92k
}
448
449
std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
450
979
                                     FileType Type) const {
451
  // Check for runtime files in the new layout without the architecture first.
452
979
  std::string CRTBasename =
453
979
      getCompilerRTBasename(Args, Component, Type, /*AddArch=*/false);
454
58
  for (const auto &LibPath : getLibraryPaths()) {
455
58
    SmallString<128> P(LibPath);
456
58
    llvm::sys::path::append(P, CRTBasename);
457
58
    if (getVFS().exists(P))
458
54
      return std::string(P.str());
459
58
  }
460
461
  // Fall back to the old expected compiler-rt name if the new one does not
462
  // exist.
463
925
  CRTBasename = getCompilerRTBasename(Args, Component, Type, /*AddArch=*/true);
464
925
  SmallString<128> Path(getCompilerRTPath());
465
925
  llvm::sys::path::append(Path, CRTBasename);
466
925
  return std::string(Path.str());
467
979
}
468
469
const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args,
470
                                              StringRef Component,
471
616
                                              FileType Type) const {
472
616
  return Args.MakeArgString(getCompilerRT(Args, Component, Type));
473
616
}
474
475
476
48.8k
Optional<std::string> ToolChain::getRuntimePath() const {
477
48.8k
  SmallString<128> P;
478
479
  // First try the triple passed to driver as --target=<triple>.
480
48.8k
  P.assign(D.ResourceDir);
481
48.8k
  llvm::sys::path::append(P, "lib", D.getTargetTriple());
482
48.8k
  if (getVFS().exists(P))
483
35
    return llvm::Optional<std::string>(std::string(P.str()));
484
485
  // Second try the normalized triple.
486
48.8k
  P.assign(D.ResourceDir);
487
48.8k
  llvm::sys::path::append(P, "lib", Triple.str());
488
48.8k
  if (getVFS().exists(P))
489
0
    return llvm::Optional<std::string>(std::string(P.str()));
490
491
48.8k
  return None;
492
48.8k
}
493
494
6.60k
Optional<std::string> ToolChain::getCXXStdlibPath() const {
495
6.60k
  SmallString<128> P;
496
497
  // First try the triple passed to driver as --target=<triple>.
498
6.60k
  P.assign(D.Dir);
499
6.60k
  llvm::sys::path::append(P, "..", "lib", D.getTargetTriple(), "c++");
500
6.60k
  if (getVFS().exists(P))
501
62
    return llvm::Optional<std::string>(std::string(P.str()));
502
503
  // Second try the normalized triple.
504
6.54k
  P.assign(D.Dir);
505
6.54k
  llvm::sys::path::append(P, "..", "lib", Triple.str(), "c++");
506
6.54k
  if (getVFS().exists(P))
507
0
    return llvm::Optional<std::string>(std::string(P.str()));
508
509
6.54k
  return None;
510
6.54k
}
511
512
48.8k
std::string ToolChain::getArchSpecificLibPath() const {
513
48.8k
  SmallString<128> Path(getDriver().ResourceDir);
514
48.8k
  llvm::sys::path::append(Path, "lib", getOSLibName(),
515
48.8k
                          llvm::Triple::getArchTypeName(getArch()));
516
48.8k
  return std::string(Path.str());
517
48.8k
}
518
519
7.36k
bool ToolChain::needsProfileRT(const ArgList &Args) {
520
7.36k
  if (Args.hasArg(options::OPT_noprofilelib))
521
4
    return false;
522
523
7.36k
  return Args.hasArg(options::OPT_fprofile_generate) ||
524
7.36k
         Args.hasArg(options::OPT_fprofile_generate_EQ) ||
525
7.36k
         Args.hasArg(options::OPT_fcs_profile_generate) ||
526
7.36k
         Args.hasArg(options::OPT_fcs_profile_generate_EQ) ||
527
7.36k
         Args.hasArg(options::OPT_fprofile_instr_generate) ||
528
7.31k
         Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
529
7.31k
         Args.hasArg(options::OPT_fcreate_profile) ||
530
7.31k
         Args.hasArg(options::OPT_forder_file_instrumentation);
531
7.36k
}
532
533
49.5k
bool ToolChain::needsGCovInstrumentation(const llvm::opt::ArgList &Args) {
534
49.5k
  return Args.hasArg(options::OPT_coverage) ||
535
49.5k
         Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
536
49.5k
                      false);
537
49.5k
}
538
539
53.3k
Tool *ToolChain::SelectTool(const JobAction &JA) const {
540
53.3k
  if (D.IsFlangMode() && 
getDriver().ShouldUseFlangCompiler(JA)20
)
return getFlang()17
;
541
53.3k
  if (getDriver().ShouldUseClangCompiler(JA)) 
return getClang()44.5k
;
542
8.77k
  Action::ActionClass AC = JA.getKind();
543
8.77k
  if (AC == Action::AssembleJobClass && 
useIntegratedAs()1.19k
)
544
383
    return getClangAs();
545
8.38k
  return getTool(AC);
546
8.38k
}
547
548
9.40k
std::string ToolChain::GetFilePath(const char *Name) const {
549
9.40k
  return D.GetFilePath(Name, *this);
550
9.40k
}
551
552
8.66k
std::string ToolChain::GetProgramPath(const char *Name) const {
553
8.66k
  return D.GetProgramPath(Name, *this);
554
8.66k
}
555
556
std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD,
557
6.11k
                                     bool *LinkerIsLLDDarwinNew) const {
558
6.11k
  if (LinkerIsLLD)
559
3.51k
    *LinkerIsLLD = false;
560
6.11k
  if (LinkerIsLLDDarwinNew)
561
3.51k
    *LinkerIsLLDDarwinNew = false;
562
563
  // Get -fuse-ld= first to prevent -Wunused-command-line-argument. -fuse-ld= is
564
  // considered as the linker flavor, e.g. "bfd", "gold", or "lld".
565
6.11k
  const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ);
566
5.76k
  StringRef UseLinker = A ? 
A->getValue()345
: CLANG_DEFAULT_LINKER;
567
568
  // --ld-path= takes precedence over -fuse-ld= and specifies the executable
569
  // name. -B, COMPILER_PATH and PATH and consulted if the value does not
570
  // contain a path component separator.
571
6.11k
  if (const Arg *A = Args.getLastArg(options::OPT_ld_path_EQ)) {
572
11
    std::string Path(A->getValue());
573
11
    if (!Path.empty()) {
574
10
      if (llvm::sys::path::parent_path(Path).empty())
575
5
        Path = GetProgramPath(A->getValue());
576
10
      if (llvm::sys::fs::can_execute(Path))
577
8
        return std::string(Path);
578
3
    }
579
3
    getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
580
3
    return GetProgramPath(getDefaultLinker());
581
3
  }
582
  // If we're passed -fuse-ld= with no argument, or with the argument ld,
583
  // then use whatever the default system linker is.
584
6.10k
  if (UseLinker.empty() || 
UseLinker == "ld"277
) {
585
5.96k
    const char *DefaultLinker = getDefaultLinker();
586
5.96k
    if (llvm::sys::path::is_absolute(DefaultLinker))
587
22
      return std::string(DefaultLinker);
588
5.94k
    else
589
5.94k
      return GetProgramPath(DefaultLinker);
590
140
  }
591
592
  // Extending -fuse-ld= to an absolute or relative path is unexpected. Checking
593
  // for the linker flavor is brittle. In addition, prepending "ld." or "ld64."
594
  // to a relative path is surprising. This is more complex due to priorities
595
  // among -B, COMPILER_PATH and PATH. --ld-path= should be used instead.
596
140
  if (UseLinker.find('/') != StringRef::npos)
597
3
    getDriver().Diag(diag::warn_drv_fuse_ld_path);
598
599
140
  if (llvm::sys::path::is_absolute(UseLinker)) {
600
    // If we're passed what looks like an absolute path, don't attempt to
601
    // second-guess that.
602
3
    if (llvm::sys::fs::can_execute(UseLinker))
603
0
      return std::string(UseLinker);
604
137
  } else {
605
137
    llvm::SmallString<8> LinkerName;
606
137
    if (Triple.isOSDarwin())
607
8
      LinkerName.append("ld64.");
608
129
    else
609
129
      LinkerName.append("ld.");
610
137
    LinkerName.append(UseLinker);
611
612
137
    std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
613
137
    if (llvm::sys::fs::can_execute(LinkerPath)) {
614
      // FIXME: Remove lld.darwinnew here once it's the only MachO lld.
615
56
      if (LinkerIsLLD)
616
8
        *LinkerIsLLD = UseLinker == "lld" || 
UseLinker == "lld.darwinnew"7
;
617
56
      if (LinkerIsLLDDarwinNew)
618
8
        *LinkerIsLLDDarwinNew = UseLinker == "lld.darwinnew";
619
56
      return LinkerPath;
620
56
    }
621
84
  }
622
623
84
  if (A)
624
84
    getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
625
626
84
  return GetProgramPath(getDefaultLinker());
627
84
}
628
629
4
std::string ToolChain::GetStaticLibToolPath() const {
630
  // TODO: Add support for static lib archiving on Windows
631
4
  return GetProgramPath("llvm-ar");
632
4
}
633
634
42.7k
types::ID ToolChain::LookupTypeForExtension(StringRef Ext) const {
635
42.7k
  types::ID id = types::lookupTypeForExtension(Ext);
636
637
  // Flang always runs the preprocessor and has no notion of "preprocessed
638
  // fortran". Here, TY_PP_Fortran is coerced to TY_Fortran to avoid treating
639
  // them differently.
640
42.7k
  if (D.IsFlangMode() && 
id == types::TY_PP_Fortran18
)
641
10
    id = types::TY_Fortran;
642
643
42.7k
  return id;
644
42.7k
}
645
646
573
bool ToolChain::HasNativeLLVMSupport() const {
647
573
  return false;
648
573
}
649
650
2.38k
bool ToolChain::isCrossCompiling() const {
651
2.38k
  llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
652
2.38k
  switch (HostTriple.getArch()) {
653
  // The A32/T32/T16 instruction sets are not separate architectures in this
654
  // context.
655
0
  case llvm::Triple::arm:
656
0
  case llvm::Triple::armeb:
657
0
  case llvm::Triple::thumb:
658
0
  case llvm::Triple::thumbeb:
659
0
    return getArch() != llvm::Triple::arm && getArch() != llvm::Triple::thumb &&
660
0
           getArch() != llvm::Triple::armeb && getArch() != llvm::Triple::thumbeb;
661
2.38k
  default:
662
2.38k
    return HostTriple.getArch() != getArch();
663
2.38k
  }
664
2.38k
}
665
666
25.9k
ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const {
667
24.5k
  return ObjCRuntime(isNonFragile ? 
ObjCRuntime::GNUstep1.43k
: ObjCRuntime::GCC,
668
25.9k
                     VersionTuple());
669
25.9k
}
670
671
llvm::ExceptionHandling
672
25.4k
ToolChain::GetExceptionModel(const llvm::opt::ArgList &Args) const {
673
25.4k
  return llvm::ExceptionHandling::None;
674
25.4k
}
675
676
14
bool ToolChain::isThreadModelSupported(const StringRef Model) const {
677
14
  if (Model == "single") {
678
    // FIXME: 'single' is only supported on ARM and WebAssembly so far.
679
5
    return Triple.getArch() == llvm::Triple::arm ||
680
2
           Triple.getArch() == llvm::Triple::armeb ||
681
2
           Triple.getArch() == llvm::Triple::thumb ||
682
2
           Triple.getArch() == llvm::Triple::thumbeb || Triple.isWasm();
683
9
  } else if (Model == "posix")
684
5
    return true;
685
686
4
  return false;
687
4
}
688
689
std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
690
53.5k
                                         types::ID InputType) const {
691
53.5k
  switch (getTriple().getArch()) {
692
16.2k
  default:
693
16.2k
    return getTripleString();
694
695
33.5k
  case llvm::Triple::x86_64: {
696
33.5k
    llvm::Triple Triple = getTriple();
697
33.5k
    if (!Triple.isOSBinFormatMachO())
698
11.6k
      return getTripleString();
699
700
21.8k
    if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
701
      // x86_64h goes in the triple. Other -march options just use the
702
      // vanilla triple we already have.
703
2
      StringRef MArch = A->getValue();
704
2
      if (MArch == "x86_64h")
705
0
        Triple.setArchName(MArch);
706
2
    }
707
21.8k
    return Triple.getTriple();
708
21.8k
  }
709
1.26k
  case llvm::Triple::aarch64: {
710
1.26k
    llvm::Triple Triple = getTriple();
711
1.26k
    if (!Triple.isOSBinFormatMachO())
712
1.12k
      return getTripleString();
713
714
145
    if (Triple.isArm64e())
715
4
      return getTripleString();
716
717
    // FIXME: older versions of ld64 expect the "arm64" component in the actual
718
    // triple string and query it to determine whether an LTO file can be
719
    // handled. Remove this when we don't care any more.
720
141
    Triple.setArchName("arm64");
721
141
    return Triple.getTriple();
722
141
  }
723
9
  case llvm::Triple::aarch64_32:
724
9
    return getTripleString();
725
2.31k
  case llvm::Triple::arm:
726
2.47k
  case llvm::Triple::armeb:
727
2.53k
  case llvm::Triple::thumb:
728
2.56k
  case llvm::Triple::thumbeb: {
729
    // FIXME: Factor into subclasses.
730
2.56k
    llvm::Triple Triple = getTriple();
731
2.56k
    bool IsBigEndian = getTriple().getArch() == llvm::Triple::armeb ||
732
2.40k
                       getTriple().getArch() == llvm::Triple::thumbeb;
733
734
    // Handle pseudo-target flags '-mlittle-endian'/'-EL' and
735
    // '-mbig-endian'/'-EB'.
736
2.56k
    if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
737
248
                                 options::OPT_mbig_endian)) {
738
248
      IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);
739
248
    }
740
741
    // Thumb2 is the default for V7 on Darwin.
742
    //
743
    // FIXME: Thumb should just be another -target-feaure, not in the triple.
744
2.56k
    StringRef MCPU, MArch;
745
2.56k
    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
746
569
      MCPU = A->getValue();
747
2.56k
    if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
748
855
      MArch = A->getValue();
749
2.56k
    std::string CPU =
750
2.56k
        Triple.isOSBinFormatMachO()
751
430
            ? tools::arm::getARMCPUForMArch(MArch, Triple).str()
752
2.13k
            : tools::arm::getARMTargetCPU(MCPU, MArch, Triple);
753
2.56k
    StringRef Suffix =
754
2.56k
      tools::arm::getLLVMArchSuffixForARM(CPU, MArch, Triple);
755
2.56k
    bool IsMProfile = ARM::parseArchProfile(Suffix) == ARM::ProfileKind::M;
756
2.56k
    bool ThumbDefault = IsMProfile || 
(2.27k
ARM::parseArchVersion(Suffix) == 72.27k
&&
757
916
                                       getTriple().isOSBinFormatMachO());
758
    // FIXME: this is invalid for WindowsCE
759
2.56k
    if (getTriple().isOSWindows())
760
81
      ThumbDefault = true;
761
2.56k
    std::string ArchName;
762
2.56k
    if (IsBigEndian)
763
302
      ArchName = "armeb";
764
2.25k
    else
765
2.25k
      ArchName = "arm";
766
767
    // Check if ARM ISA was explicitly selected (using -mno-thumb or -marm) for
768
    // M-Class CPUs/architecture variants, which is not supported.
769
2.56k
    bool ARMModeRequested = !Args.hasFlag(options::OPT_mthumb,
770
2.56k
                                          options::OPT_mno_thumb, ThumbDefault);
771
2.56k
    if (IsMProfile && 
ARMModeRequested288
) {
772
6
      if (!MCPU.empty())
773
2
        getDriver().Diag(diag::err_cpu_unsupported_isa) << CPU << "ARM";
774
4
       else
775
4
        getDriver().Diag(diag::err_arch_unsupported_isa)
776
4
          << tools::arm::getARMArch(MArch, getTriple()) << "ARM";
777
6
    }
778
779
    // Check to see if an explicit choice to use thumb has been made via
780
    // -mthumb. For assembler files we must check for -mthumb in the options
781
    // passed to the assembler via -Wa or -Xassembler.
782
2.56k
    bool IsThumb = false;
783
2.56k
    if (InputType != types::TY_PP_Asm)
784
2.46k
      IsThumb = Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb,
785
2.46k
                              ThumbDefault);
786
101
    else {
787
      // Ideally we would check for these flags in
788
      // CollectArgsForIntegratedAssembler but we can't change the ArchName at
789
      // that point. There is no assembler equivalent of -mno-thumb, -marm, or
790
      // -mno-arm.
791
101
      for (const auto *A :
792
14
           Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
793
14
        for (StringRef Value : A->getValues()) {
794
14
          if (Value == "-mthumb")
795
2
            IsThumb = true;
796
14
        }
797
14
      }
798
101
    }
799
    // Assembly files should start in ARM mode, unless arch is M-profile, or
800
    // -mthumb has been passed explicitly to the assembler. Windows is always
801
    // thumb.
802
2.56k
    if (IsThumb || 
IsMProfile1.60k
||
getTriple().isOSWindows()1.58k
) {
803
979
      if (IsBigEndian)
804
104
        ArchName = "thumbeb";
805
875
      else
806
875
        ArchName = "thumb";
807
979
    }
808
2.56k
    Triple.setArchName(ArchName + Suffix.str());
809
810
2.56k
    bool isHardFloat =
811
2.56k
        (arm::getARMFloatABI(getDriver(), Triple, Args) == arm::FloatABI::Hard);
812
2.56k
    switch (Triple.getEnvironment()) {
813
318
    case Triple::GNUEABI:
814
411
    case Triple::GNUEABIHF:
815
314
      Triple.setEnvironment(isHardFloat ? 
Triple::GNUEABIHF97
: Triple::GNUEABI);
816
411
      break;
817
705
    case Triple::EABI:
818
724
    case Triple::EABIHF:
819
688
      Triple.setEnvironment(isHardFloat ? 
Triple::EABIHF36
: Triple::EABI);
820
724
      break;
821
20
    case Triple::MuslEABI:
822
36
    case Triple::MuslEABIHF:
823
24
      Triple.setEnvironment(isHardFloat ? Triple::MuslEABIHF
824
12
                                        : Triple::MuslEABI);
825
36
      break;
826
1.39k
    default: {
827
1.39k
      arm::FloatABI DefaultABI = arm::getDefaultFloatABI(Triple);
828
1.39k
      if (DefaultABI != arm::FloatABI::Invalid &&
829
665
          isHardFloat != (DefaultABI == arm::FloatABI::Hard)) {
830
16
        Arg *ABIArg =
831
16
            Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
832
16
                            options::OPT_mfloat_abi_EQ);
833
16
        assert(ABIArg && "Non-default float abi expected to be from arg");
834
16
        D.Diag(diag::err_drv_unsupported_opt_for_target)
835
16
            << ABIArg->getAsString(Args) << Triple.getTriple();
836
16
      }
837
1.39k
      break;
838
2.56k
    }
839
2.56k
    }
840
841
2.56k
    return Triple.getTriple();
842
2.56k
  }
843
53.5k
  }
844
53.5k
}
845
846
std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
847
30.8k
                                                   types::ID InputType) const {
848
30.8k
  return ComputeLLVMTriple(Args, InputType);
849
30.8k
}
850
851
12
std::string ToolChain::computeSysRoot() const {
852
12
  return D.SysRoot;
853
12
}
854
855
void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
856
11.9k
                                          ArgStringList &CC1Args) const {
857
  // Each toolchain should provide the appropriate include flags.
858
11.9k
}
859
860
void ToolChain::addClangTargetOptions(
861
    const ArgList &DriverArgs, ArgStringList &CC1Args,
862
8.03k
    Action::OffloadKind DeviceOffloadKind) const {}
863
864
25.8k
void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {}
865
866
void ToolChain::addProfileRTLibs(const llvm::opt::ArgList &Args,
867
2.29k
                                 llvm::opt::ArgStringList &CmdArgs) const {
868
2.29k
  if (!needsProfileRT(Args) && 
!needsGCovInstrumentation(Args)2.27k
)
869
2.27k
    return;
870
871
24
  CmdArgs.push_back(getCompilerRTArgString(Args, "profile"));
872
24
}
873
874
ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
875
10.2k
    const ArgList &Args) const {
876
10.2k
  const Arg* A = Args.getLastArg(options::OPT_rtlib_EQ);
877
9.11k
  StringRef LibName = A ? 
A->getValue()1.10k
: CLANG_DEFAULT_RTLIB;
878
879
  // Only use "platform" in tests to override CLANG_DEFAULT_RTLIB!
880
10.2k
  if (LibName == "compiler-rt")
881
127
    return ToolChain::RLT_CompilerRT;
882
10.0k
  else if (LibName == "libgcc")
883
82
    return ToolChain::RLT_Libgcc;
884
10.0k
  else if (LibName == "platform")
885
894
    return GetDefaultRuntimeLibType();
886
887
9.11k
  if (A)
888
6
    getDriver().Diag(diag::err_drv_invalid_rtlib_name) << A->getAsString(Args);
889
890
9.11k
  return GetDefaultRuntimeLibType();
891
9.11k
}
892
893
ToolChain::UnwindLibType ToolChain::GetUnwindLibType(
894
3.14k
    const ArgList &Args) const {
895
3.14k
  const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
896
3.12k
  StringRef LibName = A ? 
A->getValue()15
: CLANG_DEFAULT_UNWINDLIB;
897
898
3.14k
  if (LibName == "none")
899
0
    return ToolChain::UNW_None;
900
3.14k
  else if (LibName == "platform" || LibName == "") {
901
3.12k
    ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args);
902
3.12k
    if (RtLibType == ToolChain::RLT_CompilerRT)
903
136
      return ToolChain::UNW_None;
904
2.99k
    else if (RtLibType == ToolChain::RLT_Libgcc)
905
2.99k
      return ToolChain::UNW_Libgcc;
906
15
  } else if (LibName == "libunwind") {
907
12
    if (GetRuntimeLibType(Args) == RLT_Libgcc)
908
6
      getDriver().Diag(diag::err_drv_incompatible_unwindlib);
909
12
    return ToolChain::UNW_CompilerRT;
910
3
  } else if (LibName == "libgcc")
911
3
    return ToolChain::UNW_Libgcc;
912
913
0
  if (A)
914
0
    getDriver().Diag(diag::err_drv_invalid_unwindlib_name)
915
0
        << A->getAsString(Args);
916
917
0
  return GetDefaultUnwindLibType();
918
0
}
919
920
69.6k
ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
921
69.6k
  const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
922
38.2k
  StringRef LibName = A ? A->getValue() : 
CLANG_DEFAULT_CXX_STDLIB31.4k
;
923
924
  // Only use "platform" in tests to override CLANG_DEFAULT_CXX_STDLIB!
925
69.6k
  if (LibName == "libc++")
926
37.9k
    return ToolChain::CST_Libcxx;
927
31.7k
  else if (LibName == "libstdc++")
928
245
    return ToolChain::CST_Libstdcxx;
929
31.5k
  else if (LibName == "platform")
930
119
    return GetDefaultCXXStdlibType();
931
932
31.4k
  if (A)
933
0
    getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
934
935
31.4k
  return GetDefaultCXXStdlibType();
936
31.4k
}
937
938
/// Utility function to add a system include directory to CC1 arguments.
939
/*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs,
940
                                            ArgStringList &CC1Args,
941
64.2k
                                            const Twine &Path) {
942
64.2k
  CC1Args.push_back("-internal-isystem");
943
64.2k
  CC1Args.push_back(DriverArgs.MakeArgString(Path));
944
64.2k
}
945
946
/// Utility function to add a system include directory with extern "C"
947
/// semantics to CC1 arguments.
948
///
949
/// Note that this should be used rarely, and only for directories that
950
/// historically and for legacy reasons are treated as having implicit extern
951
/// "C" semantics. These semantics are *ignored* by and large today, but its
952
/// important to preserve the preprocessor changes resulting from the
953
/// classification.
954
/*static*/ void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs,
955
                                                   ArgStringList &CC1Args,
956
30.0k
                                                   const Twine &Path) {
957
30.0k
  CC1Args.push_back("-internal-externc-isystem");
958
30.0k
  CC1Args.push_back(DriverArgs.MakeArgString(Path));
959
30.0k
}
960
961
void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs,
962
                                                ArgStringList &CC1Args,
963
300
                                                const Twine &Path) {
964
300
  if (llvm::sys::fs::exists(Path))
965
296
    addExternCSystemInclude(DriverArgs, CC1Args, Path);
966
300
}
967
968
/// Utility function to add a list of system include directories to CC1.
969
/*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs,
970
                                             ArgStringList &CC1Args,
971
0
                                             ArrayRef<StringRef> Paths) {
972
0
  for (const auto &Path : Paths) {
973
0
    CC1Args.push_back("-internal-isystem");
974
0
    CC1Args.push_back(DriverArgs.MakeArgString(Path));
975
0
  }
976
0
}
977
978
void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
979
13.0k
                                             ArgStringList &CC1Args) const {
980
  // Header search paths should be handled by each of the subclasses.
981
  // Historically, they have not been, and instead have been handled inside of
982
  // the CC1-layer frontend. As the logic is hoisted out, this generic function
983
  // will slowly stop being called.
984
  //
985
  // While it is being called, replicate a bit of a hack to propagate the
986
  // '-stdlib=' flag down to CC1 so that it can in turn customize the C++
987
  // header search paths with it. Once all systems are overriding this
988
  // function, the CC1 flag and this line can be removed.
989
13.0k
  DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
990
13.0k
}
991
992
void ToolChain::AddClangCXXStdlibIsystemArgs(
993
    const llvm::opt::ArgList &DriverArgs,
994
8
    llvm::opt::ArgStringList &CC1Args) const {
995
8
  DriverArgs.ClaimAllArgs(options::OPT_stdlibxx_isystem);
996
8
  if (!DriverArgs.hasArg(options::OPT_nostdincxx))
997
6
    for (const auto &P :
998
6
         DriverArgs.getAllArgValues(options::OPT_stdlibxx_isystem))
999
10
      addSystemInclude(DriverArgs, CC1Args, P);
1000
8
}
1001
1002
4.01k
bool ToolChain::ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const {
1003
4.01k
  return getDriver().CCCIsCXX() &&
1004
2.89k
         !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
1005
2.89k
                      options::OPT_nostdlibxx);
1006
4.01k
}
1007
1008
void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
1009
75
                                    ArgStringList &CmdArgs) const {
1010
75
  assert(!Args.hasArg(options::OPT_nostdlibxx) &&
1011
75
         "should not have called this");
1012
75
  CXXStdlibType Type = GetCXXStdlibType(Args);
1013
1014
75
  switch (Type) {
1015
30
  case ToolChain::CST_Libcxx:
1016
30
    CmdArgs.push_back("-lc++");
1017
30
    break;
1018
1019
45
  case ToolChain::CST_Libstdcxx:
1020
45
    CmdArgs.push_back("-lstdc++");
1021
45
    break;
1022
75
  }
1023
75
}
1024
1025
void ToolChain::AddFilePathLibArgs(const ArgList &Args,
1026
2.19k
                                   ArgStringList &CmdArgs) const {
1027
2.19k
  for (const auto &LibPath : getFilePaths())
1028
5.56k
    if(LibPath.length() > 0)
1029
5.50k
      CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
1030
2.19k
}
1031
1032
void ToolChain::AddCCKextLibArgs(const ArgList &Args,
1033
0
                                 ArgStringList &CmdArgs) const {
1034
0
  CmdArgs.push_back("-lcc_kext");
1035
0
}
1036
1037
bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args,
1038
6.77k
                                           std::string &Path) const {
1039
  // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed
1040
  // (to keep the linker options consistent with gcc and clang itself).
1041
6.77k
  if (!isOptimizationLevelFast(Args)) {
1042
    // Check if -ffast-math or -funsafe-math.
1043
6.75k
    Arg *A =
1044
6.75k
      Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
1045
6.75k
                      options::OPT_funsafe_math_optimizations,
1046
6.75k
                      options::OPT_fno_unsafe_math_optimizations);
1047
1048
6.75k
    if (!A || 
A->getOption().getID() == options::OPT_fno_fast_math20
||
1049
13
        A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
1050
6.74k
      return false;
1051
39
  }
1052
  // If crtfastmath.o exists add it to the arguments.
1053
39
  Path = GetFilePath("crtfastmath.o");
1054
39
  return (Path != "crtfastmath.o"); // Not found.
1055
39
}
1056
1057
bool ToolChain::addFastMathRuntimeIfAvailable(const ArgList &Args,
1058
1.57k
                                              ArgStringList &CmdArgs) const {
1059
1.57k
  std::string Path;
1060
1.57k
  if (isFastMathRuntimeAvailable(Args, Path)) {
1061
9
    CmdArgs.push_back(Args.MakeArgString(Path));
1062
9
    return true;
1063
9
  }
1064
1065
1.56k
  return false;
1066
1.56k
}
1067
1068
46.9k
SanitizerMask ToolChain::getSupportedSanitizers() const {
1069
  // Return sanitizers which don't require runtime support and are not
1070
  // platform dependent.
1071
1072
46.9k
  SanitizerMask Res =
1073
46.9k
      (SanitizerKind::Undefined & ~SanitizerKind::Vptr &
1074
46.9k
       ~SanitizerKind::Function) |
1075
46.9k
      (SanitizerKind::CFI & ~SanitizerKind::CFIICall) |
1076
46.9k
      SanitizerKind::CFICastStrict | SanitizerKind::FloatDivideByZero |
1077
46.9k
      SanitizerKind::UnsignedIntegerOverflow |
1078
46.9k
      SanitizerKind::UnsignedShiftBase | SanitizerKind::ImplicitConversion |
1079
46.9k
      SanitizerKind::Nullability | SanitizerKind::LocalBounds;
1080
46.9k
  if (getTriple().getArch() == llvm::Triple::x86 ||
1081
36.7k
      getTriple().getArch() == llvm::Triple::x86_64 ||
1082
5.24k
      getTriple().getArch() == llvm::Triple::arm || 
getTriple().isWasm()3.63k
||
1083
3.55k
      getTriple().isAArch64())
1084
44.5k
    Res |= SanitizerKind::CFIICall;
1085
46.9k
  if (getTriple().getArch() == llvm::Triple::x86_64 ||
1086
15.4k
      getTriple().isAArch64(64) || 
getTriple().isRISCV()14.2k
)
1087
33.0k
    Res |= SanitizerKind::ShadowCallStack;
1088
46.9k
  if (getTriple().isAArch64(64))
1089
1.19k
    Res |= SanitizerKind::MemTag;
1090
46.9k
  return Res;
1091
46.9k
}
1092
1093
void ToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
1094
4
                                   ArgStringList &CC1Args) const {}
1095
1096
void ToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs,
1097
1
                                  ArgStringList &CC1Args) const {}
1098
1099
void ToolChain::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
1100
0
                                    ArgStringList &CC1Args) const {}
1101
1102
38
static VersionTuple separateMSVCFullVersion(unsigned Version) {
1103
38
  if (Version < 100)
1104
2
    return VersionTuple(Version);
1105
1106
36
  if (Version < 10000)
1107
34
    return VersionTuple(Version / 100, Version % 100);
1108
1109
2
  unsigned Build = 0, Factor = 1;
1110
12
  for (; Version > 10000; 
Version = Version / 10, Factor = Factor * 1010
)
1111
10
    Build = Build + (Version % 10) * Factor;
1112
2
  return VersionTuple(Version / 100, Version % 100, Build);
1113
2
}
1114
1115
VersionTuple
1116
ToolChain::computeMSVCVersion(const Driver *D,
1117
52.6k
                              const llvm::opt::ArgList &Args) const {
1118
52.6k
  const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version);
1119
52.6k
  const Arg *MSCompatibilityVersion =
1120
52.6k
      Args.getLastArg(options::OPT_fms_compatibility_version);
1121
1122
52.6k
  if (MSCVersion && 
MSCompatibilityVersion40
) {
1123
2
    if (D)
1124
1
      D->Diag(diag::err_drv_argument_not_allowed_with)
1125
1
          << MSCVersion->getAsString(Args)
1126
1
          << MSCompatibilityVersion->getAsString(Args);
1127
2
    return VersionTuple();
1128
2
  }
1129
1130
52.6k
  if (MSCompatibilityVersion) {
1131
22
    VersionTuple MSVT;
1132
22
    if (MSVT.tryParse(MSCompatibilityVersion->getValue())) {
1133
0
      if (D)
1134
0
        D->Diag(diag::err_drv_invalid_value)
1135
0
            << MSCompatibilityVersion->getAsString(Args)
1136
0
            << MSCompatibilityVersion->getValue();
1137
22
    } else {
1138
22
      return MSVT;
1139
22
    }
1140
52.6k
  }
1141
1142
52.6k
  if (MSCVersion) {
1143
38
    unsigned Version = 0;
1144
38
    if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version)) {
1145
0
      if (D)
1146
0
        D->Diag(diag::err_drv_invalid_value)
1147
0
            << MSCVersion->getAsString(Args) << MSCVersion->getValue();
1148
38
    } else {
1149
38
      return separateMSVCFullVersion(Version);
1150
38
    }
1151
52.6k
  }
1152
1153
52.6k
  return VersionTuple();
1154
52.6k
}
1155
1156
llvm::opt::DerivedArgList *ToolChain::TranslateOpenMPTargetArgs(
1157
    const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost,
1158
84
    SmallVectorImpl<llvm::opt::Arg *> &AllocatedArgs) const {
1159
84
  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
1160
84
  const OptTable &Opts = getDriver().getOpts();
1161
84
  bool Modified = false;
1162
1163
  // Handle -Xopenmp-target flags
1164
736
  for (auto *A : Args) {
1165
    // Exclude flags which may only apply to the host toolchain.
1166
    // Do not exclude flags when the host triple (AuxTriple)
1167
    // matches the current toolchain triple. If it is not present
1168
    // at all, target and host share a toolchain.
1169
736
    if (A->getOption().matches(options::OPT_m_Group)) {
1170
4
      if (SameTripleAsHost)
1171
1
        DAL->append(A);
1172
3
      else
1173
3
        Modified = true;
1174
4
      continue;
1175
4
    }
1176
1177
732
    unsigned Index;
1178
732
    unsigned Prev;
1179
732
    bool XOpenMPTargetNoTriple =
1180
732
        A->getOption().matches(options::OPT_Xopenmp_target);
1181
1182
732
    if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) {
1183
      // Passing device args: -Xopenmp-target=<triple> -opt=val.
1184
3
      if (A->getValue(0) == getTripleString())
1185
2
        Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
1186
1
      else
1187
1
        continue;
1188
729
    } else if (XOpenMPTargetNoTriple) {
1189
      // Passing device args: -Xopenmp-target -opt=val.
1190
44
      Index = Args.getBaseArgs().MakeIndex(A->getValue(0));
1191
685
    } else {
1192
685
      DAL->append(A);
1193
685
      continue;
1194
685
    }
1195
1196
    // Parse the argument to -Xopenmp-target.
1197
46
    Prev = Index;
1198
46
    std::unique_ptr<Arg> XOpenMPTargetArg(Opts.ParseOneArg(Args, Index));
1199
46
    if (!XOpenMPTargetArg || 
Index > Prev + 145
) {
1200
1
      getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
1201
1
          << A->getAsString(Args);
1202
1
      continue;
1203
1
    }
1204
45
    if (XOpenMPTargetNoTriple && 
XOpenMPTargetArg43
&&
1205
43
        Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() != 1) {
1206
2
      getDriver().Diag(diag::err_drv_Xopenmp_target_missing_triple);
1207
2
      continue;
1208
2
    }
1209
43
    XOpenMPTargetArg->setBaseArg(A);
1210
43
    A = XOpenMPTargetArg.release();
1211
43
    AllocatedArgs.push_back(A);
1212
43
    DAL->append(A);
1213
43
    Modified = true;
1214
43
  }
1215
1216
84
  if (Modified)
1217
45
    return DAL;
1218
1219
39
  delete DAL;
1220
39
  return nullptr;
1221
39
}
1222
1223
// TODO: Currently argument values separated by space e.g.
1224
// -Xclang -mframe-pointer=no cannot be passed by -Xarch_. This should be
1225
// fixed.
1226
void ToolChain::TranslateXarchArgs(
1227
    const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A,
1228
    llvm::opt::DerivedArgList *DAL,
1229
19
    SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const {
1230
19
  const OptTable &Opts = getDriver().getOpts();
1231
19
  unsigned ValuePos = 1;
1232
19
  if (A->getOption().matches(options::OPT_Xarch_device) ||
1233
13
      A->getOption().matches(options::OPT_Xarch_host))
1234
9
    ValuePos = 0;
1235
1236
19
  unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(ValuePos));
1237
19
  unsigned Prev = Index;
1238
19
  std::unique_ptr<llvm::opt::Arg> XarchArg(Opts.ParseOneArg(Args, Index));
1239
1240
  // If the argument parsing failed or more than one argument was
1241
  // consumed, the -Xarch_ argument's parameter tried to consume
1242
  // extra arguments. Emit an error and ignore.
1243
  //
1244
  // We also want to disallow any options which would alter the
1245
  // driver behavior; that isn't going to work in our model. We
1246
  // use options::NoXarchOption to control this.
1247
19
  if (!XarchArg || 
Index > Prev + 117
) {
1248
2
    getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
1249
2
        << A->getAsString(Args);
1250
2
    return;
1251
17
  } else if (XarchArg->getOption().hasFlag(options::NoXarchOption)) {
1252
1
    auto &Diags = getDriver().getDiags();
1253
1
    unsigned DiagID =
1254
1
        Diags.getCustomDiagID(DiagnosticsEngine::Error,
1255
1
                              "invalid Xarch argument: '%0', not all driver "
1256
1
                              "options can be forwared via Xarch argument");
1257
1
    Diags.Report(DiagID) << A->getAsString(Args);
1258
1
    return;
1259
1
  }
1260
16
  XarchArg->setBaseArg(A);
1261
16
  A = XarchArg.release();
1262
16
  if (!AllocatedArgs)
1263
6
    DAL->AddSynthesizedArg(A);
1264
10
  else
1265
10
    AllocatedArgs->push_back(A);
1266
16
}
1267
1268
llvm::opt::DerivedArgList *ToolChain::TranslateXarchArgs(
1269
    const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
1270
    Action::OffloadKind OFK,
1271
48.1k
    SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const {
1272
48.1k
  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
1273
48.1k
  bool Modified = false;
1274
1275
48.1k
  bool IsGPU = OFK == Action::OFK_Cuda || 
OFK == Action::OFK_HIP47.6k
;
1276
795k
  for (Arg *A : Args) {
1277
795k
    bool NeedTrans = false;
1278
795k
    bool Skip = false;
1279
795k
    if (A->getOption().matches(options::OPT_Xarch_device)) {
1280
12
      NeedTrans = IsGPU;
1281
12
      Skip = !IsGPU;
1282
795k
    } else if (A->getOption().matches(options::OPT_Xarch_host)) {
1283
6
      NeedTrans = !IsGPU;
1284
6
      Skip = IsGPU;
1285
795k
    } else if (A->getOption().matches(options::OPT_Xarch__) && 
IsGPU15
) {
1286
      // Do not translate -Xarch_ options for non CUDA/HIP toolchain since
1287
      // they may need special translation.
1288
      // Skip this argument unless the architecture matches BoundArch
1289
1
      if (BoundArch.empty() || A->getValue(0) != BoundArch)
1290
0
        Skip = true;
1291
1
      else
1292
1
        NeedTrans = true;
1293
1
    }
1294
795k
    if (NeedTrans || 
Skip795k
)
1295
19
      Modified = true;
1296
795k
    if (NeedTrans)
1297
10
      TranslateXarchArgs(Args, A, DAL, AllocatedArgs);
1298
795k
    if (!Skip)
1299
795k
      DAL->append(A);
1300
795k
  }
1301
1302
48.1k
  if (Modified)
1303
13
    return DAL;
1304
1305
48.1k
  delete DAL;
1306
48.1k
  return nullptr;
1307
48.1k
}