Home | History | Annotate | Line # | Download | only in ToolChains
      1      1.1  joerg //===--- CommonArgs.cpp - Args handling for multiple toolchains -*- C++ -*-===//
      2      1.1  joerg //
      3      1.1  joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4      1.1  joerg // See https://llvm.org/LICENSE.txt for license information.
      5      1.1  joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6      1.1  joerg //
      7      1.1  joerg //===----------------------------------------------------------------------===//
      8      1.1  joerg 
      9      1.1  joerg #include "CommonArgs.h"
     10      1.1  joerg #include "Arch/AArch64.h"
     11      1.1  joerg #include "Arch/ARM.h"
     12  1.1.1.2  joerg #include "Arch/M68k.h"
     13      1.1  joerg #include "Arch/Mips.h"
     14      1.1  joerg #include "Arch/PPC.h"
     15      1.1  joerg #include "Arch/SystemZ.h"
     16  1.1.1.2  joerg #include "Arch/VE.h"
     17      1.1  joerg #include "Arch/X86.h"
     18      1.1  joerg #include "HIP.h"
     19      1.1  joerg #include "Hexagon.h"
     20      1.1  joerg #include "InputInfo.h"
     21      1.1  joerg #include "clang/Basic/CharInfo.h"
     22      1.1  joerg #include "clang/Basic/LangOptions.h"
     23      1.1  joerg #include "clang/Basic/ObjCRuntime.h"
     24      1.1  joerg #include "clang/Basic/Version.h"
     25      1.1  joerg #include "clang/Config/config.h"
     26      1.1  joerg #include "clang/Driver/Action.h"
     27      1.1  joerg #include "clang/Driver/Compilation.h"
     28      1.1  joerg #include "clang/Driver/Driver.h"
     29      1.1  joerg #include "clang/Driver/DriverDiagnostic.h"
     30      1.1  joerg #include "clang/Driver/Job.h"
     31      1.1  joerg #include "clang/Driver/Options.h"
     32      1.1  joerg #include "clang/Driver/SanitizerArgs.h"
     33      1.1  joerg #include "clang/Driver/ToolChain.h"
     34      1.1  joerg #include "clang/Driver/Util.h"
     35      1.1  joerg #include "clang/Driver/XRayArgs.h"
     36      1.1  joerg #include "llvm/ADT/STLExtras.h"
     37      1.1  joerg #include "llvm/ADT/SmallString.h"
     38      1.1  joerg #include "llvm/ADT/StringExtras.h"
     39      1.1  joerg #include "llvm/ADT/StringSwitch.h"
     40      1.1  joerg #include "llvm/ADT/Twine.h"
     41  1.1.1.2  joerg #include "llvm/Config/llvm-config.h"
     42      1.1  joerg #include "llvm/Option/Arg.h"
     43      1.1  joerg #include "llvm/Option/ArgList.h"
     44      1.1  joerg #include "llvm/Option/Option.h"
     45      1.1  joerg #include "llvm/Support/CodeGen.h"
     46      1.1  joerg #include "llvm/Support/Compression.h"
     47      1.1  joerg #include "llvm/Support/Debug.h"
     48      1.1  joerg #include "llvm/Support/ErrorHandling.h"
     49      1.1  joerg #include "llvm/Support/FileSystem.h"
     50      1.1  joerg #include "llvm/Support/Host.h"
     51      1.1  joerg #include "llvm/Support/Path.h"
     52      1.1  joerg #include "llvm/Support/Process.h"
     53      1.1  joerg #include "llvm/Support/Program.h"
     54      1.1  joerg #include "llvm/Support/ScopedPrinter.h"
     55      1.1  joerg #include "llvm/Support/TargetParser.h"
     56  1.1.1.2  joerg #include "llvm/Support/Threading.h"
     57      1.1  joerg #include "llvm/Support/VirtualFileSystem.h"
     58      1.1  joerg #include "llvm/Support/YAMLParser.h"
     59      1.1  joerg 
     60      1.1  joerg using namespace clang::driver;
     61      1.1  joerg using namespace clang::driver::tools;
     62      1.1  joerg using namespace clang;
     63      1.1  joerg using namespace llvm::opt;
     64      1.1  joerg 
     65  1.1.1.2  joerg static void renderRpassOptions(const ArgList &Args, ArgStringList &CmdArgs) {
     66  1.1.1.2  joerg   if (const Arg *A = Args.getLastArg(options::OPT_Rpass_EQ))
     67  1.1.1.2  joerg     CmdArgs.push_back(Args.MakeArgString(Twine("--plugin-opt=-pass-remarks=") +
     68  1.1.1.2  joerg                                          A->getValue()));
     69  1.1.1.2  joerg 
     70  1.1.1.2  joerg   if (const Arg *A = Args.getLastArg(options::OPT_Rpass_missed_EQ))
     71  1.1.1.2  joerg     CmdArgs.push_back(Args.MakeArgString(
     72  1.1.1.2  joerg         Twine("--plugin-opt=-pass-remarks-missed=") + A->getValue()));
     73  1.1.1.2  joerg 
     74  1.1.1.2  joerg   if (const Arg *A = Args.getLastArg(options::OPT_Rpass_analysis_EQ))
     75  1.1.1.2  joerg     CmdArgs.push_back(Args.MakeArgString(
     76  1.1.1.2  joerg         Twine("--plugin-opt=-pass-remarks-analysis=") + A->getValue()));
     77  1.1.1.2  joerg }
     78  1.1.1.2  joerg 
     79  1.1.1.2  joerg static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs,
     80  1.1.1.2  joerg                                  const llvm::Triple &Triple,
     81  1.1.1.2  joerg                                  const InputInfo &Input,
     82  1.1.1.2  joerg                                  const InputInfo &Output) {
     83  1.1.1.2  joerg   StringRef Format = "yaml";
     84  1.1.1.2  joerg   if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ))
     85  1.1.1.2  joerg     Format = A->getValue();
     86  1.1.1.2  joerg 
     87  1.1.1.2  joerg   SmallString<128> F;
     88  1.1.1.2  joerg   const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ);
     89  1.1.1.2  joerg   if (A)
     90  1.1.1.2  joerg     F = A->getValue();
     91  1.1.1.2  joerg   else if (Output.isFilename())
     92  1.1.1.2  joerg     F = Output.getFilename();
     93  1.1.1.2  joerg 
     94  1.1.1.2  joerg   assert(!F.empty() && "Cannot determine remarks output name.");
     95  1.1.1.2  joerg   // Append "opt.ld.<format>" to the end of the file name.
     96  1.1.1.2  joerg   CmdArgs.push_back(
     97  1.1.1.2  joerg       Args.MakeArgString(Twine("--plugin-opt=opt-remarks-filename=") + F +
     98  1.1.1.2  joerg                          Twine(".opt.ld.") + Format));
     99  1.1.1.2  joerg 
    100  1.1.1.2  joerg   if (const Arg *A =
    101  1.1.1.2  joerg           Args.getLastArg(options::OPT_foptimization_record_passes_EQ))
    102  1.1.1.2  joerg     CmdArgs.push_back(Args.MakeArgString(
    103  1.1.1.2  joerg         Twine("--plugin-opt=opt-remarks-passes=") + A->getValue()));
    104  1.1.1.2  joerg 
    105  1.1.1.2  joerg   CmdArgs.push_back(Args.MakeArgString(
    106  1.1.1.2  joerg       Twine("--plugin-opt=opt-remarks-format=") + Format.data()));
    107  1.1.1.2  joerg }
    108  1.1.1.2  joerg 
    109  1.1.1.2  joerg static void renderRemarksHotnessOptions(const ArgList &Args,
    110  1.1.1.2  joerg                                         ArgStringList &CmdArgs) {
    111  1.1.1.2  joerg   if (Args.hasFlag(options::OPT_fdiagnostics_show_hotness,
    112  1.1.1.2  joerg                    options::OPT_fno_diagnostics_show_hotness, false))
    113  1.1.1.2  joerg     CmdArgs.push_back("--plugin-opt=opt-remarks-with-hotness");
    114  1.1.1.2  joerg 
    115  1.1.1.2  joerg   if (const Arg *A =
    116  1.1.1.2  joerg           Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ))
    117  1.1.1.2  joerg     CmdArgs.push_back(Args.MakeArgString(
    118  1.1.1.2  joerg         Twine("--plugin-opt=opt-remarks-hotness-threshold=") + A->getValue()));
    119  1.1.1.2  joerg }
    120  1.1.1.2  joerg 
    121      1.1  joerg void tools::addPathIfExists(const Driver &D, const Twine &Path,
    122      1.1  joerg                             ToolChain::path_list &Paths) {
    123      1.1  joerg   if (D.getVFS().exists(Path))
    124      1.1  joerg     Paths.push_back(Path.str());
    125      1.1  joerg }
    126      1.1  joerg 
    127      1.1  joerg void tools::handleTargetFeaturesGroup(const ArgList &Args,
    128      1.1  joerg                                       std::vector<StringRef> &Features,
    129      1.1  joerg                                       OptSpecifier Group) {
    130      1.1  joerg   for (const Arg *A : Args.filtered(Group)) {
    131      1.1  joerg     StringRef Name = A->getOption().getName();
    132      1.1  joerg     A->claim();
    133      1.1  joerg 
    134      1.1  joerg     // Skip over "-m".
    135      1.1  joerg     assert(Name.startswith("m") && "Invalid feature name.");
    136      1.1  joerg     Name = Name.substr(1);
    137      1.1  joerg 
    138      1.1  joerg     bool IsNegative = Name.startswith("no-");
    139      1.1  joerg     if (IsNegative)
    140      1.1  joerg       Name = Name.substr(3);
    141      1.1  joerg     Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
    142      1.1  joerg   }
    143      1.1  joerg }
    144      1.1  joerg 
    145  1.1.1.2  joerg std::vector<StringRef>
    146  1.1.1.2  joerg tools::unifyTargetFeatures(const std::vector<StringRef> &Features) {
    147  1.1.1.2  joerg   std::vector<StringRef> UnifiedFeatures;
    148  1.1.1.2  joerg   // Find the last of each feature.
    149  1.1.1.2  joerg   llvm::StringMap<unsigned> LastOpt;
    150  1.1.1.2  joerg   for (unsigned I = 0, N = Features.size(); I < N; ++I) {
    151  1.1.1.2  joerg     StringRef Name = Features[I];
    152  1.1.1.2  joerg     assert(Name[0] == '-' || Name[0] == '+');
    153  1.1.1.2  joerg     LastOpt[Name.drop_front(1)] = I;
    154  1.1.1.2  joerg   }
    155  1.1.1.2  joerg 
    156  1.1.1.2  joerg   for (unsigned I = 0, N = Features.size(); I < N; ++I) {
    157  1.1.1.2  joerg     // If this feature was overridden, ignore it.
    158  1.1.1.2  joerg     StringRef Name = Features[I];
    159  1.1.1.2  joerg     llvm::StringMap<unsigned>::iterator LastI = LastOpt.find(Name.drop_front(1));
    160  1.1.1.2  joerg     assert(LastI != LastOpt.end());
    161  1.1.1.2  joerg     unsigned Last = LastI->second;
    162  1.1.1.2  joerg     if (Last != I)
    163  1.1.1.2  joerg       continue;
    164  1.1.1.2  joerg 
    165  1.1.1.2  joerg     UnifiedFeatures.push_back(Name);
    166  1.1.1.2  joerg   }
    167  1.1.1.2  joerg   return UnifiedFeatures;
    168  1.1.1.2  joerg }
    169  1.1.1.2  joerg 
    170      1.1  joerg void tools::addDirectoryList(const ArgList &Args, ArgStringList &CmdArgs,
    171      1.1  joerg                              const char *ArgName, const char *EnvVar) {
    172      1.1  joerg   const char *DirList = ::getenv(EnvVar);
    173      1.1  joerg   bool CombinedArg = false;
    174      1.1  joerg 
    175      1.1  joerg   if (!DirList)
    176      1.1  joerg     return; // Nothing to do.
    177      1.1  joerg 
    178      1.1  joerg   StringRef Name(ArgName);
    179  1.1.1.2  joerg   if (Name.equals("-I") || Name.equals("-L") || Name.empty())
    180      1.1  joerg     CombinedArg = true;
    181      1.1  joerg 
    182      1.1  joerg   StringRef Dirs(DirList);
    183      1.1  joerg   if (Dirs.empty()) // Empty string should not add '.'.
    184      1.1  joerg     return;
    185      1.1  joerg 
    186      1.1  joerg   StringRef::size_type Delim;
    187      1.1  joerg   while ((Delim = Dirs.find(llvm::sys::EnvPathSeparator)) != StringRef::npos) {
    188      1.1  joerg     if (Delim == 0) { // Leading colon.
    189      1.1  joerg       if (CombinedArg) {
    190      1.1  joerg         CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
    191      1.1  joerg       } else {
    192      1.1  joerg         CmdArgs.push_back(ArgName);
    193      1.1  joerg         CmdArgs.push_back(".");
    194      1.1  joerg       }
    195      1.1  joerg     } else {
    196      1.1  joerg       if (CombinedArg) {
    197      1.1  joerg         CmdArgs.push_back(
    198      1.1  joerg             Args.MakeArgString(std::string(ArgName) + Dirs.substr(0, Delim)));
    199      1.1  joerg       } else {
    200      1.1  joerg         CmdArgs.push_back(ArgName);
    201      1.1  joerg         CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim)));
    202      1.1  joerg       }
    203      1.1  joerg     }
    204      1.1  joerg     Dirs = Dirs.substr(Delim + 1);
    205      1.1  joerg   }
    206      1.1  joerg 
    207      1.1  joerg   if (Dirs.empty()) { // Trailing colon.
    208      1.1  joerg     if (CombinedArg) {
    209      1.1  joerg       CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
    210      1.1  joerg     } else {
    211      1.1  joerg       CmdArgs.push_back(ArgName);
    212      1.1  joerg       CmdArgs.push_back(".");
    213      1.1  joerg     }
    214      1.1  joerg   } else { // Add the last path.
    215      1.1  joerg     if (CombinedArg) {
    216      1.1  joerg       CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs));
    217      1.1  joerg     } else {
    218      1.1  joerg       CmdArgs.push_back(ArgName);
    219      1.1  joerg       CmdArgs.push_back(Args.MakeArgString(Dirs));
    220      1.1  joerg     }
    221      1.1  joerg   }
    222      1.1  joerg }
    223      1.1  joerg 
    224      1.1  joerg void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
    225      1.1  joerg                             const ArgList &Args, ArgStringList &CmdArgs,
    226      1.1  joerg                             const JobAction &JA) {
    227      1.1  joerg   const Driver &D = TC.getDriver();
    228      1.1  joerg 
    229      1.1  joerg   // Add extra linker input arguments which are not treated as inputs
    230      1.1  joerg   // (constructed via -Xarch_).
    231      1.1  joerg   Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input);
    232      1.1  joerg 
    233      1.1  joerg   // LIBRARY_PATH are included before user inputs and only supported on native
    234      1.1  joerg   // toolchains.
    235      1.1  joerg   if (!TC.isCrossCompiling())
    236      1.1  joerg     addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
    237      1.1  joerg 
    238      1.1  joerg   for (const auto &II : Inputs) {
    239  1.1.1.2  joerg     // If the current tool chain refers to an OpenMP offloading host, we
    240  1.1.1.2  joerg     // should ignore inputs that refer to OpenMP offloading devices -
    241      1.1  joerg     // they will be embedded according to a proper linker script.
    242      1.1  joerg     if (auto *IA = II.getAction())
    243      1.1  joerg       if ((JA.isHostOffloading(Action::OFK_OpenMP) &&
    244  1.1.1.2  joerg            IA->isDeviceOffloading(Action::OFK_OpenMP)))
    245      1.1  joerg         continue;
    246      1.1  joerg 
    247      1.1  joerg     if (!TC.HasNativeLLVMSupport() && types::isLLVMIR(II.getType()))
    248      1.1  joerg       // Don't try to pass LLVM inputs unless we have native support.
    249      1.1  joerg       D.Diag(diag::err_drv_no_linker_llvm_support) << TC.getTripleString();
    250      1.1  joerg 
    251      1.1  joerg     // Add filenames immediately.
    252      1.1  joerg     if (II.isFilename()) {
    253      1.1  joerg       CmdArgs.push_back(II.getFilename());
    254      1.1  joerg       continue;
    255      1.1  joerg     }
    256      1.1  joerg 
    257      1.1  joerg     // Otherwise, this is a linker input argument.
    258      1.1  joerg     const Arg &A = II.getInputArg();
    259      1.1  joerg 
    260      1.1  joerg     // Handle reserved library options.
    261      1.1  joerg     if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx))
    262      1.1  joerg       TC.AddCXXStdlibLibArgs(Args, CmdArgs);
    263      1.1  joerg     else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext))
    264      1.1  joerg       TC.AddCCKextLibArgs(Args, CmdArgs);
    265      1.1  joerg     else if (A.getOption().matches(options::OPT_z)) {
    266      1.1  joerg       // Pass -z prefix for gcc linker compatibility.
    267      1.1  joerg       A.claim();
    268      1.1  joerg       A.render(Args, CmdArgs);
    269      1.1  joerg     } else {
    270      1.1  joerg       A.renderAsInput(Args, CmdArgs);
    271      1.1  joerg     }
    272      1.1  joerg   }
    273      1.1  joerg }
    274      1.1  joerg 
    275  1.1.1.2  joerg void tools::addLinkerCompressDebugSectionsOption(
    276  1.1.1.2  joerg     const ToolChain &TC, const llvm::opt::ArgList &Args,
    277  1.1.1.2  joerg     llvm::opt::ArgStringList &CmdArgs) {
    278  1.1.1.2  joerg   // GNU ld supports --compress-debug-sections=none|zlib|zlib-gnu|zlib-gabi
    279  1.1.1.2  joerg   // whereas zlib is an alias to zlib-gabi. Therefore -gz=none|zlib|zlib-gnu
    280  1.1.1.2  joerg   // are translated to --compress-debug-sections=none|zlib|zlib-gnu.
    281  1.1.1.2  joerg   // -gz is not translated since ld --compress-debug-sections option requires an
    282  1.1.1.2  joerg   // argument.
    283  1.1.1.2  joerg   if (const Arg *A = Args.getLastArg(options::OPT_gz_EQ)) {
    284  1.1.1.2  joerg     StringRef V = A->getValue();
    285  1.1.1.2  joerg     if (V == "none" || V == "zlib" || V == "zlib-gnu")
    286  1.1.1.2  joerg       CmdArgs.push_back(Args.MakeArgString("--compress-debug-sections=" + V));
    287  1.1.1.2  joerg     else
    288  1.1.1.2  joerg       TC.getDriver().Diag(diag::err_drv_unsupported_option_argument)
    289  1.1.1.2  joerg           << A->getOption().getName() << V;
    290  1.1.1.2  joerg   }
    291  1.1.1.2  joerg }
    292  1.1.1.2  joerg 
    293      1.1  joerg void tools::AddTargetFeature(const ArgList &Args,
    294      1.1  joerg                              std::vector<StringRef> &Features,
    295      1.1  joerg                              OptSpecifier OnOpt, OptSpecifier OffOpt,
    296      1.1  joerg                              StringRef FeatureName) {
    297      1.1  joerg   if (Arg *A = Args.getLastArg(OnOpt, OffOpt)) {
    298      1.1  joerg     if (A->getOption().matches(OnOpt))
    299      1.1  joerg       Features.push_back(Args.MakeArgString("+" + FeatureName));
    300      1.1  joerg     else
    301      1.1  joerg       Features.push_back(Args.MakeArgString("-" + FeatureName));
    302      1.1  joerg   }
    303      1.1  joerg }
    304      1.1  joerg 
    305  1.1.1.2  joerg /// Get the (LLVM) name of the AMDGPU gpu we are targeting.
    306  1.1.1.2  joerg static std::string getAMDGPUTargetGPU(const llvm::Triple &T,
    307  1.1.1.2  joerg                                       const ArgList &Args) {
    308      1.1  joerg   if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
    309  1.1.1.2  joerg     auto GPUName = getProcessorFromTargetID(T, A->getValue());
    310  1.1.1.2  joerg     return llvm::StringSwitch<std::string>(GPUName)
    311      1.1  joerg         .Cases("rv630", "rv635", "r600")
    312      1.1  joerg         .Cases("rv610", "rv620", "rs780", "rs880")
    313      1.1  joerg         .Case("rv740", "rv770")
    314      1.1  joerg         .Case("palm", "cedar")
    315      1.1  joerg         .Cases("sumo", "sumo2", "sumo")
    316      1.1  joerg         .Case("hemlock", "cypress")
    317      1.1  joerg         .Case("aruba", "cayman")
    318  1.1.1.2  joerg         .Default(GPUName.str());
    319      1.1  joerg   }
    320      1.1  joerg   return "";
    321      1.1  joerg }
    322      1.1  joerg 
    323      1.1  joerg static std::string getLanaiTargetCPU(const ArgList &Args) {
    324      1.1  joerg   if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
    325      1.1  joerg     return A->getValue();
    326      1.1  joerg   }
    327      1.1  joerg   return "";
    328      1.1  joerg }
    329      1.1  joerg 
    330      1.1  joerg /// Get the (LLVM) name of the WebAssembly cpu we are targeting.
    331      1.1  joerg static StringRef getWebAssemblyTargetCPU(const ArgList &Args) {
    332      1.1  joerg   // If we have -mcpu=, use that.
    333      1.1  joerg   if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
    334      1.1  joerg     StringRef CPU = A->getValue();
    335      1.1  joerg 
    336      1.1  joerg #ifdef __wasm__
    337      1.1  joerg     // Handle "native" by examining the host. "native" isn't meaningful when
    338      1.1  joerg     // cross compiling, so only support this when the host is also WebAssembly.
    339      1.1  joerg     if (CPU == "native")
    340      1.1  joerg       return llvm::sys::getHostCPUName();
    341      1.1  joerg #endif
    342      1.1  joerg 
    343      1.1  joerg     return CPU;
    344      1.1  joerg   }
    345      1.1  joerg 
    346      1.1  joerg   return "generic";
    347      1.1  joerg }
    348      1.1  joerg 
    349      1.1  joerg std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T,
    350      1.1  joerg                               bool FromAs) {
    351      1.1  joerg   Arg *A;
    352      1.1  joerg 
    353      1.1  joerg   switch (T.getArch()) {
    354      1.1  joerg   default:
    355      1.1  joerg     return "";
    356      1.1  joerg 
    357      1.1  joerg   case llvm::Triple::aarch64:
    358  1.1.1.2  joerg   case llvm::Triple::aarch64_32:
    359      1.1  joerg   case llvm::Triple::aarch64_be:
    360      1.1  joerg     return aarch64::getAArch64TargetCPU(Args, T, A);
    361      1.1  joerg 
    362      1.1  joerg   case llvm::Triple::arm:
    363      1.1  joerg   case llvm::Triple::armeb:
    364      1.1  joerg   case llvm::Triple::thumb:
    365      1.1  joerg   case llvm::Triple::thumbeb: {
    366      1.1  joerg     StringRef MArch, MCPU;
    367      1.1  joerg     arm::getARMArchCPUFromArgs(Args, MArch, MCPU, FromAs);
    368      1.1  joerg     return arm::getARMTargetCPU(MCPU, MArch, T);
    369      1.1  joerg   }
    370      1.1  joerg 
    371      1.1  joerg   case llvm::Triple::avr:
    372      1.1  joerg     if (const Arg *A = Args.getLastArg(options::OPT_mmcu_EQ))
    373      1.1  joerg       return A->getValue();
    374      1.1  joerg     return "";
    375      1.1  joerg 
    376  1.1.1.2  joerg   case llvm::Triple::m68k:
    377  1.1.1.2  joerg     return m68k::getM68kTargetCPU(Args);
    378  1.1.1.2  joerg 
    379      1.1  joerg   case llvm::Triple::mips:
    380      1.1  joerg   case llvm::Triple::mipsel:
    381      1.1  joerg   case llvm::Triple::mips64:
    382      1.1  joerg   case llvm::Triple::mips64el: {
    383      1.1  joerg     StringRef CPUName;
    384      1.1  joerg     StringRef ABIName;
    385      1.1  joerg     mips::getMipsCPUAndABI(Args, T, CPUName, ABIName);
    386  1.1.1.2  joerg     return std::string(CPUName);
    387      1.1  joerg   }
    388      1.1  joerg 
    389      1.1  joerg   case llvm::Triple::nvptx:
    390      1.1  joerg   case llvm::Triple::nvptx64:
    391      1.1  joerg     if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
    392      1.1  joerg       return A->getValue();
    393      1.1  joerg     return "";
    394      1.1  joerg 
    395      1.1  joerg   case llvm::Triple::ppc:
    396  1.1.1.2  joerg   case llvm::Triple::ppcle:
    397      1.1  joerg   case llvm::Triple::ppc64:
    398      1.1  joerg   case llvm::Triple::ppc64le: {
    399      1.1  joerg     std::string TargetCPUName = ppc::getPPCTargetCPU(Args);
    400      1.1  joerg     // LLVM may default to generating code for the native CPU,
    401      1.1  joerg     // but, like gcc, we default to a more generic option for
    402  1.1.1.2  joerg     // each architecture. (except on AIX)
    403  1.1.1.2  joerg     if (!TargetCPUName.empty())
    404  1.1.1.2  joerg       return TargetCPUName;
    405  1.1.1.2  joerg 
    406  1.1.1.2  joerg     if (T.isOSAIX()) {
    407  1.1.1.2  joerg       unsigned major, minor, unused_micro;
    408  1.1.1.2  joerg       T.getOSVersion(major, minor, unused_micro);
    409  1.1.1.2  joerg       // The minimal arch level moved from pwr4 for AIX7.1 to
    410  1.1.1.2  joerg       // pwr7 for AIX7.2.
    411  1.1.1.2  joerg       TargetCPUName =
    412  1.1.1.2  joerg           (major < 7 || (major == 7 && minor < 2)) ? "pwr4" : "pwr7";
    413  1.1.1.2  joerg     } else if (T.getArch() == llvm::Triple::ppc64le)
    414  1.1.1.2  joerg       TargetCPUName = "ppc64le";
    415  1.1.1.2  joerg     else if (T.getArch() == llvm::Triple::ppc64)
    416  1.1.1.2  joerg       TargetCPUName = "ppc64";
    417  1.1.1.2  joerg     else
    418  1.1.1.2  joerg       TargetCPUName = "ppc";
    419  1.1.1.2  joerg 
    420      1.1  joerg     return TargetCPUName;
    421      1.1  joerg   }
    422  1.1.1.2  joerg   case llvm::Triple::riscv32:
    423  1.1.1.2  joerg   case llvm::Triple::riscv64:
    424  1.1.1.2  joerg     if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
    425  1.1.1.2  joerg       return A->getValue();
    426  1.1.1.2  joerg     return "";
    427      1.1  joerg 
    428      1.1  joerg   case llvm::Triple::bpfel:
    429      1.1  joerg   case llvm::Triple::bpfeb:
    430      1.1  joerg   case llvm::Triple::sparc:
    431      1.1  joerg   case llvm::Triple::sparcel:
    432      1.1  joerg   case llvm::Triple::sparcv9:
    433      1.1  joerg     if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
    434      1.1  joerg       return A->getValue();
    435  1.1.1.2  joerg     if (T.getArch() == llvm::Triple::sparc && T.isOSSolaris())
    436  1.1.1.2  joerg       return "v9";
    437      1.1  joerg     return "";
    438      1.1  joerg 
    439      1.1  joerg   case llvm::Triple::x86:
    440      1.1  joerg   case llvm::Triple::x86_64:
    441      1.1  joerg     return x86::getX86TargetCPU(Args, T);
    442      1.1  joerg 
    443      1.1  joerg   case llvm::Triple::hexagon:
    444      1.1  joerg     return "hexagon" +
    445      1.1  joerg            toolchains::HexagonToolChain::GetTargetCPUVersion(Args).str();
    446      1.1  joerg 
    447      1.1  joerg   case llvm::Triple::lanai:
    448      1.1  joerg     return getLanaiTargetCPU(Args);
    449      1.1  joerg 
    450      1.1  joerg   case llvm::Triple::systemz:
    451      1.1  joerg     return systemz::getSystemZTargetCPU(Args);
    452      1.1  joerg 
    453      1.1  joerg   case llvm::Triple::r600:
    454      1.1  joerg   case llvm::Triple::amdgcn:
    455  1.1.1.2  joerg     return getAMDGPUTargetGPU(T, Args);
    456      1.1  joerg 
    457      1.1  joerg   case llvm::Triple::wasm32:
    458      1.1  joerg   case llvm::Triple::wasm64:
    459  1.1.1.2  joerg     return std::string(getWebAssemblyTargetCPU(Args));
    460      1.1  joerg   }
    461      1.1  joerg }
    462      1.1  joerg 
    463  1.1.1.2  joerg llvm::StringRef tools::getLTOParallelism(const ArgList &Args, const Driver &D) {
    464      1.1  joerg   Arg *LtoJobsArg = Args.getLastArg(options::OPT_flto_jobs_EQ);
    465  1.1.1.2  joerg   if (!LtoJobsArg)
    466  1.1.1.2  joerg     return {};
    467  1.1.1.2  joerg   if (!llvm::get_threadpool_strategy(LtoJobsArg->getValue()))
    468  1.1.1.2  joerg     D.Diag(diag::err_drv_invalid_int_value)
    469  1.1.1.2  joerg         << LtoJobsArg->getAsString(Args) << LtoJobsArg->getValue();
    470  1.1.1.2  joerg   return LtoJobsArg->getValue();
    471      1.1  joerg }
    472      1.1  joerg 
    473      1.1  joerg // CloudABI uses -ffunction-sections and -fdata-sections by default.
    474      1.1  joerg bool tools::isUseSeparateSections(const llvm::Triple &Triple) {
    475      1.1  joerg   return Triple.getOS() == llvm::Triple::CloudABI;
    476      1.1  joerg }
    477      1.1  joerg 
    478  1.1.1.2  joerg void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
    479      1.1  joerg                           ArgStringList &CmdArgs, const InputInfo &Output,
    480      1.1  joerg                           const InputInfo &Input, bool IsThinLTO) {
    481  1.1.1.2  joerg   const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath());
    482  1.1.1.2  joerg   const Driver &D = ToolChain.getDriver();
    483  1.1.1.2  joerg   if (llvm::sys::path::filename(Linker) != "ld.lld" &&
    484  1.1.1.2  joerg       llvm::sys::path::stem(Linker) != "ld.lld") {
    485  1.1.1.2  joerg     // Tell the linker to load the plugin. This has to come before
    486  1.1.1.2  joerg     // AddLinkerInputs as gold requires -plugin to come before any -plugin-opt
    487  1.1.1.2  joerg     // that -Wl might forward.
    488  1.1.1.2  joerg     CmdArgs.push_back("-plugin");
    489      1.1  joerg 
    490      1.1  joerg #if defined(_WIN32)
    491  1.1.1.2  joerg     const char *Suffix = ".dll";
    492      1.1  joerg #elif defined(__APPLE__)
    493  1.1.1.2  joerg     const char *Suffix = ".dylib";
    494      1.1  joerg #else
    495  1.1.1.2  joerg     const char *Suffix = ".so";
    496      1.1  joerg #endif
    497      1.1  joerg 
    498  1.1.1.2  joerg     SmallString<1024> Plugin;
    499  1.1.1.2  joerg     llvm::sys::path::native(
    500  1.1.1.2  joerg         Twine(D.Dir) + "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold" + Suffix,
    501  1.1.1.2  joerg         Plugin);
    502  1.1.1.2  joerg     CmdArgs.push_back(Args.MakeArgString(Plugin));
    503  1.1.1.2  joerg   }
    504      1.1  joerg 
    505      1.1  joerg   // Try to pass driver level flags relevant to LTO code generation down to
    506      1.1  joerg   // the plugin.
    507      1.1  joerg 
    508      1.1  joerg   // Handle flags for selecting CPU variants.
    509      1.1  joerg   std::string CPU = getCPUName(Args, ToolChain.getTriple());
    510      1.1  joerg   if (!CPU.empty())
    511      1.1  joerg     CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=mcpu=") + CPU));
    512      1.1  joerg 
    513      1.1  joerg   if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
    514  1.1.1.2  joerg     // The optimization level matches
    515  1.1.1.2  joerg     // CompilerInvocation.cpp:getOptimizationLevel().
    516      1.1  joerg     StringRef OOpt;
    517      1.1  joerg     if (A->getOption().matches(options::OPT_O4) ||
    518      1.1  joerg         A->getOption().matches(options::OPT_Ofast))
    519      1.1  joerg       OOpt = "3";
    520  1.1.1.2  joerg     else if (A->getOption().matches(options::OPT_O)) {
    521      1.1  joerg       OOpt = A->getValue();
    522  1.1.1.2  joerg       if (OOpt == "g")
    523  1.1.1.2  joerg         OOpt = "1";
    524  1.1.1.2  joerg       else if (OOpt == "s" || OOpt == "z")
    525  1.1.1.2  joerg         OOpt = "2";
    526  1.1.1.2  joerg     } else if (A->getOption().matches(options::OPT_O0))
    527      1.1  joerg       OOpt = "0";
    528      1.1  joerg     if (!OOpt.empty())
    529      1.1  joerg       CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=O") + OOpt));
    530      1.1  joerg   }
    531      1.1  joerg 
    532      1.1  joerg   if (Args.hasArg(options::OPT_gsplit_dwarf)) {
    533      1.1  joerg     CmdArgs.push_back(
    534      1.1  joerg         Args.MakeArgString(Twine("-plugin-opt=dwo_dir=") +
    535      1.1  joerg             Output.getFilename() + "_dwo"));
    536      1.1  joerg   }
    537      1.1  joerg 
    538      1.1  joerg   if (IsThinLTO)
    539      1.1  joerg     CmdArgs.push_back("-plugin-opt=thinlto");
    540      1.1  joerg 
    541  1.1.1.2  joerg   StringRef Parallelism = getLTOParallelism(Args, D);
    542  1.1.1.2  joerg   if (!Parallelism.empty())
    543      1.1  joerg     CmdArgs.push_back(
    544      1.1  joerg         Args.MakeArgString("-plugin-opt=jobs=" + Twine(Parallelism)));
    545      1.1  joerg 
    546      1.1  joerg   // If an explicit debugger tuning argument appeared, pass it along.
    547      1.1  joerg   if (Arg *A = Args.getLastArg(options::OPT_gTune_Group,
    548      1.1  joerg                                options::OPT_ggdbN_Group)) {
    549      1.1  joerg     if (A->getOption().matches(options::OPT_glldb))
    550      1.1  joerg       CmdArgs.push_back("-plugin-opt=-debugger-tune=lldb");
    551      1.1  joerg     else if (A->getOption().matches(options::OPT_gsce))
    552      1.1  joerg       CmdArgs.push_back("-plugin-opt=-debugger-tune=sce");
    553  1.1.1.2  joerg     else if (A->getOption().matches(options::OPT_gdbx))
    554  1.1.1.2  joerg       CmdArgs.push_back("-plugin-opt=-debugger-tune=dbx");
    555      1.1  joerg     else
    556      1.1  joerg       CmdArgs.push_back("-plugin-opt=-debugger-tune=gdb");
    557      1.1  joerg   }
    558      1.1  joerg 
    559      1.1  joerg   bool UseSeparateSections =
    560      1.1  joerg       isUseSeparateSections(ToolChain.getEffectiveTriple());
    561      1.1  joerg 
    562      1.1  joerg   if (Args.hasFlag(options::OPT_ffunction_sections,
    563      1.1  joerg                    options::OPT_fno_function_sections, UseSeparateSections)) {
    564      1.1  joerg     CmdArgs.push_back("-plugin-opt=-function-sections");
    565      1.1  joerg   }
    566      1.1  joerg 
    567      1.1  joerg   if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
    568      1.1  joerg                    UseSeparateSections)) {
    569      1.1  joerg     CmdArgs.push_back("-plugin-opt=-data-sections");
    570      1.1  joerg   }
    571      1.1  joerg 
    572      1.1  joerg   if (Arg *A = getLastProfileSampleUseArg(Args)) {
    573      1.1  joerg     StringRef FName = A->getValue();
    574      1.1  joerg     if (!llvm::sys::fs::exists(FName))
    575  1.1.1.2  joerg       D.Diag(diag::err_drv_no_such_file) << FName;
    576      1.1  joerg     else
    577      1.1  joerg       CmdArgs.push_back(
    578      1.1  joerg           Args.MakeArgString(Twine("-plugin-opt=sample-profile=") + FName));
    579      1.1  joerg   }
    580      1.1  joerg 
    581      1.1  joerg   auto *CSPGOGenerateArg = Args.getLastArg(options::OPT_fcs_profile_generate,
    582      1.1  joerg                                            options::OPT_fcs_profile_generate_EQ,
    583      1.1  joerg                                            options::OPT_fno_profile_generate);
    584      1.1  joerg   if (CSPGOGenerateArg &&
    585      1.1  joerg       CSPGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate))
    586      1.1  joerg     CSPGOGenerateArg = nullptr;
    587      1.1  joerg 
    588      1.1  joerg   auto *ProfileUseArg = getLastProfileUseArg(Args);
    589      1.1  joerg 
    590      1.1  joerg   if (CSPGOGenerateArg) {
    591      1.1  joerg     CmdArgs.push_back(Args.MakeArgString("-plugin-opt=cs-profile-generate"));
    592      1.1  joerg     if (CSPGOGenerateArg->getOption().matches(
    593      1.1  joerg             options::OPT_fcs_profile_generate_EQ)) {
    594      1.1  joerg       SmallString<128> Path(CSPGOGenerateArg->getValue());
    595      1.1  joerg       llvm::sys::path::append(Path, "default_%m.profraw");
    596      1.1  joerg       CmdArgs.push_back(
    597      1.1  joerg           Args.MakeArgString(Twine("-plugin-opt=cs-profile-path=") + Path));
    598      1.1  joerg     } else
    599      1.1  joerg       CmdArgs.push_back(
    600      1.1  joerg           Args.MakeArgString("-plugin-opt=cs-profile-path=default_%m.profraw"));
    601      1.1  joerg   } else if (ProfileUseArg) {
    602      1.1  joerg     SmallString<128> Path(
    603      1.1  joerg         ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue());
    604      1.1  joerg     if (Path.empty() || llvm::sys::fs::is_directory(Path))
    605      1.1  joerg       llvm::sys::path::append(Path, "default.profdata");
    606      1.1  joerg     CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=cs-profile-path=") +
    607      1.1  joerg                                          Path));
    608      1.1  joerg   }
    609      1.1  joerg 
    610  1.1.1.2  joerg   // Pass an option to enable/disable the new pass manager.
    611  1.1.1.2  joerg   if (auto *A = Args.getLastArg(options::OPT_flegacy_pass_manager,
    612  1.1.1.2  joerg                                 options::OPT_fno_legacy_pass_manager)) {
    613  1.1.1.2  joerg     if (A->getOption().matches(options::OPT_flegacy_pass_manager))
    614  1.1.1.2  joerg       CmdArgs.push_back("-plugin-opt=legacy-pass-manager");
    615  1.1.1.2  joerg     else
    616  1.1.1.2  joerg       CmdArgs.push_back("-plugin-opt=new-pass-manager");
    617      1.1  joerg   }
    618      1.1  joerg 
    619  1.1.1.2  joerg   // Pass an option to enable pseudo probe emission.
    620  1.1.1.2  joerg   if (Args.hasFlag(options::OPT_fpseudo_probe_for_profiling,
    621  1.1.1.2  joerg                    options::OPT_fno_pseudo_probe_for_profiling, false))
    622  1.1.1.2  joerg     CmdArgs.push_back("-plugin-opt=pseudo-probe-for-profiling");
    623  1.1.1.2  joerg 
    624      1.1  joerg   // Setup statistics file output.
    625  1.1.1.2  joerg   SmallString<128> StatsFile = getStatsFileName(Args, Output, Input, D);
    626      1.1  joerg   if (!StatsFile.empty())
    627      1.1  joerg     CmdArgs.push_back(
    628      1.1  joerg         Args.MakeArgString(Twine("-plugin-opt=stats-file=") + StatsFile));
    629      1.1  joerg 
    630  1.1.1.2  joerg   addX86AlignBranchArgs(D, Args, CmdArgs, /*IsLTO=*/true);
    631      1.1  joerg 
    632  1.1.1.2  joerg   // Handle remark diagnostics on screen options: '-Rpass-*'.
    633  1.1.1.2  joerg   renderRpassOptions(Args, CmdArgs);
    634  1.1.1.2  joerg 
    635  1.1.1.2  joerg   // Handle serialized remarks options: '-fsave-optimization-record'
    636  1.1.1.2  joerg   // and '-foptimization-record-*'.
    637  1.1.1.2  joerg   if (willEmitRemarks(Args))
    638  1.1.1.2  joerg     renderRemarksOptions(Args, CmdArgs, ToolChain.getEffectiveTriple(), Input,
    639  1.1.1.2  joerg                          Output);
    640  1.1.1.2  joerg 
    641  1.1.1.2  joerg   // Handle remarks hotness/threshold related options.
    642  1.1.1.2  joerg   renderRemarksHotnessOptions(Args, CmdArgs);
    643  1.1.1.2  joerg 
    644  1.1.1.2  joerg   addMachineOutlinerArgs(D, Args, CmdArgs, ToolChain.getEffectiveTriple(),
    645  1.1.1.2  joerg                          /*IsLTO=*/true);
    646      1.1  joerg }
    647      1.1  joerg 
    648      1.1  joerg void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
    649      1.1  joerg                                  ArgStringList &CmdArgs) {
    650  1.1.1.2  joerg   // Enable -frtlib-add-rpath by default for the case of VE.
    651  1.1.1.2  joerg   const bool IsVE = TC.getTriple().isVE();
    652  1.1.1.2  joerg   bool DefaultValue = IsVE;
    653      1.1  joerg   if (!Args.hasFlag(options::OPT_frtlib_add_rpath,
    654  1.1.1.2  joerg                     options::OPT_fno_rtlib_add_rpath, DefaultValue))
    655      1.1  joerg     return;
    656      1.1  joerg 
    657      1.1  joerg   std::string CandidateRPath = TC.getArchSpecificLibPath();
    658      1.1  joerg   if (TC.getVFS().exists(CandidateRPath)) {
    659      1.1  joerg     CmdArgs.push_back("-rpath");
    660      1.1  joerg     CmdArgs.push_back(Args.MakeArgString(CandidateRPath.c_str()));
    661      1.1  joerg   }
    662      1.1  joerg }
    663      1.1  joerg 
    664      1.1  joerg bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
    665      1.1  joerg                              const ArgList &Args, bool ForceStaticHostRuntime,
    666      1.1  joerg                              bool IsOffloadingHost, bool GompNeedsRT) {
    667      1.1  joerg   if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
    668      1.1  joerg                     options::OPT_fno_openmp, false))
    669      1.1  joerg     return false;
    670      1.1  joerg 
    671      1.1  joerg   Driver::OpenMPRuntimeKind RTKind = TC.getDriver().getOpenMPRuntime(Args);
    672      1.1  joerg 
    673      1.1  joerg   if (RTKind == Driver::OMPRT_Unknown)
    674      1.1  joerg     // Already diagnosed.
    675      1.1  joerg     return false;
    676      1.1  joerg 
    677      1.1  joerg   if (ForceStaticHostRuntime)
    678      1.1  joerg     CmdArgs.push_back("-Bstatic");
    679      1.1  joerg 
    680      1.1  joerg   switch (RTKind) {
    681      1.1  joerg   case Driver::OMPRT_OMP:
    682      1.1  joerg     CmdArgs.push_back("-lomp");
    683      1.1  joerg     break;
    684      1.1  joerg   case Driver::OMPRT_GOMP:
    685      1.1  joerg     CmdArgs.push_back("-lgomp");
    686      1.1  joerg     break;
    687      1.1  joerg   case Driver::OMPRT_IOMP5:
    688      1.1  joerg     CmdArgs.push_back("-liomp5");
    689      1.1  joerg     break;
    690      1.1  joerg   case Driver::OMPRT_Unknown:
    691      1.1  joerg     break;
    692      1.1  joerg   }
    693      1.1  joerg 
    694      1.1  joerg   if (ForceStaticHostRuntime)
    695      1.1  joerg     CmdArgs.push_back("-Bdynamic");
    696      1.1  joerg 
    697      1.1  joerg   if (RTKind == Driver::OMPRT_GOMP && GompNeedsRT)
    698      1.1  joerg       CmdArgs.push_back("-lrt");
    699      1.1  joerg 
    700      1.1  joerg   if (IsOffloadingHost)
    701      1.1  joerg     CmdArgs.push_back("-lomptarget");
    702      1.1  joerg 
    703      1.1  joerg   addArchSpecificRPath(TC, Args, CmdArgs);
    704      1.1  joerg 
    705      1.1  joerg   return true;
    706      1.1  joerg }
    707      1.1  joerg 
    708      1.1  joerg static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
    709      1.1  joerg                                 ArgStringList &CmdArgs, StringRef Sanitizer,
    710      1.1  joerg                                 bool IsShared, bool IsWhole) {
    711      1.1  joerg   // Wrap any static runtimes that must be forced into executable in
    712      1.1  joerg   // whole-archive.
    713      1.1  joerg   if (IsWhole) CmdArgs.push_back("--whole-archive");
    714      1.1  joerg   CmdArgs.push_back(TC.getCompilerRTArgString(
    715      1.1  joerg       Args, Sanitizer, IsShared ? ToolChain::FT_Shared : ToolChain::FT_Static));
    716      1.1  joerg   if (IsWhole) CmdArgs.push_back("--no-whole-archive");
    717      1.1  joerg 
    718      1.1  joerg   if (IsShared) {
    719      1.1  joerg     addArchSpecificRPath(TC, Args, CmdArgs);
    720      1.1  joerg   }
    721      1.1  joerg }
    722      1.1  joerg 
    723      1.1  joerg // Tries to use a file with the list of dynamic symbols that need to be exported
    724      1.1  joerg // from the runtime library. Returns true if the file was found.
    725      1.1  joerg static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args,
    726      1.1  joerg                                     ArgStringList &CmdArgs,
    727      1.1  joerg                                     StringRef Sanitizer) {
    728      1.1  joerg   // Solaris ld defaults to --export-dynamic behaviour but doesn't support
    729      1.1  joerg   // the option, so don't try to pass it.
    730      1.1  joerg   if (TC.getTriple().getOS() == llvm::Triple::Solaris)
    731      1.1  joerg     return true;
    732      1.1  joerg   // Myriad is static linking only.  Furthermore, some versions of its
    733      1.1  joerg   // linker have the bug where --export-dynamic overrides -static, so
    734      1.1  joerg   // don't use --export-dynamic on that platform.
    735      1.1  joerg   if (TC.getTriple().getVendor() == llvm::Triple::Myriad)
    736      1.1  joerg     return true;
    737      1.1  joerg   SmallString<128> SanRT(TC.getCompilerRT(Args, Sanitizer));
    738      1.1  joerg   if (llvm::sys::fs::exists(SanRT + ".syms")) {
    739      1.1  joerg     CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + SanRT + ".syms"));
    740      1.1  joerg     return true;
    741      1.1  joerg   }
    742      1.1  joerg   return false;
    743      1.1  joerg }
    744      1.1  joerg 
    745  1.1.1.2  joerg static const char *getAsNeededOption(const ToolChain &TC, bool as_needed) {
    746  1.1.1.2  joerg   // While the Solaris 11.2 ld added --as-needed/--no-as-needed as aliases
    747  1.1.1.2  joerg   // for the native forms -z ignore/-z record, they are missing in Illumos,
    748  1.1.1.2  joerg   // so always use the native form.
    749  1.1.1.2  joerg   if (TC.getTriple().isOSSolaris())
    750  1.1.1.2  joerg     return as_needed ? "-zignore" : "-zrecord";
    751  1.1.1.2  joerg   else
    752  1.1.1.2  joerg     return as_needed ? "--as-needed" : "--no-as-needed";
    753  1.1.1.2  joerg }
    754  1.1.1.2  joerg 
    755      1.1  joerg void tools::linkSanitizerRuntimeDeps(const ToolChain &TC,
    756      1.1  joerg                                      ArgStringList &CmdArgs) {
    757  1.1.1.2  joerg   // Fuchsia never needs these.  Any sanitizer runtimes with system
    758  1.1.1.2  joerg   // dependencies use the `.deplibs` feature instead.
    759  1.1.1.2  joerg   if (TC.getTriple().isOSFuchsia())
    760  1.1.1.2  joerg     return;
    761  1.1.1.2  joerg 
    762      1.1  joerg   // Force linking against the system libraries sanitizers depends on
    763      1.1  joerg   // (see PR15823 why this is necessary).
    764  1.1.1.2  joerg   CmdArgs.push_back(getAsNeededOption(TC, false));
    765      1.1  joerg   // There's no libpthread or librt on RTEMS & Android.
    766      1.1  joerg   if (TC.getTriple().getOS() != llvm::Triple::RTEMS &&
    767      1.1  joerg       !TC.getTriple().isAndroid()) {
    768      1.1  joerg     CmdArgs.push_back("-lpthread");
    769      1.1  joerg     if (!TC.getTriple().isOSOpenBSD())
    770      1.1  joerg       CmdArgs.push_back("-lrt");
    771      1.1  joerg   }
    772      1.1  joerg   CmdArgs.push_back("-lm");
    773      1.1  joerg   // There's no libdl on all OSes.
    774      1.1  joerg   if (!TC.getTriple().isOSFreeBSD() &&
    775      1.1  joerg       !TC.getTriple().isOSNetBSD() &&
    776      1.1  joerg       !TC.getTriple().isOSOpenBSD() &&
    777      1.1  joerg        TC.getTriple().getOS() != llvm::Triple::RTEMS)
    778      1.1  joerg     CmdArgs.push_back("-ldl");
    779      1.1  joerg   // Required for backtrace on some OSes
    780      1.1  joerg   if (TC.getTriple().isOSFreeBSD() ||
    781      1.1  joerg       TC.getTriple().isOSNetBSD())
    782      1.1  joerg     CmdArgs.push_back("-lexecinfo");
    783      1.1  joerg }
    784      1.1  joerg 
    785      1.1  joerg static void
    786      1.1  joerg collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
    787      1.1  joerg                          SmallVectorImpl<StringRef> &SharedRuntimes,
    788      1.1  joerg                          SmallVectorImpl<StringRef> &StaticRuntimes,
    789      1.1  joerg                          SmallVectorImpl<StringRef> &NonWholeStaticRuntimes,
    790      1.1  joerg                          SmallVectorImpl<StringRef> &HelperStaticRuntimes,
    791      1.1  joerg                          SmallVectorImpl<StringRef> &RequiredSymbols) {
    792      1.1  joerg   const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
    793      1.1  joerg   // Collect shared runtimes.
    794      1.1  joerg   if (SanArgs.needsSharedRt()) {
    795      1.1  joerg     if (SanArgs.needsAsanRt() && SanArgs.linkRuntimes()) {
    796      1.1  joerg       SharedRuntimes.push_back("asan");
    797      1.1  joerg       if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid())
    798      1.1  joerg         HelperStaticRuntimes.push_back("asan-preinit");
    799      1.1  joerg     }
    800  1.1.1.2  joerg     if (SanArgs.needsMemProfRt() && SanArgs.linkRuntimes()) {
    801  1.1.1.2  joerg       SharedRuntimes.push_back("memprof");
    802  1.1.1.2  joerg       if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid())
    803  1.1.1.2  joerg         HelperStaticRuntimes.push_back("memprof-preinit");
    804  1.1.1.2  joerg     }
    805      1.1  joerg     if (SanArgs.needsUbsanRt() && SanArgs.linkRuntimes()) {
    806      1.1  joerg       if (SanArgs.requiresMinimalRuntime())
    807      1.1  joerg         SharedRuntimes.push_back("ubsan_minimal");
    808      1.1  joerg       else
    809      1.1  joerg         SharedRuntimes.push_back("ubsan_standalone");
    810      1.1  joerg     }
    811      1.1  joerg     if (SanArgs.needsScudoRt() && SanArgs.linkRuntimes()) {
    812      1.1  joerg       if (SanArgs.requiresMinimalRuntime())
    813      1.1  joerg         SharedRuntimes.push_back("scudo_minimal");
    814      1.1  joerg       else
    815      1.1  joerg         SharedRuntimes.push_back("scudo");
    816      1.1  joerg     }
    817  1.1.1.2  joerg     if (SanArgs.needsTsanRt() && SanArgs.linkRuntimes())
    818  1.1.1.2  joerg       SharedRuntimes.push_back("tsan");
    819  1.1.1.2  joerg     if (SanArgs.needsHwasanRt() && SanArgs.linkRuntimes()) {
    820  1.1.1.2  joerg       if (SanArgs.needsHwasanAliasesRt())
    821  1.1.1.2  joerg         SharedRuntimes.push_back("hwasan_aliases");
    822  1.1.1.2  joerg       else
    823  1.1.1.2  joerg         SharedRuntimes.push_back("hwasan");
    824  1.1.1.2  joerg     }
    825      1.1  joerg   }
    826      1.1  joerg 
    827      1.1  joerg   // The stats_client library is also statically linked into DSOs.
    828      1.1  joerg   if (SanArgs.needsStatsRt() && SanArgs.linkRuntimes())
    829      1.1  joerg     StaticRuntimes.push_back("stats_client");
    830      1.1  joerg 
    831      1.1  joerg   // Collect static runtimes.
    832  1.1.1.2  joerg   if (Args.hasArg(options::OPT_shared)) {
    833  1.1.1.2  joerg     // Don't link static runtimes into DSOs.
    834      1.1  joerg     return;
    835      1.1  joerg   }
    836  1.1.1.2  joerg 
    837  1.1.1.2  joerg   // Each static runtime that has a DSO counterpart above is excluded below,
    838  1.1.1.2  joerg   // but runtimes that exist only as static are not affected by needsSharedRt.
    839  1.1.1.2  joerg 
    840  1.1.1.2  joerg   if (!SanArgs.needsSharedRt() && SanArgs.needsAsanRt() && SanArgs.linkRuntimes()) {
    841      1.1  joerg     StaticRuntimes.push_back("asan");
    842      1.1  joerg     if (SanArgs.linkCXXRuntimes())
    843      1.1  joerg       StaticRuntimes.push_back("asan_cxx");
    844      1.1  joerg   }
    845      1.1  joerg 
    846  1.1.1.2  joerg   if (!SanArgs.needsSharedRt() && SanArgs.needsMemProfRt() &&
    847  1.1.1.2  joerg       SanArgs.linkRuntimes()) {
    848  1.1.1.2  joerg     StaticRuntimes.push_back("memprof");
    849      1.1  joerg     if (SanArgs.linkCXXRuntimes())
    850  1.1.1.2  joerg       StaticRuntimes.push_back("memprof_cxx");
    851  1.1.1.2  joerg   }
    852  1.1.1.2  joerg 
    853  1.1.1.2  joerg   if (!SanArgs.needsSharedRt() && SanArgs.needsHwasanRt() && SanArgs.linkRuntimes()) {
    854  1.1.1.2  joerg     if (SanArgs.needsHwasanAliasesRt()) {
    855  1.1.1.2  joerg       StaticRuntimes.push_back("hwasan_aliases");
    856  1.1.1.2  joerg       if (SanArgs.linkCXXRuntimes())
    857  1.1.1.2  joerg         StaticRuntimes.push_back("hwasan_aliases_cxx");
    858  1.1.1.2  joerg     } else {
    859  1.1.1.2  joerg       StaticRuntimes.push_back("hwasan");
    860  1.1.1.2  joerg       if (SanArgs.linkCXXRuntimes())
    861  1.1.1.2  joerg         StaticRuntimes.push_back("hwasan_cxx");
    862  1.1.1.2  joerg     }
    863      1.1  joerg   }
    864      1.1  joerg   if (SanArgs.needsDfsanRt() && SanArgs.linkRuntimes())
    865      1.1  joerg     StaticRuntimes.push_back("dfsan");
    866      1.1  joerg   if (SanArgs.needsLsanRt() && SanArgs.linkRuntimes())
    867      1.1  joerg     StaticRuntimes.push_back("lsan");
    868      1.1  joerg   if (SanArgs.needsMsanRt() && SanArgs.linkRuntimes()) {
    869      1.1  joerg     StaticRuntimes.push_back("msan");
    870      1.1  joerg     if (SanArgs.linkCXXRuntimes())
    871      1.1  joerg       StaticRuntimes.push_back("msan_cxx");
    872      1.1  joerg   }
    873  1.1.1.2  joerg   if (!SanArgs.needsSharedRt() && SanArgs.needsTsanRt() &&
    874  1.1.1.2  joerg       SanArgs.linkRuntimes()) {
    875      1.1  joerg     StaticRuntimes.push_back("tsan");
    876      1.1  joerg     if (SanArgs.linkCXXRuntimes())
    877      1.1  joerg       StaticRuntimes.push_back("tsan_cxx");
    878      1.1  joerg   }
    879  1.1.1.2  joerg   if (!SanArgs.needsSharedRt() && SanArgs.needsUbsanRt() && SanArgs.linkRuntimes()) {
    880      1.1  joerg     if (SanArgs.requiresMinimalRuntime()) {
    881      1.1  joerg       StaticRuntimes.push_back("ubsan_minimal");
    882      1.1  joerg     } else {
    883      1.1  joerg       StaticRuntimes.push_back("ubsan_standalone");
    884      1.1  joerg       if (SanArgs.linkCXXRuntimes())
    885      1.1  joerg         StaticRuntimes.push_back("ubsan_standalone_cxx");
    886      1.1  joerg     }
    887      1.1  joerg   }
    888      1.1  joerg   if (SanArgs.needsSafeStackRt() && SanArgs.linkRuntimes()) {
    889      1.1  joerg     NonWholeStaticRuntimes.push_back("safestack");
    890      1.1  joerg     RequiredSymbols.push_back("__safestack_init");
    891      1.1  joerg   }
    892  1.1.1.2  joerg   if (!(SanArgs.needsSharedRt() && SanArgs.needsUbsanRt() && SanArgs.linkRuntimes())) {
    893  1.1.1.2  joerg     if (SanArgs.needsCfiRt() && SanArgs.linkRuntimes())
    894  1.1.1.2  joerg       StaticRuntimes.push_back("cfi");
    895  1.1.1.2  joerg     if (SanArgs.needsCfiDiagRt() && SanArgs.linkRuntimes()) {
    896  1.1.1.2  joerg       StaticRuntimes.push_back("cfi_diag");
    897  1.1.1.2  joerg       if (SanArgs.linkCXXRuntimes())
    898  1.1.1.2  joerg         StaticRuntimes.push_back("ubsan_standalone_cxx");
    899  1.1.1.2  joerg     }
    900      1.1  joerg   }
    901      1.1  joerg   if (SanArgs.needsStatsRt() && SanArgs.linkRuntimes()) {
    902      1.1  joerg     NonWholeStaticRuntimes.push_back("stats");
    903      1.1  joerg     RequiredSymbols.push_back("__sanitizer_stats_register");
    904      1.1  joerg   }
    905  1.1.1.2  joerg   if (!SanArgs.needsSharedRt() && SanArgs.needsScudoRt() && SanArgs.linkRuntimes()) {
    906      1.1  joerg     if (SanArgs.requiresMinimalRuntime()) {
    907      1.1  joerg       StaticRuntimes.push_back("scudo_minimal");
    908      1.1  joerg       if (SanArgs.linkCXXRuntimes())
    909      1.1  joerg         StaticRuntimes.push_back("scudo_cxx_minimal");
    910      1.1  joerg     } else {
    911      1.1  joerg       StaticRuntimes.push_back("scudo");
    912      1.1  joerg       if (SanArgs.linkCXXRuntimes())
    913      1.1  joerg         StaticRuntimes.push_back("scudo_cxx");
    914      1.1  joerg     }
    915      1.1  joerg   }
    916      1.1  joerg }
    917      1.1  joerg 
    918      1.1  joerg // Should be called before we add system libraries (C++ ABI, libstdc++/libc++,
    919      1.1  joerg // C runtime, etc). Returns true if sanitizer system deps need to be linked in.
    920      1.1  joerg bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
    921      1.1  joerg                                  ArgStringList &CmdArgs) {
    922      1.1  joerg   SmallVector<StringRef, 4> SharedRuntimes, StaticRuntimes,
    923      1.1  joerg       NonWholeStaticRuntimes, HelperStaticRuntimes, RequiredSymbols;
    924      1.1  joerg   collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes,
    925      1.1  joerg                            NonWholeStaticRuntimes, HelperStaticRuntimes,
    926      1.1  joerg                            RequiredSymbols);
    927      1.1  joerg 
    928      1.1  joerg   const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
    929      1.1  joerg   // Inject libfuzzer dependencies.
    930      1.1  joerg   if (SanArgs.needsFuzzer() && SanArgs.linkRuntimes() &&
    931      1.1  joerg       !Args.hasArg(options::OPT_shared)) {
    932      1.1  joerg 
    933      1.1  joerg     addSanitizerRuntime(TC, Args, CmdArgs, "fuzzer", false, true);
    934  1.1.1.2  joerg     if (SanArgs.needsFuzzerInterceptors())
    935  1.1.1.2  joerg       addSanitizerRuntime(TC, Args, CmdArgs, "fuzzer_interceptors", false,
    936  1.1.1.2  joerg                           true);
    937  1.1.1.2  joerg     if (!Args.hasArg(clang::driver::options::OPT_nostdlibxx)) {
    938  1.1.1.2  joerg       bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
    939  1.1.1.2  joerg                                  !Args.hasArg(options::OPT_static);
    940  1.1.1.2  joerg       if (OnlyLibstdcxxStatic)
    941  1.1.1.2  joerg         CmdArgs.push_back("-Bstatic");
    942      1.1  joerg       TC.AddCXXStdlibLibArgs(Args, CmdArgs);
    943  1.1.1.2  joerg       if (OnlyLibstdcxxStatic)
    944  1.1.1.2  joerg         CmdArgs.push_back("-Bdynamic");
    945  1.1.1.2  joerg     }
    946      1.1  joerg   }
    947      1.1  joerg 
    948      1.1  joerg   for (auto RT : SharedRuntimes)
    949      1.1  joerg     addSanitizerRuntime(TC, Args, CmdArgs, RT, true, false);
    950      1.1  joerg   for (auto RT : HelperStaticRuntimes)
    951      1.1  joerg     addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true);
    952      1.1  joerg   bool AddExportDynamic = false;
    953      1.1  joerg   for (auto RT : StaticRuntimes) {
    954      1.1  joerg     addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true);
    955      1.1  joerg     AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT);
    956      1.1  joerg   }
    957      1.1  joerg   for (auto RT : NonWholeStaticRuntimes) {
    958      1.1  joerg     addSanitizerRuntime(TC, Args, CmdArgs, RT, false, false);
    959      1.1  joerg     AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT);
    960      1.1  joerg   }
    961      1.1  joerg   for (auto S : RequiredSymbols) {
    962      1.1  joerg     CmdArgs.push_back("-u");
    963      1.1  joerg     CmdArgs.push_back(Args.MakeArgString(S));
    964      1.1  joerg   }
    965      1.1  joerg   // If there is a static runtime with no dynamic list, force all the symbols
    966      1.1  joerg   // to be dynamic to be sure we export sanitizer interface functions.
    967      1.1  joerg   if (AddExportDynamic)
    968      1.1  joerg     CmdArgs.push_back("--export-dynamic");
    969      1.1  joerg 
    970      1.1  joerg   if (SanArgs.hasCrossDsoCfi() && !AddExportDynamic)
    971  1.1.1.2  joerg     CmdArgs.push_back("--export-dynamic-symbol=__cfi_check");
    972      1.1  joerg 
    973      1.1  joerg   return !StaticRuntimes.empty() || !NonWholeStaticRuntimes.empty();
    974      1.1  joerg }
    975      1.1  joerg 
    976      1.1  joerg bool tools::addXRayRuntime(const ToolChain&TC, const ArgList &Args, ArgStringList &CmdArgs) {
    977      1.1  joerg   if (Args.hasArg(options::OPT_shared))
    978      1.1  joerg     return false;
    979      1.1  joerg 
    980      1.1  joerg   if (TC.getXRayArgs().needsXRayRt()) {
    981      1.1  joerg     CmdArgs.push_back("-whole-archive");
    982      1.1  joerg     CmdArgs.push_back(TC.getCompilerRTArgString(Args, "xray"));
    983      1.1  joerg     for (const auto &Mode : TC.getXRayArgs().modeList())
    984      1.1  joerg       CmdArgs.push_back(TC.getCompilerRTArgString(Args, Mode));
    985      1.1  joerg     CmdArgs.push_back("-no-whole-archive");
    986      1.1  joerg     return true;
    987      1.1  joerg   }
    988      1.1  joerg 
    989      1.1  joerg   return false;
    990      1.1  joerg }
    991      1.1  joerg 
    992      1.1  joerg void tools::linkXRayRuntimeDeps(const ToolChain &TC, ArgStringList &CmdArgs) {
    993  1.1.1.2  joerg   CmdArgs.push_back(getAsNeededOption(TC, false));
    994      1.1  joerg   CmdArgs.push_back("-lpthread");
    995      1.1  joerg   if (!TC.getTriple().isOSOpenBSD())
    996      1.1  joerg     CmdArgs.push_back("-lrt");
    997      1.1  joerg   CmdArgs.push_back("-lm");
    998      1.1  joerg 
    999      1.1  joerg   if (!TC.getTriple().isOSFreeBSD() &&
   1000      1.1  joerg       !TC.getTriple().isOSNetBSD() &&
   1001      1.1  joerg       !TC.getTriple().isOSOpenBSD())
   1002      1.1  joerg     CmdArgs.push_back("-ldl");
   1003      1.1  joerg }
   1004      1.1  joerg 
   1005      1.1  joerg bool tools::areOptimizationsEnabled(const ArgList &Args) {
   1006      1.1  joerg   // Find the last -O arg and see if it is non-zero.
   1007      1.1  joerg   if (Arg *A = Args.getLastArg(options::OPT_O_Group))
   1008      1.1  joerg     return !A->getOption().matches(options::OPT_O0);
   1009      1.1  joerg   // Defaults to -O0.
   1010      1.1  joerg   return false;
   1011      1.1  joerg }
   1012      1.1  joerg 
   1013  1.1.1.2  joerg const char *tools::SplitDebugName(const JobAction &JA, const ArgList &Args,
   1014  1.1.1.2  joerg                                   const InputInfo &Input,
   1015      1.1  joerg                                   const InputInfo &Output) {
   1016  1.1.1.2  joerg   auto AddPostfix = [JA](auto &F) {
   1017  1.1.1.2  joerg     if (JA.getOffloadingDeviceKind() == Action::OFK_HIP)
   1018  1.1.1.2  joerg       F += (Twine("_") + JA.getOffloadingArch()).str();
   1019  1.1.1.2  joerg     F += ".dwo";
   1020  1.1.1.2  joerg   };
   1021      1.1  joerg   if (Arg *A = Args.getLastArg(options::OPT_gsplit_dwarf_EQ))
   1022      1.1  joerg     if (StringRef(A->getValue()) == "single")
   1023      1.1  joerg       return Args.MakeArgString(Output.getFilename());
   1024      1.1  joerg 
   1025      1.1  joerg   Arg *FinalOutput = Args.getLastArg(options::OPT_o);
   1026      1.1  joerg   if (FinalOutput && Args.hasArg(options::OPT_c)) {
   1027      1.1  joerg     SmallString<128> T(FinalOutput->getValue());
   1028  1.1.1.2  joerg     llvm::sys::path::remove_filename(T);
   1029  1.1.1.2  joerg     llvm::sys::path::append(T, llvm::sys::path::stem(FinalOutput->getValue()));
   1030  1.1.1.2  joerg     AddPostfix(T);
   1031      1.1  joerg     return Args.MakeArgString(T);
   1032      1.1  joerg   } else {
   1033      1.1  joerg     // Use the compilation dir.
   1034  1.1.1.2  joerg     Arg *A = Args.getLastArg(options::OPT_ffile_compilation_dir_EQ,
   1035  1.1.1.2  joerg                              options::OPT_fdebug_compilation_dir_EQ);
   1036  1.1.1.2  joerg     SmallString<128> T(A ? A->getValue() : "");
   1037      1.1  joerg     SmallString<128> F(llvm::sys::path::stem(Input.getBaseInput()));
   1038  1.1.1.2  joerg     AddPostfix(F);
   1039      1.1  joerg     T += F;
   1040  1.1.1.2  joerg     return Args.MakeArgString(T);
   1041      1.1  joerg   }
   1042      1.1  joerg }
   1043      1.1  joerg 
   1044      1.1  joerg void tools::SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T,
   1045      1.1  joerg                            const JobAction &JA, const ArgList &Args,
   1046      1.1  joerg                            const InputInfo &Output, const char *OutFile) {
   1047      1.1  joerg   ArgStringList ExtractArgs;
   1048      1.1  joerg   ExtractArgs.push_back("--extract-dwo");
   1049      1.1  joerg 
   1050      1.1  joerg   ArgStringList StripArgs;
   1051      1.1  joerg   StripArgs.push_back("--strip-dwo");
   1052      1.1  joerg 
   1053      1.1  joerg   // Grabbing the output of the earlier compile step.
   1054      1.1  joerg   StripArgs.push_back(Output.getFilename());
   1055      1.1  joerg   ExtractArgs.push_back(Output.getFilename());
   1056      1.1  joerg   ExtractArgs.push_back(OutFile);
   1057      1.1  joerg 
   1058      1.1  joerg   const char *Exec =
   1059      1.1  joerg       Args.MakeArgString(TC.GetProgramPath(CLANG_DEFAULT_OBJCOPY));
   1060      1.1  joerg   InputInfo II(types::TY_Object, Output.getFilename(), Output.getFilename());
   1061      1.1  joerg 
   1062      1.1  joerg   // First extract the dwo sections.
   1063  1.1.1.2  joerg   C.addCommand(std::make_unique<Command>(JA, T,
   1064  1.1.1.2  joerg                                          ResponseFileSupport::AtFileCurCP(),
   1065  1.1.1.2  joerg                                          Exec, ExtractArgs, II, Output));
   1066      1.1  joerg 
   1067      1.1  joerg   // Then remove them from the original .o file.
   1068  1.1.1.2  joerg   C.addCommand(std::make_unique<Command>(
   1069  1.1.1.2  joerg       JA, T, ResponseFileSupport::AtFileCurCP(), Exec, StripArgs, II, Output));
   1070      1.1  joerg }
   1071      1.1  joerg 
   1072      1.1  joerg // Claim options we don't want to warn if they are unused. We do this for
   1073      1.1  joerg // options that build systems might add but are unused when assembling or only
   1074      1.1  joerg // running the preprocessor for example.
   1075      1.1  joerg void tools::claimNoWarnArgs(const ArgList &Args) {
   1076      1.1  joerg   // Don't warn about unused -f(no-)?lto.  This can happen when we're
   1077      1.1  joerg   // preprocessing, precompiling or assembling.
   1078      1.1  joerg   Args.ClaimAllArgs(options::OPT_flto_EQ);
   1079      1.1  joerg   Args.ClaimAllArgs(options::OPT_flto);
   1080      1.1  joerg   Args.ClaimAllArgs(options::OPT_fno_lto);
   1081      1.1  joerg }
   1082      1.1  joerg 
   1083      1.1  joerg Arg *tools::getLastProfileUseArg(const ArgList &Args) {
   1084      1.1  joerg   auto *ProfileUseArg = Args.getLastArg(
   1085      1.1  joerg       options::OPT_fprofile_instr_use, options::OPT_fprofile_instr_use_EQ,
   1086      1.1  joerg       options::OPT_fprofile_use, options::OPT_fprofile_use_EQ,
   1087      1.1  joerg       options::OPT_fno_profile_instr_use);
   1088      1.1  joerg 
   1089      1.1  joerg   if (ProfileUseArg &&
   1090      1.1  joerg       ProfileUseArg->getOption().matches(options::OPT_fno_profile_instr_use))
   1091      1.1  joerg     ProfileUseArg = nullptr;
   1092      1.1  joerg 
   1093      1.1  joerg   return ProfileUseArg;
   1094      1.1  joerg }
   1095      1.1  joerg 
   1096      1.1  joerg Arg *tools::getLastProfileSampleUseArg(const ArgList &Args) {
   1097      1.1  joerg   auto *ProfileSampleUseArg = Args.getLastArg(
   1098      1.1  joerg       options::OPT_fprofile_sample_use, options::OPT_fprofile_sample_use_EQ,
   1099      1.1  joerg       options::OPT_fauto_profile, options::OPT_fauto_profile_EQ,
   1100      1.1  joerg       options::OPT_fno_profile_sample_use, options::OPT_fno_auto_profile);
   1101      1.1  joerg 
   1102      1.1  joerg   if (ProfileSampleUseArg &&
   1103      1.1  joerg       (ProfileSampleUseArg->getOption().matches(
   1104      1.1  joerg            options::OPT_fno_profile_sample_use) ||
   1105      1.1  joerg        ProfileSampleUseArg->getOption().matches(options::OPT_fno_auto_profile)))
   1106      1.1  joerg     return nullptr;
   1107      1.1  joerg 
   1108      1.1  joerg   return Args.getLastArg(options::OPT_fprofile_sample_use_EQ,
   1109      1.1  joerg                          options::OPT_fauto_profile_EQ);
   1110      1.1  joerg }
   1111      1.1  joerg 
   1112      1.1  joerg /// Parses the various -fpic/-fPIC/-fpie/-fPIE arguments.  Then,
   1113      1.1  joerg /// smooshes them together with platform defaults, to decide whether
   1114      1.1  joerg /// this compile should be using PIC mode or not. Returns a tuple of
   1115      1.1  joerg /// (RelocationModel, PICLevel, IsPIE).
   1116      1.1  joerg std::tuple<llvm::Reloc::Model, unsigned, bool>
   1117      1.1  joerg tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) {
   1118      1.1  joerg   const llvm::Triple &EffectiveTriple = ToolChain.getEffectiveTriple();
   1119      1.1  joerg   const llvm::Triple &Triple = ToolChain.getTriple();
   1120      1.1  joerg 
   1121      1.1  joerg   bool PIE = ToolChain.isPIEDefault();
   1122      1.1  joerg   bool PIC = PIE || ToolChain.isPICDefault();
   1123      1.1  joerg   // The Darwin/MachO default to use PIC does not apply when using -static.
   1124      1.1  joerg   if (Triple.isOSBinFormatMachO() && Args.hasArg(options::OPT_static))
   1125      1.1  joerg     PIE = PIC = false;
   1126      1.1  joerg   bool IsPICLevelTwo = PIC;
   1127      1.1  joerg 
   1128      1.1  joerg   bool KernelOrKext =
   1129      1.1  joerg       Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
   1130      1.1  joerg 
   1131      1.1  joerg   // Android-specific defaults for PIC/PIE
   1132      1.1  joerg   if (Triple.isAndroid()) {
   1133      1.1  joerg     switch (Triple.getArch()) {
   1134      1.1  joerg     case llvm::Triple::arm:
   1135      1.1  joerg     case llvm::Triple::armeb:
   1136      1.1  joerg     case llvm::Triple::thumb:
   1137      1.1  joerg     case llvm::Triple::thumbeb:
   1138      1.1  joerg     case llvm::Triple::aarch64:
   1139      1.1  joerg     case llvm::Triple::mips:
   1140      1.1  joerg     case llvm::Triple::mipsel:
   1141      1.1  joerg     case llvm::Triple::mips64:
   1142      1.1  joerg     case llvm::Triple::mips64el:
   1143      1.1  joerg       PIC = true; // "-fpic"
   1144      1.1  joerg       break;
   1145      1.1  joerg 
   1146      1.1  joerg     case llvm::Triple::x86:
   1147      1.1  joerg     case llvm::Triple::x86_64:
   1148      1.1  joerg       PIC = true; // "-fPIC"
   1149      1.1  joerg       IsPICLevelTwo = true;
   1150      1.1  joerg       break;
   1151      1.1  joerg 
   1152      1.1  joerg     default:
   1153      1.1  joerg       break;
   1154      1.1  joerg     }
   1155      1.1  joerg   }
   1156      1.1  joerg 
   1157      1.1  joerg   // OpenBSD-specific defaults for PIE
   1158      1.1  joerg   if (Triple.isOSOpenBSD()) {
   1159      1.1  joerg     switch (ToolChain.getArch()) {
   1160      1.1  joerg     case llvm::Triple::arm:
   1161      1.1  joerg     case llvm::Triple::aarch64:
   1162      1.1  joerg     case llvm::Triple::mips64:
   1163      1.1  joerg     case llvm::Triple::mips64el:
   1164      1.1  joerg     case llvm::Triple::x86:
   1165      1.1  joerg     case llvm::Triple::x86_64:
   1166      1.1  joerg       IsPICLevelTwo = false; // "-fpie"
   1167      1.1  joerg       break;
   1168      1.1  joerg 
   1169      1.1  joerg     case llvm::Triple::ppc:
   1170      1.1  joerg     case llvm::Triple::sparcv9:
   1171      1.1  joerg       IsPICLevelTwo = true; // "-fPIE"
   1172      1.1  joerg       break;
   1173      1.1  joerg 
   1174      1.1  joerg     default:
   1175      1.1  joerg       break;
   1176      1.1  joerg     }
   1177      1.1  joerg   }
   1178      1.1  joerg 
   1179      1.1  joerg   // AMDGPU-specific defaults for PIC.
   1180      1.1  joerg   if (Triple.getArch() == llvm::Triple::amdgcn)
   1181      1.1  joerg     PIC = true;
   1182      1.1  joerg 
   1183      1.1  joerg   // The last argument relating to either PIC or PIE wins, and no
   1184      1.1  joerg   // other argument is used. If the last argument is any flavor of the
   1185      1.1  joerg   // '-fno-...' arguments, both PIC and PIE are disabled. Any PIE
   1186      1.1  joerg   // option implicitly enables PIC at the same level.
   1187      1.1  joerg   Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
   1188      1.1  joerg                                     options::OPT_fpic, options::OPT_fno_pic,
   1189      1.1  joerg                                     options::OPT_fPIE, options::OPT_fno_PIE,
   1190      1.1  joerg                                     options::OPT_fpie, options::OPT_fno_pie);
   1191      1.1  joerg   if (Triple.isOSWindows() && LastPICArg &&
   1192      1.1  joerg       LastPICArg ==
   1193      1.1  joerg           Args.getLastArg(options::OPT_fPIC, options::OPT_fpic,
   1194      1.1  joerg                           options::OPT_fPIE, options::OPT_fpie)) {
   1195      1.1  joerg     ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
   1196      1.1  joerg         << LastPICArg->getSpelling() << Triple.str();
   1197      1.1  joerg     if (Triple.getArch() == llvm::Triple::x86_64)
   1198      1.1  joerg       return std::make_tuple(llvm::Reloc::PIC_, 2U, false);
   1199      1.1  joerg     return std::make_tuple(llvm::Reloc::Static, 0U, false);
   1200      1.1  joerg   }
   1201      1.1  joerg 
   1202      1.1  joerg   // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness
   1203      1.1  joerg   // is forced, then neither PIC nor PIE flags will have no effect.
   1204      1.1  joerg   if (!ToolChain.isPICDefaultForced()) {
   1205      1.1  joerg     if (LastPICArg) {
   1206      1.1  joerg       Option O = LastPICArg->getOption();
   1207      1.1  joerg       if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
   1208      1.1  joerg           O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) {
   1209      1.1  joerg         PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie);
   1210      1.1  joerg         PIC =
   1211      1.1  joerg             PIE || O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic);
   1212      1.1  joerg         IsPICLevelTwo =
   1213      1.1  joerg             O.matches(options::OPT_fPIE) || O.matches(options::OPT_fPIC);
   1214      1.1  joerg       } else {
   1215      1.1  joerg         PIE = PIC = false;
   1216      1.1  joerg         if (EffectiveTriple.isPS4CPU()) {
   1217      1.1  joerg           Arg *ModelArg = Args.getLastArg(options::OPT_mcmodel_EQ);
   1218      1.1  joerg           StringRef Model = ModelArg ? ModelArg->getValue() : "";
   1219      1.1  joerg           if (Model != "kernel") {
   1220      1.1  joerg             PIC = true;
   1221      1.1  joerg             ToolChain.getDriver().Diag(diag::warn_drv_ps4_force_pic)
   1222      1.1  joerg                 << LastPICArg->getSpelling();
   1223      1.1  joerg           }
   1224      1.1  joerg         }
   1225      1.1  joerg       }
   1226      1.1  joerg     }
   1227      1.1  joerg   }
   1228      1.1  joerg 
   1229      1.1  joerg   // Introduce a Darwin and PS4-specific hack. If the default is PIC, but the
   1230      1.1  joerg   // PIC level would've been set to level 1, force it back to level 2 PIC
   1231      1.1  joerg   // instead.
   1232      1.1  joerg   if (PIC && (Triple.isOSDarwin() || EffectiveTriple.isPS4CPU()))
   1233      1.1  joerg     IsPICLevelTwo |= ToolChain.isPICDefault();
   1234      1.1  joerg 
   1235      1.1  joerg   // This kernel flags are a trump-card: they will disable PIC/PIE
   1236      1.1  joerg   // generation, independent of the argument order.
   1237      1.1  joerg   if (KernelOrKext &&
   1238      1.1  joerg       ((!EffectiveTriple.isiOS() || EffectiveTriple.isOSVersionLT(6)) &&
   1239      1.1  joerg        !EffectiveTriple.isWatchOS()))
   1240      1.1  joerg     PIC = PIE = false;
   1241      1.1  joerg 
   1242      1.1  joerg   if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) {
   1243      1.1  joerg     // This is a very special mode. It trumps the other modes, almost no one
   1244      1.1  joerg     // uses it, and it isn't even valid on any OS but Darwin.
   1245      1.1  joerg     if (!Triple.isOSDarwin())
   1246      1.1  joerg       ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
   1247      1.1  joerg           << A->getSpelling() << Triple.str();
   1248      1.1  joerg 
   1249      1.1  joerg     // FIXME: Warn when this flag trumps some other PIC or PIE flag.
   1250      1.1  joerg 
   1251      1.1  joerg     // Only a forced PIC mode can cause the actual compile to have PIC defines
   1252      1.1  joerg     // etc., no flags are sufficient. This behavior was selected to closely
   1253      1.1  joerg     // match that of llvm-gcc and Apple GCC before that.
   1254      1.1  joerg     PIC = ToolChain.isPICDefault() && ToolChain.isPICDefaultForced();
   1255      1.1  joerg 
   1256      1.1  joerg     return std::make_tuple(llvm::Reloc::DynamicNoPIC, PIC ? 2U : 0U, false);
   1257      1.1  joerg   }
   1258      1.1  joerg 
   1259      1.1  joerg   bool EmbeddedPISupported;
   1260      1.1  joerg   switch (Triple.getArch()) {
   1261      1.1  joerg     case llvm::Triple::arm:
   1262      1.1  joerg     case llvm::Triple::armeb:
   1263      1.1  joerg     case llvm::Triple::thumb:
   1264      1.1  joerg     case llvm::Triple::thumbeb:
   1265      1.1  joerg       EmbeddedPISupported = true;
   1266      1.1  joerg       break;
   1267      1.1  joerg     default:
   1268      1.1  joerg       EmbeddedPISupported = false;
   1269      1.1  joerg       break;
   1270      1.1  joerg   }
   1271      1.1  joerg 
   1272      1.1  joerg   bool ROPI = false, RWPI = false;
   1273      1.1  joerg   Arg* LastROPIArg = Args.getLastArg(options::OPT_fropi, options::OPT_fno_ropi);
   1274      1.1  joerg   if (LastROPIArg && LastROPIArg->getOption().matches(options::OPT_fropi)) {
   1275      1.1  joerg     if (!EmbeddedPISupported)
   1276      1.1  joerg       ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
   1277      1.1  joerg           << LastROPIArg->getSpelling() << Triple.str();
   1278      1.1  joerg     ROPI = true;
   1279      1.1  joerg   }
   1280      1.1  joerg   Arg *LastRWPIArg = Args.getLastArg(options::OPT_frwpi, options::OPT_fno_rwpi);
   1281      1.1  joerg   if (LastRWPIArg && LastRWPIArg->getOption().matches(options::OPT_frwpi)) {
   1282      1.1  joerg     if (!EmbeddedPISupported)
   1283      1.1  joerg       ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
   1284      1.1  joerg           << LastRWPIArg->getSpelling() << Triple.str();
   1285      1.1  joerg     RWPI = true;
   1286      1.1  joerg   }
   1287      1.1  joerg 
   1288      1.1  joerg   // ROPI and RWPI are not compatible with PIC or PIE.
   1289      1.1  joerg   if ((ROPI || RWPI) && (PIC || PIE))
   1290      1.1  joerg     ToolChain.getDriver().Diag(diag::err_drv_ropi_rwpi_incompatible_with_pic);
   1291      1.1  joerg 
   1292      1.1  joerg   if (Triple.isMIPS()) {
   1293      1.1  joerg     StringRef CPUName;
   1294      1.1  joerg     StringRef ABIName;
   1295      1.1  joerg     mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
   1296      1.1  joerg     // When targeting the N64 ABI, PIC is the default, except in the case
   1297      1.1  joerg     // when the -mno-abicalls option is used. In that case we exit
   1298      1.1  joerg     // at next check regardless of PIC being set below.
   1299      1.1  joerg     if (ABIName == "n64")
   1300      1.1  joerg       PIC = true;
   1301      1.1  joerg     // When targettng MIPS with -mno-abicalls, it's always static.
   1302      1.1  joerg     if(Args.hasArg(options::OPT_mno_abicalls))
   1303      1.1  joerg       return std::make_tuple(llvm::Reloc::Static, 0U, false);
   1304      1.1  joerg     // Unlike other architectures, MIPS, even with -fPIC/-mxgot/multigot,
   1305      1.1  joerg     // does not use PIC level 2 for historical reasons.
   1306      1.1  joerg     IsPICLevelTwo = false;
   1307      1.1  joerg   }
   1308      1.1  joerg 
   1309      1.1  joerg   if (PIC)
   1310      1.1  joerg     return std::make_tuple(llvm::Reloc::PIC_, IsPICLevelTwo ? 2U : 1U, PIE);
   1311      1.1  joerg 
   1312      1.1  joerg   llvm::Reloc::Model RelocM = llvm::Reloc::Static;
   1313      1.1  joerg   if (ROPI && RWPI)
   1314      1.1  joerg     RelocM = llvm::Reloc::ROPI_RWPI;
   1315      1.1  joerg   else if (ROPI)
   1316      1.1  joerg     RelocM = llvm::Reloc::ROPI;
   1317      1.1  joerg   else if (RWPI)
   1318      1.1  joerg     RelocM = llvm::Reloc::RWPI;
   1319      1.1  joerg 
   1320      1.1  joerg   return std::make_tuple(RelocM, 0U, false);
   1321      1.1  joerg }
   1322      1.1  joerg 
   1323      1.1  joerg // `-falign-functions` indicates that the functions should be aligned to a
   1324      1.1  joerg // 16-byte boundary.
   1325      1.1  joerg //
   1326      1.1  joerg // `-falign-functions=1` is the same as `-fno-align-functions`.
   1327      1.1  joerg //
   1328      1.1  joerg // The scalar `n` in `-falign-functions=n` must be an integral value between
   1329      1.1  joerg // [0, 65536].  If the value is not a power-of-two, it will be rounded up to
   1330      1.1  joerg // the nearest power-of-two.
   1331      1.1  joerg //
   1332      1.1  joerg // If we return `0`, the frontend will default to the backend's preferred
   1333      1.1  joerg // alignment.
   1334      1.1  joerg //
   1335      1.1  joerg // NOTE: icc only allows values between [0, 4096].  icc uses `-falign-functions`
   1336      1.1  joerg // to mean `-falign-functions=16`.  GCC defaults to the backend's preferred
   1337      1.1  joerg // alignment.  For unaligned functions, we default to the backend's preferred
   1338      1.1  joerg // alignment.
   1339      1.1  joerg unsigned tools::ParseFunctionAlignment(const ToolChain &TC,
   1340      1.1  joerg                                        const ArgList &Args) {
   1341      1.1  joerg   const Arg *A = Args.getLastArg(options::OPT_falign_functions,
   1342      1.1  joerg                                  options::OPT_falign_functions_EQ,
   1343      1.1  joerg                                  options::OPT_fno_align_functions);
   1344      1.1  joerg   if (!A || A->getOption().matches(options::OPT_fno_align_functions))
   1345      1.1  joerg     return 0;
   1346      1.1  joerg 
   1347      1.1  joerg   if (A->getOption().matches(options::OPT_falign_functions))
   1348      1.1  joerg     return 0;
   1349      1.1  joerg 
   1350      1.1  joerg   unsigned Value = 0;
   1351      1.1  joerg   if (StringRef(A->getValue()).getAsInteger(10, Value) || Value > 65536)
   1352      1.1  joerg     TC.getDriver().Diag(diag::err_drv_invalid_int_value)
   1353      1.1  joerg         << A->getAsString(Args) << A->getValue();
   1354      1.1  joerg   return Value ? llvm::Log2_32_Ceil(std::min(Value, 65536u)) : Value;
   1355      1.1  joerg }
   1356      1.1  joerg 
   1357  1.1.1.2  joerg unsigned tools::ParseDebugDefaultVersion(const ToolChain &TC,
   1358  1.1.1.2  joerg                                          const ArgList &Args) {
   1359  1.1.1.2  joerg   const Arg *A = Args.getLastArg(options::OPT_fdebug_default_version);
   1360  1.1.1.2  joerg 
   1361  1.1.1.2  joerg   if (!A)
   1362  1.1.1.2  joerg     return 0;
   1363  1.1.1.2  joerg 
   1364  1.1.1.2  joerg   unsigned Value = 0;
   1365  1.1.1.2  joerg   if (StringRef(A->getValue()).getAsInteger(10, Value) || Value > 5 ||
   1366  1.1.1.2  joerg       Value < 2)
   1367  1.1.1.2  joerg     TC.getDriver().Diag(diag::err_drv_invalid_int_value)
   1368  1.1.1.2  joerg         << A->getAsString(Args) << A->getValue();
   1369  1.1.1.2  joerg   return Value;
   1370  1.1.1.2  joerg }
   1371  1.1.1.2  joerg 
   1372      1.1  joerg void tools::AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args,
   1373      1.1  joerg                              ArgStringList &CmdArgs) {
   1374      1.1  joerg   llvm::Reloc::Model RelocationModel;
   1375      1.1  joerg   unsigned PICLevel;
   1376      1.1  joerg   bool IsPIE;
   1377      1.1  joerg   std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(ToolChain, Args);
   1378      1.1  joerg 
   1379      1.1  joerg   if (RelocationModel != llvm::Reloc::Static)
   1380      1.1  joerg     CmdArgs.push_back("-KPIC");
   1381      1.1  joerg }
   1382      1.1  joerg 
   1383      1.1  joerg /// Determine whether Objective-C automated reference counting is
   1384      1.1  joerg /// enabled.
   1385      1.1  joerg bool tools::isObjCAutoRefCount(const ArgList &Args) {
   1386      1.1  joerg   return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
   1387      1.1  joerg }
   1388      1.1  joerg 
   1389      1.1  joerg enum class LibGccType { UnspecifiedLibGcc, StaticLibGcc, SharedLibGcc };
   1390      1.1  joerg 
   1391  1.1.1.2  joerg static LibGccType getLibGccType(const ToolChain &TC, const Driver &D,
   1392  1.1.1.2  joerg                                 const ArgList &Args) {
   1393      1.1  joerg   if (Args.hasArg(options::OPT_static_libgcc) ||
   1394      1.1  joerg       Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_static_pie))
   1395      1.1  joerg     return LibGccType::StaticLibGcc;
   1396  1.1.1.2  joerg   if (Args.hasArg(options::OPT_shared_libgcc))
   1397  1.1.1.2  joerg     return LibGccType::SharedLibGcc;
   1398  1.1.1.2  joerg   // The Android NDK only provides libunwind.a, not libunwind.so.
   1399  1.1.1.2  joerg   if (TC.getTriple().isAndroid())
   1400  1.1.1.2  joerg     return LibGccType::StaticLibGcc;
   1401  1.1.1.2  joerg   // For MinGW, don't imply a shared libgcc here, we only want to return
   1402  1.1.1.2  joerg   // SharedLibGcc if that was explicitly requested.
   1403  1.1.1.2  joerg   if (D.CCCIsCXX() && !TC.getTriple().isOSCygMing())
   1404      1.1  joerg     return LibGccType::SharedLibGcc;
   1405      1.1  joerg   return LibGccType::UnspecifiedLibGcc;
   1406      1.1  joerg }
   1407      1.1  joerg 
   1408      1.1  joerg // Gcc adds libgcc arguments in various ways:
   1409      1.1  joerg //
   1410      1.1  joerg // gcc <none>:     -lgcc --as-needed -lgcc_s --no-as-needed
   1411      1.1  joerg // g++ <none>:                       -lgcc_s               -lgcc
   1412      1.1  joerg // gcc shared:                       -lgcc_s               -lgcc
   1413      1.1  joerg // g++ shared:                       -lgcc_s               -lgcc
   1414      1.1  joerg // gcc static:     -lgcc             -lgcc_eh
   1415      1.1  joerg // g++ static:     -lgcc             -lgcc_eh
   1416      1.1  joerg // gcc static-pie: -lgcc             -lgcc_eh
   1417      1.1  joerg // g++ static-pie: -lgcc             -lgcc_eh
   1418      1.1  joerg //
   1419      1.1  joerg // Also, certain targets need additional adjustments.
   1420      1.1  joerg 
   1421      1.1  joerg static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
   1422      1.1  joerg                              ArgStringList &CmdArgs, const ArgList &Args) {
   1423      1.1  joerg   ToolChain::UnwindLibType UNW = TC.GetUnwindLibType(Args);
   1424      1.1  joerg   // Targets that don't use unwind libraries.
   1425  1.1.1.2  joerg   if ((TC.getTriple().isAndroid() && UNW == ToolChain::UNW_Libgcc) ||
   1426  1.1.1.2  joerg       TC.getTriple().isOSIAMCU() || TC.getTriple().isOSBinFormatWasm() ||
   1427      1.1  joerg       UNW == ToolChain::UNW_None)
   1428      1.1  joerg     return;
   1429      1.1  joerg 
   1430  1.1.1.2  joerg   LibGccType LGT = getLibGccType(TC, D, Args);
   1431      1.1  joerg   bool AsNeeded = LGT == LibGccType::UnspecifiedLibGcc &&
   1432      1.1  joerg                   !TC.getTriple().isAndroid() && !TC.getTriple().isOSCygMing();
   1433      1.1  joerg   if (AsNeeded)
   1434  1.1.1.2  joerg     CmdArgs.push_back(getAsNeededOption(TC, true));
   1435      1.1  joerg 
   1436      1.1  joerg   switch (UNW) {
   1437      1.1  joerg   case ToolChain::UNW_None:
   1438      1.1  joerg     return;
   1439      1.1  joerg   case ToolChain::UNW_Libgcc: {
   1440      1.1  joerg     if (LGT == LibGccType::StaticLibGcc)
   1441      1.1  joerg       CmdArgs.push_back("-lgcc_eh");
   1442      1.1  joerg     else
   1443      1.1  joerg       CmdArgs.push_back("-lgcc_s");
   1444      1.1  joerg     break;
   1445      1.1  joerg   }
   1446      1.1  joerg   case ToolChain::UNW_CompilerRT:
   1447  1.1.1.2  joerg     if (LGT == LibGccType::StaticLibGcc)
   1448  1.1.1.2  joerg       CmdArgs.push_back("-l:libunwind.a");
   1449  1.1.1.2  joerg     else if (TC.getTriple().isOSCygMing()) {
   1450  1.1.1.2  joerg       if (LGT == LibGccType::SharedLibGcc)
   1451  1.1.1.2  joerg         CmdArgs.push_back("-l:libunwind.dll.a");
   1452  1.1.1.2  joerg       else
   1453  1.1.1.2  joerg         // Let the linker choose between libunwind.dll.a and libunwind.a
   1454  1.1.1.2  joerg         // depending on what's available, and depending on the -static flag
   1455  1.1.1.2  joerg         CmdArgs.push_back("-lunwind");
   1456  1.1.1.2  joerg     } else
   1457  1.1.1.2  joerg       CmdArgs.push_back("-l:libunwind.so");
   1458      1.1  joerg     break;
   1459      1.1  joerg   }
   1460      1.1  joerg 
   1461      1.1  joerg   if (AsNeeded)
   1462  1.1.1.2  joerg     CmdArgs.push_back(getAsNeededOption(TC, false));
   1463      1.1  joerg }
   1464      1.1  joerg 
   1465      1.1  joerg static void AddLibgcc(const ToolChain &TC, const Driver &D,
   1466      1.1  joerg                       ArgStringList &CmdArgs, const ArgList &Args) {
   1467  1.1.1.2  joerg   LibGccType LGT = getLibGccType(TC, D, Args);
   1468      1.1  joerg   if (LGT != LibGccType::SharedLibGcc)
   1469      1.1  joerg     CmdArgs.push_back("-lgcc");
   1470      1.1  joerg   AddUnwindLibrary(TC, D, CmdArgs, Args);
   1471      1.1  joerg   if (LGT == LibGccType::SharedLibGcc)
   1472      1.1  joerg     CmdArgs.push_back("-lgcc");
   1473      1.1  joerg }
   1474      1.1  joerg 
   1475      1.1  joerg void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
   1476      1.1  joerg                            ArgStringList &CmdArgs, const ArgList &Args) {
   1477      1.1  joerg   // Make use of compiler-rt if --rtlib option is used
   1478      1.1  joerg   ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(Args);
   1479      1.1  joerg 
   1480      1.1  joerg   switch (RLT) {
   1481      1.1  joerg   case ToolChain::RLT_CompilerRT:
   1482      1.1  joerg     CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins"));
   1483      1.1  joerg     AddUnwindLibrary(TC, D, CmdArgs, Args);
   1484      1.1  joerg     break;
   1485      1.1  joerg   case ToolChain::RLT_Libgcc:
   1486      1.1  joerg     // Make sure libgcc is not used under MSVC environment by default
   1487      1.1  joerg     if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
   1488      1.1  joerg       // Issue error diagnostic if libgcc is explicitly specified
   1489      1.1  joerg       // through command line as --rtlib option argument.
   1490      1.1  joerg       if (Args.hasArg(options::OPT_rtlib_EQ)) {
   1491      1.1  joerg         TC.getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform)
   1492      1.1  joerg             << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "MSVC";
   1493      1.1  joerg       }
   1494      1.1  joerg     } else
   1495      1.1  joerg       AddLibgcc(TC, D, CmdArgs, Args);
   1496      1.1  joerg     break;
   1497      1.1  joerg   }
   1498      1.1  joerg 
   1499  1.1.1.2  joerg   // On Android, the unwinder uses dl_iterate_phdr (or one of
   1500  1.1.1.2  joerg   // dl_unwind_find_exidx/__gnu_Unwind_Find_exidx on arm32) from libdl.so. For
   1501  1.1.1.2  joerg   // statically-linked executables, these functions come from libc.a instead.
   1502  1.1.1.2  joerg   if (TC.getTriple().isAndroid() && !Args.hasArg(options::OPT_static) &&
   1503  1.1.1.2  joerg       !Args.hasArg(options::OPT_static_pie))
   1504  1.1.1.2  joerg     CmdArgs.push_back("-ldl");
   1505      1.1  joerg }
   1506      1.1  joerg 
   1507      1.1  joerg SmallString<128> tools::getStatsFileName(const llvm::opt::ArgList &Args,
   1508      1.1  joerg                                          const InputInfo &Output,
   1509      1.1  joerg                                          const InputInfo &Input,
   1510      1.1  joerg                                          const Driver &D) {
   1511      1.1  joerg   const Arg *A = Args.getLastArg(options::OPT_save_stats_EQ);
   1512      1.1  joerg   if (!A)
   1513      1.1  joerg     return {};
   1514      1.1  joerg 
   1515      1.1  joerg   StringRef SaveStats = A->getValue();
   1516      1.1  joerg   SmallString<128> StatsFile;
   1517      1.1  joerg   if (SaveStats == "obj" && Output.isFilename()) {
   1518      1.1  joerg     StatsFile.assign(Output.getFilename());
   1519      1.1  joerg     llvm::sys::path::remove_filename(StatsFile);
   1520      1.1  joerg   } else if (SaveStats != "cwd") {
   1521      1.1  joerg     D.Diag(diag::err_drv_invalid_value) << A->getAsString(Args) << SaveStats;
   1522      1.1  joerg     return {};
   1523      1.1  joerg   }
   1524      1.1  joerg 
   1525      1.1  joerg   StringRef BaseName = llvm::sys::path::filename(Input.getBaseInput());
   1526      1.1  joerg   llvm::sys::path::append(StatsFile, BaseName);
   1527      1.1  joerg   llvm::sys::path::replace_extension(StatsFile, "stats");
   1528      1.1  joerg   return StatsFile;
   1529      1.1  joerg }
   1530      1.1  joerg 
   1531      1.1  joerg void tools::addMultilibFlag(bool Enabled, const char *const Flag,
   1532      1.1  joerg                             Multilib::flags_list &Flags) {
   1533      1.1  joerg   Flags.push_back(std::string(Enabled ? "+" : "-") + Flag);
   1534      1.1  joerg }
   1535      1.1  joerg 
   1536  1.1.1.2  joerg void tools::addX86AlignBranchArgs(const Driver &D, const ArgList &Args,
   1537  1.1.1.2  joerg                                   ArgStringList &CmdArgs, bool IsLTO) {
   1538  1.1.1.2  joerg   auto addArg = [&, IsLTO](const Twine &Arg) {
   1539  1.1.1.2  joerg     if (IsLTO) {
   1540  1.1.1.2  joerg       CmdArgs.push_back(Args.MakeArgString("-plugin-opt=" + Arg));
   1541  1.1.1.2  joerg     } else {
   1542  1.1.1.2  joerg       CmdArgs.push_back("-mllvm");
   1543  1.1.1.2  joerg       CmdArgs.push_back(Args.MakeArgString(Arg));
   1544  1.1.1.2  joerg     }
   1545  1.1.1.2  joerg   };
   1546      1.1  joerg 
   1547  1.1.1.2  joerg   if (Args.hasArg(options::OPT_mbranches_within_32B_boundaries)) {
   1548  1.1.1.2  joerg     addArg(Twine("-x86-branches-within-32B-boundaries"));
   1549  1.1.1.2  joerg   }
   1550  1.1.1.2  joerg   if (const Arg *A = Args.getLastArg(options::OPT_malign_branch_boundary_EQ)) {
   1551  1.1.1.2  joerg     StringRef Value = A->getValue();
   1552  1.1.1.2  joerg     unsigned Boundary;
   1553  1.1.1.2  joerg     if (Value.getAsInteger(10, Boundary) || Boundary < 16 ||
   1554  1.1.1.2  joerg         !llvm::isPowerOf2_64(Boundary)) {
   1555  1.1.1.2  joerg       D.Diag(diag::err_drv_invalid_argument_to_option)
   1556  1.1.1.2  joerg           << Value << A->getOption().getName();
   1557  1.1.1.2  joerg     } else {
   1558  1.1.1.2  joerg       addArg("-x86-align-branch-boundary=" + Twine(Boundary));
   1559  1.1.1.2  joerg     }
   1560  1.1.1.2  joerg   }
   1561  1.1.1.2  joerg   if (const Arg *A = Args.getLastArg(options::OPT_malign_branch_EQ)) {
   1562  1.1.1.2  joerg     std::string AlignBranch;
   1563  1.1.1.2  joerg     for (StringRef T : A->getValues()) {
   1564  1.1.1.2  joerg       if (T != "fused" && T != "jcc" && T != "jmp" && T != "call" &&
   1565  1.1.1.2  joerg           T != "ret" && T != "indirect")
   1566  1.1.1.2  joerg         D.Diag(diag::err_drv_invalid_malign_branch_EQ)
   1567  1.1.1.2  joerg             << T << "fused, jcc, jmp, call, ret, indirect";
   1568  1.1.1.2  joerg       if (!AlignBranch.empty())
   1569  1.1.1.2  joerg         AlignBranch += '+';
   1570  1.1.1.2  joerg       AlignBranch += T;
   1571  1.1.1.2  joerg     }
   1572  1.1.1.2  joerg     addArg("-x86-align-branch=" + Twine(AlignBranch));
   1573  1.1.1.2  joerg   }
   1574  1.1.1.2  joerg   if (const Arg *A = Args.getLastArg(options::OPT_mpad_max_prefix_size_EQ)) {
   1575  1.1.1.2  joerg     StringRef Value = A->getValue();
   1576  1.1.1.2  joerg     unsigned PrefixSize;
   1577  1.1.1.2  joerg     if (Value.getAsInteger(10, PrefixSize)) {
   1578  1.1.1.2  joerg       D.Diag(diag::err_drv_invalid_argument_to_option)
   1579  1.1.1.2  joerg           << Value << A->getOption().getName();
   1580  1.1.1.2  joerg     } else {
   1581  1.1.1.2  joerg       addArg("-x86-pad-max-prefix-size=" + Twine(PrefixSize));
   1582  1.1.1.2  joerg     }
   1583  1.1.1.2  joerg   }
   1584  1.1.1.2  joerg }
   1585      1.1  joerg 
   1586  1.1.1.2  joerg static llvm::opt::Arg *
   1587  1.1.1.2  joerg getAMDGPUCodeObjectArgument(const Driver &D, const llvm::opt::ArgList &Args) {
   1588  1.1.1.2  joerg   // The last of -mcode-object-v3, -mno-code-object-v3 and
   1589  1.1.1.2  joerg   // -mcode-object-version=<version> wins.
   1590  1.1.1.2  joerg   return Args.getLastArg(options::OPT_mcode_object_v3_legacy,
   1591  1.1.1.2  joerg                          options::OPT_mno_code_object_v3_legacy,
   1592  1.1.1.2  joerg                          options::OPT_mcode_object_version_EQ);
   1593  1.1.1.2  joerg }
   1594  1.1.1.2  joerg 
   1595  1.1.1.2  joerg void tools::checkAMDGPUCodeObjectVersion(const Driver &D,
   1596  1.1.1.2  joerg                                          const llvm::opt::ArgList &Args) {
   1597  1.1.1.2  joerg   const unsigned MinCodeObjVer = 2;
   1598  1.1.1.2  joerg   const unsigned MaxCodeObjVer = 4;
   1599  1.1.1.2  joerg 
   1600  1.1.1.2  joerg   // Emit warnings for legacy options even if they are overridden.
   1601  1.1.1.2  joerg   if (Args.hasArg(options::OPT_mno_code_object_v3_legacy))
   1602  1.1.1.2  joerg     D.Diag(diag::warn_drv_deprecated_arg) << "-mno-code-object-v3"
   1603  1.1.1.2  joerg                                           << "-mcode-object-version=2";
   1604  1.1.1.2  joerg 
   1605  1.1.1.2  joerg   if (Args.hasArg(options::OPT_mcode_object_v3_legacy))
   1606  1.1.1.2  joerg     D.Diag(diag::warn_drv_deprecated_arg) << "-mcode-object-v3"
   1607  1.1.1.2  joerg                                           << "-mcode-object-version=3";
   1608  1.1.1.2  joerg 
   1609  1.1.1.2  joerg   if (auto *CodeObjArg = getAMDGPUCodeObjectArgument(D, Args)) {
   1610  1.1.1.2  joerg     if (CodeObjArg->getOption().getID() ==
   1611  1.1.1.2  joerg         options::OPT_mcode_object_version_EQ) {
   1612  1.1.1.2  joerg       unsigned CodeObjVer = MaxCodeObjVer;
   1613  1.1.1.2  joerg       auto Remnant =
   1614  1.1.1.2  joerg           StringRef(CodeObjArg->getValue()).getAsInteger(0, CodeObjVer);
   1615  1.1.1.2  joerg       if (Remnant || CodeObjVer < MinCodeObjVer || CodeObjVer > MaxCodeObjVer)
   1616  1.1.1.2  joerg         D.Diag(diag::err_drv_invalid_int_value)
   1617  1.1.1.2  joerg             << CodeObjArg->getAsString(Args) << CodeObjArg->getValue();
   1618  1.1.1.2  joerg     }
   1619      1.1  joerg   }
   1620  1.1.1.2  joerg }
   1621      1.1  joerg 
   1622  1.1.1.2  joerg unsigned tools::getAMDGPUCodeObjectVersion(const Driver &D,
   1623  1.1.1.2  joerg                                            const llvm::opt::ArgList &Args) {
   1624  1.1.1.2  joerg   unsigned CodeObjVer = 4; // default
   1625  1.1.1.2  joerg   if (auto *CodeObjArg = getAMDGPUCodeObjectArgument(D, Args)) {
   1626  1.1.1.2  joerg     if (CodeObjArg->getOption().getID() ==
   1627  1.1.1.2  joerg         options::OPT_mno_code_object_v3_legacy) {
   1628  1.1.1.2  joerg       CodeObjVer = 2;
   1629  1.1.1.2  joerg     } else if (CodeObjArg->getOption().getID() ==
   1630  1.1.1.2  joerg                options::OPT_mcode_object_v3_legacy) {
   1631  1.1.1.2  joerg       CodeObjVer = 3;
   1632  1.1.1.2  joerg     } else {
   1633  1.1.1.2  joerg       StringRef(CodeObjArg->getValue()).getAsInteger(0, CodeObjVer);
   1634  1.1.1.2  joerg     }
   1635      1.1  joerg   }
   1636  1.1.1.2  joerg   return CodeObjVer;
   1637  1.1.1.2  joerg }
   1638      1.1  joerg 
   1639  1.1.1.2  joerg bool tools::haveAMDGPUCodeObjectVersionArgument(
   1640  1.1.1.2  joerg     const Driver &D, const llvm::opt::ArgList &Args) {
   1641  1.1.1.2  joerg   return getAMDGPUCodeObjectArgument(D, Args) != nullptr;
   1642  1.1.1.2  joerg }
   1643  1.1.1.2  joerg 
   1644  1.1.1.2  joerg void tools::addMachineOutlinerArgs(const Driver &D,
   1645  1.1.1.2  joerg                                    const llvm::opt::ArgList &Args,
   1646  1.1.1.2  joerg                                    llvm::opt::ArgStringList &CmdArgs,
   1647  1.1.1.2  joerg                                    const llvm::Triple &Triple, bool IsLTO) {
   1648  1.1.1.2  joerg   auto addArg = [&, IsLTO](const Twine &Arg) {
   1649  1.1.1.2  joerg     if (IsLTO) {
   1650  1.1.1.2  joerg       CmdArgs.push_back(Args.MakeArgString("-plugin-opt=" + Arg));
   1651      1.1  joerg     } else {
   1652  1.1.1.2  joerg       CmdArgs.push_back("-mllvm");
   1653  1.1.1.2  joerg       CmdArgs.push_back(Args.MakeArgString(Arg));
   1654  1.1.1.2  joerg     }
   1655  1.1.1.2  joerg   };
   1656  1.1.1.2  joerg 
   1657  1.1.1.2  joerg   if (Arg *A = Args.getLastArg(options::OPT_moutline,
   1658  1.1.1.2  joerg                                options::OPT_mno_outline)) {
   1659  1.1.1.2  joerg     if (A->getOption().matches(options::OPT_moutline)) {
   1660  1.1.1.2  joerg       // We only support -moutline in AArch64 and ARM targets right now. If
   1661  1.1.1.2  joerg       // we're not compiling for these, emit a warning and ignore the flag.
   1662  1.1.1.2  joerg       // Otherwise, add the proper mllvm flags.
   1663  1.1.1.2  joerg       if (!(Triple.isARM() || Triple.isThumb() ||
   1664  1.1.1.2  joerg             Triple.getArch() == llvm::Triple::aarch64 ||
   1665  1.1.1.2  joerg             Triple.getArch() == llvm::Triple::aarch64_32)) {
   1666  1.1.1.2  joerg         D.Diag(diag::warn_drv_moutline_unsupported_opt) << Triple.getArchName();
   1667  1.1.1.2  joerg       } else {
   1668  1.1.1.2  joerg         addArg(Twine("-enable-machine-outliner"));
   1669  1.1.1.2  joerg       }
   1670  1.1.1.2  joerg     } else {
   1671  1.1.1.2  joerg       // Disable all outlining behaviour.
   1672  1.1.1.2  joerg       addArg(Twine("-enable-machine-outliner=never"));
   1673      1.1  joerg     }
   1674      1.1  joerg   }
   1675      1.1  joerg }
   1676      1.1  joerg 
   1677  1.1.1.2  joerg void tools::addOpenMPDeviceRTL(const Driver &D,
   1678  1.1.1.2  joerg                                const llvm::opt::ArgList &DriverArgs,
   1679  1.1.1.2  joerg                                llvm::opt::ArgStringList &CC1Args,
   1680  1.1.1.2  joerg                                StringRef BitcodeSuffix,
   1681  1.1.1.2  joerg                                const llvm::Triple &Triple) {
   1682  1.1.1.2  joerg   SmallVector<StringRef, 8> LibraryPaths;
   1683  1.1.1.2  joerg   // Add user defined library paths from LIBRARY_PATH.
   1684  1.1.1.2  joerg   llvm::Optional<std::string> LibPath =
   1685  1.1.1.2  joerg       llvm::sys::Process::GetEnv("LIBRARY_PATH");
   1686  1.1.1.2  joerg   if (LibPath) {
   1687  1.1.1.2  joerg     SmallVector<StringRef, 8> Frags;
   1688  1.1.1.2  joerg     const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
   1689  1.1.1.2  joerg     llvm::SplitString(*LibPath, Frags, EnvPathSeparatorStr);
   1690  1.1.1.2  joerg     for (StringRef Path : Frags)
   1691  1.1.1.2  joerg       LibraryPaths.emplace_back(Path.trim());
   1692  1.1.1.2  joerg   }
   1693  1.1.1.2  joerg 
   1694  1.1.1.2  joerg   // Add path to lib / lib64 folder.
   1695  1.1.1.2  joerg   SmallString<256> DefaultLibPath = llvm::sys::path::parent_path(D.Dir);
   1696  1.1.1.2  joerg   llvm::sys::path::append(DefaultLibPath, Twine("lib") + CLANG_LIBDIR_SUFFIX);
   1697  1.1.1.2  joerg   LibraryPaths.emplace_back(DefaultLibPath.c_str());
   1698  1.1.1.2  joerg 
   1699  1.1.1.2  joerg   OptSpecifier LibomptargetBCPathOpt =
   1700  1.1.1.2  joerg       Triple.isAMDGCN() ? options::OPT_libomptarget_amdgcn_bc_path_EQ
   1701  1.1.1.2  joerg                         : options::OPT_libomptarget_nvptx_bc_path_EQ;
   1702  1.1.1.2  joerg 
   1703  1.1.1.2  joerg   StringRef ArchPrefix = Triple.isAMDGCN() ? "amdgcn" : "nvptx";
   1704  1.1.1.2  joerg   // First check whether user specifies bc library
   1705  1.1.1.2  joerg   if (const Arg *A = DriverArgs.getLastArg(LibomptargetBCPathOpt)) {
   1706  1.1.1.2  joerg     std::string LibOmpTargetName(A->getValue());
   1707  1.1.1.2  joerg     if (llvm::sys::fs::exists(LibOmpTargetName)) {
   1708  1.1.1.2  joerg       CC1Args.push_back("-mlink-builtin-bitcode");
   1709  1.1.1.2  joerg       CC1Args.push_back(DriverArgs.MakeArgString(LibOmpTargetName));
   1710  1.1.1.2  joerg     } else {
   1711  1.1.1.2  joerg       D.Diag(diag::err_drv_omp_offload_target_bcruntime_not_found)
   1712  1.1.1.2  joerg           << LibOmpTargetName;
   1713  1.1.1.2  joerg     }
   1714  1.1.1.2  joerg   } else {
   1715  1.1.1.2  joerg     bool FoundBCLibrary = false;
   1716  1.1.1.2  joerg 
   1717  1.1.1.2  joerg     std::string LibOmpTargetName =
   1718  1.1.1.2  joerg         "libomptarget-" + BitcodeSuffix.str() + ".bc";
   1719  1.1.1.2  joerg 
   1720  1.1.1.2  joerg     for (StringRef LibraryPath : LibraryPaths) {
   1721  1.1.1.2  joerg       SmallString<128> LibOmpTargetFile(LibraryPath);
   1722  1.1.1.2  joerg       llvm::sys::path::append(LibOmpTargetFile, LibOmpTargetName);
   1723  1.1.1.2  joerg       if (llvm::sys::fs::exists(LibOmpTargetFile)) {
   1724  1.1.1.2  joerg         CC1Args.push_back("-mlink-builtin-bitcode");
   1725  1.1.1.2  joerg         CC1Args.push_back(DriverArgs.MakeArgString(LibOmpTargetFile));
   1726  1.1.1.2  joerg         FoundBCLibrary = true;
   1727  1.1.1.2  joerg         break;
   1728  1.1.1.2  joerg       }
   1729  1.1.1.2  joerg     }
   1730  1.1.1.2  joerg 
   1731  1.1.1.2  joerg     if (!FoundBCLibrary)
   1732  1.1.1.2  joerg       D.Diag(diag::err_drv_omp_offload_target_missingbcruntime)
   1733  1.1.1.2  joerg           << LibOmpTargetName << ArchPrefix;
   1734      1.1  joerg   }
   1735      1.1  joerg }
   1736