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