clang  19.0.0git
CommonArgs.cpp
Go to the documentation of this file.
1 //===--- CommonArgs.cpp - Args handling for multiple toolchains -*- 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 "CommonArgs.h"
10 #include "Arch/AArch64.h"
11 #include "Arch/ARM.h"
12 #include "Arch/CSKY.h"
13 #include "Arch/LoongArch.h"
14 #include "Arch/M68k.h"
15 #include "Arch/Mips.h"
16 #include "Arch/PPC.h"
17 #include "Arch/RISCV.h"
18 #include "Arch/Sparc.h"
19 #include "Arch/SystemZ.h"
20 #include "Arch/VE.h"
21 #include "Arch/X86.h"
22 #include "HIPAMD.h"
23 #include "Hexagon.h"
24 #include "MSP430.h"
25 #include "Solaris.h"
26 #include "clang/Basic/CharInfo.h"
30 #include "clang/Basic/Version.h"
31 #include "clang/Config/config.h"
32 #include "clang/Driver/Action.h"
34 #include "clang/Driver/Driver.h"
36 #include "clang/Driver/InputInfo.h"
37 #include "clang/Driver/Job.h"
38 #include "clang/Driver/Options.h"
40 #include "clang/Driver/ToolChain.h"
41 #include "clang/Driver/Util.h"
42 #include "clang/Driver/XRayArgs.h"
43 #include "llvm/ADT/STLExtras.h"
44 #include "llvm/ADT/SmallSet.h"
45 #include "llvm/ADT/SmallString.h"
46 #include "llvm/ADT/StringExtras.h"
47 #include "llvm/ADT/StringSwitch.h"
48 #include "llvm/ADT/Twine.h"
49 #include "llvm/BinaryFormat/Magic.h"
50 #include "llvm/Config/llvm-config.h"
51 #include "llvm/Option/Arg.h"
52 #include "llvm/Option/ArgList.h"
53 #include "llvm/Option/Option.h"
54 #include "llvm/Support/CodeGen.h"
55 #include "llvm/Support/Compression.h"
56 #include "llvm/Support/Debug.h"
57 #include "llvm/Support/ErrorHandling.h"
58 #include "llvm/Support/FileSystem.h"
59 #include "llvm/Support/Path.h"
60 #include "llvm/Support/Process.h"
61 #include "llvm/Support/Program.h"
62 #include "llvm/Support/ScopedPrinter.h"
63 #include "llvm/Support/Threading.h"
64 #include "llvm/Support/VirtualFileSystem.h"
65 #include "llvm/Support/YAMLParser.h"
66 #include "llvm/TargetParser/Host.h"
67 #include "llvm/TargetParser/TargetParser.h"
68 #include <optional>
69 
70 using namespace clang::driver;
71 using namespace clang::driver::tools;
72 using namespace clang;
73 using namespace llvm::opt;
74 
75 static bool useFramePointerForTargetByDefault(const llvm::opt::ArgList &Args,
76  const llvm::Triple &Triple) {
77  if (Args.hasArg(clang::driver::options::OPT_pg) &&
78  !Args.hasArg(clang::driver::options::OPT_mfentry))
79  return true;
80 
81  if (Triple.isAndroid()) {
82  switch (Triple.getArch()) {
83  case llvm::Triple::aarch64:
84  case llvm::Triple::arm:
85  case llvm::Triple::armeb:
86  case llvm::Triple::thumb:
87  case llvm::Triple::thumbeb:
88  case llvm::Triple::riscv64:
89  return true;
90  default:
91  break;
92  }
93  }
94 
95  switch (Triple.getArch()) {
96  case llvm::Triple::xcore:
97  case llvm::Triple::wasm32:
98  case llvm::Triple::wasm64:
99  case llvm::Triple::msp430:
100  // XCore never wants frame pointers, regardless of OS.
101  // WebAssembly never wants frame pointers.
102  return false;
103  case llvm::Triple::ppc:
104  case llvm::Triple::ppcle:
105  case llvm::Triple::ppc64:
106  case llvm::Triple::ppc64le:
107  case llvm::Triple::riscv32:
108  case llvm::Triple::riscv64:
109  case llvm::Triple::sparc:
110  case llvm::Triple::sparcel:
111  case llvm::Triple::sparcv9:
112  case llvm::Triple::amdgcn:
113  case llvm::Triple::r600:
114  case llvm::Triple::csky:
115  case llvm::Triple::loongarch32:
116  case llvm::Triple::loongarch64:
117  case llvm::Triple::m68k:
119  default:
120  break;
121  }
122 
123  if (Triple.isOSFuchsia() || Triple.isOSNetBSD()) {
125  }
126 
127  if (Triple.isOSLinux() || Triple.isOSHurd()) {
128  switch (Triple.getArch()) {
129  // Don't use a frame pointer on linux if optimizing for certain targets.
130  case llvm::Triple::arm:
131  case llvm::Triple::armeb:
132  case llvm::Triple::thumb:
133  case llvm::Triple::thumbeb:
134  case llvm::Triple::mips64:
135  case llvm::Triple::mips64el:
136  case llvm::Triple::mips:
137  case llvm::Triple::mipsel:
138  case llvm::Triple::systemz:
139  case llvm::Triple::x86:
140  case llvm::Triple::x86_64:
142  default:
143  return true;
144  }
145  }
146 
147  if (Triple.isOSWindows()) {
148  switch (Triple.getArch()) {
149  case llvm::Triple::x86:
151  case llvm::Triple::x86_64:
152  return Triple.isOSBinFormatMachO();
153  case llvm::Triple::arm:
154  case llvm::Triple::thumb:
155  // Windows on ARM builds with FPO disabled to aid fast stack walking
156  return true;
157  default:
158  // All other supported Windows ISAs use xdata unwind information, so frame
159  // pointers are not generally useful.
160  return false;
161  }
162  }
163 
164  return true;
165 }
166 
167 static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) {
168  switch (Triple.getArch()) {
169  default:
170  return false;
171  case llvm::Triple::arm:
172  case llvm::Triple::thumb:
173  // ARM Darwin targets require a frame pointer to be always present to aid
174  // offline debugging via backtraces.
175  return Triple.isOSDarwin();
176  }
177 }
178 
180 getFramePointerKind(const llvm::opt::ArgList &Args,
181  const llvm::Triple &Triple) {
182  // We have 4 states:
183  //
184  // 00) leaf retained, non-leaf retained
185  // 01) leaf retained, non-leaf omitted (this is invalid)
186  // 10) leaf omitted, non-leaf retained
187  // (what -momit-leaf-frame-pointer was designed for)
188  // 11) leaf omitted, non-leaf omitted
189  //
190  // "omit" options taking precedence over "no-omit" options is the only way
191  // to make 3 valid states representable
192  llvm::opt::Arg *A =
193  Args.getLastArg(clang::driver::options::OPT_fomit_frame_pointer,
194  clang::driver::options::OPT_fno_omit_frame_pointer);
195 
196  bool OmitFP = A && A->getOption().matches(
197  clang::driver::options::OPT_fomit_frame_pointer);
198  bool NoOmitFP = A && A->getOption().matches(
199  clang::driver::options::OPT_fno_omit_frame_pointer);
200  bool OmitLeafFP =
201  Args.hasFlag(clang::driver::options::OPT_momit_leaf_frame_pointer,
202  clang::driver::options::OPT_mno_omit_leaf_frame_pointer,
203  Triple.isAArch64() || Triple.isPS() || Triple.isVE() ||
204  (Triple.isAndroid() && Triple.isRISCV64()));
205  if (NoOmitFP || mustUseNonLeafFramePointerForTarget(Triple) ||
206  (!OmitFP && useFramePointerForTargetByDefault(Args, Triple))) {
207  if (OmitLeafFP)
210  }
212 }
213 
214 static void renderRpassOptions(const ArgList &Args, ArgStringList &CmdArgs,
215  const StringRef PluginOptPrefix) {
216  if (const Arg *A = Args.getLastArg(options::OPT_Rpass_EQ))
217  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
218  "-pass-remarks=" + A->getValue()));
219 
220  if (const Arg *A = Args.getLastArg(options::OPT_Rpass_missed_EQ))
221  CmdArgs.push_back(Args.MakeArgString(
222  Twine(PluginOptPrefix) + "-pass-remarks-missed=" + A->getValue()));
223 
224  if (const Arg *A = Args.getLastArg(options::OPT_Rpass_analysis_EQ))
225  CmdArgs.push_back(Args.MakeArgString(
226  Twine(PluginOptPrefix) + "-pass-remarks-analysis=" + A->getValue()));
227 }
228 
229 static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs,
230  const llvm::Triple &Triple,
231  const InputInfo &Input,
232  const InputInfo &Output,
233  const StringRef PluginOptPrefix) {
234  StringRef Format = "yaml";
235  if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ))
236  Format = A->getValue();
237 
239  const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ);
240  if (A)
241  F = A->getValue();
242  else if (Output.isFilename())
243  F = Output.getFilename();
244 
245  assert(!F.empty() && "Cannot determine remarks output name.");
246  // Append "opt.ld.<format>" to the end of the file name.
247  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
248  "opt-remarks-filename=" + F +
249  ".opt.ld." + Format));
250 
251  if (const Arg *A =
252  Args.getLastArg(options::OPT_foptimization_record_passes_EQ))
253  CmdArgs.push_back(Args.MakeArgString(
254  Twine(PluginOptPrefix) + "opt-remarks-passes=" + A->getValue()));
255 
256  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
257  "opt-remarks-format=" + Format.data()));
258 }
259 
260 static void renderRemarksHotnessOptions(const ArgList &Args,
261  ArgStringList &CmdArgs,
262  const StringRef PluginOptPrefix) {
263  if (Args.hasFlag(options::OPT_fdiagnostics_show_hotness,
264  options::OPT_fno_diagnostics_show_hotness, false))
265  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
266  "opt-remarks-with-hotness"));
267 
268  if (const Arg *A =
269  Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ))
270  CmdArgs.push_back(
271  Args.MakeArgString(Twine(PluginOptPrefix) +
272  "opt-remarks-hotness-threshold=" + A->getValue()));
273 }
274 
275 static bool shouldIgnoreUnsupportedTargetFeature(const Arg &TargetFeatureArg,
276  llvm::Triple T,
277  StringRef Processor) {
278  // Warn no-cumode for AMDGCN processors not supporing WGP mode.
279  if (!T.isAMDGPU())
280  return false;
281  auto GPUKind = T.isAMDGCN() ? llvm::AMDGPU::parseArchAMDGCN(Processor)
282  : llvm::AMDGPU::parseArchR600(Processor);
283  auto GPUFeatures = T.isAMDGCN() ? llvm::AMDGPU::getArchAttrAMDGCN(GPUKind)
284  : llvm::AMDGPU::getArchAttrR600(GPUKind);
285  if (GPUFeatures & llvm::AMDGPU::FEATURE_WGP)
286  return false;
287  return TargetFeatureArg.getOption().matches(options::OPT_mno_cumode);
288 }
289 
290 void tools::addPathIfExists(const Driver &D, const Twine &Path,
291  ToolChain::path_list &Paths) {
292  if (D.getVFS().exists(Path))
293  Paths.push_back(Path.str());
294 }
295 
297  const llvm::Triple &Triple,
298  const ArgList &Args,
299  std::vector<StringRef> &Features,
300  OptSpecifier Group) {
301  std::set<StringRef> Warned;
302  for (const Arg *A : Args.filtered(Group)) {
303  StringRef Name = A->getOption().getName();
304  A->claim();
305 
306  // Skip over "-m".
307  assert(Name.starts_with("m") && "Invalid feature name.");
308  Name = Name.substr(1);
309 
310  auto Proc = getCPUName(D, Args, Triple);
311  if (shouldIgnoreUnsupportedTargetFeature(*A, Triple, Proc)) {
312  if (Warned.count(Name) == 0) {
313  D.getDiags().Report(
314  clang::diag::warn_drv_unsupported_option_for_processor)
315  << A->getAsString(Args) << Proc;
316  Warned.insert(Name);
317  }
318  continue;
319  }
320 
321  bool IsNegative = Name.consume_front("no-");
322 
323  Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
324  }
325 }
326 
329  // Only add a feature if it hasn't been seen before starting from the end.
330  SmallVector<StringRef> UnifiedFeatures;
331  llvm::DenseSet<StringRef> UsedFeatures;
332  for (StringRef Feature : llvm::reverse(Features)) {
333  if (UsedFeatures.insert(Feature.drop_front()).second)
334  UnifiedFeatures.insert(UnifiedFeatures.begin(), Feature);
335  }
336 
337  return UnifiedFeatures;
338 }
339 
340 void tools::addDirectoryList(const ArgList &Args, ArgStringList &CmdArgs,
341  const char *ArgName, const char *EnvVar) {
342  const char *DirList = ::getenv(EnvVar);
343  bool CombinedArg = false;
344 
345  if (!DirList)
346  return; // Nothing to do.
347 
348  StringRef Name(ArgName);
349  if (Name == "-I" || Name == "-L" || Name.empty())
350  CombinedArg = true;
351 
352  StringRef Dirs(DirList);
353  if (Dirs.empty()) // Empty string should not add '.'.
354  return;
355 
356  StringRef::size_type Delim;
357  while ((Delim = Dirs.find(llvm::sys::EnvPathSeparator)) != StringRef::npos) {
358  if (Delim == 0) { // Leading colon.
359  if (CombinedArg) {
360  CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
361  } else {
362  CmdArgs.push_back(ArgName);
363  CmdArgs.push_back(".");
364  }
365  } else {
366  if (CombinedArg) {
367  CmdArgs.push_back(
368  Args.MakeArgString(std::string(ArgName) + Dirs.substr(0, Delim)));
369  } else {
370  CmdArgs.push_back(ArgName);
371  CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim)));
372  }
373  }
374  Dirs = Dirs.substr(Delim + 1);
375  }
376 
377  if (Dirs.empty()) { // Trailing colon.
378  if (CombinedArg) {
379  CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
380  } else {
381  CmdArgs.push_back(ArgName);
382  CmdArgs.push_back(".");
383  }
384  } else { // Add the last path.
385  if (CombinedArg) {
386  CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs));
387  } else {
388  CmdArgs.push_back(ArgName);
389  CmdArgs.push_back(Args.MakeArgString(Dirs));
390  }
391  }
392 }
393 
394 void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
395  const ArgList &Args, ArgStringList &CmdArgs,
396  const JobAction &JA) {
397  const Driver &D = TC.getDriver();
398 
399  // Add extra linker input arguments which are not treated as inputs
400  // (constructed via -Xarch_).
401  Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input);
402 
403  // LIBRARY_PATH are included before user inputs and only supported on native
404  // toolchains.
405  if (!TC.isCrossCompiling())
406  addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
407 
408  for (const auto &II : Inputs) {
409  // If the current tool chain refers to an OpenMP offloading host, we
410  // should ignore inputs that refer to OpenMP offloading devices -
411  // they will be embedded according to a proper linker script.
412  if (auto *IA = II.getAction())
414  IA->isDeviceOffloading(Action::OFK_OpenMP)))
415  continue;
416 
417  if (!TC.HasNativeLLVMSupport() && types::isLLVMIR(II.getType()))
418  // Don't try to pass LLVM inputs unless we have native support.
419  D.Diag(diag::err_drv_no_linker_llvm_support) << TC.getTripleString();
420 
421  if (II.getType() == types::TY_Tempfilelist) {
422  // Take the list file and pass it in with '@'.
423  std::string FileName(II.getFilename());
424  const char *ArgFile = Args.MakeArgString("@" + FileName);
425  CmdArgs.push_back(ArgFile);
426  continue;
427  }
428 
429  // Add filenames immediately.
430  if (II.isFilename()) {
431  CmdArgs.push_back(II.getFilename());
432  continue;
433  }
434 
435  // In some error cases, the input could be Nothing; skip those.
436  if (II.isNothing())
437  continue;
438 
439  // Otherwise, this is a linker input argument.
440  const Arg &A = II.getInputArg();
441 
442  // Handle reserved library options.
443  if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx))
444  TC.AddCXXStdlibLibArgs(Args, CmdArgs);
445  else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext))
446  TC.AddCCKextLibArgs(Args, CmdArgs);
447  else
448  A.renderAsInput(Args, CmdArgs);
449  }
450 }
451 
453  const ToolChain &TC, const llvm::opt::ArgList &Args,
454  llvm::opt::ArgStringList &CmdArgs) {
455  // GNU ld supports --compress-debug-sections=none|zlib|zlib-gnu|zlib-gabi
456  // whereas zlib is an alias to zlib-gabi and zlib-gnu is obsoleted. Therefore
457  // -gz=none|zlib are translated to --compress-debug-sections=none|zlib. -gz
458  // is not translated since ld --compress-debug-sections option requires an
459  // argument.
460  if (const Arg *A = Args.getLastArg(options::OPT_gz_EQ)) {
461  StringRef V = A->getValue();
462  if (V == "none" || V == "zlib" || V == "zstd")
463  CmdArgs.push_back(Args.MakeArgString("--compress-debug-sections=" + V));
464  else
465  TC.getDriver().Diag(diag::err_drv_unsupported_option_argument)
466  << A->getSpelling() << V;
467  }
468 }
469 
470 void tools::AddTargetFeature(const ArgList &Args,
471  std::vector<StringRef> &Features,
472  OptSpecifier OnOpt, OptSpecifier OffOpt,
473  StringRef FeatureName) {
474  if (Arg *A = Args.getLastArg(OnOpt, OffOpt)) {
475  if (A->getOption().matches(OnOpt))
476  Features.push_back(Args.MakeArgString("+" + FeatureName));
477  else
478  Features.push_back(Args.MakeArgString("-" + FeatureName));
479  }
480 }
481 
482 /// Get the (LLVM) name of the AMDGPU gpu we are targeting.
483 static std::string getAMDGPUTargetGPU(const llvm::Triple &T,
484  const ArgList &Args) {
485  Arg *MArch = Args.getLastArg(options::OPT_march_EQ);
486  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
487  auto GPUName = getProcessorFromTargetID(T, A->getValue());
488  return llvm::StringSwitch<std::string>(GPUName)
489  .Cases("rv630", "rv635", "r600")
490  .Cases("rv610", "rv620", "rs780", "rs880")
491  .Case("rv740", "rv770")
492  .Case("palm", "cedar")
493  .Cases("sumo", "sumo2", "sumo")
494  .Case("hemlock", "cypress")
495  .Case("aruba", "cayman")
496  .Default(GPUName.str());
497  }
498  if (MArch)
499  return getProcessorFromTargetID(T, MArch->getValue()).str();
500  return "";
501 }
502 
503 static std::string getLanaiTargetCPU(const ArgList &Args) {
504  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
505  return A->getValue();
506  }
507  return "";
508 }
509 
510 /// Get the (LLVM) name of the WebAssembly cpu we are targeting.
511 static StringRef getWebAssemblyTargetCPU(const ArgList &Args) {
512  // If we have -mcpu=, use that.
513  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
514  StringRef CPU = A->getValue();
515 
516 #ifdef __wasm__
517  // Handle "native" by examining the host. "native" isn't meaningful when
518  // cross compiling, so only support this when the host is also WebAssembly.
519  if (CPU == "native")
520  return llvm::sys::getHostCPUName();
521 #endif
522 
523  return CPU;
524  }
525 
526  return "generic";
527 }
528 
529 std::string tools::getCPUName(const Driver &D, const ArgList &Args,
530  const llvm::Triple &T, bool FromAs) {
531  Arg *A;
532 
533  switch (T.getArch()) {
534  default:
535  return "";
536 
537  case llvm::Triple::aarch64:
538  case llvm::Triple::aarch64_32:
539  case llvm::Triple::aarch64_be:
540  return aarch64::getAArch64TargetCPU(Args, T, A);
541 
542  case llvm::Triple::arm:
543  case llvm::Triple::armeb:
544  case llvm::Triple::thumb:
545  case llvm::Triple::thumbeb: {
546  StringRef MArch, MCPU;
547  arm::getARMArchCPUFromArgs(Args, MArch, MCPU, FromAs);
548  return arm::getARMTargetCPU(MCPU, MArch, T);
549  }
550 
551  case llvm::Triple::avr:
552  if (const Arg *A = Args.getLastArg(options::OPT_mmcu_EQ))
553  return A->getValue();
554  return "";
555 
556  case llvm::Triple::m68k:
557  return m68k::getM68kTargetCPU(Args);
558 
559  case llvm::Triple::mips:
560  case llvm::Triple::mipsel:
561  case llvm::Triple::mips64:
562  case llvm::Triple::mips64el: {
563  StringRef CPUName;
564  StringRef ABIName;
565  mips::getMipsCPUAndABI(Args, T, CPUName, ABIName);
566  return std::string(CPUName);
567  }
568 
569  case llvm::Triple::nvptx:
570  case llvm::Triple::nvptx64:
571  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
572  return A->getValue();
573  return "";
574 
575  case llvm::Triple::ppc:
576  case llvm::Triple::ppcle:
577  case llvm::Triple::ppc64:
578  case llvm::Triple::ppc64le:
579  return ppc::getPPCTargetCPU(D, Args, T);
580 
581  case llvm::Triple::csky:
582  if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
583  return A->getValue();
584  else if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
585  return A->getValue();
586  else
587  return "ck810";
588  case llvm::Triple::riscv32:
589  case llvm::Triple::riscv64:
590  return riscv::getRISCVTargetCPU(Args, T);
591 
592  case llvm::Triple::bpfel:
593  case llvm::Triple::bpfeb:
594  if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
595  return A->getValue();
596  return "";
597 
598  case llvm::Triple::sparc:
599  case llvm::Triple::sparcel:
600  case llvm::Triple::sparcv9:
601  return sparc::getSparcTargetCPU(D, Args, T);
602 
603  case llvm::Triple::x86:
604  case llvm::Triple::x86_64:
605  return x86::getX86TargetCPU(D, Args, T);
606 
607  case llvm::Triple::hexagon:
608  return "hexagon" +
610 
611  case llvm::Triple::lanai:
612  return getLanaiTargetCPU(Args);
613 
614  case llvm::Triple::systemz:
615  return systemz::getSystemZTargetCPU(Args);
616 
617  case llvm::Triple::r600:
618  case llvm::Triple::amdgcn:
619  return getAMDGPUTargetGPU(T, Args);
620 
621  case llvm::Triple::wasm32:
622  case llvm::Triple::wasm64:
623  return std::string(getWebAssemblyTargetCPU(Args));
624 
625  case llvm::Triple::loongarch32:
626  case llvm::Triple::loongarch64:
627  return loongarch::getLoongArchTargetCPU(Args, T);
628  }
629 }
630 
632  const llvm::Triple &Triple,
633  const ArgList &Args,
634  std::vector<StringRef> &Features) {
635  handleTargetFeaturesGroup(D, Triple, Args, Features,
636  options::OPT_m_wasm_Features_Group);
637 }
638 
639 void tools::getTargetFeatures(const Driver &D, const llvm::Triple &Triple,
640  const ArgList &Args, ArgStringList &CmdArgs,
641  bool ForAS, bool IsAux) {
642  std::vector<StringRef> Features;
643  switch (Triple.getArch()) {
644  default:
645  break;
646  case llvm::Triple::mips:
647  case llvm::Triple::mipsel:
648  case llvm::Triple::mips64:
649  case llvm::Triple::mips64el:
650  mips::getMIPSTargetFeatures(D, Triple, Args, Features);
651  break;
652  case llvm::Triple::arm:
653  case llvm::Triple::armeb:
654  case llvm::Triple::thumb:
655  case llvm::Triple::thumbeb:
656  arm::getARMTargetFeatures(D, Triple, Args, Features, ForAS);
657  break;
658  case llvm::Triple::ppc:
659  case llvm::Triple::ppcle:
660  case llvm::Triple::ppc64:
661  case llvm::Triple::ppc64le:
662  ppc::getPPCTargetFeatures(D, Triple, Args, Features);
663  break;
664  case llvm::Triple::riscv32:
665  case llvm::Triple::riscv64:
666  riscv::getRISCVTargetFeatures(D, Triple, Args, Features);
667  break;
668  case llvm::Triple::systemz:
669  systemz::getSystemZTargetFeatures(D, Args, Features);
670  break;
671  case llvm::Triple::aarch64:
672  case llvm::Triple::aarch64_32:
673  case llvm::Triple::aarch64_be:
674  aarch64::getAArch64TargetFeatures(D, Triple, Args, Features, ForAS);
675  break;
676  case llvm::Triple::x86:
677  case llvm::Triple::x86_64:
678  x86::getX86TargetFeatures(D, Triple, Args, Features);
679  break;
680  case llvm::Triple::hexagon:
681  hexagon::getHexagonTargetFeatures(D, Triple, Args, Features);
682  break;
683  case llvm::Triple::wasm32:
684  case llvm::Triple::wasm64:
685  getWebAssemblyTargetFeatures(D, Triple, Args, Features);
686  break;
687  case llvm::Triple::sparc:
688  case llvm::Triple::sparcel:
689  case llvm::Triple::sparcv9:
690  sparc::getSparcTargetFeatures(D, Args, Features);
691  break;
692  case llvm::Triple::r600:
693  case llvm::Triple::amdgcn:
694  amdgpu::getAMDGPUTargetFeatures(D, Triple, Args, Features);
695  break;
696  case llvm::Triple::nvptx:
697  case llvm::Triple::nvptx64:
698  NVPTX::getNVPTXTargetFeatures(D, Triple, Args, Features);
699  break;
700  case llvm::Triple::m68k:
701  m68k::getM68kTargetFeatures(D, Triple, Args, Features);
702  break;
703  case llvm::Triple::msp430:
704  msp430::getMSP430TargetFeatures(D, Args, Features);
705  break;
706  case llvm::Triple::ve:
707  ve::getVETargetFeatures(D, Args, Features);
708  break;
709  case llvm::Triple::csky:
710  csky::getCSKYTargetFeatures(D, Triple, Args, CmdArgs, Features);
711  break;
712  case llvm::Triple::loongarch32:
713  case llvm::Triple::loongarch64:
714  loongarch::getLoongArchTargetFeatures(D, Triple, Args, Features);
715  break;
716  }
717 
718  for (auto Feature : unifyTargetFeatures(Features)) {
719  CmdArgs.push_back(IsAux ? "-aux-target-feature" : "-target-feature");
720  CmdArgs.push_back(Feature.data());
721  }
722 }
723 
724 llvm::StringRef tools::getLTOParallelism(const ArgList &Args, const Driver &D) {
725  Arg *LtoJobsArg = Args.getLastArg(options::OPT_flto_jobs_EQ);
726  if (!LtoJobsArg)
727  return {};
728  if (!llvm::get_threadpool_strategy(LtoJobsArg->getValue()))
729  D.Diag(diag::err_drv_invalid_int_value)
730  << LtoJobsArg->getAsString(Args) << LtoJobsArg->getValue();
731  return LtoJobsArg->getValue();
732 }
733 
734 // PS4/PS5 uses -ffunction-sections and -fdata-sections by default.
735 bool tools::isUseSeparateSections(const llvm::Triple &Triple) {
736  return Triple.isPS();
737 }
738 
740  const llvm::opt::ArgList &Args) {
741  const llvm::Triple &Triple = TC.getEffectiveTriple();
742  Arg *A = Args.getLastArg(options::OPT_mtls_dialect_EQ);
743  if (!A)
744  return Triple.hasDefaultTLSDESC();
745  StringRef V = A->getValue();
746  bool SupportedArgument = false, EnableTLSDESC = false;
747  bool Unsupported = !Triple.isOSBinFormatELF();
748  if (Triple.isLoongArch() || Triple.isRISCV()) {
749  SupportedArgument = V == "desc" || V == "trad";
750  EnableTLSDESC = V == "desc";
751  } else if (Triple.isX86()) {
752  SupportedArgument = V == "gnu" || V == "gnu2";
753  EnableTLSDESC = V == "gnu2";
754  } else {
755  Unsupported = true;
756  }
757  if (Unsupported) {
758  TC.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
759  << A->getSpelling() << Triple.getTriple();
760  } else if (!SupportedArgument) {
761  TC.getDriver().Diag(diag::err_drv_unsupported_option_argument_for_target)
762  << A->getSpelling() << V << Triple.getTriple();
763  }
764  return EnableTLSDESC;
765 }
766 
767 void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
768  ArgStringList &CmdArgs, const InputInfo &Output,
769  const InputInfo &Input, bool IsThinLTO) {
770  const llvm::Triple &Triple = ToolChain.getTriple();
771  const bool IsOSAIX = Triple.isOSAIX();
772  const bool IsAMDGCN = Triple.isAMDGCN();
773  const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath());
774  const Driver &D = ToolChain.getDriver();
775  const bool IsFatLTO = Args.hasArg(options::OPT_ffat_lto_objects);
776  const bool IsUnifiedLTO = Args.hasArg(options::OPT_funified_lto);
777  if (llvm::sys::path::filename(Linker) != "ld.lld" &&
778  llvm::sys::path::stem(Linker) != "ld.lld" && !Triple.isOSOpenBSD()) {
779  // Tell the linker to load the plugin. This has to come before
780  // AddLinkerInputs as gold requires -plugin and AIX ld requires -bplugin to
781  // come before any -plugin-opt/-bplugin_opt that -Wl might forward.
782  const char *PluginPrefix = IsOSAIX ? "-bplugin:" : "";
783  const char *PluginName = IsOSAIX ? "/libLTO" : "/LLVMgold";
784 
785  if (!IsOSAIX)
786  CmdArgs.push_back("-plugin");
787 
788 #if defined(_WIN32)
789  const char *Suffix = ".dll";
790 #elif defined(__APPLE__)
791  const char *Suffix = ".dylib";
792 #else
793  const char *Suffix = ".so";
794 #endif
795 
796  SmallString<1024> Plugin;
797  llvm::sys::path::native(Twine(D.Dir) +
798  "/../" CLANG_INSTALL_LIBDIR_BASENAME +
799  PluginName + Suffix,
800  Plugin);
801  CmdArgs.push_back(Args.MakeArgString(Twine(PluginPrefix) + Plugin));
802  } else {
803  // Tell LLD to find and use .llvm.lto section in regular relocatable object
804  // files
805  if (IsFatLTO)
806  CmdArgs.push_back("--fat-lto-objects");
807  }
808 
809  const char *PluginOptPrefix = IsOSAIX ? "-bplugin_opt:" : "-plugin-opt=";
810  const char *ExtraDash = IsOSAIX ? "-" : "";
811  const char *ParallelismOpt = IsOSAIX ? "-threads=" : "jobs=";
812 
813  // Note, this solution is far from perfect, better to encode it into IR
814  // metadata, but this may not be worth it, since it looks like aranges is on
815  // the way out.
816  if (Args.hasArg(options::OPT_gdwarf_aranges)) {
817  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
818  "-generate-arange-section"));
819  }
820 
821  // Pass vector library arguments to LTO.
822  Arg *ArgVecLib = Args.getLastArg(options::OPT_fveclib);
823  if (ArgVecLib && ArgVecLib->getNumValues() == 1) {
824  // Map the vector library names from clang front-end to opt front-end. The
825  // values are taken from the TargetLibraryInfo class command line options.
826  std::optional<StringRef> OptVal =
827  llvm::StringSwitch<std::optional<StringRef>>(ArgVecLib->getValue())
828  .Case("Accelerate", "Accelerate")
829  .Case("LIBMVEC", "LIBMVEC-X86")
830  .Case("MASSV", "MASSV")
831  .Case("SVML", "SVML")
832  .Case("SLEEF", "sleefgnuabi")
833  .Case("Darwin_libsystem_m", "Darwin_libsystem_m")
834  .Case("ArmPL", "ArmPL")
835  .Case("none", "none")
836  .Default(std::nullopt);
837 
838  if (OptVal)
839  CmdArgs.push_back(Args.MakeArgString(
840  Twine(PluginOptPrefix) + "-vector-library=" + OptVal.value()));
841  }
842 
843  // Try to pass driver level flags relevant to LTO code generation down to
844  // the plugin.
845 
846  // Handle flags for selecting CPU variants.
847  std::string CPU = getCPUName(D, Args, Triple);
848  if (!CPU.empty())
849  CmdArgs.push_back(
850  Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash + "mcpu=" + CPU));
851 
852  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
853  // The optimization level matches
854  // CompilerInvocation.cpp:getOptimizationLevel().
855  StringRef OOpt;
856  if (A->getOption().matches(options::OPT_O4) ||
857  A->getOption().matches(options::OPT_Ofast))
858  OOpt = "3";
859  else if (A->getOption().matches(options::OPT_O)) {
860  OOpt = A->getValue();
861  if (OOpt == "g")
862  OOpt = "1";
863  else if (OOpt == "s" || OOpt == "z")
864  OOpt = "2";
865  } else if (A->getOption().matches(options::OPT_O0))
866  OOpt = "0";
867  if (!OOpt.empty()) {
868  CmdArgs.push_back(
869  Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash + "O" + OOpt));
870  if (IsAMDGCN)
871  CmdArgs.push_back(Args.MakeArgString(Twine("--lto-CGO") + OOpt));
872  }
873  }
874 
875  if (Args.hasArg(options::OPT_gsplit_dwarf))
876  CmdArgs.push_back(Args.MakeArgString(
877  Twine(PluginOptPrefix) + "dwo_dir=" + Output.getFilename() + "_dwo"));
878 
879  if (IsThinLTO && !IsOSAIX)
880  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + "thinlto"));
881  else if (IsThinLTO && IsOSAIX)
882  CmdArgs.push_back(Args.MakeArgString(Twine("-bdbg:thinlto")));
883 
884  // Matrix intrinsic lowering happens at link time with ThinLTO. Enable
885  // LowerMatrixIntrinsicsPass, which is transitively called by
886  // buildThinLTODefaultPipeline under EnableMatrix.
887  if ((IsThinLTO || IsFatLTO || IsUnifiedLTO) &&
888  Args.hasArg(options::OPT_fenable_matrix))
889  CmdArgs.push_back(
890  Args.MakeArgString(Twine(PluginOptPrefix) + "-enable-matrix"));
891 
892  StringRef Parallelism = getLTOParallelism(Args, D);
893  if (!Parallelism.empty())
894  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
895  ParallelismOpt + Parallelism));
896 
897  // Pass down GlobalISel options.
898  if (Arg *A = Args.getLastArg(options::OPT_fglobal_isel,
899  options::OPT_fno_global_isel)) {
900  // Parsing -fno-global-isel explicitly gives architectures that enable GISel
901  // by default a chance to disable it.
902  CmdArgs.push_back(Args.MakeArgString(
903  Twine(PluginOptPrefix) + "-global-isel=" +
904  (A->getOption().matches(options::OPT_fglobal_isel) ? "1" : "0")));
905  }
906 
907  // If an explicit debugger tuning argument appeared, pass it along.
908  if (Arg *A =
909  Args.getLastArg(options::OPT_gTune_Group, options::OPT_ggdbN_Group)) {
910  if (A->getOption().matches(options::OPT_glldb))
911  CmdArgs.push_back(
912  Args.MakeArgString(Twine(PluginOptPrefix) + "-debugger-tune=lldb"));
913  else if (A->getOption().matches(options::OPT_gsce))
914  CmdArgs.push_back(
915  Args.MakeArgString(Twine(PluginOptPrefix) + "-debugger-tune=sce"));
916  else if (A->getOption().matches(options::OPT_gdbx))
917  CmdArgs.push_back(
918  Args.MakeArgString(Twine(PluginOptPrefix) + "-debugger-tune=dbx"));
919  else
920  CmdArgs.push_back(
921  Args.MakeArgString(Twine(PluginOptPrefix) + "-debugger-tune=gdb"));
922  }
923 
924  if (IsOSAIX) {
925  if (!ToolChain.useIntegratedAs())
926  CmdArgs.push_back(
927  Args.MakeArgString(Twine(PluginOptPrefix) + "-no-integrated-as=1"));
928 
929  // On AIX, clang assumes strict-dwarf is true if any debug option is
930  // specified, unless it is told explicitly not to assume so.
931  Arg *A = Args.getLastArg(options::OPT_g_Group);
932  bool EnableDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
933  !A->getOption().matches(options::OPT_ggdb0);
934  if (EnableDebugInfo && Args.hasFlag(options::OPT_gstrict_dwarf,
935  options::OPT_gno_strict_dwarf, true))
936  CmdArgs.push_back(
937  Args.MakeArgString(Twine(PluginOptPrefix) + "-strict-dwarf=true"));
938 
939  for (const Arg *A : Args.filtered_reverse(options::OPT_mabi_EQ)) {
940  StringRef V = A->getValue();
941  if (V == "vec-default")
942  break;
943  if (V == "vec-extabi") {
944  CmdArgs.push_back(
945  Args.MakeArgString(Twine(PluginOptPrefix) + "-vec-extabi"));
946  break;
947  }
948  }
949  }
950 
951  bool UseSeparateSections =
953 
954  if (Args.hasFlag(options::OPT_ffunction_sections,
955  options::OPT_fno_function_sections, UseSeparateSections))
956  CmdArgs.push_back(
957  Args.MakeArgString(Twine(PluginOptPrefix) + "-function-sections=1"));
958  else if (Args.hasArg(options::OPT_fno_function_sections))
959  CmdArgs.push_back(
960  Args.MakeArgString(Twine(PluginOptPrefix) + "-function-sections=0"));
961 
962  bool DataSectionsTurnedOff = false;
963  if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
964  UseSeparateSections)) {
965  CmdArgs.push_back(
966  Args.MakeArgString(Twine(PluginOptPrefix) + "-data-sections=1"));
967  } else if (Args.hasArg(options::OPT_fno_data_sections)) {
968  DataSectionsTurnedOff = true;
969  CmdArgs.push_back(
970  Args.MakeArgString(Twine(PluginOptPrefix) + "-data-sections=0"));
971  }
972 
973  if (Args.hasArg(options::OPT_mxcoff_roptr) ||
974  Args.hasArg(options::OPT_mno_xcoff_roptr)) {
975  bool HasRoptr = Args.hasFlag(options::OPT_mxcoff_roptr,
976  options::OPT_mno_xcoff_roptr, false);
977  StringRef OptStr = HasRoptr ? "-mxcoff-roptr" : "-mno-xcoff-roptr";
978  if (!IsOSAIX)
979  D.Diag(diag::err_drv_unsupported_opt_for_target)
980  << OptStr << Triple.str();
981 
982  if (HasRoptr) {
983  // The data sections option is on by default on AIX. We only need to error
984  // out when -fno-data-sections is specified explicitly to turn off data
985  // sections.
986  if (DataSectionsTurnedOff)
987  D.Diag(diag::err_roptr_requires_data_sections);
988 
989  CmdArgs.push_back(
990  Args.MakeArgString(Twine(PluginOptPrefix) + "-mxcoff-roptr"));
991  }
992  }
993 
994  // Pass an option to enable split machine functions.
995  if (auto *A = Args.getLastArg(options::OPT_fsplit_machine_functions,
996  options::OPT_fno_split_machine_functions)) {
997  if (A->getOption().matches(options::OPT_fsplit_machine_functions))
998  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
999  "-split-machine-functions"));
1000  }
1001 
1002  if (Arg *A = getLastProfileSampleUseArg(Args)) {
1003  StringRef FName = A->getValue();
1004  if (!llvm::sys::fs::exists(FName))
1005  D.Diag(diag::err_drv_no_such_file) << FName;
1006  else
1007  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
1008  "sample-profile=" + FName));
1009  }
1010 
1011  if (auto *CSPGOGenerateArg = getLastCSProfileGenerateArg(Args)) {
1012  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash +
1013  "cs-profile-generate"));
1014  if (CSPGOGenerateArg->getOption().matches(
1015  options::OPT_fcs_profile_generate_EQ)) {
1016  SmallString<128> Path(CSPGOGenerateArg->getValue());
1017  llvm::sys::path::append(Path, "default_%m.profraw");
1018  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash +
1019  "cs-profile-path=" + Path));
1020  } else
1021  CmdArgs.push_back(
1022  Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash +
1023  "cs-profile-path=default_%m.profraw"));
1024  } else if (auto *ProfileUseArg = getLastProfileUseArg(Args)) {
1025  SmallString<128> Path(
1026  ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue());
1027  if (Path.empty() || llvm::sys::fs::is_directory(Path))
1028  llvm::sys::path::append(Path, "default.profdata");
1029  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash +
1030  "cs-profile-path=" + Path));
1031  }
1032 
1033  // This controls whether or not we perform JustMyCode instrumentation.
1034  if (Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false)) {
1035  if (ToolChain.getEffectiveTriple().isOSBinFormatELF())
1036  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
1037  "-enable-jmc-instrument"));
1038  else
1039  D.Diag(clang::diag::warn_drv_fjmc_for_elf_only);
1040  }
1041 
1042  if (Args.hasFlag(options::OPT_femulated_tls, options::OPT_fno_emulated_tls,
1043  Triple.hasDefaultEmulatedTLS())) {
1044  CmdArgs.push_back(
1045  Args.MakeArgString(Twine(PluginOptPrefix) + "-emulated-tls"));
1046  }
1047  if (isTLSDESCEnabled(ToolChain, Args))
1048  CmdArgs.push_back(
1049  Args.MakeArgString(Twine(PluginOptPrefix) + "-enable-tlsdesc"));
1050 
1051  if (Args.hasFlag(options::OPT_fstack_size_section,
1052  options::OPT_fno_stack_size_section, false))
1053  CmdArgs.push_back(
1054  Args.MakeArgString(Twine(PluginOptPrefix) + "-stack-size-section"));
1055 
1056  // Setup statistics file output.
1057  SmallString<128> StatsFile = getStatsFileName(Args, Output, Input, D);
1058  if (!StatsFile.empty())
1059  CmdArgs.push_back(
1060  Args.MakeArgString(Twine(PluginOptPrefix) + "stats-file=" + StatsFile));
1061 
1062  // Setup crash diagnostics dir.
1063  if (Arg *A = Args.getLastArg(options::OPT_fcrash_diagnostics_dir))
1064  CmdArgs.push_back(Args.MakeArgString(
1065  Twine(PluginOptPrefix) + "-crash-diagnostics-dir=" + A->getValue()));
1066 
1067  addX86AlignBranchArgs(D, Args, CmdArgs, /*IsLTO=*/true, PluginOptPrefix);
1068 
1069  // Handle remark diagnostics on screen options: '-Rpass-*'.
1070  renderRpassOptions(Args, CmdArgs, PluginOptPrefix);
1071 
1072  // Handle serialized remarks options: '-fsave-optimization-record'
1073  // and '-foptimization-record-*'.
1074  if (willEmitRemarks(Args))
1075  renderRemarksOptions(Args, CmdArgs, ToolChain.getEffectiveTriple(), Input,
1076  Output, PluginOptPrefix);
1077 
1078  // Handle remarks hotness/threshold related options.
1079  renderRemarksHotnessOptions(Args, CmdArgs, PluginOptPrefix);
1080 
1082  /*IsLTO=*/true, PluginOptPrefix);
1083 }
1084 
1085 /// Adds the '-lcgpu' and '-lmgpu' libraries to the compilation to include the
1086 /// LLVM C library for GPUs.
1087 static void addOpenMPDeviceLibC(const Compilation &C, const ArgList &Args,
1088  ArgStringList &CmdArgs) {
1089  if (Args.hasArg(options::OPT_nogpulib) || Args.hasArg(options::OPT_nolibc))
1090  return;
1091 
1092  // Check the resource directory for the LLVM libc GPU declarations. If it's
1093  // found we can assume that LLVM was built with support for the GPU libc.
1094  SmallString<256> LibCDecls(C.getDriver().ResourceDir);
1095  llvm::sys::path::append(LibCDecls, "include", "llvm_libc_wrappers",
1096  "llvm-libc-decls");
1097  bool HasLibC = llvm::sys::fs::exists(LibCDecls) &&
1098  llvm::sys::fs::is_directory(LibCDecls);
1099  if (!Args.hasFlag(options::OPT_gpulibc, options::OPT_nogpulibc, HasLibC))
1100  return;
1101 
1102  SmallVector<const ToolChain *> ToolChains;
1103  auto TCRange = C.getOffloadToolChains(Action::OFK_OpenMP);
1104  for (auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
1105  ToolChains.push_back(TI->second);
1106 
1107  if (llvm::any_of(ToolChains, [](const ToolChain *TC) {
1108  return TC->getTriple().isAMDGPU();
1109  })) {
1110  CmdArgs.push_back("-lcgpu-amdgpu");
1111  CmdArgs.push_back("-lmgpu-amdgpu");
1112  }
1113  if (llvm::any_of(ToolChains, [](const ToolChain *TC) {
1114  return TC->getTriple().isNVPTX();
1115  })) {
1116  CmdArgs.push_back("-lcgpu-nvptx");
1117  CmdArgs.push_back("-lmgpu-nvptx");
1118  }
1119 }
1120 
1122  const ArgList &Args,
1123  ArgStringList &CmdArgs) {
1124  // Default to clang lib / lib64 folder, i.e. the same location as device
1125  // runtime.
1126  SmallString<256> DefaultLibPath =
1127  llvm::sys::path::parent_path(TC.getDriver().Dir);
1128  llvm::sys::path::append(DefaultLibPath, CLANG_INSTALL_LIBDIR_BASENAME);
1129  CmdArgs.push_back(Args.MakeArgString("-L" + DefaultLibPath));
1130 }
1131 
1132 void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
1133  ArgStringList &CmdArgs) {
1134  if (!Args.hasFlag(options::OPT_frtlib_add_rpath,
1135  options::OPT_fno_rtlib_add_rpath, false))
1136  return;
1137 
1138  SmallVector<std::string> CandidateRPaths(TC.getArchSpecificLibPaths());
1139  if (const auto CandidateRPath = TC.getStdlibPath())
1140  CandidateRPaths.emplace_back(*CandidateRPath);
1141 
1142  for (const auto &CandidateRPath : CandidateRPaths) {
1143  if (TC.getVFS().exists(CandidateRPath)) {
1144  CmdArgs.push_back("-rpath");
1145  CmdArgs.push_back(Args.MakeArgString(CandidateRPath));
1146  }
1147  }
1148 }
1149 
1150 bool tools::addOpenMPRuntime(const Compilation &C, ArgStringList &CmdArgs,
1151  const ToolChain &TC, const ArgList &Args,
1152  bool ForceStaticHostRuntime, bool IsOffloadingHost,
1153  bool GompNeedsRT) {
1154  if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1155  options::OPT_fno_openmp, false))
1156  return false;
1157 
1159 
1160  if (RTKind == Driver::OMPRT_Unknown)
1161  // Already diagnosed.
1162  return false;
1163 
1164  if (ForceStaticHostRuntime)
1165  CmdArgs.push_back("-Bstatic");
1166 
1167  switch (RTKind) {
1168  case Driver::OMPRT_OMP:
1169  CmdArgs.push_back("-lomp");
1170  break;
1171  case Driver::OMPRT_GOMP:
1172  CmdArgs.push_back("-lgomp");
1173  break;
1174  case Driver::OMPRT_IOMP5:
1175  CmdArgs.push_back("-liomp5");
1176  break;
1177  }
1178 
1179  if (ForceStaticHostRuntime)
1180  CmdArgs.push_back("-Bdynamic");
1181 
1182  if (RTKind == Driver::OMPRT_GOMP && GompNeedsRT)
1183  CmdArgs.push_back("-lrt");
1184 
1185  if (IsOffloadingHost)
1186  CmdArgs.push_back("-lomptarget");
1187 
1188  if (IsOffloadingHost && !Args.hasArg(options::OPT_nogpulib))
1189  CmdArgs.push_back("-lomptarget.devicertl");
1190 
1191  if (IsOffloadingHost)
1192  addOpenMPDeviceLibC(C, Args, CmdArgs);
1193 
1194  addArchSpecificRPath(TC, Args, CmdArgs);
1195  addOpenMPRuntimeLibraryPath(TC, Args, CmdArgs);
1196 
1197  return true;
1198 }
1199 
1200 /// Add Fortran runtime libs
1201 void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args,
1202  llvm::opt::ArgStringList &CmdArgs) {
1203  // Link FortranRuntime and FortranDecimal
1204  // These are handled earlier on Windows by telling the frontend driver to
1205  // add the correct libraries to link against as dependents in the object
1206  // file.
1207  if (!TC.getTriple().isKnownWindowsMSVCEnvironment()) {
1208  StringRef F128LibName = TC.getDriver().getFlangF128MathLibrary();
1209  F128LibName.consume_front_insensitive("lib");
1210  if (!F128LibName.empty()) {
1211  bool AsNeeded = !TC.getTriple().isOSAIX();
1212  CmdArgs.push_back("-lFortranFloat128Math");
1213  if (AsNeeded)
1214  addAsNeededOption(TC, Args, CmdArgs, /*as_needed=*/true);
1215  CmdArgs.push_back(Args.MakeArgString("-l" + F128LibName));
1216  if (AsNeeded)
1217  addAsNeededOption(TC, Args, CmdArgs, /*as_needed=*/false);
1218  }
1219  CmdArgs.push_back("-lFortranRuntime");
1220  CmdArgs.push_back("-lFortranDecimal");
1221  }
1222 }
1223 
1225  const llvm::opt::ArgList &Args,
1226  ArgStringList &CmdArgs) {
1227  // Default to the <driver-path>/../lib directory. This works fine on the
1228  // platforms that we have tested so far. We will probably have to re-fine
1229  // this in the future. In particular, on some platforms, we may need to use
1230  // lib64 instead of lib.
1231  SmallString<256> DefaultLibPath =
1232  llvm::sys::path::parent_path(TC.getDriver().Dir);
1233  llvm::sys::path::append(DefaultLibPath, "lib");
1234  if (TC.getTriple().isKnownWindowsMSVCEnvironment())
1235  CmdArgs.push_back(Args.MakeArgString("-libpath:" + DefaultLibPath));
1236  else
1237  CmdArgs.push_back(Args.MakeArgString("-L" + DefaultLibPath));
1238 }
1239 
1240 static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
1241  ArgStringList &CmdArgs, StringRef Sanitizer,
1242  bool IsShared, bool IsWhole) {
1243  // Wrap any static runtimes that must be forced into executable in
1244  // whole-archive.
1245  if (IsWhole) CmdArgs.push_back("--whole-archive");
1246  CmdArgs.push_back(TC.getCompilerRTArgString(
1247  Args, Sanitizer, IsShared ? ToolChain::FT_Shared : ToolChain::FT_Static));
1248  if (IsWhole) CmdArgs.push_back("--no-whole-archive");
1249 
1250  if (IsShared) {
1251  addArchSpecificRPath(TC, Args, CmdArgs);
1252  }
1253 }
1254 
1255 // Tries to use a file with the list of dynamic symbols that need to be exported
1256 // from the runtime library. Returns true if the file was found.
1257 static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args,
1258  ArgStringList &CmdArgs,
1259  StringRef Sanitizer) {
1260  bool LinkerIsGnuLd = solaris::isLinkerGnuLd(TC, Args);
1261 
1262  // Solaris ld defaults to --export-dynamic behaviour but doesn't support
1263  // the option, so don't try to pass it.
1264  if (TC.getTriple().isOSSolaris() && !LinkerIsGnuLd)
1265  return true;
1266  SmallString<128> SanRT(TC.getCompilerRT(Args, Sanitizer));
1267  if (llvm::sys::fs::exists(SanRT + ".syms")) {
1268  CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + SanRT + ".syms"));
1269  return true;
1270  }
1271  return false;
1272 }
1273 
1275  const llvm::opt::ArgList &Args,
1276  llvm::opt::ArgStringList &CmdArgs,
1277  bool as_needed) {
1278  assert(!TC.getTriple().isOSAIX() &&
1279  "AIX linker does not support any form of --as-needed option yet.");
1280  bool LinkerIsGnuLd = solaris::isLinkerGnuLd(TC, Args);
1281 
1282  // While the Solaris 11.2 ld added --as-needed/--no-as-needed as aliases
1283  // for the native forms -z ignore/-z record, they are missing in Illumos,
1284  // so always use the native form.
1285  // GNU ld doesn't support -z ignore/-z record, so don't use them even on
1286  // Solaris.
1287  if (TC.getTriple().isOSSolaris() && !LinkerIsGnuLd) {
1288  CmdArgs.push_back("-z");
1289  CmdArgs.push_back(as_needed ? "ignore" : "record");
1290  } else {
1291  CmdArgs.push_back(as_needed ? "--as-needed" : "--no-as-needed");
1292  }
1293 }
1294 
1296  const llvm::opt::ArgList &Args,
1297  ArgStringList &CmdArgs) {
1298  // Force linking against the system libraries sanitizers depends on
1299  // (see PR15823 why this is necessary).
1300  addAsNeededOption(TC, Args, CmdArgs, false);
1301  // There's no libpthread or librt on RTEMS & Android.
1302  if (TC.getTriple().getOS() != llvm::Triple::RTEMS &&
1303  !TC.getTriple().isAndroid() && !TC.getTriple().isOHOSFamily()) {
1304  CmdArgs.push_back("-lpthread");
1305  if (!TC.getTriple().isOSOpenBSD())
1306  CmdArgs.push_back("-lrt");
1307  }
1308  CmdArgs.push_back("-lm");
1309  // There's no libdl on all OSes.
1310  if (!TC.getTriple().isOSFreeBSD() && !TC.getTriple().isOSNetBSD() &&
1311  !TC.getTriple().isOSOpenBSD() &&
1312  TC.getTriple().getOS() != llvm::Triple::RTEMS)
1313  CmdArgs.push_back("-ldl");
1314  // Required for backtrace on some OSes
1315  if (TC.getTriple().isOSFreeBSD() ||
1316  TC.getTriple().isOSNetBSD() ||
1317  TC.getTriple().isOSOpenBSD())
1318  CmdArgs.push_back("-lexecinfo");
1319  // There is no libresolv on Android, FreeBSD, OpenBSD, etc. On musl
1320  // libresolv.a, even if exists, is an empty archive to satisfy POSIX -lresolv
1321  // requirement.
1322  if (TC.getTriple().isOSLinux() && !TC.getTriple().isAndroid() &&
1323  !TC.getTriple().isMusl())
1324  CmdArgs.push_back("-lresolv");
1325 }
1326 
1327 static void
1328 collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
1329  SmallVectorImpl<StringRef> &SharedRuntimes,
1330  SmallVectorImpl<StringRef> &StaticRuntimes,
1331  SmallVectorImpl<StringRef> &NonWholeStaticRuntimes,
1332  SmallVectorImpl<StringRef> &HelperStaticRuntimes,
1333  SmallVectorImpl<StringRef> &RequiredSymbols) {
1334  const SanitizerArgs &SanArgs = TC.getSanitizerArgs(Args);
1335  // Collect shared runtimes.
1336  if (SanArgs.needsSharedRt()) {
1337  if (SanArgs.needsAsanRt()) {
1338  SharedRuntimes.push_back("asan");
1339  if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid())
1340  HelperStaticRuntimes.push_back("asan-preinit");
1341  }
1342  if (SanArgs.needsMemProfRt()) {
1343  SharedRuntimes.push_back("memprof");
1344  if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid())
1345  HelperStaticRuntimes.push_back("memprof-preinit");
1346  }
1347  if (SanArgs.needsUbsanRt()) {
1348  if (SanArgs.requiresMinimalRuntime())
1349  SharedRuntimes.push_back("ubsan_minimal");
1350  else
1351  SharedRuntimes.push_back("ubsan_standalone");
1352  }
1353  if (SanArgs.needsScudoRt()) {
1354  SharedRuntimes.push_back("scudo_standalone");
1355  }
1356  if (SanArgs.needsTsanRt())
1357  SharedRuntimes.push_back("tsan");
1358  if (SanArgs.needsHwasanRt()) {
1359  if (SanArgs.needsHwasanAliasesRt())
1360  SharedRuntimes.push_back("hwasan_aliases");
1361  else
1362  SharedRuntimes.push_back("hwasan");
1363  if (!Args.hasArg(options::OPT_shared))
1364  HelperStaticRuntimes.push_back("hwasan-preinit");
1365  }
1366  }
1367 
1368  // The stats_client library is also statically linked into DSOs.
1369  if (SanArgs.needsStatsRt())
1370  StaticRuntimes.push_back("stats_client");
1371 
1372  // Always link the static runtime regardless of DSO or executable.
1373  if (SanArgs.needsAsanRt())
1374  HelperStaticRuntimes.push_back("asan_static");
1375 
1376  // Collect static runtimes.
1377  if (Args.hasArg(options::OPT_shared)) {
1378  // Don't link static runtimes into DSOs.
1379  return;
1380  }
1381 
1382  // Each static runtime that has a DSO counterpart above is excluded below,
1383  // but runtimes that exist only as static are not affected by needsSharedRt.
1384 
1385  if (!SanArgs.needsSharedRt() && SanArgs.needsAsanRt()) {
1386  StaticRuntimes.push_back("asan");
1387  if (SanArgs.linkCXXRuntimes())
1388  StaticRuntimes.push_back("asan_cxx");
1389  }
1390 
1391  if (!SanArgs.needsSharedRt() && SanArgs.needsMemProfRt()) {
1392  StaticRuntimes.push_back("memprof");
1393  if (SanArgs.linkCXXRuntimes())
1394  StaticRuntimes.push_back("memprof_cxx");
1395  }
1396 
1397  if (!SanArgs.needsSharedRt() && SanArgs.needsHwasanRt()) {
1398  if (SanArgs.needsHwasanAliasesRt()) {
1399  StaticRuntimes.push_back("hwasan_aliases");
1400  if (SanArgs.linkCXXRuntimes())
1401  StaticRuntimes.push_back("hwasan_aliases_cxx");
1402  } else {
1403  StaticRuntimes.push_back("hwasan");
1404  if (SanArgs.linkCXXRuntimes())
1405  StaticRuntimes.push_back("hwasan_cxx");
1406  }
1407  }
1408  if (SanArgs.needsDfsanRt())
1409  StaticRuntimes.push_back("dfsan");
1410  if (SanArgs.needsLsanRt())
1411  StaticRuntimes.push_back("lsan");
1412  if (SanArgs.needsMsanRt()) {
1413  StaticRuntimes.push_back("msan");
1414  if (SanArgs.linkCXXRuntimes())
1415  StaticRuntimes.push_back("msan_cxx");
1416  }
1417  if (!SanArgs.needsSharedRt() && SanArgs.needsTsanRt()) {
1418  StaticRuntimes.push_back("tsan");
1419  if (SanArgs.linkCXXRuntimes())
1420  StaticRuntimes.push_back("tsan_cxx");
1421  }
1422  if (!SanArgs.needsSharedRt() && SanArgs.needsUbsanRt()) {
1423  if (SanArgs.requiresMinimalRuntime()) {
1424  StaticRuntimes.push_back("ubsan_minimal");
1425  } else {
1426  StaticRuntimes.push_back("ubsan_standalone");
1427  if (SanArgs.linkCXXRuntimes())
1428  StaticRuntimes.push_back("ubsan_standalone_cxx");
1429  }
1430  }
1431  if (SanArgs.needsSafeStackRt()) {
1432  NonWholeStaticRuntimes.push_back("safestack");
1433  RequiredSymbols.push_back("__safestack_init");
1434  }
1435  if (!(SanArgs.needsSharedRt() && SanArgs.needsUbsanRt())) {
1436  if (SanArgs.needsCfiRt())
1437  StaticRuntimes.push_back("cfi");
1438  if (SanArgs.needsCfiDiagRt()) {
1439  StaticRuntimes.push_back("cfi_diag");
1440  if (SanArgs.linkCXXRuntimes())
1441  StaticRuntimes.push_back("ubsan_standalone_cxx");
1442  }
1443  }
1444  if (SanArgs.needsStatsRt()) {
1445  NonWholeStaticRuntimes.push_back("stats");
1446  RequiredSymbols.push_back("__sanitizer_stats_register");
1447  }
1448  if (!SanArgs.needsSharedRt() && SanArgs.needsScudoRt()) {
1449  StaticRuntimes.push_back("scudo_standalone");
1450  if (SanArgs.linkCXXRuntimes())
1451  StaticRuntimes.push_back("scudo_standalone_cxx");
1452  }
1453 }
1454 
1455 // Should be called before we add system libraries (C++ ABI, libstdc++/libc++,
1456 // C runtime, etc). Returns true if sanitizer system deps need to be linked in.
1457 bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
1458  ArgStringList &CmdArgs) {
1459  const SanitizerArgs &SanArgs = TC.getSanitizerArgs(Args);
1460  SmallVector<StringRef, 4> SharedRuntimes, StaticRuntimes,
1461  NonWholeStaticRuntimes, HelperStaticRuntimes, RequiredSymbols;
1462  if (SanArgs.linkRuntimes()) {
1463  collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes,
1464  NonWholeStaticRuntimes, HelperStaticRuntimes,
1465  RequiredSymbols);
1466  }
1467 
1468  // Inject libfuzzer dependencies.
1469  if (SanArgs.needsFuzzer() && SanArgs.linkRuntimes() &&
1470  !Args.hasArg(options::OPT_shared)) {
1471 
1472  addSanitizerRuntime(TC, Args, CmdArgs, "fuzzer", false, true);
1473  if (SanArgs.needsFuzzerInterceptors())
1474  addSanitizerRuntime(TC, Args, CmdArgs, "fuzzer_interceptors", false,
1475  true);
1476  if (!Args.hasArg(clang::driver::options::OPT_nostdlibxx)) {
1477  bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
1478  !Args.hasArg(options::OPT_static);
1479  if (OnlyLibstdcxxStatic)
1480  CmdArgs.push_back("-Bstatic");
1481  TC.AddCXXStdlibLibArgs(Args, CmdArgs);
1482  if (OnlyLibstdcxxStatic)
1483  CmdArgs.push_back("-Bdynamic");
1484  }
1485  }
1486 
1487  for (auto RT : SharedRuntimes)
1488  addSanitizerRuntime(TC, Args, CmdArgs, RT, true, false);
1489  for (auto RT : HelperStaticRuntimes)
1490  addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true);
1491  bool AddExportDynamic = false;
1492  for (auto RT : StaticRuntimes) {
1493  addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true);
1494  AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT);
1495  }
1496  for (auto RT : NonWholeStaticRuntimes) {
1497  addSanitizerRuntime(TC, Args, CmdArgs, RT, false, false);
1498  AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT);
1499  }
1500  for (auto S : RequiredSymbols) {
1501  CmdArgs.push_back("-u");
1502  CmdArgs.push_back(Args.MakeArgString(S));
1503  }
1504  // If there is a static runtime with no dynamic list, force all the symbols
1505  // to be dynamic to be sure we export sanitizer interface functions.
1506  if (AddExportDynamic)
1507  CmdArgs.push_back("--export-dynamic");
1508 
1509  if (SanArgs.hasCrossDsoCfi() && !AddExportDynamic)
1510  CmdArgs.push_back("--export-dynamic-symbol=__cfi_check");
1511 
1512  if (SanArgs.hasMemTag()) {
1513  if (!TC.getTriple().isAndroid()) {
1514  TC.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
1515  << "-fsanitize=memtag*" << TC.getTriple().str();
1516  }
1517  CmdArgs.push_back(
1518  Args.MakeArgString("--android-memtag-mode=" + SanArgs.getMemtagMode()));
1519  if (SanArgs.hasMemtagHeap())
1520  CmdArgs.push_back("--android-memtag-heap");
1521  if (SanArgs.hasMemtagStack())
1522  CmdArgs.push_back("--android-memtag-stack");
1523  }
1524 
1525  return !StaticRuntimes.empty() || !NonWholeStaticRuntimes.empty();
1526 }
1527 
1528 bool tools::addXRayRuntime(const ToolChain&TC, const ArgList &Args, ArgStringList &CmdArgs) {
1529  if (Args.hasArg(options::OPT_shared))
1530  return false;
1531 
1532  if (TC.getXRayArgs().needsXRayRt()) {
1533  CmdArgs.push_back("--whole-archive");
1534  CmdArgs.push_back(TC.getCompilerRTArgString(Args, "xray"));
1535  for (const auto &Mode : TC.getXRayArgs().modeList())
1536  CmdArgs.push_back(TC.getCompilerRTArgString(Args, Mode));
1537  CmdArgs.push_back("--no-whole-archive");
1538  return true;
1539  }
1540 
1541  return false;
1542 }
1543 
1544 void tools::linkXRayRuntimeDeps(const ToolChain &TC,
1545  const llvm::opt::ArgList &Args,
1546  ArgStringList &CmdArgs) {
1547  addAsNeededOption(TC, Args, CmdArgs, false);
1548  CmdArgs.push_back("-lpthread");
1549  if (!TC.getTriple().isOSOpenBSD())
1550  CmdArgs.push_back("-lrt");
1551  CmdArgs.push_back("-lm");
1552 
1553  if (!TC.getTriple().isOSFreeBSD() &&
1554  !TC.getTriple().isOSNetBSD() &&
1555  !TC.getTriple().isOSOpenBSD())
1556  CmdArgs.push_back("-ldl");
1557 }
1558 
1559 bool tools::areOptimizationsEnabled(const ArgList &Args) {
1560  // Find the last -O arg and see if it is non-zero.
1561  if (Arg *A = Args.getLastArg(options::OPT_O_Group))
1562  return !A->getOption().matches(options::OPT_O0);
1563  // Defaults to -O0.
1564  return false;
1565 }
1566 
1567 bool tools::isDependentLibAdded(const ArgList &Args, StringRef Lib) {
1568  // Check if given Lib is added via --dependent-lib
1569  SmallString<64> DepLib("--dependent-lib=");
1570  DepLib += Lib;
1571  return llvm::any_of(Args.getAllArgValues(options::OPT_Xclang),
1572  [&DepLib](StringRef Option) { return Option == DepLib; });
1573 }
1574 
1575 const char *tools::SplitDebugName(const JobAction &JA, const ArgList &Args,
1576  const InputInfo &Input,
1577  const InputInfo &Output) {
1578  auto AddPostfix = [JA](auto &F) {
1580  F += (Twine("_") + JA.getOffloadingArch()).str();
1581  F += ".dwo";
1582  };
1583  if (Arg *A = Args.getLastArg(options::OPT_gsplit_dwarf_EQ))
1584  if (StringRef(A->getValue()) == "single" && Output.isFilename())
1585  return Args.MakeArgString(Output.getFilename());
1586 
1588  if (const Arg *A = Args.getLastArg(options::OPT_dumpdir)) {
1589  T = A->getValue();
1590  } else {
1591  Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
1592  if (FinalOutput && Args.hasArg(options::OPT_c)) {
1593  T = FinalOutput->getValue();
1594  llvm::sys::path::remove_filename(T);
1595  llvm::sys::path::append(T,
1596  llvm::sys::path::stem(FinalOutput->getValue()));
1597  AddPostfix(T);
1598  return Args.MakeArgString(T);
1599  }
1600  }
1601 
1602  T += llvm::sys::path::stem(Input.getBaseInput());
1603  AddPostfix(T);
1604  return Args.MakeArgString(T);
1605 }
1606 
1607 void tools::SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T,
1608  const JobAction &JA, const ArgList &Args,
1609  const InputInfo &Output, const char *OutFile) {
1610  ArgStringList ExtractArgs;
1611  ExtractArgs.push_back("--extract-dwo");
1612 
1613  ArgStringList StripArgs;
1614  StripArgs.push_back("--strip-dwo");
1615 
1616  // Grabbing the output of the earlier compile step.
1617  StripArgs.push_back(Output.getFilename());
1618  ExtractArgs.push_back(Output.getFilename());
1619  ExtractArgs.push_back(OutFile);
1620 
1621  const char *Exec =
1622  Args.MakeArgString(TC.GetProgramPath(CLANG_DEFAULT_OBJCOPY));
1623  InputInfo II(types::TY_Object, Output.getFilename(), Output.getFilename());
1624 
1625  // First extract the dwo sections.
1626  C.addCommand(std::make_unique<Command>(JA, T,
1628  Exec, ExtractArgs, II, Output));
1629 
1630  // Then remove them from the original .o file.
1631  C.addCommand(std::make_unique<Command>(
1632  JA, T, ResponseFileSupport::AtFileCurCP(), Exec, StripArgs, II, Output));
1633 }
1634 
1635 // Claim options we don't want to warn if they are unused. We do this for
1636 // options that build systems might add but are unused when assembling or only
1637 // running the preprocessor for example.
1638 void tools::claimNoWarnArgs(const ArgList &Args) {
1639  // Don't warn about unused -f(no-)?lto. This can happen when we're
1640  // preprocessing, precompiling or assembling.
1641  Args.ClaimAllArgs(options::OPT_flto_EQ);
1642  Args.ClaimAllArgs(options::OPT_flto);
1643  Args.ClaimAllArgs(options::OPT_fno_lto);
1644 }
1645 
1646 Arg *tools::getLastCSProfileGenerateArg(const ArgList &Args) {
1647  auto *CSPGOGenerateArg = Args.getLastArg(options::OPT_fcs_profile_generate,
1648  options::OPT_fcs_profile_generate_EQ,
1649  options::OPT_fno_profile_generate);
1650  if (CSPGOGenerateArg &&
1651  CSPGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate))
1652  CSPGOGenerateArg = nullptr;
1653 
1654  return CSPGOGenerateArg;
1655 }
1656 
1657 Arg *tools::getLastProfileUseArg(const ArgList &Args) {
1658  auto *ProfileUseArg = Args.getLastArg(
1659  options::OPT_fprofile_instr_use, options::OPT_fprofile_instr_use_EQ,
1660  options::OPT_fprofile_use, options::OPT_fprofile_use_EQ,
1661  options::OPT_fno_profile_instr_use);
1662 
1663  if (ProfileUseArg &&
1664  ProfileUseArg->getOption().matches(options::OPT_fno_profile_instr_use))
1665  ProfileUseArg = nullptr;
1666 
1667  return ProfileUseArg;
1668 }
1669 
1670 Arg *tools::getLastProfileSampleUseArg(const ArgList &Args) {
1671  auto *ProfileSampleUseArg = Args.getLastArg(
1672  options::OPT_fprofile_sample_use, options::OPT_fprofile_sample_use_EQ,
1673  options::OPT_fauto_profile, options::OPT_fauto_profile_EQ,
1674  options::OPT_fno_profile_sample_use, options::OPT_fno_auto_profile);
1675 
1676  if (ProfileSampleUseArg &&
1677  (ProfileSampleUseArg->getOption().matches(
1678  options::OPT_fno_profile_sample_use) ||
1679  ProfileSampleUseArg->getOption().matches(options::OPT_fno_auto_profile)))
1680  return nullptr;
1681 
1682  return Args.getLastArg(options::OPT_fprofile_sample_use_EQ,
1683  options::OPT_fauto_profile_EQ);
1684 }
1685 
1686 const char *tools::RelocationModelName(llvm::Reloc::Model Model) {
1687  switch (Model) {
1688  case llvm::Reloc::Static:
1689  return "static";
1690  case llvm::Reloc::PIC_:
1691  return "pic";
1692  case llvm::Reloc::DynamicNoPIC:
1693  return "dynamic-no-pic";
1694  case llvm::Reloc::ROPI:
1695  return "ropi";
1696  case llvm::Reloc::RWPI:
1697  return "rwpi";
1698  case llvm::Reloc::ROPI_RWPI:
1699  return "ropi-rwpi";
1700  }
1701  llvm_unreachable("Unknown Reloc::Model kind");
1702 }
1703 
1704 /// Parses the various -fpic/-fPIC/-fpie/-fPIE arguments. Then,
1705 /// smooshes them together with platform defaults, to decide whether
1706 /// this compile should be using PIC mode or not. Returns a tuple of
1707 /// (RelocationModel, PICLevel, IsPIE).
1708 std::tuple<llvm::Reloc::Model, unsigned, bool>
1709 tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) {
1710  const llvm::Triple &EffectiveTriple = ToolChain.getEffectiveTriple();
1711  const llvm::Triple &Triple = ToolChain.getTriple();
1712 
1713  bool PIE = ToolChain.isPIEDefault(Args);
1714  bool PIC = PIE || ToolChain.isPICDefault();
1715  // The Darwin/MachO default to use PIC does not apply when using -static.
1716  if (Triple.isOSBinFormatMachO() && Args.hasArg(options::OPT_static))
1717  PIE = PIC = false;
1718  bool IsPICLevelTwo = PIC;
1719 
1720  bool KernelOrKext =
1721  Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
1722 
1723  // Android-specific defaults for PIC/PIE
1724  if (Triple.isAndroid()) {
1725  switch (Triple.getArch()) {
1726  case llvm::Triple::arm:
1727  case llvm::Triple::armeb:
1728  case llvm::Triple::thumb:
1729  case llvm::Triple::thumbeb:
1730  case llvm::Triple::aarch64:
1731  case llvm::Triple::mips:
1732  case llvm::Triple::mipsel:
1733  case llvm::Triple::mips64:
1734  case llvm::Triple::mips64el:
1735  PIC = true; // "-fpic"
1736  break;
1737 
1738  case llvm::Triple::x86:
1739  case llvm::Triple::x86_64:
1740  PIC = true; // "-fPIC"
1741  IsPICLevelTwo = true;
1742  break;
1743 
1744  default:
1745  break;
1746  }
1747  }
1748 
1749  // OHOS-specific defaults for PIC/PIE
1750  if (Triple.isOHOSFamily() && Triple.getArch() == llvm::Triple::aarch64)
1751  PIC = true;
1752 
1753  // OpenBSD-specific defaults for PIE
1754  if (Triple.isOSOpenBSD()) {
1755  switch (ToolChain.getArch()) {
1756  case llvm::Triple::arm:
1757  case llvm::Triple::aarch64:
1758  case llvm::Triple::mips64:
1759  case llvm::Triple::mips64el:
1760  case llvm::Triple::x86:
1761  case llvm::Triple::x86_64:
1762  IsPICLevelTwo = false; // "-fpie"
1763  break;
1764 
1765  case llvm::Triple::ppc:
1766  case llvm::Triple::sparcv9:
1767  IsPICLevelTwo = true; // "-fPIE"
1768  break;
1769 
1770  default:
1771  break;
1772  }
1773  }
1774 
1775  // The last argument relating to either PIC or PIE wins, and no
1776  // other argument is used. If the last argument is any flavor of the
1777  // '-fno-...' arguments, both PIC and PIE are disabled. Any PIE
1778  // option implicitly enables PIC at the same level.
1779  Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
1780  options::OPT_fpic, options::OPT_fno_pic,
1781  options::OPT_fPIE, options::OPT_fno_PIE,
1782  options::OPT_fpie, options::OPT_fno_pie);
1783  if (Triple.isOSWindows() && !Triple.isOSCygMing() && LastPICArg &&
1784  LastPICArg == Args.getLastArg(options::OPT_fPIC, options::OPT_fpic,
1785  options::OPT_fPIE, options::OPT_fpie)) {
1786  ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
1787  << LastPICArg->getSpelling() << Triple.str();
1788  if (Triple.getArch() == llvm::Triple::x86_64)
1789  return std::make_tuple(llvm::Reloc::PIC_, 2U, false);
1790  return std::make_tuple(llvm::Reloc::Static, 0U, false);
1791  }
1792 
1793  // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness
1794  // is forced, then neither PIC nor PIE flags will have no effect.
1795  if (!ToolChain.isPICDefaultForced()) {
1796  if (LastPICArg) {
1797  Option O = LastPICArg->getOption();
1798  if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
1799  O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) {
1800  PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie);
1801  PIC =
1802  PIE || O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic);
1803  IsPICLevelTwo =
1804  O.matches(options::OPT_fPIE) || O.matches(options::OPT_fPIC);
1805  } else {
1806  PIE = PIC = false;
1807  if (EffectiveTriple.isPS()) {
1808  Arg *ModelArg = Args.getLastArg(options::OPT_mcmodel_EQ);
1809  StringRef Model = ModelArg ? ModelArg->getValue() : "";
1810  if (Model != "kernel") {
1811  PIC = true;
1812  ToolChain.getDriver().Diag(diag::warn_drv_ps_force_pic)
1813  << LastPICArg->getSpelling()
1814  << (EffectiveTriple.isPS4() ? "PS4" : "PS5");
1815  }
1816  }
1817  }
1818  }
1819  }
1820 
1821  // Introduce a Darwin and PS4/PS5-specific hack. If the default is PIC, but
1822  // the PIC level would've been set to level 1, force it back to level 2 PIC
1823  // instead.
1824  if (PIC && (Triple.isOSDarwin() || EffectiveTriple.isPS()))
1825  IsPICLevelTwo |= ToolChain.isPICDefault();
1826 
1827  // This kernel flags are a trump-card: they will disable PIC/PIE
1828  // generation, independent of the argument order.
1829  if (KernelOrKext &&
1830  ((!EffectiveTriple.isiOS() || EffectiveTriple.isOSVersionLT(6)) &&
1831  !EffectiveTriple.isWatchOS() && !EffectiveTriple.isDriverKit()))
1832  PIC = PIE = false;
1833 
1834  if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) {
1835  // This is a very special mode. It trumps the other modes, almost no one
1836  // uses it, and it isn't even valid on any OS but Darwin.
1837  if (!Triple.isOSDarwin())
1838  ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
1839  << A->getSpelling() << Triple.str();
1840 
1841  // FIXME: Warn when this flag trumps some other PIC or PIE flag.
1842 
1843  // Only a forced PIC mode can cause the actual compile to have PIC defines
1844  // etc., no flags are sufficient. This behavior was selected to closely
1845  // match that of llvm-gcc and Apple GCC before that.
1847 
1848  return std::make_tuple(llvm::Reloc::DynamicNoPIC, PIC ? 2U : 0U, false);
1849  }
1850 
1851  bool EmbeddedPISupported;
1852  switch (Triple.getArch()) {
1853  case llvm::Triple::arm:
1854  case llvm::Triple::armeb:
1855  case llvm::Triple::thumb:
1856  case llvm::Triple::thumbeb:
1857  EmbeddedPISupported = true;
1858  break;
1859  default:
1860  EmbeddedPISupported = false;
1861  break;
1862  }
1863 
1864  bool ROPI = false, RWPI = false;
1865  Arg* LastROPIArg = Args.getLastArg(options::OPT_fropi, options::OPT_fno_ropi);
1866  if (LastROPIArg && LastROPIArg->getOption().matches(options::OPT_fropi)) {
1867  if (!EmbeddedPISupported)
1868  ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
1869  << LastROPIArg->getSpelling() << Triple.str();
1870  ROPI = true;
1871  }
1872  Arg *LastRWPIArg = Args.getLastArg(options::OPT_frwpi, options::OPT_fno_rwpi);
1873  if (LastRWPIArg && LastRWPIArg->getOption().matches(options::OPT_frwpi)) {
1874  if (!EmbeddedPISupported)
1875  ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
1876  << LastRWPIArg->getSpelling() << Triple.str();
1877  RWPI = true;
1878  }
1879 
1880  // ROPI and RWPI are not compatible with PIC or PIE.
1881  if ((ROPI || RWPI) && (PIC || PIE))
1882  ToolChain.getDriver().Diag(diag::err_drv_ropi_rwpi_incompatible_with_pic);
1883 
1884  if (Triple.isMIPS()) {
1885  StringRef CPUName;
1886  StringRef ABIName;
1887  mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
1888  // When targeting the N64 ABI, PIC is the default, except in the case
1889  // when the -mno-abicalls option is used. In that case we exit
1890  // at next check regardless of PIC being set below.
1891  if (ABIName == "n64")
1892  PIC = true;
1893  // When targettng MIPS with -mno-abicalls, it's always static.
1894  if(Args.hasArg(options::OPT_mno_abicalls))
1895  return std::make_tuple(llvm::Reloc::Static, 0U, false);
1896  // Unlike other architectures, MIPS, even with -fPIC/-mxgot/multigot,
1897  // does not use PIC level 2 for historical reasons.
1898  IsPICLevelTwo = false;
1899  }
1900 
1901  if (PIC)
1902  return std::make_tuple(llvm::Reloc::PIC_, IsPICLevelTwo ? 2U : 1U, PIE);
1903 
1904  llvm::Reloc::Model RelocM = llvm::Reloc::Static;
1905  if (ROPI && RWPI)
1906  RelocM = llvm::Reloc::ROPI_RWPI;
1907  else if (ROPI)
1908  RelocM = llvm::Reloc::ROPI;
1909  else if (RWPI)
1910  RelocM = llvm::Reloc::RWPI;
1911 
1912  return std::make_tuple(RelocM, 0U, false);
1913 }
1914 
1915 // `-falign-functions` indicates that the functions should be aligned to a
1916 // 16-byte boundary.
1917 //
1918 // `-falign-functions=1` is the same as `-fno-align-functions`.
1919 //
1920 // The scalar `n` in `-falign-functions=n` must be an integral value between
1921 // [0, 65536]. If the value is not a power-of-two, it will be rounded up to
1922 // the nearest power-of-two.
1923 //
1924 // If we return `0`, the frontend will default to the backend's preferred
1925 // alignment.
1926 //
1927 // NOTE: icc only allows values between [0, 4096]. icc uses `-falign-functions`
1928 // to mean `-falign-functions=16`. GCC defaults to the backend's preferred
1929 // alignment. For unaligned functions, we default to the backend's preferred
1930 // alignment.
1931 unsigned tools::ParseFunctionAlignment(const ToolChain &TC,
1932  const ArgList &Args) {
1933  const Arg *A = Args.getLastArg(options::OPT_falign_functions,
1934  options::OPT_falign_functions_EQ,
1935  options::OPT_fno_align_functions);
1936  if (!A || A->getOption().matches(options::OPT_fno_align_functions))
1937  return 0;
1938 
1939  if (A->getOption().matches(options::OPT_falign_functions))
1940  return 0;
1941 
1942  unsigned Value = 0;
1943  if (StringRef(A->getValue()).getAsInteger(10, Value) || Value > 65536)
1944  TC.getDriver().Diag(diag::err_drv_invalid_int_value)
1945  << A->getAsString(Args) << A->getValue();
1946  return Value ? llvm::Log2_32_Ceil(std::min(Value, 65536u)) : Value;
1947 }
1948 
1950  ArgStringList &CmdArgs, llvm::codegenoptions::DebugInfoKind DebugInfoKind) {
1951  switch (DebugInfoKind) {
1952  case llvm::codegenoptions::DebugDirectivesOnly:
1953  CmdArgs.push_back("-debug-info-kind=line-directives-only");
1954  break;
1955  case llvm::codegenoptions::DebugLineTablesOnly:
1956  CmdArgs.push_back("-debug-info-kind=line-tables-only");
1957  break;
1958  case llvm::codegenoptions::DebugInfoConstructor:
1959  CmdArgs.push_back("-debug-info-kind=constructor");
1960  break;
1961  case llvm::codegenoptions::LimitedDebugInfo:
1962  CmdArgs.push_back("-debug-info-kind=limited");
1963  break;
1964  case llvm::codegenoptions::FullDebugInfo:
1965  CmdArgs.push_back("-debug-info-kind=standalone");
1966  break;
1967  case llvm::codegenoptions::UnusedTypeInfo:
1968  CmdArgs.push_back("-debug-info-kind=unused-types");
1969  break;
1970  default:
1971  break;
1972  }
1973 }
1974 
1975 // Convert an arg of the form "-gN" or "-ggdbN" or one of their aliases
1976 // to the corresponding DebugInfoKind.
1977 llvm::codegenoptions::DebugInfoKind tools::debugLevelToInfoKind(const Arg &A) {
1978  assert(A.getOption().matches(options::OPT_gN_Group) &&
1979  "Not a -g option that specifies a debug-info level");
1980  if (A.getOption().matches(options::OPT_g0) ||
1981  A.getOption().matches(options::OPT_ggdb0))
1982  return llvm::codegenoptions::NoDebugInfo;
1983  if (A.getOption().matches(options::OPT_gline_tables_only) ||
1984  A.getOption().matches(options::OPT_ggdb1))
1985  return llvm::codegenoptions::DebugLineTablesOnly;
1986  if (A.getOption().matches(options::OPT_gline_directives_only))
1987  return llvm::codegenoptions::DebugDirectivesOnly;
1988  return llvm::codegenoptions::DebugInfoConstructor;
1989 }
1990 
1991 static unsigned ParseDebugDefaultVersion(const ToolChain &TC,
1992  const ArgList &Args) {
1993  const Arg *A = Args.getLastArg(options::OPT_fdebug_default_version);
1994 
1995  if (!A)
1996  return 0;
1997 
1998  unsigned Value = 0;
1999  if (StringRef(A->getValue()).getAsInteger(10, Value) || Value > 5 ||
2000  Value < 2)
2001  TC.getDriver().Diag(diag::err_drv_invalid_int_value)
2002  << A->getAsString(Args) << A->getValue();
2003  return Value;
2004 }
2005 
2006 unsigned tools::DwarfVersionNum(StringRef ArgValue) {
2007  return llvm::StringSwitch<unsigned>(ArgValue)
2008  .Case("-gdwarf-2", 2)
2009  .Case("-gdwarf-3", 3)
2010  .Case("-gdwarf-4", 4)
2011  .Case("-gdwarf-5", 5)
2012  .Default(0);
2013 }
2014 
2015 const Arg *tools::getDwarfNArg(const ArgList &Args) {
2016  return Args.getLastArg(options::OPT_gdwarf_2, options::OPT_gdwarf_3,
2017  options::OPT_gdwarf_4, options::OPT_gdwarf_5,
2018  options::OPT_gdwarf);
2019 }
2020 
2022  const llvm::opt::ArgList &Args) {
2023  unsigned DwarfVersion = ParseDebugDefaultVersion(TC, Args);
2024  if (const Arg *GDwarfN = getDwarfNArg(Args))
2025  if (int N = DwarfVersionNum(GDwarfN->getSpelling())) {
2026  DwarfVersion = N;
2027  if (DwarfVersion == 5 && TC.getTriple().isOSAIX())
2028  TC.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
2029  << GDwarfN->getSpelling() << TC.getTriple().str();
2030  }
2031  if (DwarfVersion == 0) {
2032  DwarfVersion = TC.GetDefaultDwarfVersion();
2033  assert(DwarfVersion && "toolchain default DWARF version must be nonzero");
2034  }
2035  return DwarfVersion;
2036 }
2037 
2038 void tools::AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args,
2039  ArgStringList &CmdArgs) {
2040  llvm::Reloc::Model RelocationModel;
2041  unsigned PICLevel;
2042  bool IsPIE;
2043  std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(ToolChain, Args);
2044 
2045  if (RelocationModel != llvm::Reloc::Static)
2046  CmdArgs.push_back("-KPIC");
2047 }
2048 
2049 /// Determine whether Objective-C automated reference counting is
2050 /// enabled.
2051 bool tools::isObjCAutoRefCount(const ArgList &Args) {
2052  return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
2053 }
2054 
2056 
2057 static LibGccType getLibGccType(const ToolChain &TC, const Driver &D,
2058  const ArgList &Args) {
2059  if (Args.hasArg(options::OPT_static_libgcc) ||
2060  Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_static_pie) ||
2061  // The Android NDK only provides libunwind.a, not libunwind.so.
2062  TC.getTriple().isAndroid())
2063  return LibGccType::StaticLibGcc;
2064  if (Args.hasArg(options::OPT_shared_libgcc))
2065  return LibGccType::SharedLibGcc;
2067 }
2068 
2069 // Gcc adds libgcc arguments in various ways:
2070 //
2071 // gcc <none>: -lgcc --as-needed -lgcc_s --no-as-needed
2072 // g++ <none>: -lgcc_s -lgcc
2073 // gcc shared: -lgcc_s -lgcc
2074 // g++ shared: -lgcc_s -lgcc
2075 // gcc static: -lgcc -lgcc_eh
2076 // g++ static: -lgcc -lgcc_eh
2077 // gcc static-pie: -lgcc -lgcc_eh
2078 // g++ static-pie: -lgcc -lgcc_eh
2079 //
2080 // Also, certain targets need additional adjustments.
2081 
2082 static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
2083  ArgStringList &CmdArgs, const ArgList &Args) {
2085  // By default OHOS binaries are linked statically to libunwind.
2086  if (TC.getTriple().isOHOSFamily() && UNW == ToolChain::UNW_CompilerRT) {
2087  CmdArgs.push_back("-l:libunwind.a");
2088  return;
2089  }
2090 
2091  // Targets that don't use unwind libraries.
2092  if ((TC.getTriple().isAndroid() && UNW == ToolChain::UNW_Libgcc) ||
2093  TC.getTriple().isOSIAMCU() || TC.getTriple().isOSBinFormatWasm() ||
2094  TC.getTriple().isWindowsMSVCEnvironment() || UNW == ToolChain::UNW_None)
2095  return;
2096 
2097  LibGccType LGT = getLibGccType(TC, D, Args);
2098  bool AsNeeded = LGT == LibGccType::UnspecifiedLibGcc &&
2099  (UNW == ToolChain::UNW_CompilerRT || !D.CCCIsCXX()) &&
2100  !TC.getTriple().isAndroid() &&
2101  !TC.getTriple().isOSCygMing() && !TC.getTriple().isOSAIX();
2102  if (AsNeeded)
2103  addAsNeededOption(TC, Args, CmdArgs, true);
2104 
2105  switch (UNW) {
2106  case ToolChain::UNW_Libgcc: {
2107  if (LGT == LibGccType::StaticLibGcc)
2108  CmdArgs.push_back("-lgcc_eh");
2109  else
2110  CmdArgs.push_back("-lgcc_s");
2111  break;
2112  }
2114  if (TC.getTriple().isOSAIX()) {
2115  // AIX only has libunwind as a shared library. So do not pass
2116  // anything in if -static is specified.
2117  if (LGT != LibGccType::StaticLibGcc)
2118  CmdArgs.push_back("-lunwind");
2119  } else if (LGT == LibGccType::StaticLibGcc) {
2120  CmdArgs.push_back("-l:libunwind.a");
2121  } else if (LGT == LibGccType::SharedLibGcc) {
2122  if (TC.getTriple().isOSCygMing())
2123  CmdArgs.push_back("-l:libunwind.dll.a");
2124  else
2125  CmdArgs.push_back("-l:libunwind.so");
2126  } else {
2127  // Let the linker choose between libunwind.so and libunwind.a
2128  // depending on what's available, and depending on the -static flag
2129  CmdArgs.push_back("-lunwind");
2130  }
2131  break;
2132  }
2133 
2134  if (AsNeeded)
2135  addAsNeededOption(TC, Args, CmdArgs, false);
2136 }
2137 
2138 static void AddLibgcc(const ToolChain &TC, const Driver &D,
2139  ArgStringList &CmdArgs, const ArgList &Args) {
2140  LibGccType LGT = getLibGccType(TC, D, Args);
2141  if (LGT == LibGccType::StaticLibGcc ||
2142  (LGT == LibGccType::UnspecifiedLibGcc && !D.CCCIsCXX()))
2143  CmdArgs.push_back("-lgcc");
2144  AddUnwindLibrary(TC, D, CmdArgs, Args);
2145  if (LGT == LibGccType::SharedLibGcc ||
2146  (LGT == LibGccType::UnspecifiedLibGcc && D.CCCIsCXX()))
2147  CmdArgs.push_back("-lgcc");
2148 }
2149 
2150 void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
2151  ArgStringList &CmdArgs, const ArgList &Args) {
2152  // Make use of compiler-rt if --rtlib option is used
2154 
2155  switch (RLT) {
2157  CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins"));
2158  AddUnwindLibrary(TC, D, CmdArgs, Args);
2159  break;
2160  case ToolChain::RLT_Libgcc:
2161  // Make sure libgcc is not used under MSVC environment by default
2162  if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
2163  // Issue error diagnostic if libgcc is explicitly specified
2164  // through command line as --rtlib option argument.
2165  Arg *A = Args.getLastArg(options::OPT_rtlib_EQ);
2166  if (A && A->getValue() != StringRef("platform")) {
2167  TC.getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform)
2168  << A->getValue() << "MSVC";
2169  }
2170  } else
2171  AddLibgcc(TC, D, CmdArgs, Args);
2172  break;
2173  }
2174 
2175  // On Android, the unwinder uses dl_iterate_phdr (or one of
2176  // dl_unwind_find_exidx/__gnu_Unwind_Find_exidx on arm32) from libdl.so. For
2177  // statically-linked executables, these functions come from libc.a instead.
2178  if (TC.getTriple().isAndroid() && !Args.hasArg(options::OPT_static) &&
2179  !Args.hasArg(options::OPT_static_pie))
2180  CmdArgs.push_back("-ldl");
2181 }
2182 
2183 SmallString<128> tools::getStatsFileName(const llvm::opt::ArgList &Args,
2184  const InputInfo &Output,
2185  const InputInfo &Input,
2186  const Driver &D) {
2187  const Arg *A = Args.getLastArg(options::OPT_save_stats_EQ);
2188  if (!A && !D.CCPrintInternalStats)
2189  return {};
2190 
2191  SmallString<128> StatsFile;
2192  if (A) {
2193  StringRef SaveStats = A->getValue();
2194  if (SaveStats == "obj" && Output.isFilename()) {
2195  StatsFile.assign(Output.getFilename());
2196  llvm::sys::path::remove_filename(StatsFile);
2197  } else if (SaveStats != "cwd") {
2198  D.Diag(diag::err_drv_invalid_value) << A->getAsString(Args) << SaveStats;
2199  return {};
2200  }
2201 
2202  StringRef BaseName = llvm::sys::path::filename(Input.getBaseInput());
2203  llvm::sys::path::append(StatsFile, BaseName);
2204  llvm::sys::path::replace_extension(StatsFile, "stats");
2205  } else {
2206  assert(D.CCPrintInternalStats);
2207  StatsFile.assign(D.CCPrintInternalStatReportFilename.empty()
2208  ? "-"
2210  }
2211  return StatsFile;
2212 }
2213 
2214 void tools::addMultilibFlag(bool Enabled, const StringRef Flag,
2215  Multilib::flags_list &Flags) {
2216  assert(Flag.front() == '-');
2217  if (Enabled) {
2218  Flags.push_back(Flag.str());
2219  } else {
2220  Flags.push_back(("!" + Flag.substr(1)).str());
2221  }
2222 }
2223 
2224 void tools::addX86AlignBranchArgs(const Driver &D, const ArgList &Args,
2225  ArgStringList &CmdArgs, bool IsLTO,
2226  const StringRef PluginOptPrefix) {
2227  auto addArg = [&, IsLTO](const Twine &Arg) {
2228  if (IsLTO) {
2229  assert(!PluginOptPrefix.empty() && "Cannot have empty PluginOptPrefix!");
2230  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + Arg));
2231  } else {
2232  CmdArgs.push_back("-mllvm");
2233  CmdArgs.push_back(Args.MakeArgString(Arg));
2234  }
2235  };
2236 
2237  if (Args.hasArg(options::OPT_mbranches_within_32B_boundaries)) {
2238  addArg(Twine("-x86-branches-within-32B-boundaries"));
2239  }
2240  if (const Arg *A = Args.getLastArg(options::OPT_malign_branch_boundary_EQ)) {
2241  StringRef Value = A->getValue();
2242  unsigned Boundary;
2243  if (Value.getAsInteger(10, Boundary) || Boundary < 16 ||
2244  !llvm::isPowerOf2_64(Boundary)) {
2245  D.Diag(diag::err_drv_invalid_argument_to_option)
2246  << Value << A->getOption().getName();
2247  } else {
2248  addArg("-x86-align-branch-boundary=" + Twine(Boundary));
2249  }
2250  }
2251  if (const Arg *A = Args.getLastArg(options::OPT_malign_branch_EQ)) {
2252  std::string AlignBranch;
2253  for (StringRef T : A->getValues()) {
2254  if (T != "fused" && T != "jcc" && T != "jmp" && T != "call" &&
2255  T != "ret" && T != "indirect")
2256  D.Diag(diag::err_drv_invalid_malign_branch_EQ)
2257  << T << "fused, jcc, jmp, call, ret, indirect";
2258  if (!AlignBranch.empty())
2259  AlignBranch += '+';
2260  AlignBranch += T;
2261  }
2262  addArg("-x86-align-branch=" + Twine(AlignBranch));
2263  }
2264  if (const Arg *A = Args.getLastArg(options::OPT_mpad_max_prefix_size_EQ)) {
2265  StringRef Value = A->getValue();
2266  unsigned PrefixSize;
2267  if (Value.getAsInteger(10, PrefixSize)) {
2268  D.Diag(diag::err_drv_invalid_argument_to_option)
2269  << Value << A->getOption().getName();
2270  } else {
2271  addArg("-x86-pad-max-prefix-size=" + Twine(PrefixSize));
2272  }
2273  }
2274 }
2275 
2276 /// SDLSearch: Search for Static Device Library
2277 /// The search for SDL bitcode files is consistent with how static host
2278 /// libraries are discovered. That is, the -l option triggers a search for
2279 /// files in a set of directories called the LINKPATH. The host library search
2280 /// procedure looks for a specific filename in the LINKPATH. The filename for
2281 /// a host library is lib<libname>.a or lib<libname>.so. For SDLs, there is an
2282 /// ordered-set of filenames that are searched. We call this ordered-set of
2283 /// filenames as SEARCH-ORDER. Since an SDL can either be device-type specific,
2284 /// architecture specific, or generic across all architectures, a naming
2285 /// convention and search order is used where the file name embeds the
2286 /// architecture name <arch-name> (nvptx or amdgcn) and the GPU device type
2287 /// <device-name> such as sm_30 and gfx906. <device-name> is absent in case of
2288 /// device-independent SDLs. To reduce congestion in host library directories,
2289 /// the search first looks for files in the “libdevice” subdirectory. SDLs that
2290 /// are bc files begin with the prefix “lib”.
2291 ///
2292 /// Machine-code SDLs can also be managed as an archive (*.a file). The
2293 /// convention has been to use the prefix “lib”. To avoid confusion with host
2294 /// archive libraries, we use prefix "libbc-" for the bitcode SDL archives.
2295 ///
2296 static bool SDLSearch(const Driver &D, const llvm::opt::ArgList &DriverArgs,
2297  llvm::opt::ArgStringList &CC1Args,
2298  const SmallVectorImpl<std::string> &LibraryPaths,
2299  StringRef Lib, StringRef Arch, StringRef Target,
2300  bool isBitCodeSDL) {
2302 
2303  std::string LibDeviceLoc = "/libdevice";
2304  std::string LibBcPrefix = "/libbc-";
2305  std::string LibPrefix = "/lib";
2306 
2307  if (isBitCodeSDL) {
2308  // SEARCH-ORDER for Bitcode SDLs:
2309  // libdevice/libbc-<libname>-<arch-name>-<device-type>.a
2310  // libbc-<libname>-<arch-name>-<device-type>.a
2311  // libdevice/libbc-<libname>-<arch-name>.a
2312  // libbc-<libname>-<arch-name>.a
2313  // libdevice/libbc-<libname>.a
2314  // libbc-<libname>.a
2315  // libdevice/lib<libname>-<arch-name>-<device-type>.bc
2316  // lib<libname>-<arch-name>-<device-type>.bc
2317  // libdevice/lib<libname>-<arch-name>.bc
2318  // lib<libname>-<arch-name>.bc
2319  // libdevice/lib<libname>.bc
2320  // lib<libname>.bc
2321 
2322  for (StringRef Base : {LibBcPrefix, LibPrefix}) {
2323  const auto *Ext = Base.contains(LibBcPrefix) ? ".a" : ".bc";
2324 
2325  for (auto Suffix : {Twine(Lib + "-" + Arch + "-" + Target).str(),
2326  Twine(Lib + "-" + Arch).str(), Twine(Lib).str()}) {
2327  SDLs.push_back(Twine(LibDeviceLoc + Base + Suffix + Ext).str());
2328  SDLs.push_back(Twine(Base + Suffix + Ext).str());
2329  }
2330  }
2331  } else {
2332  // SEARCH-ORDER for Machine-code SDLs:
2333  // libdevice/lib<libname>-<arch-name>-<device-type>.a
2334  // lib<libname>-<arch-name>-<device-type>.a
2335  // libdevice/lib<libname>-<arch-name>.a
2336  // lib<libname>-<arch-name>.a
2337 
2338  const auto *Ext = ".a";
2339 
2340  for (auto Suffix : {Twine(Lib + "-" + Arch + "-" + Target).str(),
2341  Twine(Lib + "-" + Arch).str()}) {
2342  SDLs.push_back(Twine(LibDeviceLoc + LibPrefix + Suffix + Ext).str());
2343  SDLs.push_back(Twine(LibPrefix + Suffix + Ext).str());
2344  }
2345  }
2346 
2347  // The CUDA toolchain does not use a global device llvm-link before the LLVM
2348  // backend generates ptx. So currently, the use of bitcode SDL for nvptx is
2349  // only possible with post-clang-cc1 linking. Clang cc1 has a feature that
2350  // will link libraries after clang compilation while the LLVM IR is still in
2351  // memory. This utilizes a clang cc1 option called “-mlink-builtin-bitcode”.
2352  // This is a clang -cc1 option that is generated by the clang driver. The
2353  // option value must a full path to an existing file.
2354  bool FoundSDL = false;
2355  for (auto LPath : LibraryPaths) {
2356  for (auto SDL : SDLs) {
2357  auto FullName = Twine(LPath + SDL).str();
2358  if (llvm::sys::fs::exists(FullName)) {
2359  CC1Args.push_back(DriverArgs.MakeArgString(FullName));
2360  FoundSDL = true;
2361  break;
2362  }
2363  }
2364  if (FoundSDL)
2365  break;
2366  }
2367  return FoundSDL;
2368 }
2369 
2370 /// Search if a user provided archive file lib<libname>.a exists in any of
2371 /// the library paths. If so, add a new command to clang-offload-bundler to
2372 /// unbundle this archive and create a temporary device specific archive. Name
2373 /// of this SDL is passed to the llvm-link (for amdgcn) or to the
2374 /// clang-nvlink-wrapper (for nvptx) commands by the driver.
2376  Compilation &C, const Driver &D, const Tool &T, const JobAction &JA,
2377  const InputInfoList &Inputs, const llvm::opt::ArgList &DriverArgs,
2378  llvm::opt::ArgStringList &CC1Args,
2379  const SmallVectorImpl<std::string> &LibraryPaths, StringRef Lib,
2380  StringRef Arch, StringRef Target, bool isBitCodeSDL) {
2381 
2382  // We don't support bitcode archive bundles for nvptx
2383  if (isBitCodeSDL && Arch.contains("nvptx"))
2384  return;
2385 
2386  bool FoundAOB = false;
2387  std::string ArchiveOfBundles;
2388 
2389  llvm::Triple Triple(D.getTargetTriple());
2390  bool IsMSVC = Triple.isWindowsMSVCEnvironment();
2391  auto Ext = IsMSVC ? ".lib" : ".a";
2392  if (!Lib.starts_with(":") && !Lib.starts_with("-l")) {
2393  if (llvm::sys::fs::exists(Lib)) {
2394  ArchiveOfBundles = Lib;
2395  FoundAOB = true;
2396  }
2397  } else {
2398  Lib.consume_front("-l");
2399  for (auto LPath : LibraryPaths) {
2400  ArchiveOfBundles.clear();
2401  auto LibFile = (Lib.starts_with(":") ? Lib.drop_front()
2402  : IsMSVC ? Lib + Ext
2403  : "lib" + Lib + Ext)
2404  .str();
2405  for (auto Prefix : {"/libdevice/", "/"}) {
2406  auto AOB = Twine(LPath + Prefix + LibFile).str();
2407  if (llvm::sys::fs::exists(AOB)) {
2408  ArchiveOfBundles = AOB;
2409  FoundAOB = true;
2410  break;
2411  }
2412  }
2413  if (FoundAOB)
2414  break;
2415  }
2416  }
2417 
2418  if (!FoundAOB)
2419  return;
2420 
2421  llvm::file_magic Magic;
2422  auto EC = llvm::identify_magic(ArchiveOfBundles, Magic);
2423  if (EC || Magic != llvm::file_magic::archive)
2424  return;
2425 
2426  StringRef Prefix = isBitCodeSDL ? "libbc-" : "lib";
2427  std::string OutputLib =
2428  D.GetTemporaryPath(Twine(Prefix + llvm::sys::path::filename(Lib) + "-" +
2429  Arch + "-" + Target)
2430  .str(),
2431  "a");
2432 
2433  C.addTempFile(C.getArgs().MakeArgString(OutputLib));
2434 
2435  ArgStringList CmdArgs;
2436  SmallString<128> DeviceTriple;
2438  DeviceTriple += '-';
2439  std::string NormalizedTriple = T.getToolChain().getTriple().normalize();
2440  DeviceTriple += NormalizedTriple;
2441  if (!Target.empty()) {
2442  DeviceTriple += '-';
2443  DeviceTriple += Target;
2444  }
2445 
2446  std::string UnbundleArg("-unbundle");
2447  std::string TypeArg("-type=a");
2448  std::string InputArg("-input=" + ArchiveOfBundles);
2449  std::string OffloadArg("-targets=" + std::string(DeviceTriple));
2450  std::string OutputArg("-output=" + OutputLib);
2451 
2452  const char *UBProgram = DriverArgs.MakeArgString(
2453  T.getToolChain().GetProgramPath("clang-offload-bundler"));
2454 
2455  ArgStringList UBArgs;
2456  UBArgs.push_back(C.getArgs().MakeArgString(UnbundleArg));
2457  UBArgs.push_back(C.getArgs().MakeArgString(TypeArg));
2458  UBArgs.push_back(C.getArgs().MakeArgString(InputArg));
2459  UBArgs.push_back(C.getArgs().MakeArgString(OffloadArg));
2460  UBArgs.push_back(C.getArgs().MakeArgString(OutputArg));
2461 
2462  // Add this flag to not exit from clang-offload-bundler if no compatible
2463  // code object is found in heterogenous archive library.
2464  std::string AdditionalArgs("-allow-missing-bundles");
2465  UBArgs.push_back(C.getArgs().MakeArgString(AdditionalArgs));
2466 
2467  // Add this flag to treat hip and hipv4 offload kinds as compatible with
2468  // openmp offload kind while extracting code objects from a heterogenous
2469  // archive library. Vice versa is also considered compatible.
2470  std::string HipCompatibleArgs("-hip-openmp-compatible");
2471  UBArgs.push_back(C.getArgs().MakeArgString(HipCompatibleArgs));
2472 
2473  C.addCommand(std::make_unique<Command>(
2474  JA, T, ResponseFileSupport::AtFileCurCP(), UBProgram, UBArgs, Inputs,
2475  InputInfo(&JA, C.getArgs().MakeArgString(OutputLib))));
2476 
2477  CC1Args.push_back(DriverArgs.MakeArgString(OutputLib));
2478 
2479  return;
2480 }
2481 
2482 // Wrapper function used by driver for adding SDLs during link phase.
2484  const JobAction &JA,
2485  const InputInfoList &Inputs,
2486  const llvm::opt::ArgList &DriverArgs,
2487  llvm::opt::ArgStringList &CC1Args,
2488  StringRef Arch, StringRef Target,
2489  bool isBitCodeSDL) {
2490  AddStaticDeviceLibs(&C, &T, &JA, &Inputs, C.getDriver(), DriverArgs, CC1Args,
2491  Arch, Target, isBitCodeSDL);
2492 }
2493 
2494 // Wrapper function used for post clang linking of bitcode SDLS for nvptx by
2495 // the CUDA toolchain.
2497  const llvm::opt::ArgList &DriverArgs,
2498  llvm::opt::ArgStringList &CC1Args,
2499  StringRef Arch, StringRef Target,
2500  bool isBitCodeSDL, bool postClangLink) {
2501  AddStaticDeviceLibs(nullptr, nullptr, nullptr, nullptr, D, DriverArgs,
2502  CC1Args, Arch, Target, isBitCodeSDL);
2503 }
2504 
2505 // User defined Static Device Libraries(SDLs) can be passed to clang for
2506 // offloading GPU compilers. Like static host libraries, the use of a SDL is
2507 // specified with the -l command line option. The primary difference between
2508 // host and SDLs is the filenames for SDLs (refer SEARCH-ORDER for Bitcode SDLs
2509 // and SEARCH-ORDER for Machine-code SDLs for the naming convention).
2510 // SDLs are of following types:
2511 //
2512 // * Bitcode SDLs: They can either be a *.bc file or an archive of *.bc files.
2513 // For NVPTX, these libraries are post-clang linked following each
2514 // compilation. For AMDGPU, these libraries are linked one time
2515 // during the application link phase.
2516 //
2517 // * Machine-code SDLs: They are archive files. For NVPTX, the archive members
2518 // contain cubin for Nvidia GPUs and are linked one time during the
2519 // link phase by the CUDA SDK linker called nvlink. For AMDGPU, the
2520 // process for machine code SDLs is still in development. But they
2521 // will be linked by the LLVM tool lld.
2522 //
2523 // * Bundled objects that contain both host and device codes: Bundled objects
2524 // may also contain library code compiled from source. For NVPTX, the
2525 // bundle contains cubin. For AMDGPU, the bundle contains bitcode.
2526 //
2527 // For Bitcode and Machine-code SDLs, current compiler toolchains hardcode the
2528 // inclusion of specific SDLs such as math libraries and the OpenMP device
2529 // library libomptarget.
2531  const JobAction *JA,
2532  const InputInfoList *Inputs, const Driver &D,
2533  const llvm::opt::ArgList &DriverArgs,
2534  llvm::opt::ArgStringList &CC1Args,
2535  StringRef Arch, StringRef Target,
2536  bool isBitCodeSDL) {
2537 
2538  SmallVector<std::string, 8> LibraryPaths;
2539  // Add search directories from LIBRARY_PATH env variable
2540  std::optional<std::string> LibPath =
2541  llvm::sys::Process::GetEnv("LIBRARY_PATH");
2542  if (LibPath) {
2544  const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
2545  llvm::SplitString(*LibPath, Frags, EnvPathSeparatorStr);
2546  for (StringRef Path : Frags)
2547  LibraryPaths.emplace_back(Path.trim());
2548  }
2549 
2550  // Add directories from user-specified -L options
2551  for (std::string Search_Dir : DriverArgs.getAllArgValues(options::OPT_L))
2552  LibraryPaths.emplace_back(Search_Dir);
2553 
2554  // Add path to lib-debug folders
2555  SmallString<256> DefaultLibPath = llvm::sys::path::parent_path(D.Dir);
2556  llvm::sys::path::append(DefaultLibPath, CLANG_INSTALL_LIBDIR_BASENAME);
2557  LibraryPaths.emplace_back(DefaultLibPath.c_str());
2558 
2559  // Build list of Static Device Libraries SDLs specified by -l option
2560  llvm::SmallSet<std::string, 16> SDLNames;
2561  static const StringRef HostOnlyArchives[] = {
2562  "omp", "cudart", "m", "gcc", "gcc_s", "pthread", "hip_hcc"};
2563  for (auto SDLName : DriverArgs.getAllArgValues(options::OPT_l)) {
2564  if (!llvm::is_contained(HostOnlyArchives, SDLName)) {
2565  SDLNames.insert(std::string("-l") + SDLName);
2566  }
2567  }
2568 
2569  for (auto Input : DriverArgs.getAllArgValues(options::OPT_INPUT)) {
2570  auto FileName = StringRef(Input);
2571  // Clang treats any unknown file types as archives and passes them to the
2572  // linker. Files with extension 'lib' are classified as TY_Object by clang
2573  // but they are usually archives. It is OK if the file is not really an
2574  // archive since GetSDLFromOffloadArchive will check the magic of the file
2575  // and only unbundle it if it is really an archive.
2576  const StringRef LibFileExt = ".lib";
2577  if (!llvm::sys::path::has_extension(FileName) ||
2579  llvm::sys::path::extension(FileName).drop_front()) ==
2581  llvm::sys::path::extension(FileName) == LibFileExt)
2582  SDLNames.insert(Input);
2583  }
2584 
2585  // The search stops as soon as an SDL file is found. The driver then provides
2586  // the full filename of the SDL to the llvm-link or clang-nvlink-wrapper
2587  // command. If no SDL is found after searching each LINKPATH with
2588  // SEARCH-ORDER, it is possible that an archive file lib<libname>.a exists
2589  // and may contain bundled object files.
2590  for (auto SDLName : SDLNames) {
2591  // This is the only call to SDLSearch
2592  if (!SDLSearch(D, DriverArgs, CC1Args, LibraryPaths, SDLName, Arch, Target,
2593  isBitCodeSDL)) {
2594  GetSDLFromOffloadArchive(*C, D, *T, *JA, *Inputs, DriverArgs, CC1Args,
2595  LibraryPaths, SDLName, Arch, Target,
2596  isBitCodeSDL);
2597  }
2598  }
2599 }
2600 
2601 static llvm::opt::Arg *
2602 getAMDGPUCodeObjectArgument(const Driver &D, const llvm::opt::ArgList &Args) {
2603  return Args.getLastArg(options::OPT_mcode_object_version_EQ);
2604 }
2605 
2607  const llvm::opt::ArgList &Args) {
2608  const unsigned MinCodeObjVer = 4;
2609  const unsigned MaxCodeObjVer = 6;
2610 
2611  if (auto *CodeObjArg = getAMDGPUCodeObjectArgument(D, Args)) {
2612  if (CodeObjArg->getOption().getID() ==
2613  options::OPT_mcode_object_version_EQ) {
2614  unsigned CodeObjVer = MaxCodeObjVer;
2615  auto Remnant =
2616  StringRef(CodeObjArg->getValue()).getAsInteger(0, CodeObjVer);
2617  if (Remnant || CodeObjVer < MinCodeObjVer || CodeObjVer > MaxCodeObjVer)
2618  D.Diag(diag::err_drv_invalid_int_value)
2619  << CodeObjArg->getAsString(Args) << CodeObjArg->getValue();
2620 
2621  // COV6 is only supported by LLVM at the time of writing this, and it's
2622  // expected to take some time before all ROCm components fully
2623  // support it. In the meantime, make sure users are aware of this.
2624  if (CodeObjVer == 6)
2625  D.Diag(diag::warn_drv_amdgpu_cov6);
2626  }
2627  }
2628 }
2629 
2631  const llvm::opt::ArgList &Args) {
2632  unsigned CodeObjVer = 4; // default
2633  if (auto *CodeObjArg = getAMDGPUCodeObjectArgument(D, Args))
2634  StringRef(CodeObjArg->getValue()).getAsInteger(0, CodeObjVer);
2635  return CodeObjVer;
2636 }
2637 
2639  const Driver &D, const llvm::opt::ArgList &Args) {
2640  return getAMDGPUCodeObjectArgument(D, Args) != nullptr;
2641 }
2642 
2644  const llvm::opt::ArgList &Args,
2645  llvm::opt::ArgStringList &CmdArgs,
2646  const llvm::Triple &Triple, bool IsLTO,
2647  const StringRef PluginOptPrefix) {
2648  auto addArg = [&, IsLTO](const Twine &Arg) {
2649  if (IsLTO) {
2650  assert(!PluginOptPrefix.empty() && "Cannot have empty PluginOptPrefix!");
2651  CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + Arg));
2652  } else {
2653  CmdArgs.push_back("-mllvm");
2654  CmdArgs.push_back(Args.MakeArgString(Arg));
2655  }
2656  };
2657 
2658  if (Arg *A = Args.getLastArg(options::OPT_moutline,
2659  options::OPT_mno_outline)) {
2660  if (A->getOption().matches(options::OPT_moutline)) {
2661  // We only support -moutline in AArch64 and ARM targets right now. If
2662  // we're not compiling for these, emit a warning and ignore the flag.
2663  // Otherwise, add the proper mllvm flags.
2664  if (!(Triple.isARM() || Triple.isThumb() || Triple.isAArch64())) {
2665  D.Diag(diag::warn_drv_moutline_unsupported_opt) << Triple.getArchName();
2666  } else {
2667  addArg(Twine("-enable-machine-outliner"));
2668  }
2669  } else {
2670  // Disable all outlining behaviour.
2671  addArg(Twine("-enable-machine-outliner=never"));
2672  }
2673  }
2674 }
2675 
2677  const llvm::opt::ArgList &DriverArgs,
2678  llvm::opt::ArgStringList &CC1Args,
2679  StringRef BitcodeSuffix,
2680  const llvm::Triple &Triple,
2681  const ToolChain &HostTC) {
2682  SmallVector<StringRef, 8> LibraryPaths;
2683 
2684  // Add user defined library paths from LIBRARY_PATH.
2685  std::optional<std::string> LibPath =
2686  llvm::sys::Process::GetEnv("LIBRARY_PATH");
2687  if (LibPath) {
2689  const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
2690  llvm::SplitString(*LibPath, Frags, EnvPathSeparatorStr);
2691  for (StringRef Path : Frags)
2692  LibraryPaths.emplace_back(Path.trim());
2693  }
2694 
2695  // Check all of the standard library search paths used by the compiler.
2696  for (const auto &LibPath : HostTC.getFilePaths())
2697  LibraryPaths.emplace_back(LibPath);
2698 
2699  OptSpecifier LibomptargetBCPathOpt =
2700  Triple.isAMDGCN() ? options::OPT_libomptarget_amdgpu_bc_path_EQ
2701  : options::OPT_libomptarget_nvptx_bc_path_EQ;
2702 
2703  StringRef ArchPrefix = Triple.isAMDGCN() ? "amdgpu" : "nvptx";
2704  std::string LibOmpTargetName =
2705  ("libomptarget-" + ArchPrefix + "-" + BitcodeSuffix + ".bc").str();
2706 
2707  // First check whether user specifies bc library
2708  if (const Arg *A = DriverArgs.getLastArg(LibomptargetBCPathOpt)) {
2709  SmallString<128> LibOmpTargetFile(A->getValue());
2710  if (llvm::sys::fs::exists(LibOmpTargetFile) &&
2711  llvm::sys::fs::is_directory(LibOmpTargetFile)) {
2712  llvm::sys::path::append(LibOmpTargetFile, LibOmpTargetName);
2713  }
2714 
2715  if (llvm::sys::fs::exists(LibOmpTargetFile)) {
2716  CC1Args.push_back("-mlink-builtin-bitcode");
2717  CC1Args.push_back(DriverArgs.MakeArgString(LibOmpTargetFile));
2718  } else {
2719  D.Diag(diag::err_drv_omp_offload_target_bcruntime_not_found)
2720  << LibOmpTargetFile;
2721  }
2722  } else {
2723  bool FoundBCLibrary = false;
2724 
2725  for (StringRef LibraryPath : LibraryPaths) {
2726  SmallString<128> LibOmpTargetFile(LibraryPath);
2727  llvm::sys::path::append(LibOmpTargetFile, LibOmpTargetName);
2728  if (llvm::sys::fs::exists(LibOmpTargetFile)) {
2729  CC1Args.push_back("-mlink-builtin-bitcode");
2730  CC1Args.push_back(DriverArgs.MakeArgString(LibOmpTargetFile));
2731  FoundBCLibrary = true;
2732  break;
2733  }
2734  }
2735 
2736  if (!FoundBCLibrary)
2737  D.Diag(diag::err_drv_omp_offload_target_missingbcruntime)
2738  << LibOmpTargetName << ArchPrefix;
2739  }
2740 }
2742  const llvm::opt::ArgList &Args,
2743  llvm::opt::ArgStringList &CmdArgs) {
2744  if ((C.getActiveOffloadKinds() & Action::OFK_HIP) &&
2745  !Args.hasArg(options::OPT_nostdlib) &&
2746  !Args.hasArg(options::OPT_no_hip_rt) && !Args.hasArg(options::OPT_r)) {
2747  TC.AddHIPRuntimeLibArgs(Args, CmdArgs);
2748  } else {
2749  // Claim "no HIP libraries" arguments if any
2750  for (auto *Arg : Args.filtered(options::OPT_no_hip_rt)) {
2751  Arg->claim();
2752  }
2753  }
2754 }
2755 
2757  const llvm::opt::ArgList &Args,
2758  llvm::opt::ArgStringList &CmdArgs,
2759  const llvm::Triple &Triple) {
2760  if (Arg *A = Args.getLastArg(options::OPT_moutline_atomics,
2761  options::OPT_mno_outline_atomics)) {
2762  // Option -moutline-atomics supported for AArch64 target only.
2763  if (!Triple.isAArch64()) {
2764  D.Diag(diag::warn_drv_moutline_atomics_unsupported_opt)
2765  << Triple.getArchName() << A->getOption().getName();
2766  } else {
2767  if (A->getOption().matches(options::OPT_moutline_atomics)) {
2768  CmdArgs.push_back("-target-feature");
2769  CmdArgs.push_back("+outline-atomics");
2770  } else {
2771  CmdArgs.push_back("-target-feature");
2772  CmdArgs.push_back("-outline-atomics");
2773  }
2774  }
2775  } else if (Triple.isAArch64() && TC.IsAArch64OutlineAtomicsDefault(Args)) {
2776  CmdArgs.push_back("-target-feature");
2777  CmdArgs.push_back("+outline-atomics");
2778  }
2779 }
2780 
2781 void tools::addOffloadCompressArgs(const llvm::opt::ArgList &TCArgs,
2782  llvm::opt::ArgStringList &CmdArgs) {
2783  if (TCArgs.hasFlag(options::OPT_offload_compress,
2784  options::OPT_no_offload_compress, false))
2785  CmdArgs.push_back("-compress");
2786  if (TCArgs.hasArg(options::OPT_v))
2787  CmdArgs.push_back("-verbose");
2788  if (auto *Arg = TCArgs.getLastArg(options::OPT_offload_compression_level_EQ))
2789  CmdArgs.push_back(
2790  TCArgs.MakeArgString(Twine("-compression-level=") + Arg->getValue()));
2791 }
#define V(N, I)
Definition: ASTContext.h:3299
static unsigned ParseDebugDefaultVersion(const ToolChain &TC, const ArgList &Args)
static void getWebAssemblyTargetFeatures(const Driver &D, const llvm::Triple &Triple, const ArgList &Args, std::vector< StringRef > &Features)
Definition: CommonArgs.cpp:631
static llvm::opt::Arg * getAMDGPUCodeObjectArgument(const Driver &D, const llvm::opt::ArgList &Args)
LibGccType
static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs, StringRef Sanitizer)
static void addOpenMPDeviceLibC(const Compilation &C, const ArgList &Args, ArgStringList &CmdArgs)
Adds the '-lcgpu' and '-lmgpu' libraries to the compilation to include the LLVM C library for GPUs.
static void collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, SmallVectorImpl< StringRef > &SharedRuntimes, SmallVectorImpl< StringRef > &StaticRuntimes, SmallVectorImpl< StringRef > &NonWholeStaticRuntimes, SmallVectorImpl< StringRef > &HelperStaticRuntimes, SmallVectorImpl< StringRef > &RequiredSymbols)
static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs, StringRef Sanitizer, bool IsShared, bool IsWhole)
static void AddUnwindLibrary(const ToolChain &TC, const Driver &D, ArgStringList &CmdArgs, const ArgList &Args)
static bool SDLSearch(const Driver &D, const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const SmallVectorImpl< std::string > &LibraryPaths, StringRef Lib, StringRef Arch, StringRef Target, bool isBitCodeSDL)
SDLSearch: Search for Static Device Library The search for SDL bitcode files is consistent with how s...
static void renderRpassOptions(const ArgList &Args, ArgStringList &CmdArgs, const StringRef PluginOptPrefix)
Definition: CommonArgs.cpp:214
static StringRef getWebAssemblyTargetCPU(const ArgList &Args)
Get the (LLVM) name of the WebAssembly cpu we are targeting.
Definition: CommonArgs.cpp:511
static void renderRemarksHotnessOptions(const ArgList &Args, ArgStringList &CmdArgs, const StringRef PluginOptPrefix)
Definition: CommonArgs.cpp:260
static void GetSDLFromOffloadArchive(Compilation &C, const Driver &D, const Tool &T, const JobAction &JA, const InputInfoList &Inputs, const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const SmallVectorImpl< std::string > &LibraryPaths, StringRef Lib, StringRef Arch, StringRef Target, bool isBitCodeSDL)
Search if a user provided archive file lib<libname>.a exists in any of the library paths.
static std::string getLanaiTargetCPU(const ArgList &Args)
Definition: CommonArgs.cpp:503
static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs, const llvm::Triple &Triple, const InputInfo &Input, const InputInfo &Output, const StringRef PluginOptPrefix)
Definition: CommonArgs.cpp:229
static bool useFramePointerForTargetByDefault(const llvm::opt::ArgList &Args, const llvm::Triple &Triple)
Definition: CommonArgs.cpp:75
static void AddLibgcc(const ToolChain &TC, const Driver &D, ArgStringList &CmdArgs, const ArgList &Args)
static LibGccType getLibGccType(const ToolChain &TC, const Driver &D, const ArgList &Args)
clang::CodeGenOptions::FramePointerKind getFramePointerKind(const llvm::opt::ArgList &Args, const llvm::Triple &Triple)
Definition: CommonArgs.cpp:180
static std::string getAMDGPUTargetGPU(const llvm::Triple &T, const ArgList &Args)
Get the (LLVM) name of the AMDGPU gpu we are targeting.
Definition: CommonArgs.cpp:483
static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple)
Definition: CommonArgs.cpp:167
static bool shouldIgnoreUnsupportedTargetFeature(const Arg &TargetFeatureArg, llvm::Triple T, StringRef Processor)
Definition: CommonArgs.cpp:275
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
Definition: MachO.h:50
Defines types useful for describing an Objective-C runtime.
Defines version macros and version-related utility functions for Clang.
__DEVICE__ int min(int __a, int __b)
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1553
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
Definition: Action.cpp:181
OffloadKind getOffloadingDeviceKind() const
Definition: Action.h:222
bool isHostOffloading(unsigned int OKind) const
Check if this action have any offload kinds.
Definition: Action.h:230
const char * getOffloadingArch() const
Definition: Action.h:223
Compilation - A set of tasks to perform for a single driver invocation.
Definition: Compilation.h:45
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:77
std::string CCPrintInternalStatReportFilename
The file to log CC_PRINT_INTERNAL_STAT_FILE output to, if enabled.
Definition: Driver.h:197
llvm::vfs::FileSystem & getVFS() const
Definition: Driver.h:405
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
Definition: Driver.cpp:791
DiagnosticBuilder Diag(unsigned DiagID) const
Definition: Driver.h:146
unsigned CCPrintInternalStats
Set CC_PRINT_INTERNAL_STAT mode, which causes the driver to dump internal performance report to CC_PR...
Definition: Driver.h:276
StringRef getFlangF128MathLibrary() const
Definition: Driver.h:444
DiagnosticsEngine & getDiags() const
Definition: Driver.h:403
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
Definition: Driver.cpp:9923
std::string Dir
The path the driver executable was in, as invoked from the command line.
Definition: Driver.h:157
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
Definition: Driver.h:142
@ OMPRT_OMP
The LLVM OpenMP runtime.
Definition: Driver.h:132
@ OMPRT_Unknown
An unknown OpenMP runtime.
Definition: Driver.h:128
@ OMPRT_GOMP
The GNU OpenMP runtime.
Definition: Driver.h:137
std::string getTargetTriple() const
Definition: Driver.h:422
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
Definition: Driver.h:215
InputInfo - Wrapper for information about an input source.
Definition: InputInfo.h:22
const char * getBaseInput() const
Definition: InputInfo.h:78
const char * getFilename() const
Definition: InputInfo.h:83
bool isFilename() const
Definition: InputInfo.h:75
std::vector< std::string > flags_list
Definition: Multilib.h:34
const std::string & getMemtagMode() const
bool requiresMinimalRuntime() const
Definition: SanitizerArgs.h:99
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:92
const Driver & getDriver() const
Definition: ToolChain.h:269
virtual void AddCCKextLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
AddCCKextLibArgs - Add the system specific linker arguments to use for kernel extensions (Darwin-spec...
Definition: ToolChain.cpp:1381
path_list & getFilePaths()
Definition: ToolChain.h:311
virtual bool useIntegratedAs() const
Check if the toolchain should use the integrated assembler.
Definition: ToolChain.cpp:146
virtual void AddHIPRuntimeLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
Add the system specific linker arguments to use for the given HIP runtime library type.
Definition: ToolChain.h:796
std::optional< std::string > getStdlibPath() const
Definition: ToolChain.cpp:886
virtual unsigned GetDefaultDwarfVersion() const
Definition: ToolChain.h:602
virtual RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const
Definition: ToolChain.cpp:1159
const char * getCompilerRTArgString(const llvm::opt::ArgList &Args, StringRef Component, FileType Type=ToolChain::FT_Static) const
Definition: ToolChain.cpp:782
llvm::Triple::ArchType getArch() const
Definition: ToolChain.h:285
const llvm::Triple & getTriple() const
Definition: ToolChain.h:271
llvm::vfs::FileSystem & getVFS() const
Definition: ToolChain.cpp:142
const XRayArgs & getXRayArgs() const
Definition: ToolChain.cpp:307
virtual bool isPIEDefault(const llvm::opt::ArgList &Args) const =0
Test whether this toolchain defaults to PIE.
virtual bool isPICDefaultForced() const =0
Tests whether this toolchain forces its default for PIC, PIE or non-PIC.
virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
AddCXXStdlibLibArgs - Add the system specific linker arguments to use for the given C++ standard libr...
Definition: ToolChain.cpp:1355
const llvm::Triple & getEffectiveTriple() const
Get the toolchain's effective clang triple.
Definition: ToolChain.h:299
virtual bool HasNativeLLVMSupport() const
HasNativeLTOLinker - Check whether the linker and related tools have native LLVM support.
Definition: ToolChain.cpp:1037
virtual UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const
Definition: ToolChain.cpp:1185
std::string GetLinkerPath(bool *LinkerIsLLD=nullptr) const
Returns the linker path, respecting the -fuse-ld= argument to determine the linker suffix or name.
Definition: ToolChain.cpp:946
virtual std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, FileType Type=ToolChain::FT_Static) const
Definition: ToolChain.cpp:751
std::string GetProgramPath(const char *Name) const
Definition: ToolChain.cpp:942
std::string getTripleString() const
Definition: ToolChain.h:294
SanitizerArgs getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const
Definition: ToolChain.cpp:301
virtual bool IsAArch64OutlineAtomicsDefault(const llvm::opt::ArgList &Args) const
Test whether this toolchain supports outline atomics by default.
Definition: ToolChain.h:566
virtual path_list getArchSpecificLibPaths() const
Definition: ToolChain.cpp:892
virtual bool isCrossCompiling() const
Returns true if the toolchain is targeting a non-native architecture.
Definition: ToolChain.cpp:1041
virtual bool isPICDefault() const =0
Test whether this toolchain defaults to PIC.
Tool - Information on a specific compilation tool.
Definition: Tool.h:32
bool needsXRayRt() const
Definition: XRayArgs.h:37
llvm::ArrayRef< std::string > modeList() const
Definition: XRayArgs.h:38
static StringRef GetTargetCPUVersion(const llvm::opt::ArgList &Args)
Definition: Hexagon.cpp:794
void getNVPTXTargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< StringRef > &Features)
Definition: Cuda.cpp:761
void getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< llvm::StringRef > &Features, bool ForAS)
std::string getAArch64TargetCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple, llvm::opt::Arg *&A)
void getAMDGPUTargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< StringRef > &Features)
Definition: AMDGPU.cpp:642
void getARMArchCPUFromArgs(const llvm::opt::ArgList &Args, llvm::StringRef &Arch, llvm::StringRef &CPU, bool FromAs=false)
std::string getARMTargetCPU(StringRef CPU, llvm::StringRef Arch, const llvm::Triple &Triple)
llvm::ARM::FPUKind getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< llvm::StringRef > &Features, bool ForAS, bool ForMultilib=false)
void getCSKYTargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, std::vector< llvm::StringRef > &Features)
void getHexagonTargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< StringRef > &Features)
std::string getLoongArchTargetCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple)
Definition: LoongArch.cpp:224
void getLoongArchTargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< llvm::StringRef > &Features)
void getM68kTargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< llvm::StringRef > &Features)
std::string getM68kTargetCPU(const llvm::opt::ArgList &Args)
void getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< StringRef > &Features)
void getMipsCPUAndABI(const llvm::opt::ArgList &Args, const llvm::Triple &Triple, StringRef &CPUName, StringRef &ABIName)
void getMSP430TargetFeatures(const Driver &D, const llvm::opt::ArgList &Args, std::vector< llvm::StringRef > &Features)
std::string getPPCTargetCPU(const Driver &D, const llvm::opt::ArgList &Args, const llvm::Triple &T)
void getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< llvm::StringRef > &Features)
std::string getRISCVTargetCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple)
Definition: RISCV.cpp:339
void getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< llvm::StringRef > &Features)
bool isLinkerGnuLd(const ToolChain &TC, const llvm::opt::ArgList &Args)
void getSparcTargetFeatures(const Driver &D, const llvm::opt::ArgList &Args, std::vector< llvm::StringRef > &Features)
std::string getSparcTargetCPU(const Driver &D, const llvm::opt::ArgList &Args, const llvm::Triple &Triple)
void getSystemZTargetFeatures(const Driver &D, const llvm::opt::ArgList &Args, std::vector< llvm::StringRef > &Features)
std::string getSystemZTargetCPU(const llvm::opt::ArgList &Args)
void getVETargetFeatures(const Driver &D, const llvm::opt::ArgList &Args, std::vector< llvm::StringRef > &Features)
std::string getX86TargetCPU(const Driver &D, const llvm::opt::ArgList &Args, const llvm::Triple &Triple)
void getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< llvm::StringRef > &Features)
void AddStaticDeviceLibs(Compilation *C, const Tool *T, const JobAction *JA, const InputInfoList *Inputs, const Driver &D, const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CmdArgs, StringRef Arch, StringRef Target, bool isBitCodeSDL)
llvm::opt::Arg * getLastProfileSampleUseArg(const llvm::opt::ArgList &Args)
void addX86AlignBranchArgs(const Driver &D, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, bool IsLTO, const StringRef PluginOptPrefix="")
void addMachineOutlinerArgs(const Driver &D, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const llvm::Triple &Triple, bool IsLTO, const StringRef PluginOptPrefix="")
unsigned ParseFunctionAlignment(const ToolChain &TC, const llvm::opt::ArgList &Args)
void AddStaticDeviceLibsPostLinking(const Driver &D, const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CmdArgs, StringRef Arch, StringRef Target, bool isBitCodeSDL, bool postClangLink)
void addOffloadCompressArgs(const llvm::opt::ArgList &TCArgs, llvm::opt::ArgStringList &CmdArgs)
void handleTargetFeaturesGroup(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< StringRef > &Features, llvm::opt::OptSpecifier Group)
Iterate Args and convert -mxxx to +xxx and -mno-xxx to -xxx and append it to Features.
SmallVector< StringRef > unifyTargetFeatures(ArrayRef< StringRef > Features)
If there are multiple +xxx or -xxx features, keep the last one.
Definition: CommonArgs.cpp:328
void addOpenMPDeviceRTL(const Driver &D, const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, StringRef BitcodeSuffix, const llvm::Triple &Triple, const ToolChain &HostTC)
std::tuple< llvm::Reloc::Model, unsigned, bool > ParsePICArgs(const ToolChain &ToolChain, const llvm::opt::ArgList &Args)
void addOutlineAtomicsArgs(const Driver &D, const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const llvm::Triple &Triple)
void checkAMDGPUCodeObjectVersion(const Driver &D, const llvm::opt::ArgList &Args)
llvm::opt::Arg * getLastCSProfileGenerateArg(const llvm::opt::ArgList &Args)
void getTargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, bool ForAS, bool IsAux=false)
const char * SplitDebugName(const JobAction &JA, const llvm::opt::ArgList &Args, const InputInfo &Input, const InputInfo &Output)
void AddStaticDeviceLibsLinking(Compilation &C, const Tool &T, const JobAction &JA, const InputInfoList &Inputs, const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CmdArgs, StringRef Arch, StringRef Target, bool isBitCodeSDL)
void addAsNeededOption(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, bool as_needed)
std::string getCPUName(const Driver &D, const llvm::opt::ArgList &Args, const llvm::Triple &T, bool FromAs=false)
void addHIPRuntimeLibArgs(const ToolChain &TC, Compilation &C, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs)
void addMultilibFlag(bool Enabled, const StringRef Flag, Multilib::flags_list &Flags)
Flag must be a flag accepted by the driver.
bool isUseSeparateSections(const llvm::Triple &Triple)
Definition: CommonArgs.cpp:735
void linkXRayRuntimeDeps(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs)
void AddRunTimeLibs(const ToolChain &TC, const Driver &D, llvm::opt::ArgStringList &CmdArgs, const llvm::opt::ArgList &Args)
llvm::opt::Arg * getLastProfileUseArg(const llvm::opt::ArgList &Args)
void SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T, const JobAction &JA, const llvm::opt::ArgList &Args, const InputInfo &Output, const char *OutFile)
void linkSanitizerRuntimeDeps(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs)
void addDirectoryList(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const char *ArgName, const char *EnvVar)
EnvVar is split by system delimiter for environment variables.
bool addSanitizerRuntimes(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs)
bool areOptimizationsEnabled(const llvm::opt::ArgList &Args)
void addOpenMPRuntimeLibraryPath(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs)
bool addXRayRuntime(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs)
void AddAssemblerKPIC(const ToolChain &ToolChain, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs)
bool haveAMDGPUCodeObjectVersionArgument(const Driver &D, const llvm::opt::ArgList &Args)
bool isTLSDESCEnabled(const ToolChain &TC, const llvm::opt::ArgList &Args)
Definition: CommonArgs.cpp:739
void addDebugInfoKind(llvm::opt::ArgStringList &CmdArgs, llvm::codegenoptions::DebugInfoKind DebugInfoKind)
void addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths)
Definition: CommonArgs.cpp:290
llvm::codegenoptions::DebugInfoKind debugLevelToInfoKind(const llvm::opt::Arg &A)
bool isDependentLibAdded(const llvm::opt::ArgList &Args, StringRef Lib)
void addFortranRuntimeLibraryPath(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs)
Adds the path for the Fortran runtime libraries to CmdArgs.
llvm::StringRef getLTOParallelism(const llvm::opt::ArgList &Args, const Driver &D)
void addLinkerCompressDebugSectionsOption(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs)
Definition: CommonArgs.cpp:452
void addLTOOptions(const ToolChain &ToolChain, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const InputInfo &Output, const InputInfo &Input, bool IsThinLTO)
bool addOpenMPRuntime(const Compilation &C, llvm::opt::ArgStringList &CmdArgs, const ToolChain &TC, const llvm::opt::ArgList &Args, bool ForceStaticHostRuntime=false, bool IsOffloadingHost=false, bool GompNeedsRT=false)
Returns true, if an OpenMP runtime has been added.
void claimNoWarnArgs(const llvm::opt::ArgList &Args)
unsigned DwarfVersionNum(StringRef ArgValue)
void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const JobAction &JA)
unsigned getDwarfVersion(const ToolChain &TC, const llvm::opt::ArgList &Args)
const llvm::opt::Arg * getDwarfNArg(const llvm::opt::ArgList &Args)
unsigned getAMDGPUCodeObjectVersion(const Driver &D, const llvm::opt::ArgList &Args)
void AddTargetFeature(const llvm::opt::ArgList &Args, std::vector< StringRef > &Features, llvm::opt::OptSpecifier OnOpt, llvm::opt::OptSpecifier OffOpt, StringRef FeatureName)
SmallString< 128 > getStatsFileName(const llvm::opt::ArgList &Args, const InputInfo &Output, const InputInfo &Input, const Driver &D)
Handles the -save-stats option and returns the filename to save statistics to.
void addArchSpecificRPath(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs)
bool isObjCAutoRefCount(const llvm::opt::ArgList &Args)
void addFortranRuntimeLibs(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs)
Adds Fortran runtime libraries to CmdArgs.
const char * RelocationModelName(llvm::Reloc::Model Model)
bool isLLVMIR(ID Id)
Is this LLVM IR.
Definition: Types.cpp:256
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
Definition: Types.cpp:322
bool willEmitRemarks(const llvm::opt::ArgList &Args)
The JSON file list parser is used to communicate input to InstallAPI.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
Definition: TargetID.cpp:54
const FunctionProtoType * T
static constexpr ResponseFileSupport AtFileCurCP()
Definition: Job.h:93