1317019Sdim//===--- Darwin.cpp - Darwin Tool and ToolChain Implementations -*- C++ -*-===// 2317019Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6317019Sdim// 7317019Sdim//===----------------------------------------------------------------------===// 8317019Sdim 9317019Sdim#include "Darwin.h" 10317019Sdim#include "Arch/ARM.h" 11317019Sdim#include "CommonArgs.h" 12327952Sdim#include "clang/Basic/AlignedAllocation.h" 13317019Sdim#include "clang/Basic/ObjCRuntime.h" 14353358Sdim#include "clang/Config/config.h" 15317019Sdim#include "clang/Driver/Compilation.h" 16317019Sdim#include "clang/Driver/Driver.h" 17317019Sdim#include "clang/Driver/DriverDiagnostic.h" 18317019Sdim#include "clang/Driver/Options.h" 19317019Sdim#include "clang/Driver/SanitizerArgs.h" 20317019Sdim#include "llvm/ADT/StringSwitch.h" 21317019Sdim#include "llvm/Option/ArgList.h" 22360784Sdim#include "llvm/ProfileData/InstrProf.h" 23317019Sdim#include "llvm/Support/Path.h" 24317019Sdim#include "llvm/Support/ScopedPrinter.h" 25317019Sdim#include "llvm/Support/TargetParser.h" 26344779Sdim#include "llvm/Support/VirtualFileSystem.h" 27317019Sdim#include <cstdlib> // ::getenv 28317019Sdim 29317019Sdimusing namespace clang::driver; 30317019Sdimusing namespace clang::driver::tools; 31317019Sdimusing namespace clang::driver::toolchains; 32317019Sdimusing namespace clang; 33317019Sdimusing namespace llvm::opt; 34317019Sdim 35317019Sdimllvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) { 36317019Sdim // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for 37317019Sdim // archs which Darwin doesn't use. 38317019Sdim 39317019Sdim // The matching this routine does is fairly pointless, since it is neither the 40317019Sdim // complete architecture list, nor a reasonable subset. The problem is that 41317019Sdim // historically the driver driver accepts this and also ties its -march= 42317019Sdim // handling to the architecture name, so we need to be careful before removing 43317019Sdim // support for it. 44317019Sdim 45317019Sdim // This code must be kept in sync with Clang's Darwin specific argument 46317019Sdim // translation. 47317019Sdim 48317019Sdim return llvm::StringSwitch<llvm::Triple::ArchType>(Str) 49317019Sdim .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc) 50317019Sdim .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc) 51317019Sdim .Case("ppc64", llvm::Triple::ppc64) 52317019Sdim .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86) 53317019Sdim .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4", 54317019Sdim llvm::Triple::x86) 55317019Sdim .Cases("x86_64", "x86_64h", llvm::Triple::x86_64) 56317019Sdim // This is derived from the driver driver. 57317019Sdim .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm) 58317019Sdim .Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm) 59317019Sdim .Cases("armv7s", "xscale", llvm::Triple::arm) 60317019Sdim .Case("arm64", llvm::Triple::aarch64) 61360784Sdim .Case("arm64_32", llvm::Triple::aarch64_32) 62317019Sdim .Case("r600", llvm::Triple::r600) 63317019Sdim .Case("amdgcn", llvm::Triple::amdgcn) 64317019Sdim .Case("nvptx", llvm::Triple::nvptx) 65317019Sdim .Case("nvptx64", llvm::Triple::nvptx64) 66317019Sdim .Case("amdil", llvm::Triple::amdil) 67317019Sdim .Case("spir", llvm::Triple::spir) 68317019Sdim .Default(llvm::Triple::UnknownArch); 69317019Sdim} 70317019Sdim 71317019Sdimvoid darwin::setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str) { 72317019Sdim const llvm::Triple::ArchType Arch = getArchTypeForMachOArchName(Str); 73327952Sdim llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(Str); 74317019Sdim T.setArch(Arch); 75317019Sdim 76317019Sdim if (Str == "x86_64h") 77317019Sdim T.setArchName(Str); 78327952Sdim else if (ArchKind == llvm::ARM::ArchKind::ARMV6M || 79327952Sdim ArchKind == llvm::ARM::ArchKind::ARMV7M || 80327952Sdim ArchKind == llvm::ARM::ArchKind::ARMV7EM) { 81317019Sdim T.setOS(llvm::Triple::UnknownOS); 82317019Sdim T.setObjectFormat(llvm::Triple::MachO); 83317019Sdim } 84317019Sdim} 85317019Sdim 86317019Sdimvoid darwin::Assembler::ConstructJob(Compilation &C, const JobAction &JA, 87317019Sdim const InputInfo &Output, 88317019Sdim const InputInfoList &Inputs, 89317019Sdim const ArgList &Args, 90317019Sdim const char *LinkingOutput) const { 91317019Sdim ArgStringList CmdArgs; 92317019Sdim 93317019Sdim assert(Inputs.size() == 1 && "Unexpected number of inputs."); 94317019Sdim const InputInfo &Input = Inputs[0]; 95317019Sdim 96317019Sdim // Determine the original source input. 97317019Sdim const Action *SourceAction = &JA; 98317019Sdim while (SourceAction->getKind() != Action::InputClass) { 99317019Sdim assert(!SourceAction->getInputs().empty() && "unexpected root action!"); 100317019Sdim SourceAction = SourceAction->getInputs()[0]; 101317019Sdim } 102317019Sdim 103344779Sdim // If -fno-integrated-as is used add -Q to the darwin assembler driver to make 104317019Sdim // sure it runs its system assembler not clang's integrated assembler. 105317019Sdim // Applicable to darwin11+ and Xcode 4+. darwin<10 lacked integrated-as. 106317019Sdim // FIXME: at run-time detect assembler capabilities or rely on version 107317019Sdim // information forwarded by -target-assembler-version. 108317019Sdim if (Args.hasArg(options::OPT_fno_integrated_as)) { 109317019Sdim const llvm::Triple &T(getToolChain().getTriple()); 110317019Sdim if (!(T.isMacOSX() && T.isMacOSXVersionLT(10, 7))) 111317019Sdim CmdArgs.push_back("-Q"); 112317019Sdim } 113317019Sdim 114317019Sdim // Forward -g, assuming we are dealing with an actual assembly file. 115317019Sdim if (SourceAction->getType() == types::TY_Asm || 116317019Sdim SourceAction->getType() == types::TY_PP_Asm) { 117317019Sdim if (Args.hasArg(options::OPT_gstabs)) 118317019Sdim CmdArgs.push_back("--gstabs"); 119317019Sdim else if (Args.hasArg(options::OPT_g_Group)) 120317019Sdim CmdArgs.push_back("-g"); 121317019Sdim } 122317019Sdim 123317019Sdim // Derived from asm spec. 124317019Sdim AddMachOArch(Args, CmdArgs); 125317019Sdim 126317019Sdim // Use -force_cpusubtype_ALL on x86 by default. 127360784Sdim if (getToolChain().getTriple().isX86() || 128317019Sdim Args.hasArg(options::OPT_force__cpusubtype__ALL)) 129317019Sdim CmdArgs.push_back("-force_cpusubtype_ALL"); 130317019Sdim 131317019Sdim if (getToolChain().getArch() != llvm::Triple::x86_64 && 132317019Sdim (((Args.hasArg(options::OPT_mkernel) || 133317019Sdim Args.hasArg(options::OPT_fapple_kext)) && 134317019Sdim getMachOToolChain().isKernelStatic()) || 135317019Sdim Args.hasArg(options::OPT_static))) 136317019Sdim CmdArgs.push_back("-static"); 137317019Sdim 138317019Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); 139317019Sdim 140317019Sdim assert(Output.isFilename() && "Unexpected lipo output."); 141317019Sdim CmdArgs.push_back("-o"); 142317019Sdim CmdArgs.push_back(Output.getFilename()); 143317019Sdim 144317019Sdim assert(Input.isFilename() && "Invalid input."); 145317019Sdim CmdArgs.push_back(Input.getFilename()); 146317019Sdim 147317019Sdim // asm_final spec is empty. 148317019Sdim 149317019Sdim const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); 150360784Sdim C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 151317019Sdim} 152317019Sdim 153317019Sdimvoid darwin::MachOTool::anchor() {} 154317019Sdim 155317019Sdimvoid darwin::MachOTool::AddMachOArch(const ArgList &Args, 156317019Sdim ArgStringList &CmdArgs) const { 157317019Sdim StringRef ArchName = getMachOToolChain().getMachOArchName(Args); 158317019Sdim 159317019Sdim // Derived from darwin_arch spec. 160317019Sdim CmdArgs.push_back("-arch"); 161317019Sdim CmdArgs.push_back(Args.MakeArgString(ArchName)); 162317019Sdim 163317019Sdim // FIXME: Is this needed anymore? 164317019Sdim if (ArchName == "arm") 165317019Sdim CmdArgs.push_back("-force_cpusubtype_ALL"); 166317019Sdim} 167317019Sdim 168317019Sdimbool darwin::Linker::NeedsTempPath(const InputInfoList &Inputs) const { 169317019Sdim // We only need to generate a temp path for LTO if we aren't compiling object 170317019Sdim // files. When compiling source files, we run 'dsymutil' after linking. We 171317019Sdim // don't run 'dsymutil' when compiling object files. 172317019Sdim for (const auto &Input : Inputs) 173317019Sdim if (Input.getType() != types::TY_Object) 174317019Sdim return true; 175317019Sdim 176317019Sdim return false; 177317019Sdim} 178317019Sdim 179341825Sdim/// Pass -no_deduplicate to ld64 under certain conditions: 180317019Sdim/// 181317019Sdim/// - Either -O0 or -O1 is explicitly specified 182317019Sdim/// - No -O option is specified *and* this is a compile+link (implicit -O0) 183317019Sdim/// 184317019Sdim/// Also do *not* add -no_deduplicate when no -O option is specified and this 185317019Sdim/// is just a link (we can't imply -O0) 186317019Sdimstatic bool shouldLinkerNotDedup(bool IsLinkerOnlyAction, const ArgList &Args) { 187317019Sdim if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { 188317019Sdim if (A->getOption().matches(options::OPT_O0)) 189317019Sdim return true; 190317019Sdim if (A->getOption().matches(options::OPT_O)) 191317019Sdim return llvm::StringSwitch<bool>(A->getValue()) 192317019Sdim .Case("1", true) 193317019Sdim .Default(false); 194317019Sdim return false; // OPT_Ofast & OPT_O4 195317019Sdim } 196317019Sdim 197317019Sdim if (!IsLinkerOnlyAction) // Implicit -O0 for compile+linker only. 198317019Sdim return true; 199317019Sdim return false; 200317019Sdim} 201317019Sdim 202317019Sdimvoid darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args, 203317019Sdim ArgStringList &CmdArgs, 204317019Sdim const InputInfoList &Inputs) const { 205317019Sdim const Driver &D = getToolChain().getDriver(); 206317019Sdim const toolchains::MachO &MachOTC = getMachOToolChain(); 207317019Sdim 208317019Sdim unsigned Version[5] = {0, 0, 0, 0, 0}; 209317019Sdim if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) { 210317019Sdim if (!Driver::GetReleaseVersion(A->getValue(), Version)) 211317019Sdim D.Diag(diag::err_drv_invalid_version_number) << A->getAsString(Args); 212317019Sdim } 213317019Sdim 214317019Sdim // Newer linkers support -demangle. Pass it if supported and not disabled by 215317019Sdim // the user. 216317019Sdim if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) 217317019Sdim CmdArgs.push_back("-demangle"); 218317019Sdim 219317019Sdim if (Args.hasArg(options::OPT_rdynamic) && Version[0] >= 137) 220317019Sdim CmdArgs.push_back("-export_dynamic"); 221317019Sdim 222317019Sdim // If we are using App Extension restrictions, pass a flag to the linker 223317019Sdim // telling it that the compiled code has been audited. 224317019Sdim if (Args.hasFlag(options::OPT_fapplication_extension, 225317019Sdim options::OPT_fno_application_extension, false)) 226317019Sdim CmdArgs.push_back("-application_extension"); 227317019Sdim 228344779Sdim if (D.isUsingLTO() && Version[0] >= 116 && NeedsTempPath(Inputs)) { 229344779Sdim std::string TmpPathName; 230344779Sdim if (D.getLTOMode() == LTOK_Full) { 231344779Sdim // If we are using full LTO, then automatically create a temporary file 232344779Sdim // path for the linker to use, so that it's lifetime will extend past a 233344779Sdim // possible dsymutil step. 234344779Sdim TmpPathName = 235344779Sdim D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object)); 236344779Sdim } else if (D.getLTOMode() == LTOK_Thin) 237344779Sdim // If we are using thin LTO, then create a directory instead. 238344779Sdim TmpPathName = D.GetTemporaryDirectory("thinlto"); 239344779Sdim 240344779Sdim if (!TmpPathName.empty()) { 241344779Sdim auto *TmpPath = C.getArgs().MakeArgString(TmpPathName); 242317019Sdim C.addTempFile(TmpPath); 243317019Sdim CmdArgs.push_back("-object_path_lto"); 244317019Sdim CmdArgs.push_back(TmpPath); 245317019Sdim } 246317019Sdim } 247317019Sdim 248317019Sdim // Use -lto_library option to specify the libLTO.dylib path. Try to find 249317019Sdim // it in clang installed libraries. ld64 will only look at this argument 250317019Sdim // when it actually uses LTO, so libLTO.dylib only needs to exist at link 251317019Sdim // time if ld64 decides that it needs to use LTO. 252317019Sdim // Since this is passed unconditionally, ld64 will never look for libLTO.dylib 253317019Sdim // next to it. That's ok since ld64 using a libLTO.dylib not matching the 254317019Sdim // clang version won't work anyways. 255317019Sdim if (Version[0] >= 133) { 256317019Sdim // Search for libLTO in <InstalledDir>/../lib/libLTO.dylib 257317019Sdim StringRef P = llvm::sys::path::parent_path(D.Dir); 258317019Sdim SmallString<128> LibLTOPath(P); 259317019Sdim llvm::sys::path::append(LibLTOPath, "lib"); 260317019Sdim llvm::sys::path::append(LibLTOPath, "libLTO.dylib"); 261317019Sdim CmdArgs.push_back("-lto_library"); 262317019Sdim CmdArgs.push_back(C.getArgs().MakeArgString(LibLTOPath)); 263317019Sdim } 264317019Sdim 265317019Sdim // ld64 version 262 and above run the deduplicate pass by default. 266317019Sdim if (Version[0] >= 262 && shouldLinkerNotDedup(C.getJobs().empty(), Args)) 267317019Sdim CmdArgs.push_back("-no_deduplicate"); 268317019Sdim 269317019Sdim // Derived from the "link" spec. 270317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_static); 271317019Sdim if (!Args.hasArg(options::OPT_static)) 272317019Sdim CmdArgs.push_back("-dynamic"); 273317019Sdim if (Args.hasArg(options::OPT_fgnu_runtime)) { 274317019Sdim // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu 275317019Sdim // here. How do we wish to handle such things? 276317019Sdim } 277317019Sdim 278317019Sdim if (!Args.hasArg(options::OPT_dynamiclib)) { 279317019Sdim AddMachOArch(Args, CmdArgs); 280317019Sdim // FIXME: Why do this only on this path? 281317019Sdim Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL); 282317019Sdim 283317019Sdim Args.AddLastArg(CmdArgs, options::OPT_bundle); 284317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader); 285317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_client__name); 286317019Sdim 287317019Sdim Arg *A; 288317019Sdim if ((A = Args.getLastArg(options::OPT_compatibility__version)) || 289317019Sdim (A = Args.getLastArg(options::OPT_current__version)) || 290317019Sdim (A = Args.getLastArg(options::OPT_install__name))) 291317019Sdim D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args) 292317019Sdim << "-dynamiclib"; 293317019Sdim 294317019Sdim Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace); 295317019Sdim Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs); 296317019Sdim Args.AddLastArg(CmdArgs, options::OPT_private__bundle); 297317019Sdim } else { 298317019Sdim CmdArgs.push_back("-dylib"); 299317019Sdim 300317019Sdim Arg *A; 301317019Sdim if ((A = Args.getLastArg(options::OPT_bundle)) || 302317019Sdim (A = Args.getLastArg(options::OPT_bundle__loader)) || 303317019Sdim (A = Args.getLastArg(options::OPT_client__name)) || 304317019Sdim (A = Args.getLastArg(options::OPT_force__flat__namespace)) || 305317019Sdim (A = Args.getLastArg(options::OPT_keep__private__externs)) || 306317019Sdim (A = Args.getLastArg(options::OPT_private__bundle))) 307317019Sdim D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args) 308317019Sdim << "-dynamiclib"; 309317019Sdim 310317019Sdim Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version, 311317019Sdim "-dylib_compatibility_version"); 312317019Sdim Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version, 313317019Sdim "-dylib_current_version"); 314317019Sdim 315317019Sdim AddMachOArch(Args, CmdArgs); 316317019Sdim 317317019Sdim Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name, 318317019Sdim "-dylib_install_name"); 319317019Sdim } 320317019Sdim 321317019Sdim Args.AddLastArg(CmdArgs, options::OPT_all__load); 322317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_allowable__client); 323317019Sdim Args.AddLastArg(CmdArgs, options::OPT_bind__at__load); 324317019Sdim if (MachOTC.isTargetIOSBased()) 325317019Sdim Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal); 326317019Sdim Args.AddLastArg(CmdArgs, options::OPT_dead__strip); 327317019Sdim Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms); 328317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_dylib__file); 329317019Sdim Args.AddLastArg(CmdArgs, options::OPT_dynamic); 330317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list); 331317019Sdim Args.AddLastArg(CmdArgs, options::OPT_flat__namespace); 332317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_force__load); 333317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names); 334317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_image__base); 335317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_init); 336317019Sdim 337317019Sdim // Add the deployment target. 338360784Sdim if (Version[0] >= 520) 339360784Sdim MachOTC.addPlatformVersionArgs(Args, CmdArgs); 340360784Sdim else 341360784Sdim MachOTC.addMinVersionArgs(Args, CmdArgs); 342317019Sdim 343317019Sdim Args.AddLastArg(CmdArgs, options::OPT_nomultidefs); 344317019Sdim Args.AddLastArg(CmdArgs, options::OPT_multi__module); 345317019Sdim Args.AddLastArg(CmdArgs, options::OPT_single__module); 346317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined); 347317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused); 348317019Sdim 349317019Sdim if (const Arg *A = 350317019Sdim Args.getLastArg(options::OPT_fpie, options::OPT_fPIE, 351317019Sdim options::OPT_fno_pie, options::OPT_fno_PIE)) { 352317019Sdim if (A->getOption().matches(options::OPT_fpie) || 353317019Sdim A->getOption().matches(options::OPT_fPIE)) 354317019Sdim CmdArgs.push_back("-pie"); 355317019Sdim else 356317019Sdim CmdArgs.push_back("-no_pie"); 357317019Sdim } 358317019Sdim 359317019Sdim // for embed-bitcode, use -bitcode_bundle in linker command 360317019Sdim if (C.getDriver().embedBitcodeEnabled()) { 361317019Sdim // Check if the toolchain supports bitcode build flow. 362317019Sdim if (MachOTC.SupportsEmbeddedBitcode()) { 363317019Sdim CmdArgs.push_back("-bitcode_bundle"); 364317019Sdim if (C.getDriver().embedBitcodeMarkerOnly() && Version[0] >= 278) { 365317019Sdim CmdArgs.push_back("-bitcode_process_mode"); 366317019Sdim CmdArgs.push_back("marker"); 367317019Sdim } 368317019Sdim } else 369317019Sdim D.Diag(diag::err_drv_bitcode_unsupported_on_toolchain); 370317019Sdim } 371317019Sdim 372317019Sdim Args.AddLastArg(CmdArgs, options::OPT_prebind); 373317019Sdim Args.AddLastArg(CmdArgs, options::OPT_noprebind); 374317019Sdim Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding); 375317019Sdim Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules); 376317019Sdim Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs); 377317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_sectcreate); 378317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_sectorder); 379317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_seg1addr); 380317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_segprot); 381317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_segaddr); 382317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr); 383317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr); 384317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table); 385317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename); 386317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_sub__library); 387317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella); 388317019Sdim 389317019Sdim // Give --sysroot= preference, over the Apple specific behavior to also use 390317019Sdim // --isysroot as the syslibroot. 391317019Sdim StringRef sysroot = C.getSysRoot(); 392317019Sdim if (sysroot != "") { 393317019Sdim CmdArgs.push_back("-syslibroot"); 394317019Sdim CmdArgs.push_back(C.getArgs().MakeArgString(sysroot)); 395317019Sdim } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 396317019Sdim CmdArgs.push_back("-syslibroot"); 397317019Sdim CmdArgs.push_back(A->getValue()); 398317019Sdim } 399317019Sdim 400317019Sdim Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace); 401317019Sdim Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints); 402317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_umbrella); 403317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_undefined); 404317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list); 405317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches); 406317019Sdim Args.AddLastArg(CmdArgs, options::OPT_X_Flag); 407317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_y); 408317019Sdim Args.AddLastArg(CmdArgs, options::OPT_w); 409317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size); 410317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_segs__read__); 411317019Sdim Args.AddLastArg(CmdArgs, options::OPT_seglinkedit); 412317019Sdim Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit); 413317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_sectalign); 414317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols); 415317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_segcreate); 416317019Sdim Args.AddLastArg(CmdArgs, options::OPT_whyload); 417317019Sdim Args.AddLastArg(CmdArgs, options::OPT_whatsloaded); 418317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name); 419317019Sdim Args.AddLastArg(CmdArgs, options::OPT_dylinker); 420317019Sdim Args.AddLastArg(CmdArgs, options::OPT_Mach); 421317019Sdim} 422317019Sdim 423341825Sdim/// Determine whether we are linking the ObjC runtime. 424317019Sdimstatic bool isObjCRuntimeLinked(const ArgList &Args) { 425317019Sdim if (isObjCAutoRefCount(Args)) { 426317019Sdim Args.ClaimAllArgs(options::OPT_fobjc_link_runtime); 427317019Sdim return true; 428317019Sdim } 429317019Sdim return Args.hasArg(options::OPT_fobjc_link_runtime); 430317019Sdim} 431317019Sdim 432317019Sdimvoid darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, 433317019Sdim const InputInfo &Output, 434317019Sdim const InputInfoList &Inputs, 435317019Sdim const ArgList &Args, 436317019Sdim const char *LinkingOutput) const { 437317019Sdim assert(Output.getType() == types::TY_Image && "Invalid linker output type."); 438317019Sdim 439317019Sdim // If the number of arguments surpasses the system limits, we will encode the 440317019Sdim // input files in a separate file, shortening the command line. To this end, 441317019Sdim // build a list of input file names that can be passed via a file with the 442317019Sdim // -filelist linker option. 443317019Sdim llvm::opt::ArgStringList InputFileList; 444317019Sdim 445317019Sdim // The logic here is derived from gcc's behavior; most of which 446317019Sdim // comes from specs (starting with link_command). Consult gcc for 447317019Sdim // more information. 448317019Sdim ArgStringList CmdArgs; 449317019Sdim 450317019Sdim /// Hack(tm) to ignore linking errors when we are doing ARC migration. 451317019Sdim if (Args.hasArg(options::OPT_ccc_arcmt_check, 452317019Sdim options::OPT_ccc_arcmt_migrate)) { 453317019Sdim for (const auto &Arg : Args) 454317019Sdim Arg->claim(); 455317019Sdim const char *Exec = 456317019Sdim Args.MakeArgString(getToolChain().GetProgramPath("touch")); 457317019Sdim CmdArgs.push_back(Output.getFilename()); 458360784Sdim C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, None)); 459317019Sdim return; 460317019Sdim } 461317019Sdim 462317019Sdim // I'm not sure why this particular decomposition exists in gcc, but 463317019Sdim // we follow suite for ease of comparison. 464317019Sdim AddLinkArgs(C, Args, CmdArgs, Inputs); 465317019Sdim 466341825Sdim // For LTO, pass the name of the optimization record file and other 467341825Sdim // opt-remarks flags. 468317019Sdim if (Args.hasFlag(options::OPT_fsave_optimization_record, 469353358Sdim options::OPT_fsave_optimization_record_EQ, 470317019Sdim options::OPT_fno_save_optimization_record, false)) { 471317019Sdim CmdArgs.push_back("-mllvm"); 472317019Sdim CmdArgs.push_back("-lto-pass-remarks-output"); 473317019Sdim CmdArgs.push_back("-mllvm"); 474317019Sdim 475317019Sdim SmallString<128> F; 476317019Sdim F = Output.getFilename(); 477353358Sdim F += ".opt."; 478353358Sdim if (const Arg *A = 479353358Sdim Args.getLastArg(options::OPT_fsave_optimization_record_EQ)) 480353358Sdim F += A->getValue(); 481353358Sdim else 482353358Sdim F += "yaml"; 483353358Sdim 484317019Sdim CmdArgs.push_back(Args.MakeArgString(F)); 485317019Sdim 486317019Sdim if (getLastProfileUseArg(Args)) { 487317019Sdim CmdArgs.push_back("-mllvm"); 488317019Sdim CmdArgs.push_back("-lto-pass-remarks-with-hotness"); 489341825Sdim 490341825Sdim if (const Arg *A = 491341825Sdim Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) { 492341825Sdim CmdArgs.push_back("-mllvm"); 493341825Sdim std::string Opt = 494341825Sdim std::string("-lto-pass-remarks-hotness-threshold=") + A->getValue(); 495341825Sdim CmdArgs.push_back(Args.MakeArgString(Opt)); 496341825Sdim } 497317019Sdim } 498353358Sdim 499353358Sdim if (const Arg *A = 500353358Sdim Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) { 501353358Sdim CmdArgs.push_back("-mllvm"); 502353358Sdim std::string Passes = 503353358Sdim std::string("-lto-pass-remarks-filter=") + A->getValue(); 504353358Sdim CmdArgs.push_back(Args.MakeArgString(Passes)); 505353358Sdim } 506353358Sdim 507353358Sdim if (const Arg *A = 508353358Sdim Args.getLastArg(options::OPT_fsave_optimization_record_EQ)) { 509353358Sdim CmdArgs.push_back("-mllvm"); 510353358Sdim std::string Format = 511353358Sdim std::string("-lto-pass-remarks-format=") + A->getValue(); 512353358Sdim CmdArgs.push_back(Args.MakeArgString(Format)); 513353358Sdim } 514317019Sdim } 515317019Sdim 516341825Sdim // Propagate the -moutline flag to the linker in LTO. 517353358Sdim if (Arg *A = 518353358Sdim Args.getLastArg(options::OPT_moutline, options::OPT_mno_outline)) { 519353358Sdim if (A->getOption().matches(options::OPT_moutline)) { 520353358Sdim if (getMachOToolChain().getMachOArchName(Args) == "arm64") { 521353358Sdim CmdArgs.push_back("-mllvm"); 522353358Sdim CmdArgs.push_back("-enable-machine-outliner"); 523341825Sdim 524353358Sdim // Outline from linkonceodr functions by default in LTO. 525353358Sdim CmdArgs.push_back("-mllvm"); 526353358Sdim CmdArgs.push_back("-enable-linkonceodr-outlining"); 527353358Sdim } 528353358Sdim } else { 529353358Sdim // Disable all outlining behaviour if we have mno-outline. We need to do 530353358Sdim // this explicitly, because targets which support default outlining will 531353358Sdim // try to do work if we don't. 532341825Sdim CmdArgs.push_back("-mllvm"); 533353358Sdim CmdArgs.push_back("-enable-machine-outliner=never"); 534341825Sdim } 535341825Sdim } 536341825Sdim 537353358Sdim // Setup statistics file output. 538353358Sdim SmallString<128> StatsFile = 539353358Sdim getStatsFileName(Args, Output, Inputs[0], getToolChain().getDriver()); 540353358Sdim if (!StatsFile.empty()) { 541353358Sdim CmdArgs.push_back("-mllvm"); 542353358Sdim CmdArgs.push_back(Args.MakeArgString("-lto-stats-file=" + StatsFile.str())); 543353358Sdim } 544353358Sdim 545317019Sdim // It seems that the 'e' option is completely ignored for dynamic executables 546317019Sdim // (the default), and with static executables, the last one wins, as expected. 547317019Sdim Args.AddAllArgs(CmdArgs, {options::OPT_d_Flag, options::OPT_s, options::OPT_t, 548317019Sdim options::OPT_Z_Flag, options::OPT_u_Group, 549317019Sdim options::OPT_e, options::OPT_r}); 550317019Sdim 551317019Sdim // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading 552317019Sdim // members of static archive libraries which implement Objective-C classes or 553317019Sdim // categories. 554317019Sdim if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX)) 555317019Sdim CmdArgs.push_back("-ObjC"); 556317019Sdim 557317019Sdim CmdArgs.push_back("-o"); 558317019Sdim CmdArgs.push_back(Output.getFilename()); 559317019Sdim 560317019Sdim if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) 561317019Sdim getMachOToolChain().addStartObjectFileArgs(Args, CmdArgs); 562317019Sdim 563317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_L); 564317019Sdim 565317019Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); 566317019Sdim // Build the input file for -filelist (list of linker input files) in case we 567317019Sdim // need it later 568317019Sdim for (const auto &II : Inputs) { 569317019Sdim if (!II.isFilename()) { 570317019Sdim // This is a linker input argument. 571317019Sdim // We cannot mix input arguments and file names in a -filelist input, thus 572317019Sdim // we prematurely stop our list (remaining files shall be passed as 573317019Sdim // arguments). 574317019Sdim if (InputFileList.size() > 0) 575317019Sdim break; 576317019Sdim 577317019Sdim continue; 578317019Sdim } 579317019Sdim 580317019Sdim InputFileList.push_back(II.getFilename()); 581317019Sdim } 582317019Sdim 583317019Sdim if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) 584317019Sdim addOpenMPRuntime(CmdArgs, getToolChain(), Args); 585317019Sdim 586317019Sdim if (isObjCRuntimeLinked(Args) && 587317019Sdim !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { 588317019Sdim // We use arclite library for both ARC and subscripting support. 589317019Sdim getMachOToolChain().AddLinkARCArgs(Args, CmdArgs); 590317019Sdim 591317019Sdim CmdArgs.push_back("-framework"); 592317019Sdim CmdArgs.push_back("Foundation"); 593317019Sdim // Link libobj. 594317019Sdim CmdArgs.push_back("-lobjc"); 595317019Sdim } 596317019Sdim 597317019Sdim if (LinkingOutput) { 598317019Sdim CmdArgs.push_back("-arch_multiple"); 599317019Sdim CmdArgs.push_back("-final_output"); 600317019Sdim CmdArgs.push_back(LinkingOutput); 601317019Sdim } 602317019Sdim 603317019Sdim if (Args.hasArg(options::OPT_fnested_functions)) 604317019Sdim CmdArgs.push_back("-allow_stack_execute"); 605317019Sdim 606317019Sdim getMachOToolChain().addProfileRTLibs(Args, CmdArgs); 607317019Sdim 608317019Sdim if (unsigned Parallelism = 609317019Sdim getLTOParallelism(Args, getToolChain().getDriver())) { 610317019Sdim CmdArgs.push_back("-mllvm"); 611327952Sdim CmdArgs.push_back(Args.MakeArgString("-threads=" + Twine(Parallelism))); 612317019Sdim } 613317019Sdim 614327952Sdim if (getToolChain().ShouldLinkCXXStdlib(Args)) 615327952Sdim getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 616353358Sdim 617353358Sdim bool NoStdOrDefaultLibs = 618353358Sdim Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs); 619353358Sdim bool ForceLinkBuiltins = Args.hasArg(options::OPT_fapple_link_rtlib); 620353358Sdim if (!NoStdOrDefaultLibs || ForceLinkBuiltins) { 621317019Sdim // link_ssp spec is empty. 622317019Sdim 623353358Sdim // If we have both -nostdlib/nodefaultlibs and -fapple-link-rtlib then 624353358Sdim // we just want to link the builtins, not the other libs like libSystem. 625353358Sdim if (NoStdOrDefaultLibs && ForceLinkBuiltins) { 626353358Sdim getMachOToolChain().AddLinkRuntimeLib(Args, CmdArgs, "builtins"); 627353358Sdim } else { 628353358Sdim // Let the tool chain choose which runtime library to link. 629353358Sdim getMachOToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs, 630353358Sdim ForceLinkBuiltins); 631317019Sdim 632353358Sdim // No need to do anything for pthreads. Claim argument to avoid warning. 633353358Sdim Args.ClaimAllArgs(options::OPT_pthread); 634353358Sdim Args.ClaimAllArgs(options::OPT_pthreads); 635353358Sdim } 636317019Sdim } 637317019Sdim 638317019Sdim if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { 639317019Sdim // endfile_spec is empty. 640317019Sdim } 641317019Sdim 642317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 643317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_F); 644317019Sdim 645317019Sdim // -iframework should be forwarded as -F. 646317019Sdim for (const Arg *A : Args.filtered(options::OPT_iframework)) 647317019Sdim CmdArgs.push_back(Args.MakeArgString(std::string("-F") + A->getValue())); 648317019Sdim 649317019Sdim if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { 650317019Sdim if (Arg *A = Args.getLastArg(options::OPT_fveclib)) { 651317019Sdim if (A->getValue() == StringRef("Accelerate")) { 652317019Sdim CmdArgs.push_back("-framework"); 653317019Sdim CmdArgs.push_back("Accelerate"); 654317019Sdim } 655317019Sdim } 656317019Sdim } 657317019Sdim 658317019Sdim const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); 659317019Sdim std::unique_ptr<Command> Cmd = 660360784Sdim std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs); 661317019Sdim Cmd->setInputFileList(std::move(InputFileList)); 662317019Sdim C.addCommand(std::move(Cmd)); 663317019Sdim} 664317019Sdim 665317019Sdimvoid darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA, 666317019Sdim const InputInfo &Output, 667317019Sdim const InputInfoList &Inputs, 668317019Sdim const ArgList &Args, 669317019Sdim const char *LinkingOutput) const { 670317019Sdim ArgStringList CmdArgs; 671317019Sdim 672317019Sdim CmdArgs.push_back("-create"); 673317019Sdim assert(Output.isFilename() && "Unexpected lipo output."); 674317019Sdim 675317019Sdim CmdArgs.push_back("-output"); 676317019Sdim CmdArgs.push_back(Output.getFilename()); 677317019Sdim 678317019Sdim for (const auto &II : Inputs) { 679317019Sdim assert(II.isFilename() && "Unexpected lipo input."); 680317019Sdim CmdArgs.push_back(II.getFilename()); 681317019Sdim } 682317019Sdim 683317019Sdim const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("lipo")); 684360784Sdim C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 685317019Sdim} 686317019Sdim 687317019Sdimvoid darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA, 688317019Sdim const InputInfo &Output, 689317019Sdim const InputInfoList &Inputs, 690317019Sdim const ArgList &Args, 691317019Sdim const char *LinkingOutput) const { 692317019Sdim ArgStringList CmdArgs; 693317019Sdim 694317019Sdim CmdArgs.push_back("-o"); 695317019Sdim CmdArgs.push_back(Output.getFilename()); 696317019Sdim 697317019Sdim assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); 698317019Sdim const InputInfo &Input = Inputs[0]; 699317019Sdim assert(Input.isFilename() && "Unexpected dsymutil input."); 700317019Sdim CmdArgs.push_back(Input.getFilename()); 701317019Sdim 702317019Sdim const char *Exec = 703317019Sdim Args.MakeArgString(getToolChain().GetProgramPath("dsymutil")); 704360784Sdim C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 705317019Sdim} 706317019Sdim 707317019Sdimvoid darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA, 708317019Sdim const InputInfo &Output, 709317019Sdim const InputInfoList &Inputs, 710317019Sdim const ArgList &Args, 711317019Sdim const char *LinkingOutput) const { 712317019Sdim ArgStringList CmdArgs; 713317019Sdim CmdArgs.push_back("--verify"); 714317019Sdim CmdArgs.push_back("--debug-info"); 715317019Sdim CmdArgs.push_back("--eh-frame"); 716317019Sdim CmdArgs.push_back("--quiet"); 717317019Sdim 718317019Sdim assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); 719317019Sdim const InputInfo &Input = Inputs[0]; 720317019Sdim assert(Input.isFilename() && "Unexpected verify input"); 721317019Sdim 722317019Sdim // Grabbing the output of the earlier dsymutil run. 723317019Sdim CmdArgs.push_back(Input.getFilename()); 724317019Sdim 725317019Sdim const char *Exec = 726317019Sdim Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump")); 727360784Sdim C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 728317019Sdim} 729317019Sdim 730317019SdimMachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 731317019Sdim : ToolChain(D, Triple, Args) { 732317019Sdim // We expect 'as', 'ld', etc. to be adjacent to our install dir. 733317019Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 734317019Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 735317019Sdim getProgramPaths().push_back(getDriver().Dir); 736317019Sdim} 737317019Sdim 738317019Sdim/// Darwin - Darwin tool chain for i386 and x86_64. 739317019SdimDarwin::Darwin(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 740317019Sdim : MachO(D, Triple, Args), TargetInitialized(false), 741317019Sdim CudaInstallation(D, Triple, Args) {} 742317019Sdim 743317019Sdimtypes::ID MachO::LookupTypeForExtension(StringRef Ext) const { 744360784Sdim types::ID Ty = ToolChain::LookupTypeForExtension(Ext); 745317019Sdim 746317019Sdim // Darwin always preprocesses assembly files (unless -x is used explicitly). 747317019Sdim if (Ty == types::TY_PP_Asm) 748317019Sdim return types::TY_Asm; 749317019Sdim 750317019Sdim return Ty; 751317019Sdim} 752317019Sdim 753317019Sdimbool MachO::HasNativeLLVMSupport() const { return true; } 754317019Sdim 755317019SdimToolChain::CXXStdlibType Darwin::GetDefaultCXXStdlibType() const { 756317019Sdim // Default to use libc++ on OS X 10.9+ and iOS 7+. 757317019Sdim if ((isTargetMacOS() && !isMacosxVersionLT(10, 9)) || 758317019Sdim (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0)) || 759317019Sdim isTargetWatchOSBased()) 760317019Sdim return ToolChain::CST_Libcxx; 761317019Sdim 762317019Sdim return ToolChain::CST_Libstdcxx; 763317019Sdim} 764317019Sdim 765317019Sdim/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0. 766317019SdimObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const { 767317019Sdim if (isTargetWatchOSBased()) 768317019Sdim return ObjCRuntime(ObjCRuntime::WatchOS, TargetVersion); 769317019Sdim if (isTargetIOSBased()) 770317019Sdim return ObjCRuntime(ObjCRuntime::iOS, TargetVersion); 771317019Sdim if (isNonFragile) 772317019Sdim return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion); 773317019Sdim return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion); 774317019Sdim} 775317019Sdim 776317019Sdim/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2. 777317019Sdimbool Darwin::hasBlocksRuntime() const { 778317019Sdim if (isTargetWatchOSBased()) 779317019Sdim return true; 780317019Sdim else if (isTargetIOSBased()) 781317019Sdim return !isIPhoneOSVersionLT(3, 2); 782317019Sdim else { 783317019Sdim assert(isTargetMacOS() && "unexpected darwin target"); 784317019Sdim return !isMacosxVersionLT(10, 6); 785317019Sdim } 786317019Sdim} 787317019Sdim 788317019Sdimvoid Darwin::AddCudaIncludeArgs(const ArgList &DriverArgs, 789317019Sdim ArgStringList &CC1Args) const { 790317019Sdim CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); 791317019Sdim} 792317019Sdim 793317019Sdim// This is just a MachO name translation routine and there's no 794317019Sdim// way to join this into ARMTargetParser without breaking all 795317019Sdim// other assumptions. Maybe MachO should consider standardising 796317019Sdim// their nomenclature. 797317019Sdimstatic const char *ArmMachOArchName(StringRef Arch) { 798317019Sdim return llvm::StringSwitch<const char *>(Arch) 799317019Sdim .Case("armv6k", "armv6") 800317019Sdim .Case("armv6m", "armv6m") 801317019Sdim .Case("armv5tej", "armv5") 802317019Sdim .Case("xscale", "xscale") 803317019Sdim .Case("armv4t", "armv4t") 804317019Sdim .Case("armv7", "armv7") 805317019Sdim .Cases("armv7a", "armv7-a", "armv7") 806317019Sdim .Cases("armv7r", "armv7-r", "armv7") 807317019Sdim .Cases("armv7em", "armv7e-m", "armv7em") 808317019Sdim .Cases("armv7k", "armv7-k", "armv7k") 809317019Sdim .Cases("armv7m", "armv7-m", "armv7m") 810317019Sdim .Cases("armv7s", "armv7-s", "armv7s") 811317019Sdim .Default(nullptr); 812317019Sdim} 813317019Sdim 814317019Sdimstatic const char *ArmMachOArchNameCPU(StringRef CPU) { 815327952Sdim llvm::ARM::ArchKind ArchKind = llvm::ARM::parseCPUArch(CPU); 816327952Sdim if (ArchKind == llvm::ARM::ArchKind::INVALID) 817317019Sdim return nullptr; 818317019Sdim StringRef Arch = llvm::ARM::getArchName(ArchKind); 819317019Sdim 820317019Sdim // FIXME: Make sure this MachO triple mangling is really necessary. 821317019Sdim // ARMv5* normalises to ARMv5. 822317019Sdim if (Arch.startswith("armv5")) 823317019Sdim Arch = Arch.substr(0, 5); 824317019Sdim // ARMv6*, except ARMv6M, normalises to ARMv6. 825317019Sdim else if (Arch.startswith("armv6") && !Arch.endswith("6m")) 826317019Sdim Arch = Arch.substr(0, 5); 827317019Sdim // ARMv7A normalises to ARMv7. 828317019Sdim else if (Arch.endswith("v7a")) 829317019Sdim Arch = Arch.substr(0, 5); 830317019Sdim return Arch.data(); 831317019Sdim} 832317019Sdim 833317019SdimStringRef MachO::getMachOArchName(const ArgList &Args) const { 834317019Sdim switch (getTriple().getArch()) { 835317019Sdim default: 836317019Sdim return getDefaultUniversalArchName(); 837317019Sdim 838360784Sdim case llvm::Triple::aarch64_32: 839360784Sdim return "arm64_32"; 840360784Sdim 841317019Sdim case llvm::Triple::aarch64: 842317019Sdim return "arm64"; 843317019Sdim 844317019Sdim case llvm::Triple::thumb: 845317019Sdim case llvm::Triple::arm: 846317019Sdim if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) 847317019Sdim if (const char *Arch = ArmMachOArchName(A->getValue())) 848317019Sdim return Arch; 849317019Sdim 850317019Sdim if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 851317019Sdim if (const char *Arch = ArmMachOArchNameCPU(A->getValue())) 852317019Sdim return Arch; 853317019Sdim 854317019Sdim return "arm"; 855317019Sdim } 856317019Sdim} 857317019Sdim 858317019SdimDarwin::~Darwin() {} 859317019Sdim 860317019SdimMachO::~MachO() {} 861317019Sdim 862317019Sdimstd::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args, 863317019Sdim types::ID InputType) const { 864317019Sdim llvm::Triple Triple(ComputeLLVMTriple(Args, InputType)); 865317019Sdim 866317019Sdim // If the target isn't initialized (e.g., an unknown Darwin platform, return 867317019Sdim // the default triple). 868317019Sdim if (!isTargetInitialized()) 869317019Sdim return Triple.getTriple(); 870317019Sdim 871317019Sdim SmallString<16> Str; 872317019Sdim if (isTargetWatchOSBased()) 873317019Sdim Str += "watchos"; 874317019Sdim else if (isTargetTvOSBased()) 875317019Sdim Str += "tvos"; 876317019Sdim else if (isTargetIOSBased()) 877317019Sdim Str += "ios"; 878317019Sdim else 879317019Sdim Str += "macosx"; 880317019Sdim Str += getTargetVersion().getAsString(); 881317019Sdim Triple.setOSName(Str); 882317019Sdim 883317019Sdim return Triple.getTriple(); 884317019Sdim} 885317019Sdim 886317019SdimTool *MachO::getTool(Action::ActionClass AC) const { 887317019Sdim switch (AC) { 888317019Sdim case Action::LipoJobClass: 889317019Sdim if (!Lipo) 890317019Sdim Lipo.reset(new tools::darwin::Lipo(*this)); 891317019Sdim return Lipo.get(); 892317019Sdim case Action::DsymutilJobClass: 893317019Sdim if (!Dsymutil) 894317019Sdim Dsymutil.reset(new tools::darwin::Dsymutil(*this)); 895317019Sdim return Dsymutil.get(); 896317019Sdim case Action::VerifyDebugInfoJobClass: 897317019Sdim if (!VerifyDebug) 898317019Sdim VerifyDebug.reset(new tools::darwin::VerifyDebug(*this)); 899317019Sdim return VerifyDebug.get(); 900317019Sdim default: 901317019Sdim return ToolChain::getTool(AC); 902317019Sdim } 903317019Sdim} 904317019Sdim 905317019SdimTool *MachO::buildLinker() const { return new tools::darwin::Linker(*this); } 906317019Sdim 907317019SdimTool *MachO::buildAssembler() const { 908317019Sdim return new tools::darwin::Assembler(*this); 909317019Sdim} 910317019Sdim 911317019SdimDarwinClang::DarwinClang(const Driver &D, const llvm::Triple &Triple, 912317019Sdim const ArgList &Args) 913317019Sdim : Darwin(D, Triple, Args) {} 914317019Sdim 915317019Sdimvoid DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const { 916317019Sdim // For modern targets, promote certain warnings to errors. 917317019Sdim if (isTargetWatchOSBased() || getTriple().isArch64Bit()) { 918317019Sdim // Always enable -Wdeprecated-objc-isa-usage and promote it 919317019Sdim // to an error. 920317019Sdim CC1Args.push_back("-Wdeprecated-objc-isa-usage"); 921317019Sdim CC1Args.push_back("-Werror=deprecated-objc-isa-usage"); 922317019Sdim 923317019Sdim // For iOS and watchOS, also error about implicit function declarations, 924317019Sdim // as that can impact calling conventions. 925317019Sdim if (!isTargetMacOS()) 926317019Sdim CC1Args.push_back("-Werror=implicit-function-declaration"); 927317019Sdim } 928317019Sdim} 929317019Sdim 930353358Sdim/// Take a path that speculatively points into Xcode and return the 931353358Sdim/// `XCODE/Contents/Developer` path if it is an Xcode path, or an empty path 932353358Sdim/// otherwise. 933353358Sdimstatic StringRef getXcodeDeveloperPath(StringRef PathIntoXcode) { 934353358Sdim static constexpr llvm::StringLiteral XcodeAppSuffix( 935353358Sdim ".app/Contents/Developer"); 936353358Sdim size_t Index = PathIntoXcode.find(XcodeAppSuffix); 937353358Sdim if (Index == StringRef::npos) 938353358Sdim return ""; 939353358Sdim return PathIntoXcode.take_front(Index + XcodeAppSuffix.size()); 940353358Sdim} 941353358Sdim 942317019Sdimvoid DarwinClang::AddLinkARCArgs(const ArgList &Args, 943317019Sdim ArgStringList &CmdArgs) const { 944317019Sdim // Avoid linking compatibility stubs on i386 mac. 945317019Sdim if (isTargetMacOS() && getArch() == llvm::Triple::x86) 946317019Sdim return; 947317019Sdim 948317019Sdim ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true); 949317019Sdim 950317019Sdim if ((runtime.hasNativeARC() || !isObjCAutoRefCount(Args)) && 951317019Sdim runtime.hasSubscripting()) 952317019Sdim return; 953317019Sdim 954317019Sdim SmallString<128> P(getDriver().ClangExecutable); 955317019Sdim llvm::sys::path::remove_filename(P); // 'clang' 956317019Sdim llvm::sys::path::remove_filename(P); // 'bin' 957353358Sdim 958353358Sdim // 'libarclite' usually lives in the same toolchain as 'clang'. However, the 959353358Sdim // Swift open source toolchains for macOS distribute Clang without libarclite. 960353358Sdim // In that case, to allow the linker to find 'libarclite', we point to the 961353358Sdim // 'libarclite' in the XcodeDefault toolchain instead. 962353358Sdim if (getXcodeDeveloperPath(P).empty()) { 963353358Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 964353358Sdim // Try to infer the path to 'libarclite' in the toolchain from the 965353358Sdim // specified SDK path. 966353358Sdim StringRef XcodePathForSDK = getXcodeDeveloperPath(A->getValue()); 967353358Sdim if (!XcodePathForSDK.empty()) { 968353358Sdim P = XcodePathForSDK; 969353358Sdim llvm::sys::path::append(P, "Toolchains/XcodeDefault.xctoolchain/usr"); 970353358Sdim } 971353358Sdim } 972353358Sdim } 973353358Sdim 974353358Sdim CmdArgs.push_back("-force_load"); 975317019Sdim llvm::sys::path::append(P, "lib", "arc", "libarclite_"); 976317019Sdim // Mash in the platform. 977317019Sdim if (isTargetWatchOSSimulator()) 978317019Sdim P += "watchsimulator"; 979317019Sdim else if (isTargetWatchOS()) 980317019Sdim P += "watchos"; 981317019Sdim else if (isTargetTvOSSimulator()) 982317019Sdim P += "appletvsimulator"; 983317019Sdim else if (isTargetTvOS()) 984317019Sdim P += "appletvos"; 985317019Sdim else if (isTargetIOSSimulator()) 986317019Sdim P += "iphonesimulator"; 987317019Sdim else if (isTargetIPhoneOS()) 988317019Sdim P += "iphoneos"; 989317019Sdim else 990317019Sdim P += "macosx"; 991317019Sdim P += ".a"; 992317019Sdim 993317019Sdim CmdArgs.push_back(Args.MakeArgString(P)); 994317019Sdim} 995317019Sdim 996317019Sdimunsigned DarwinClang::GetDefaultDwarfVersion() const { 997317019Sdim // Default to use DWARF 2 on OS X 10.10 / iOS 8 and lower. 998317019Sdim if ((isTargetMacOS() && isMacosxVersionLT(10, 11)) || 999317019Sdim (isTargetIOSBased() && isIPhoneOSVersionLT(9))) 1000317019Sdim return 2; 1001317019Sdim return 4; 1002317019Sdim} 1003317019Sdim 1004317019Sdimvoid MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs, 1005344779Sdim StringRef Component, RuntimeLinkOptions Opts, 1006344779Sdim bool IsShared) const { 1007344779Sdim SmallString<64> DarwinLibName = StringRef("libclang_rt."); 1008344779Sdim // an Darwin the builtins compomnent is not in the library name 1009344779Sdim if (Component != "builtins") { 1010344779Sdim DarwinLibName += Component; 1011344779Sdim if (!(Opts & RLO_IsEmbedded)) 1012344779Sdim DarwinLibName += "_"; 1013344779Sdim DarwinLibName += getOSLibraryNameSuffix(); 1014344779Sdim } else 1015344779Sdim DarwinLibName += getOSLibraryNameSuffix(true); 1016344779Sdim 1017344779Sdim DarwinLibName += IsShared ? "_dynamic.dylib" : ".a"; 1018317019Sdim SmallString<128> Dir(getDriver().ResourceDir); 1019327952Sdim llvm::sys::path::append( 1020327952Sdim Dir, "lib", (Opts & RLO_IsEmbedded) ? "macho_embedded" : "darwin"); 1021317019Sdim 1022317019Sdim SmallString<128> P(Dir); 1023317019Sdim llvm::sys::path::append(P, DarwinLibName); 1024317019Sdim 1025317019Sdim // For now, allow missing resource libraries to support developers who may 1026317019Sdim // not have compiler-rt checked out or integrated into their build (unless 1027317019Sdim // we explicitly force linking with this library). 1028327952Sdim if ((Opts & RLO_AlwaysLink) || getVFS().exists(P)) { 1029327952Sdim const char *LibArg = Args.MakeArgString(P); 1030327952Sdim if (Opts & RLO_FirstLink) 1031327952Sdim CmdArgs.insert(CmdArgs.begin(), LibArg); 1032327952Sdim else 1033327952Sdim CmdArgs.push_back(LibArg); 1034327952Sdim } 1035317019Sdim 1036317019Sdim // Adding the rpaths might negatively interact when other rpaths are involved, 1037317019Sdim // so we should make sure we add the rpaths last, after all user-specified 1038317019Sdim // rpaths. This is currently true from this place, but we need to be 1039317019Sdim // careful if this function is ever called before user's rpaths are emitted. 1040327952Sdim if (Opts & RLO_AddRPath) { 1041317019Sdim assert(DarwinLibName.endswith(".dylib") && "must be a dynamic library"); 1042317019Sdim 1043317019Sdim // Add @executable_path to rpath to support having the dylib copied with 1044317019Sdim // the executable. 1045317019Sdim CmdArgs.push_back("-rpath"); 1046317019Sdim CmdArgs.push_back("@executable_path"); 1047317019Sdim 1048317019Sdim // Add the path to the resource dir to rpath to support using the dylib 1049317019Sdim // from the default location without copying. 1050317019Sdim CmdArgs.push_back("-rpath"); 1051317019Sdim CmdArgs.push_back(Args.MakeArgString(Dir)); 1052317019Sdim } 1053317019Sdim} 1054317019Sdim 1055317019SdimStringRef Darwin::getPlatformFamily() const { 1056317019Sdim switch (TargetPlatform) { 1057317019Sdim case DarwinPlatformKind::MacOS: 1058317019Sdim return "MacOSX"; 1059317019Sdim case DarwinPlatformKind::IPhoneOS: 1060317019Sdim return "iPhone"; 1061317019Sdim case DarwinPlatformKind::TvOS: 1062317019Sdim return "AppleTV"; 1063317019Sdim case DarwinPlatformKind::WatchOS: 1064317019Sdim return "Watch"; 1065317019Sdim } 1066317019Sdim llvm_unreachable("Unsupported platform"); 1067317019Sdim} 1068317019Sdim 1069317019SdimStringRef Darwin::getSDKName(StringRef isysroot) { 1070317019Sdim // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk 1071317019Sdim auto BeginSDK = llvm::sys::path::begin(isysroot); 1072317019Sdim auto EndSDK = llvm::sys::path::end(isysroot); 1073317019Sdim for (auto IT = BeginSDK; IT != EndSDK; ++IT) { 1074317019Sdim StringRef SDK = *IT; 1075317019Sdim if (SDK.endswith(".sdk")) 1076317019Sdim return SDK.slice(0, SDK.size() - 4); 1077317019Sdim } 1078317019Sdim return ""; 1079317019Sdim} 1080317019Sdim 1081344779SdimStringRef Darwin::getOSLibraryNameSuffix(bool IgnoreSim) const { 1082344779Sdim switch (TargetPlatform) { 1083317019Sdim case DarwinPlatformKind::MacOS: 1084317019Sdim return "osx"; 1085317019Sdim case DarwinPlatformKind::IPhoneOS: 1086344779Sdim return TargetEnvironment == NativeEnvironment || IgnoreSim ? "ios" 1087344779Sdim : "iossim"; 1088317019Sdim case DarwinPlatformKind::TvOS: 1089344779Sdim return TargetEnvironment == NativeEnvironment || IgnoreSim ? "tvos" 1090344779Sdim : "tvossim"; 1091317019Sdim case DarwinPlatformKind::WatchOS: 1092344779Sdim return TargetEnvironment == NativeEnvironment || IgnoreSim ? "watchos" 1093344779Sdim : "watchossim"; 1094317019Sdim } 1095317019Sdim llvm_unreachable("Unsupported platform"); 1096317019Sdim} 1097317019Sdim 1098327952Sdim/// Check if the link command contains a symbol export directive. 1099327952Sdimstatic bool hasExportSymbolDirective(const ArgList &Args) { 1100327952Sdim for (Arg *A : Args) { 1101341825Sdim if (A->getOption().matches(options::OPT_exported__symbols__list)) 1102341825Sdim return true; 1103327952Sdim if (!A->getOption().matches(options::OPT_Wl_COMMA) && 1104327952Sdim !A->getOption().matches(options::OPT_Xlinker)) 1105327952Sdim continue; 1106327952Sdim if (A->containsValue("-exported_symbols_list") || 1107327952Sdim A->containsValue("-exported_symbol")) 1108327952Sdim return true; 1109327952Sdim } 1110327952Sdim return false; 1111327952Sdim} 1112327952Sdim 1113327952Sdim/// Add an export directive for \p Symbol to the link command. 1114327952Sdimstatic void addExportedSymbol(ArgStringList &CmdArgs, const char *Symbol) { 1115327952Sdim CmdArgs.push_back("-exported_symbol"); 1116327952Sdim CmdArgs.push_back(Symbol); 1117327952Sdim} 1118327952Sdim 1119360784Sdim/// Add a sectalign directive for \p Segment and \p Section to the maximum 1120360784Sdim/// expected page size for Darwin. 1121360784Sdim/// 1122360784Sdim/// On iPhone 6+ the max supported page size is 16K. On macOS, the max is 4K. 1123360784Sdim/// Use a common alignment constant (16K) for now, and reduce the alignment on 1124360784Sdim/// macOS if it proves important. 1125360784Sdimstatic void addSectalignToPage(const ArgList &Args, ArgStringList &CmdArgs, 1126360784Sdim StringRef Segment, StringRef Section) { 1127360784Sdim for (const char *A : {"-sectalign", Args.MakeArgString(Segment), 1128360784Sdim Args.MakeArgString(Section), "0x4000"}) 1129360784Sdim CmdArgs.push_back(A); 1130360784Sdim} 1131360784Sdim 1132317019Sdimvoid Darwin::addProfileRTLibs(const ArgList &Args, 1133317019Sdim ArgStringList &CmdArgs) const { 1134317019Sdim if (!needsProfileRT(Args)) return; 1135317019Sdim 1136344779Sdim AddLinkRuntimeLib(Args, CmdArgs, "profile", 1137344779Sdim RuntimeLinkOptions(RLO_AlwaysLink | RLO_FirstLink)); 1138327952Sdim 1139360784Sdim bool ForGCOV = needsGCovInstrumentation(Args); 1140360784Sdim 1141327952Sdim // If we have a symbol export directive and we're linking in the profile 1142327952Sdim // runtime, automatically export symbols necessary to implement some of the 1143327952Sdim // runtime's functionality. 1144327952Sdim if (hasExportSymbolDirective(Args)) { 1145360784Sdim if (ForGCOV) { 1146344779Sdim addExportedSymbol(CmdArgs, "___gcov_flush"); 1147344779Sdim addExportedSymbol(CmdArgs, "_flush_fn_list"); 1148344779Sdim addExportedSymbol(CmdArgs, "_writeout_fn_list"); 1149363496Sdim addExportedSymbol(CmdArgs, "_reset_fn_list"); 1150344779Sdim } else { 1151344779Sdim addExportedSymbol(CmdArgs, "___llvm_profile_filename"); 1152344779Sdim addExportedSymbol(CmdArgs, "___llvm_profile_raw_version"); 1153344779Sdim } 1154344779Sdim addExportedSymbol(CmdArgs, "_lprofDirMode"); 1155327952Sdim } 1156360784Sdim 1157360784Sdim // Align __llvm_prf_{cnts,data} sections to the maximum expected page 1158360784Sdim // alignment. This allows profile counters to be mmap()'d to disk. Note that 1159360784Sdim // it's not enough to just page-align __llvm_prf_cnts: the following section 1160360784Sdim // must also be page-aligned so that its data is not clobbered by mmap(). 1161360784Sdim // 1162360784Sdim // The section alignment is only needed when continuous profile sync is 1163360784Sdim // enabled, but this is expected to be the default in Xcode. Specifying the 1164360784Sdim // extra alignment also allows the same binary to be used with/without sync 1165360784Sdim // enabled. 1166360784Sdim if (!ForGCOV) { 1167360784Sdim for (auto IPSK : {llvm::IPSK_cnts, llvm::IPSK_data}) { 1168360784Sdim addSectalignToPage( 1169360784Sdim Args, CmdArgs, "__DATA", 1170360784Sdim llvm::getInstrProfSectionName(IPSK, llvm::Triple::MachO, 1171360784Sdim /*AddSegmentInfo=*/false)); 1172360784Sdim } 1173360784Sdim } 1174317019Sdim} 1175317019Sdim 1176317019Sdimvoid DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args, 1177317019Sdim ArgStringList &CmdArgs, 1178327952Sdim StringRef Sanitizer, 1179327952Sdim bool Shared) const { 1180327952Sdim auto RLO = RuntimeLinkOptions(RLO_AlwaysLink | (Shared ? RLO_AddRPath : 0U)); 1181344779Sdim AddLinkRuntimeLib(Args, CmdArgs, Sanitizer, RLO, Shared); 1182317019Sdim} 1183317019Sdim 1184317019SdimToolChain::RuntimeLibType DarwinClang::GetRuntimeLibType( 1185317019Sdim const ArgList &Args) const { 1186317019Sdim if (Arg* A = Args.getLastArg(options::OPT_rtlib_EQ)) { 1187317019Sdim StringRef Value = A->getValue(); 1188317019Sdim if (Value != "compiler-rt") 1189317019Sdim getDriver().Diag(clang::diag::err_drv_unsupported_rtlib_for_platform) 1190317019Sdim << Value << "darwin"; 1191317019Sdim } 1192317019Sdim 1193317019Sdim return ToolChain::RLT_CompilerRT; 1194317019Sdim} 1195317019Sdim 1196317019Sdimvoid DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, 1197353358Sdim ArgStringList &CmdArgs, 1198353358Sdim bool ForceLinkBuiltinRT) const { 1199317019Sdim // Call once to ensure diagnostic is printed if wrong value was specified 1200317019Sdim GetRuntimeLibType(Args); 1201317019Sdim 1202317019Sdim // Darwin doesn't support real static executables, don't link any runtime 1203317019Sdim // libraries with -static. 1204317019Sdim if (Args.hasArg(options::OPT_static) || 1205317019Sdim Args.hasArg(options::OPT_fapple_kext) || 1206353358Sdim Args.hasArg(options::OPT_mkernel)) { 1207353358Sdim if (ForceLinkBuiltinRT) 1208353358Sdim AddLinkRuntimeLib(Args, CmdArgs, "builtins"); 1209317019Sdim return; 1210353358Sdim } 1211317019Sdim 1212317019Sdim // Reject -static-libgcc for now, we can deal with this when and if someone 1213317019Sdim // cares. This is useful in situations where someone wants to statically link 1214317019Sdim // something like libstdc++, and needs its runtime support routines. 1215317019Sdim if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) { 1216317019Sdim getDriver().Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args); 1217317019Sdim return; 1218317019Sdim } 1219317019Sdim 1220317019Sdim const SanitizerArgs &Sanitize = getSanitizerArgs(); 1221317019Sdim if (Sanitize.needsAsanRt()) 1222317019Sdim AddLinkSanitizerLibArgs(Args, CmdArgs, "asan"); 1223317472Sdim if (Sanitize.needsLsanRt()) 1224317472Sdim AddLinkSanitizerLibArgs(Args, CmdArgs, "lsan"); 1225317019Sdim if (Sanitize.needsUbsanRt()) 1226327952Sdim AddLinkSanitizerLibArgs(Args, CmdArgs, 1227327952Sdim Sanitize.requiresMinimalRuntime() ? "ubsan_minimal" 1228327952Sdim : "ubsan", 1229327952Sdim Sanitize.needsSharedRt()); 1230317019Sdim if (Sanitize.needsTsanRt()) 1231317019Sdim AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan"); 1232327952Sdim if (Sanitize.needsFuzzer() && !Args.hasArg(options::OPT_dynamiclib)) { 1233327952Sdim AddLinkSanitizerLibArgs(Args, CmdArgs, "fuzzer", /*shared=*/false); 1234327952Sdim 1235327952Sdim // Libfuzzer is written in C++ and requires libcxx. 1236327952Sdim AddCXXStdlibLibArgs(Args, CmdArgs); 1237327952Sdim } 1238317019Sdim if (Sanitize.needsStatsRt()) { 1239344779Sdim AddLinkRuntimeLib(Args, CmdArgs, "stats_client", RLO_AlwaysLink); 1240317019Sdim AddLinkSanitizerLibArgs(Args, CmdArgs, "stats"); 1241317019Sdim } 1242317019Sdim 1243344779Sdim const XRayArgs &XRay = getXRayArgs(); 1244344779Sdim if (XRay.needsXRayRt()) { 1245344779Sdim AddLinkRuntimeLib(Args, CmdArgs, "xray"); 1246344779Sdim AddLinkRuntimeLib(Args, CmdArgs, "xray-basic"); 1247344779Sdim AddLinkRuntimeLib(Args, CmdArgs, "xray-fdr"); 1248344779Sdim } 1249344779Sdim 1250317019Sdim // Otherwise link libSystem, then the dynamic runtime library, and finally any 1251317019Sdim // target specific static runtime library. 1252317019Sdim CmdArgs.push_back("-lSystem"); 1253317019Sdim 1254317019Sdim // Select the dynamic runtime library and the target specific static library. 1255344779Sdim if (isTargetIOSBased()) { 1256317019Sdim // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1, 1257317019Sdim // it never went into the SDK. 1258317019Sdim // Linking against libgcc_s.1 isn't needed for iOS 5.0+ 1259317019Sdim if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator() && 1260317019Sdim getTriple().getArch() != llvm::Triple::aarch64) 1261317019Sdim CmdArgs.push_back("-lgcc_s.1"); 1262317019Sdim } 1263344779Sdim AddLinkRuntimeLib(Args, CmdArgs, "builtins"); 1264317019Sdim} 1265317019Sdim 1266320970Sdim/// Returns the most appropriate macOS target version for the current process. 1267320970Sdim/// 1268320970Sdim/// If the macOS SDK version is the same or earlier than the system version, 1269320970Sdim/// then the SDK version is returned. Otherwise the system version is returned. 1270320970Sdimstatic std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion) { 1271320970Sdim unsigned Major, Minor, Micro; 1272320970Sdim llvm::Triple SystemTriple(llvm::sys::getProcessTriple()); 1273320970Sdim if (!SystemTriple.isMacOSX()) 1274320970Sdim return MacOSSDKVersion; 1275320970Sdim SystemTriple.getMacOSXVersion(Major, Minor, Micro); 1276320970Sdim VersionTuple SystemVersion(Major, Minor, Micro); 1277320970Sdim bool HadExtra; 1278320970Sdim if (!Driver::GetReleaseVersion(MacOSSDKVersion, Major, Minor, Micro, 1279320970Sdim HadExtra)) 1280320970Sdim return MacOSSDKVersion; 1281320970Sdim VersionTuple SDKVersion(Major, Minor, Micro); 1282320970Sdim if (SDKVersion > SystemVersion) 1283320970Sdim return SystemVersion.getAsString(); 1284320970Sdim return MacOSSDKVersion; 1285320970Sdim} 1286320970Sdim 1287327952Sdimnamespace { 1288317019Sdim 1289327952Sdim/// The Darwin OS that was selected or inferred from arguments / environment. 1290327952Sdimstruct DarwinPlatform { 1291327952Sdim enum SourceKind { 1292327952Sdim /// The OS was specified using the -target argument. 1293327952Sdim TargetArg, 1294327952Sdim /// The OS was specified using the -m<os>-version-min argument. 1295327952Sdim OSVersionArg, 1296327952Sdim /// The OS was specified using the OS_DEPLOYMENT_TARGET environment. 1297327952Sdim DeploymentTargetEnv, 1298327952Sdim /// The OS was inferred from the SDK. 1299327952Sdim InferredFromSDK, 1300327952Sdim /// The OS was inferred from the -arch. 1301327952Sdim InferredFromArch 1302327952Sdim }; 1303327952Sdim 1304327952Sdim using DarwinPlatformKind = Darwin::DarwinPlatformKind; 1305327952Sdim using DarwinEnvironmentKind = Darwin::DarwinEnvironmentKind; 1306327952Sdim 1307327952Sdim DarwinPlatformKind getPlatform() const { return Platform; } 1308327952Sdim 1309327952Sdim DarwinEnvironmentKind getEnvironment() const { return Environment; } 1310327952Sdim 1311341825Sdim void setEnvironment(DarwinEnvironmentKind Kind) { 1312341825Sdim Environment = Kind; 1313341825Sdim InferSimulatorFromArch = false; 1314341825Sdim } 1315341825Sdim 1316327952Sdim StringRef getOSVersion() const { 1317327952Sdim if (Kind == OSVersionArg) 1318327952Sdim return Argument->getValue(); 1319327952Sdim return OSVersion; 1320327952Sdim } 1321327952Sdim 1322327952Sdim void setOSVersion(StringRef S) { 1323327952Sdim assert(Kind == TargetArg && "Unexpected kind!"); 1324327952Sdim OSVersion = S; 1325327952Sdim } 1326327952Sdim 1327327952Sdim bool hasOSVersion() const { return HasOSVersion; } 1328327952Sdim 1329327952Sdim /// Returns true if the target OS was explicitly specified. 1330327952Sdim bool isExplicitlySpecified() const { return Kind <= DeploymentTargetEnv; } 1331327952Sdim 1332341825Sdim /// Returns true if the simulator environment can be inferred from the arch. 1333341825Sdim bool canInferSimulatorFromArch() const { return InferSimulatorFromArch; } 1334341825Sdim 1335327952Sdim /// Adds the -m<os>-version-min argument to the compiler invocation. 1336327952Sdim void addOSVersionMinArgument(DerivedArgList &Args, const OptTable &Opts) { 1337327952Sdim if (Argument) 1338327952Sdim return; 1339327952Sdim assert(Kind != TargetArg && Kind != OSVersionArg && "Invalid kind"); 1340327952Sdim options::ID Opt; 1341327952Sdim switch (Platform) { 1342327952Sdim case DarwinPlatformKind::MacOS: 1343327952Sdim Opt = options::OPT_mmacosx_version_min_EQ; 1344327952Sdim break; 1345327952Sdim case DarwinPlatformKind::IPhoneOS: 1346327952Sdim Opt = options::OPT_miphoneos_version_min_EQ; 1347327952Sdim break; 1348327952Sdim case DarwinPlatformKind::TvOS: 1349327952Sdim Opt = options::OPT_mtvos_version_min_EQ; 1350327952Sdim break; 1351327952Sdim case DarwinPlatformKind::WatchOS: 1352327952Sdim Opt = options::OPT_mwatchos_version_min_EQ; 1353327952Sdim break; 1354317019Sdim } 1355327952Sdim Argument = Args.MakeJoinedArg(nullptr, Opts.getOption(Opt), OSVersion); 1356327952Sdim Args.append(Argument); 1357317019Sdim } 1358317019Sdim 1359327952Sdim /// Returns the OS version with the argument / environment variable that 1360327952Sdim /// specified it. 1361327952Sdim std::string getAsString(DerivedArgList &Args, const OptTable &Opts) { 1362327952Sdim switch (Kind) { 1363327952Sdim case TargetArg: 1364327952Sdim case OSVersionArg: 1365327952Sdim case InferredFromSDK: 1366327952Sdim case InferredFromArch: 1367327952Sdim assert(Argument && "OS version argument not yet inferred"); 1368327952Sdim return Argument->getAsString(Args); 1369327952Sdim case DeploymentTargetEnv: 1370327952Sdim return (llvm::Twine(EnvVarName) + "=" + OSVersion).str(); 1371327952Sdim } 1372327952Sdim llvm_unreachable("Unsupported Darwin Source Kind"); 1373327952Sdim } 1374327952Sdim 1375327952Sdim static DarwinPlatform createFromTarget(const llvm::Triple &TT, 1376327952Sdim StringRef OSVersion, Arg *A) { 1377327952Sdim DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()), OSVersion, 1378327952Sdim A); 1379327952Sdim switch (TT.getEnvironment()) { 1380327952Sdim case llvm::Triple::Simulator: 1381327952Sdim Result.Environment = DarwinEnvironmentKind::Simulator; 1382327952Sdim break; 1383327952Sdim default: 1384327952Sdim break; 1385327952Sdim } 1386327952Sdim unsigned Major, Minor, Micro; 1387327952Sdim TT.getOSVersion(Major, Minor, Micro); 1388327952Sdim if (Major == 0) 1389327952Sdim Result.HasOSVersion = false; 1390327952Sdim return Result; 1391327952Sdim } 1392327952Sdim static DarwinPlatform createOSVersionArg(DarwinPlatformKind Platform, 1393327952Sdim Arg *A) { 1394327952Sdim return DarwinPlatform(OSVersionArg, Platform, A); 1395327952Sdim } 1396327952Sdim static DarwinPlatform createDeploymentTargetEnv(DarwinPlatformKind Platform, 1397327952Sdim StringRef EnvVarName, 1398327952Sdim StringRef Value) { 1399327952Sdim DarwinPlatform Result(DeploymentTargetEnv, Platform, Value); 1400327952Sdim Result.EnvVarName = EnvVarName; 1401327952Sdim return Result; 1402327952Sdim } 1403327952Sdim static DarwinPlatform createFromSDK(DarwinPlatformKind Platform, 1404341825Sdim StringRef Value, 1405341825Sdim bool IsSimulator = false) { 1406341825Sdim DarwinPlatform Result(InferredFromSDK, Platform, Value); 1407341825Sdim if (IsSimulator) 1408341825Sdim Result.Environment = DarwinEnvironmentKind::Simulator; 1409341825Sdim Result.InferSimulatorFromArch = false; 1410341825Sdim return Result; 1411327952Sdim } 1412327952Sdim static DarwinPlatform createFromArch(llvm::Triple::OSType OS, 1413327952Sdim StringRef Value) { 1414327952Sdim return DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Value); 1415327952Sdim } 1416327952Sdim 1417344779Sdim /// Constructs an inferred SDKInfo value based on the version inferred from 1418344779Sdim /// the SDK path itself. Only works for values that were created by inferring 1419344779Sdim /// the platform from the SDKPath. 1420344779Sdim DarwinSDKInfo inferSDKInfo() { 1421344779Sdim assert(Kind == InferredFromSDK && "can infer SDK info only"); 1422344779Sdim llvm::VersionTuple Version; 1423344779Sdim bool IsValid = !Version.tryParse(OSVersion); 1424344779Sdim (void)IsValid; 1425344779Sdim assert(IsValid && "invalid SDK version"); 1426344779Sdim return DarwinSDKInfo(Version); 1427344779Sdim } 1428344779Sdim 1429327952Sdimprivate: 1430327952Sdim DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument) 1431327952Sdim : Kind(Kind), Platform(Platform), Argument(Argument) {} 1432327952Sdim DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, StringRef Value, 1433327952Sdim Arg *Argument = nullptr) 1434327952Sdim : Kind(Kind), Platform(Platform), OSVersion(Value), Argument(Argument) {} 1435327952Sdim 1436327952Sdim static DarwinPlatformKind getPlatformFromOS(llvm::Triple::OSType OS) { 1437327952Sdim switch (OS) { 1438327952Sdim case llvm::Triple::Darwin: 1439327952Sdim case llvm::Triple::MacOSX: 1440327952Sdim return DarwinPlatformKind::MacOS; 1441327952Sdim case llvm::Triple::IOS: 1442327952Sdim return DarwinPlatformKind::IPhoneOS; 1443327952Sdim case llvm::Triple::TvOS: 1444327952Sdim return DarwinPlatformKind::TvOS; 1445327952Sdim case llvm::Triple::WatchOS: 1446327952Sdim return DarwinPlatformKind::WatchOS; 1447327952Sdim default: 1448327952Sdim llvm_unreachable("Unable to infer Darwin variant"); 1449327952Sdim } 1450327952Sdim } 1451327952Sdim 1452327952Sdim SourceKind Kind; 1453327952Sdim DarwinPlatformKind Platform; 1454327952Sdim DarwinEnvironmentKind Environment = DarwinEnvironmentKind::NativeEnvironment; 1455327952Sdim std::string OSVersion; 1456341825Sdim bool HasOSVersion = true, InferSimulatorFromArch = true; 1457327952Sdim Arg *Argument; 1458327952Sdim StringRef EnvVarName; 1459327952Sdim}; 1460327952Sdim 1461327952Sdim/// Returns the deployment target that's specified using the -m<os>-version-min 1462327952Sdim/// argument. 1463327952SdimOptional<DarwinPlatform> 1464327952SdimgetDeploymentTargetFromOSVersionArg(DerivedArgList &Args, 1465327952Sdim const Driver &TheDriver) { 1466317019Sdim Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ); 1467317019Sdim Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ, 1468317019Sdim options::OPT_mios_simulator_version_min_EQ); 1469317019Sdim Arg *TvOSVersion = 1470317019Sdim Args.getLastArg(options::OPT_mtvos_version_min_EQ, 1471317019Sdim options::OPT_mtvos_simulator_version_min_EQ); 1472317019Sdim Arg *WatchOSVersion = 1473317019Sdim Args.getLastArg(options::OPT_mwatchos_version_min_EQ, 1474317019Sdim options::OPT_mwatchos_simulator_version_min_EQ); 1475327952Sdim if (OSXVersion) { 1476327952Sdim if (iOSVersion || TvOSVersion || WatchOSVersion) { 1477327952Sdim TheDriver.Diag(diag::err_drv_argument_not_allowed_with) 1478327952Sdim << OSXVersion->getAsString(Args) 1479327952Sdim << (iOSVersion ? iOSVersion 1480327952Sdim : TvOSVersion ? TvOSVersion : WatchOSVersion) 1481327952Sdim ->getAsString(Args); 1482327952Sdim } 1483327952Sdim return DarwinPlatform::createOSVersionArg(Darwin::MacOS, OSXVersion); 1484327952Sdim } else if (iOSVersion) { 1485327952Sdim if (TvOSVersion || WatchOSVersion) { 1486327952Sdim TheDriver.Diag(diag::err_drv_argument_not_allowed_with) 1487327952Sdim << iOSVersion->getAsString(Args) 1488327952Sdim << (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args); 1489327952Sdim } 1490327952Sdim return DarwinPlatform::createOSVersionArg(Darwin::IPhoneOS, iOSVersion); 1491327952Sdim } else if (TvOSVersion) { 1492327952Sdim if (WatchOSVersion) { 1493327952Sdim TheDriver.Diag(diag::err_drv_argument_not_allowed_with) 1494327952Sdim << TvOSVersion->getAsString(Args) 1495327952Sdim << WatchOSVersion->getAsString(Args); 1496327952Sdim } 1497327952Sdim return DarwinPlatform::createOSVersionArg(Darwin::TvOS, TvOSVersion); 1498327952Sdim } else if (WatchOSVersion) 1499327952Sdim return DarwinPlatform::createOSVersionArg(Darwin::WatchOS, WatchOSVersion); 1500327952Sdim return None; 1501327952Sdim} 1502317019Sdim 1503327952Sdim/// Returns the deployment target that's specified using the 1504327952Sdim/// OS_DEPLOYMENT_TARGET environment variable. 1505327952SdimOptional<DarwinPlatform> 1506327952SdimgetDeploymentTargetFromEnvironmentVariables(const Driver &TheDriver, 1507327952Sdim const llvm::Triple &Triple) { 1508327952Sdim std::string Targets[Darwin::LastDarwinPlatform + 1]; 1509327952Sdim const char *EnvVars[] = { 1510327952Sdim "MACOSX_DEPLOYMENT_TARGET", 1511327952Sdim "IPHONEOS_DEPLOYMENT_TARGET", 1512327952Sdim "TVOS_DEPLOYMENT_TARGET", 1513327952Sdim "WATCHOS_DEPLOYMENT_TARGET", 1514327952Sdim }; 1515327952Sdim static_assert(llvm::array_lengthof(EnvVars) == Darwin::LastDarwinPlatform + 1, 1516327952Sdim "Missing platform"); 1517327952Sdim for (const auto &I : llvm::enumerate(llvm::makeArrayRef(EnvVars))) { 1518327952Sdim if (char *Env = ::getenv(I.value())) 1519327952Sdim Targets[I.index()] = Env; 1520327952Sdim } 1521320572Sdim 1522327952Sdim // Allow conflicts among OSX and iOS for historical reasons, but choose the 1523327952Sdim // default platform. 1524327952Sdim if (!Targets[Darwin::MacOS].empty() && 1525327952Sdim (!Targets[Darwin::IPhoneOS].empty() || 1526327952Sdim !Targets[Darwin::WatchOS].empty() || !Targets[Darwin::TvOS].empty())) { 1527327952Sdim if (Triple.getArch() == llvm::Triple::arm || 1528327952Sdim Triple.getArch() == llvm::Triple::aarch64 || 1529327952Sdim Triple.getArch() == llvm::Triple::thumb) 1530327952Sdim Targets[Darwin::MacOS] = ""; 1531327952Sdim else 1532327952Sdim Targets[Darwin::IPhoneOS] = Targets[Darwin::WatchOS] = 1533327952Sdim Targets[Darwin::TvOS] = ""; 1534360784Sdim } else { 1535360784Sdim // Don't allow conflicts in any other platform. 1536360784Sdim unsigned FirstTarget = llvm::array_lengthof(Targets); 1537360784Sdim for (unsigned I = 0; I != llvm::array_lengthof(Targets); ++I) { 1538360784Sdim if (Targets[I].empty()) 1539360784Sdim continue; 1540360784Sdim if (FirstTarget == llvm::array_lengthof(Targets)) 1541360784Sdim FirstTarget = I; 1542360784Sdim else 1543360784Sdim TheDriver.Diag(diag::err_drv_conflicting_deployment_targets) 1544360784Sdim << Targets[FirstTarget] << Targets[I]; 1545360784Sdim } 1546327952Sdim } 1547317019Sdim 1548327952Sdim for (const auto &Target : llvm::enumerate(llvm::makeArrayRef(Targets))) { 1549327952Sdim if (!Target.value().empty()) 1550327952Sdim return DarwinPlatform::createDeploymentTargetEnv( 1551327952Sdim (Darwin::DarwinPlatformKind)Target.index(), EnvVars[Target.index()], 1552327952Sdim Target.value()); 1553327952Sdim } 1554327952Sdim return None; 1555327952Sdim} 1556317019Sdim 1557327952Sdim/// Tries to infer the deployment target from the SDK specified by -isysroot 1558344779Sdim/// (or SDKROOT). Uses the version specified in the SDKSettings.json file if 1559344779Sdim/// it's available. 1560344779SdimOptional<DarwinPlatform> 1561344779SdiminferDeploymentTargetFromSDK(DerivedArgList &Args, 1562344779Sdim const Optional<DarwinSDKInfo> &SDKInfo) { 1563327952Sdim const Arg *A = Args.getLastArg(options::OPT_isysroot); 1564327952Sdim if (!A) 1565327952Sdim return None; 1566327952Sdim StringRef isysroot = A->getValue(); 1567327952Sdim StringRef SDK = Darwin::getSDKName(isysroot); 1568327952Sdim if (!SDK.size()) 1569327952Sdim return None; 1570344779Sdim 1571344779Sdim std::string Version; 1572344779Sdim if (SDKInfo) { 1573344779Sdim // Get the version from the SDKSettings.json if it's available. 1574344779Sdim Version = SDKInfo->getVersion().getAsString(); 1575344779Sdim } else { 1576344779Sdim // Slice the version number out. 1577344779Sdim // Version number is between the first and the last number. 1578344779Sdim size_t StartVer = SDK.find_first_of("0123456789"); 1579344779Sdim size_t EndVer = SDK.find_last_of("0123456789"); 1580344779Sdim if (StartVer != StringRef::npos && EndVer > StartVer) 1581344779Sdim Version = SDK.slice(StartVer, EndVer + 1); 1582327952Sdim } 1583344779Sdim if (Version.empty()) 1584344779Sdim return None; 1585344779Sdim 1586344779Sdim if (SDK.startswith("iPhoneOS") || SDK.startswith("iPhoneSimulator")) 1587344779Sdim return DarwinPlatform::createFromSDK( 1588344779Sdim Darwin::IPhoneOS, Version, 1589344779Sdim /*IsSimulator=*/SDK.startswith("iPhoneSimulator")); 1590344779Sdim else if (SDK.startswith("MacOSX")) 1591344779Sdim return DarwinPlatform::createFromSDK(Darwin::MacOS, 1592344779Sdim getSystemOrSDKMacOSVersion(Version)); 1593344779Sdim else if (SDK.startswith("WatchOS") || SDK.startswith("WatchSimulator")) 1594344779Sdim return DarwinPlatform::createFromSDK( 1595344779Sdim Darwin::WatchOS, Version, 1596344779Sdim /*IsSimulator=*/SDK.startswith("WatchSimulator")); 1597344779Sdim else if (SDK.startswith("AppleTVOS") || SDK.startswith("AppleTVSimulator")) 1598344779Sdim return DarwinPlatform::createFromSDK( 1599344779Sdim Darwin::TvOS, Version, 1600344779Sdim /*IsSimulator=*/SDK.startswith("AppleTVSimulator")); 1601327952Sdim return None; 1602327952Sdim} 1603317019Sdim 1604327952Sdimstd::string getOSVersion(llvm::Triple::OSType OS, const llvm::Triple &Triple, 1605327952Sdim const Driver &TheDriver) { 1606327952Sdim unsigned Major, Minor, Micro; 1607341825Sdim llvm::Triple SystemTriple(llvm::sys::getProcessTriple()); 1608327952Sdim switch (OS) { 1609327952Sdim case llvm::Triple::Darwin: 1610327952Sdim case llvm::Triple::MacOSX: 1611341825Sdim // If there is no version specified on triple, and both host and target are 1612341825Sdim // macos, use the host triple to infer OS version. 1613341825Sdim if (Triple.isMacOSX() && SystemTriple.isMacOSX() && 1614341825Sdim !Triple.getOSMajorVersion()) 1615341825Sdim SystemTriple.getMacOSXVersion(Major, Minor, Micro); 1616341825Sdim else if (!Triple.getMacOSXVersion(Major, Minor, Micro)) 1617327952Sdim TheDriver.Diag(diag::err_drv_invalid_darwin_version) 1618327952Sdim << Triple.getOSName(); 1619327952Sdim break; 1620327952Sdim case llvm::Triple::IOS: 1621327952Sdim Triple.getiOSVersion(Major, Minor, Micro); 1622327952Sdim break; 1623327952Sdim case llvm::Triple::TvOS: 1624327952Sdim Triple.getOSVersion(Major, Minor, Micro); 1625327952Sdim break; 1626327952Sdim case llvm::Triple::WatchOS: 1627327952Sdim Triple.getWatchOSVersion(Major, Minor, Micro); 1628327952Sdim break; 1629327952Sdim default: 1630327952Sdim llvm_unreachable("Unexpected OS type"); 1631327952Sdim break; 1632327952Sdim } 1633320572Sdim 1634327952Sdim std::string OSVersion; 1635327952Sdim llvm::raw_string_ostream(OSVersion) << Major << '.' << Minor << '.' << Micro; 1636327952Sdim return OSVersion; 1637327952Sdim} 1638317019Sdim 1639327952Sdim/// Tries to infer the target OS from the -arch. 1640327952SdimOptional<DarwinPlatform> 1641327952SdiminferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain, 1642327952Sdim const llvm::Triple &Triple, 1643327952Sdim const Driver &TheDriver) { 1644327952Sdim llvm::Triple::OSType OSTy = llvm::Triple::UnknownOS; 1645321238Sdim 1646327952Sdim StringRef MachOArchName = Toolchain.getMachOArchName(Args); 1647327952Sdim if (MachOArchName == "armv7" || MachOArchName == "armv7s" || 1648327952Sdim MachOArchName == "arm64") 1649327952Sdim OSTy = llvm::Triple::IOS; 1650360784Sdim else if (MachOArchName == "armv7k" || MachOArchName == "arm64_32") 1651327952Sdim OSTy = llvm::Triple::WatchOS; 1652327952Sdim else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" && 1653327952Sdim MachOArchName != "armv7em") 1654327952Sdim OSTy = llvm::Triple::MacOSX; 1655321238Sdim 1656327952Sdim if (OSTy == llvm::Triple::UnknownOS) 1657327952Sdim return None; 1658327952Sdim return DarwinPlatform::createFromArch(OSTy, 1659327952Sdim getOSVersion(OSTy, Triple, TheDriver)); 1660327952Sdim} 1661321238Sdim 1662327952Sdim/// Returns the deployment target that's specified using the -target option. 1663327952SdimOptional<DarwinPlatform> getDeploymentTargetFromTargetArg( 1664327952Sdim DerivedArgList &Args, const llvm::Triple &Triple, const Driver &TheDriver) { 1665327952Sdim if (!Args.hasArg(options::OPT_target)) 1666327952Sdim return None; 1667327952Sdim if (Triple.getOS() == llvm::Triple::Darwin || 1668327952Sdim Triple.getOS() == llvm::Triple::UnknownOS) 1669327952Sdim return None; 1670327952Sdim std::string OSVersion = getOSVersion(Triple.getOS(), Triple, TheDriver); 1671327952Sdim return DarwinPlatform::createFromTarget(Triple, OSVersion, 1672327952Sdim Args.getLastArg(options::OPT_target)); 1673327952Sdim} 1674321238Sdim 1675344779SdimOptional<DarwinSDKInfo> parseSDKSettings(llvm::vfs::FileSystem &VFS, 1676344779Sdim const ArgList &Args, 1677344779Sdim const Driver &TheDriver) { 1678344779Sdim const Arg *A = Args.getLastArg(options::OPT_isysroot); 1679344779Sdim if (!A) 1680344779Sdim return None; 1681344779Sdim StringRef isysroot = A->getValue(); 1682344779Sdim auto SDKInfoOrErr = driver::parseDarwinSDKInfo(VFS, isysroot); 1683344779Sdim if (!SDKInfoOrErr) { 1684344779Sdim llvm::consumeError(SDKInfoOrErr.takeError()); 1685344779Sdim TheDriver.Diag(diag::warn_drv_darwin_sdk_invalid_settings); 1686344779Sdim return None; 1687344779Sdim } 1688344779Sdim return *SDKInfoOrErr; 1689344779Sdim} 1690344779Sdim 1691327952Sdim} // namespace 1692321238Sdim 1693327952Sdimvoid Darwin::AddDeploymentTarget(DerivedArgList &Args) const { 1694327952Sdim const OptTable &Opts = getDriver().getOpts(); 1695327952Sdim 1696327952Sdim // Support allowing the SDKROOT environment variable used by xcrun and other 1697327952Sdim // Xcode tools to define the default sysroot, by making it the default for 1698327952Sdim // isysroot. 1699327952Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 1700327952Sdim // Warn if the path does not exist. 1701327952Sdim if (!getVFS().exists(A->getValue())) 1702327952Sdim getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue(); 1703327952Sdim } else { 1704327952Sdim if (char *env = ::getenv("SDKROOT")) { 1705327952Sdim // We only use this value as the default if it is an absolute path, 1706327952Sdim // exists, and it is not the root path. 1707327952Sdim if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) && 1708327952Sdim StringRef(env) != "/") { 1709327952Sdim Args.append(Args.MakeSeparateArg( 1710327952Sdim nullptr, Opts.getOption(options::OPT_isysroot), env)); 1711317019Sdim } 1712317019Sdim } 1713327952Sdim } 1714317019Sdim 1715344779Sdim // Read the SDKSettings.json file for more information, like the SDK version 1716344779Sdim // that we can pass down to the compiler. 1717344779Sdim SDKInfo = parseSDKSettings(getVFS(), Args, getDriver()); 1718344779Sdim 1719327952Sdim // The OS and the version can be specified using the -target argument. 1720327952Sdim Optional<DarwinPlatform> OSTarget = 1721327952Sdim getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver()); 1722327952Sdim if (OSTarget) { 1723327952Sdim Optional<DarwinPlatform> OSVersionArgTarget = 1724327952Sdim getDeploymentTargetFromOSVersionArg(Args, getDriver()); 1725327952Sdim if (OSVersionArgTarget) { 1726327952Sdim unsigned TargetMajor, TargetMinor, TargetMicro; 1727327952Sdim bool TargetExtra; 1728327952Sdim unsigned ArgMajor, ArgMinor, ArgMicro; 1729327952Sdim bool ArgExtra; 1730327952Sdim if (OSTarget->getPlatform() != OSVersionArgTarget->getPlatform() || 1731327952Sdim (Driver::GetReleaseVersion(OSTarget->getOSVersion(), TargetMajor, 1732327952Sdim TargetMinor, TargetMicro, TargetExtra) && 1733327952Sdim Driver::GetReleaseVersion(OSVersionArgTarget->getOSVersion(), 1734327952Sdim ArgMajor, ArgMinor, ArgMicro, ArgExtra) && 1735327952Sdim (VersionTuple(TargetMajor, TargetMinor, TargetMicro) != 1736327952Sdim VersionTuple(ArgMajor, ArgMinor, ArgMicro) || 1737327952Sdim TargetExtra != ArgExtra))) { 1738327952Sdim // Select the OS version from the -m<os>-version-min argument when 1739327952Sdim // the -target does not include an OS version. 1740327952Sdim if (OSTarget->getPlatform() == OSVersionArgTarget->getPlatform() && 1741327952Sdim !OSTarget->hasOSVersion()) { 1742327952Sdim OSTarget->setOSVersion(OSVersionArgTarget->getOSVersion()); 1743327952Sdim } else { 1744327952Sdim // Warn about -m<os>-version-min that doesn't match the OS version 1745327952Sdim // that's specified in the target. 1746327952Sdim std::string OSVersionArg = 1747327952Sdim OSVersionArgTarget->getAsString(Args, Opts); 1748327952Sdim std::string TargetArg = OSTarget->getAsString(Args, Opts); 1749327952Sdim getDriver().Diag(clang::diag::warn_drv_overriding_flag_option) 1750327952Sdim << OSVersionArg << TargetArg; 1751327952Sdim } 1752327952Sdim } 1753317019Sdim } 1754327952Sdim } else { 1755327952Sdim // The OS target can be specified using the -m<os>version-min argument. 1756327952Sdim OSTarget = getDeploymentTargetFromOSVersionArg(Args, getDriver()); 1757327952Sdim // If no deployment target was specified on the command line, check for 1758327952Sdim // environment defines. 1759341825Sdim if (!OSTarget) { 1760327952Sdim OSTarget = 1761327952Sdim getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple()); 1762341825Sdim if (OSTarget) { 1763341825Sdim // Don't infer simulator from the arch when the SDK is also specified. 1764344779Sdim Optional<DarwinPlatform> SDKTarget = 1765344779Sdim inferDeploymentTargetFromSDK(Args, SDKInfo); 1766341825Sdim if (SDKTarget) 1767341825Sdim OSTarget->setEnvironment(SDKTarget->getEnvironment()); 1768341825Sdim } 1769341825Sdim } 1770327952Sdim // If there is no command-line argument to specify the Target version and 1771327952Sdim // no environment variable defined, see if we can set the default based 1772344779Sdim // on -isysroot using SDKSettings.json if it exists. 1773344779Sdim if (!OSTarget) { 1774344779Sdim OSTarget = inferDeploymentTargetFromSDK(Args, SDKInfo); 1775344779Sdim /// If the target was successfully constructed from the SDK path, try to 1776344779Sdim /// infer the SDK info if the SDK doesn't have it. 1777344779Sdim if (OSTarget && !SDKInfo) 1778344779Sdim SDKInfo = OSTarget->inferSDKInfo(); 1779344779Sdim } 1780327952Sdim // If no OS targets have been specified, try to guess platform from -target 1781327952Sdim // or arch name and compute the version from the triple. 1782327952Sdim if (!OSTarget) 1783327952Sdim OSTarget = 1784327952Sdim inferDeploymentTargetFromArch(Args, *this, getTriple(), getDriver()); 1785317019Sdim } 1786317019Sdim 1787327952Sdim assert(OSTarget && "Unable to infer Darwin variant"); 1788327952Sdim OSTarget->addOSVersionMinArgument(Args, Opts); 1789327952Sdim DarwinPlatformKind Platform = OSTarget->getPlatform(); 1790317019Sdim 1791327952Sdim unsigned Major, Minor, Micro; 1792327952Sdim bool HadExtra; 1793317019Sdim // Set the tool chain target information. 1794317019Sdim if (Platform == MacOS) { 1795327952Sdim if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor, 1796327952Sdim Micro, HadExtra) || 1797317019Sdim HadExtra || Major != 10 || Minor >= 100 || Micro >= 100) 1798317019Sdim getDriver().Diag(diag::err_drv_invalid_version_number) 1799327952Sdim << OSTarget->getAsString(Args, Opts); 1800317019Sdim } else if (Platform == IPhoneOS) { 1801327952Sdim if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor, 1802327952Sdim Micro, HadExtra) || 1803317019Sdim HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100) 1804317019Sdim getDriver().Diag(diag::err_drv_invalid_version_number) 1805327952Sdim << OSTarget->getAsString(Args, Opts); 1806327952Sdim ; 1807322740Sdim // For 32-bit targets, the deployment target for iOS has to be earlier than 1808322740Sdim // iOS 11. 1809320572Sdim if (getTriple().isArch32Bit() && Major >= 11) { 1810322740Sdim // If the deployment target is explicitly specified, print a diagnostic. 1811327952Sdim if (OSTarget->isExplicitlySpecified()) { 1812322740Sdim getDriver().Diag(diag::warn_invalid_ios_deployment_target) 1813327952Sdim << OSTarget->getAsString(Args, Opts); 1814327952Sdim // Otherwise, set it to 10.99.99. 1815322740Sdim } else { 1816322740Sdim Major = 10; 1817322740Sdim Minor = 99; 1818322740Sdim Micro = 99; 1819322740Sdim } 1820320572Sdim } 1821317019Sdim } else if (Platform == TvOS) { 1822327952Sdim if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor, 1823327952Sdim Micro, HadExtra) || 1824327952Sdim HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100) 1825317019Sdim getDriver().Diag(diag::err_drv_invalid_version_number) 1826327952Sdim << OSTarget->getAsString(Args, Opts); 1827317019Sdim } else if (Platform == WatchOS) { 1828327952Sdim if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor, 1829327952Sdim Micro, HadExtra) || 1830327952Sdim HadExtra || Major >= 10 || Minor >= 100 || Micro >= 100) 1831317019Sdim getDriver().Diag(diag::err_drv_invalid_version_number) 1832327952Sdim << OSTarget->getAsString(Args, Opts); 1833317019Sdim } else 1834317019Sdim llvm_unreachable("unknown kind of Darwin platform"); 1835317019Sdim 1836327952Sdim DarwinEnvironmentKind Environment = OSTarget->getEnvironment(); 1837317019Sdim // Recognize iOS targets with an x86 architecture as the iOS simulator. 1838327952Sdim if (Environment == NativeEnvironment && Platform != MacOS && 1839360784Sdim OSTarget->canInferSimulatorFromArch() && getTriple().isX86()) 1840327952Sdim Environment = Simulator; 1841317019Sdim 1842327952Sdim setTarget(Platform, Environment, Major, Minor, Micro); 1843317019Sdim 1844317019Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 1845317019Sdim StringRef SDK = getSDKName(A->getValue()); 1846317019Sdim if (SDK.size() > 0) { 1847317019Sdim size_t StartVer = SDK.find_first_of("0123456789"); 1848317019Sdim StringRef SDKName = SDK.slice(0, StartVer); 1849317019Sdim if (!SDKName.startswith(getPlatformFamily())) 1850317019Sdim getDriver().Diag(diag::warn_incompatible_sysroot) 1851317019Sdim << SDKName << getPlatformFamily(); 1852317019Sdim } 1853317019Sdim } 1854317019Sdim} 1855317019Sdim 1856353358Sdim// Returns the effective header sysroot path to use. This comes either from 1857353358Sdim// -isysroot or --sysroot. 1858353358Sdimllvm::StringRef DarwinClang::GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const { 1859353358Sdim if(DriverArgs.hasArg(options::OPT_isysroot)) 1860353358Sdim return DriverArgs.getLastArgValue(options::OPT_isysroot); 1861353358Sdim if (!getDriver().SysRoot.empty()) 1862353358Sdim return getDriver().SysRoot; 1863353358Sdim return "/"; 1864353358Sdim} 1865353358Sdim 1866353358Sdimvoid DarwinClang::AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 1867353358Sdim llvm::opt::ArgStringList &CC1Args) const { 1868353358Sdim const Driver &D = getDriver(); 1869353358Sdim 1870353358Sdim llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs); 1871353358Sdim 1872353358Sdim bool NoStdInc = DriverArgs.hasArg(options::OPT_nostdinc); 1873353358Sdim bool NoStdlibInc = DriverArgs.hasArg(options::OPT_nostdlibinc); 1874353358Sdim bool NoBuiltinInc = DriverArgs.hasArg(options::OPT_nobuiltininc); 1875353358Sdim 1876353358Sdim // Add <sysroot>/usr/local/include 1877353358Sdim if (!NoStdInc && !NoStdlibInc) { 1878353358Sdim SmallString<128> P(Sysroot); 1879353358Sdim llvm::sys::path::append(P, "usr", "local", "include"); 1880353358Sdim addSystemInclude(DriverArgs, CC1Args, P); 1881353358Sdim } 1882353358Sdim 1883353358Sdim // Add the Clang builtin headers (<resource>/include) 1884353358Sdim if (!NoStdInc && !NoBuiltinInc) { 1885353358Sdim SmallString<128> P(D.ResourceDir); 1886353358Sdim llvm::sys::path::append(P, "include"); 1887353358Sdim addSystemInclude(DriverArgs, CC1Args, P); 1888353358Sdim } 1889353358Sdim 1890353358Sdim if (NoStdInc || NoStdlibInc) 1891353358Sdim return; 1892353358Sdim 1893353358Sdim // Check for configure-time C include directories. 1894353358Sdim llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS); 1895353358Sdim if (!CIncludeDirs.empty()) { 1896353358Sdim llvm::SmallVector<llvm::StringRef, 5> dirs; 1897353358Sdim CIncludeDirs.split(dirs, ":"); 1898353358Sdim for (llvm::StringRef dir : dirs) { 1899353358Sdim llvm::StringRef Prefix = 1900353358Sdim llvm::sys::path::is_absolute(dir) ? llvm::StringRef(Sysroot) : ""; 1901353358Sdim addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); 1902353358Sdim } 1903353358Sdim } else { 1904353358Sdim // Otherwise, add <sysroot>/usr/include. 1905353358Sdim SmallString<128> P(Sysroot); 1906353358Sdim llvm::sys::path::append(P, "usr", "include"); 1907353358Sdim addExternCSystemInclude(DriverArgs, CC1Args, P.str()); 1908353358Sdim } 1909353358Sdim} 1910353358Sdim 1911353358Sdimbool DarwinClang::AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, 1912353358Sdim llvm::opt::ArgStringList &CC1Args, 1913353358Sdim llvm::SmallString<128> Base, 1914353358Sdim llvm::StringRef Version, 1915353358Sdim llvm::StringRef ArchDir, 1916353358Sdim llvm::StringRef BitDir) const { 1917353358Sdim llvm::sys::path::append(Base, Version); 1918353358Sdim 1919353358Sdim // Add the base dir 1920353358Sdim addSystemInclude(DriverArgs, CC1Args, Base); 1921353358Sdim 1922353358Sdim // Add the multilib dirs 1923353358Sdim { 1924353358Sdim llvm::SmallString<128> P = Base; 1925353358Sdim if (!ArchDir.empty()) 1926353358Sdim llvm::sys::path::append(P, ArchDir); 1927353358Sdim if (!BitDir.empty()) 1928353358Sdim llvm::sys::path::append(P, BitDir); 1929353358Sdim addSystemInclude(DriverArgs, CC1Args, P); 1930353358Sdim } 1931353358Sdim 1932353358Sdim // Add the backward dir 1933353358Sdim { 1934353358Sdim llvm::SmallString<128> P = Base; 1935353358Sdim llvm::sys::path::append(P, "backward"); 1936353358Sdim addSystemInclude(DriverArgs, CC1Args, P); 1937353358Sdim } 1938353358Sdim 1939353358Sdim return getVFS().exists(Base); 1940353358Sdim} 1941353358Sdim 1942344779Sdimvoid DarwinClang::AddClangCXXStdlibIncludeArgs( 1943344779Sdim const llvm::opt::ArgList &DriverArgs, 1944344779Sdim llvm::opt::ArgStringList &CC1Args) const { 1945344779Sdim // The implementation from a base class will pass through the -stdlib to 1946344779Sdim // CC1Args. 1947344779Sdim // FIXME: this should not be necessary, remove usages in the frontend 1948344779Sdim // (e.g. HeaderSearchOptions::UseLibcxx) and don't pipe -stdlib. 1949353358Sdim // Also check whether this is used for setting library search paths. 1950344779Sdim ToolChain::AddClangCXXStdlibIncludeArgs(DriverArgs, CC1Args); 1951344779Sdim 1952344779Sdim if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 1953344779Sdim DriverArgs.hasArg(options::OPT_nostdincxx)) 1954344779Sdim return; 1955344779Sdim 1956353358Sdim llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs); 1957353358Sdim 1958344779Sdim switch (GetCXXStdlibType(DriverArgs)) { 1959344779Sdim case ToolChain::CST_Libcxx: { 1960353358Sdim // On Darwin, libc++ is installed alongside the compiler in 1961353358Sdim // include/c++/v1, so get from '<install>/bin' to '<install>/include/c++/v1'. 1962353358Sdim { 1963353358Sdim llvm::SmallString<128> P = llvm::StringRef(getDriver().getInstalledDir()); 1964353358Sdim // Note that P can be relative, so we have to '..' and not parent_path. 1965353358Sdim llvm::sys::path::append(P, "..", "include", "c++", "v1"); 1966353358Sdim addSystemInclude(DriverArgs, CC1Args, P); 1967353358Sdim } 1968353358Sdim // Also add <sysroot>/usr/include/c++/v1 unless -nostdinc is used, 1969353358Sdim // to match the legacy behavior in CC1. 1970353358Sdim if (!DriverArgs.hasArg(options::OPT_nostdinc)) { 1971353358Sdim llvm::SmallString<128> P = Sysroot; 1972353358Sdim llvm::sys::path::append(P, "usr", "include", "c++", "v1"); 1973353358Sdim addSystemInclude(DriverArgs, CC1Args, P); 1974353358Sdim } 1975344779Sdim break; 1976344779Sdim } 1977353358Sdim 1978344779Sdim case ToolChain::CST_Libstdcxx: 1979353358Sdim llvm::SmallString<128> UsrIncludeCxx = Sysroot; 1980353358Sdim llvm::sys::path::append(UsrIncludeCxx, "usr", "include", "c++"); 1981353358Sdim 1982353358Sdim llvm::Triple::ArchType arch = getTriple().getArch(); 1983353358Sdim bool IsBaseFound = true; 1984353358Sdim switch (arch) { 1985353358Sdim default: break; 1986353358Sdim 1987353358Sdim case llvm::Triple::ppc: 1988353358Sdim case llvm::Triple::ppc64: 1989353358Sdim IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 1990353358Sdim "4.2.1", 1991353358Sdim "powerpc-apple-darwin10", 1992353358Sdim arch == llvm::Triple::ppc64 ? "ppc64" : ""); 1993353358Sdim IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 1994353358Sdim "4.0.0", "powerpc-apple-darwin10", 1995353358Sdim arch == llvm::Triple::ppc64 ? "ppc64" : ""); 1996353358Sdim break; 1997353358Sdim 1998353358Sdim case llvm::Triple::x86: 1999353358Sdim case llvm::Triple::x86_64: 2000353358Sdim IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2001353358Sdim "4.2.1", 2002353358Sdim "i686-apple-darwin10", 2003353358Sdim arch == llvm::Triple::x86_64 ? "x86_64" : ""); 2004353358Sdim IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2005353358Sdim "4.0.0", "i686-apple-darwin8", 2006353358Sdim ""); 2007353358Sdim break; 2008353358Sdim 2009353358Sdim case llvm::Triple::arm: 2010353358Sdim case llvm::Triple::thumb: 2011353358Sdim IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2012353358Sdim "4.2.1", 2013353358Sdim "arm-apple-darwin10", 2014353358Sdim "v7"); 2015353358Sdim IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2016353358Sdim "4.2.1", 2017353358Sdim "arm-apple-darwin10", 2018353358Sdim "v6"); 2019353358Sdim break; 2020353358Sdim 2021353358Sdim case llvm::Triple::aarch64: 2022353358Sdim IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, 2023353358Sdim "4.2.1", 2024353358Sdim "arm64-apple-darwin10", 2025353358Sdim ""); 2026353358Sdim break; 2027353358Sdim } 2028353358Sdim 2029353358Sdim if (!IsBaseFound) { 2030353358Sdim getDriver().Diag(diag::warn_drv_libstdcxx_not_found); 2031353358Sdim } 2032353358Sdim 2033344779Sdim break; 2034344779Sdim } 2035344779Sdim} 2036317019Sdimvoid DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args, 2037317019Sdim ArgStringList &CmdArgs) const { 2038317019Sdim CXXStdlibType Type = GetCXXStdlibType(Args); 2039317019Sdim 2040317019Sdim switch (Type) { 2041317019Sdim case ToolChain::CST_Libcxx: 2042317019Sdim CmdArgs.push_back("-lc++"); 2043317019Sdim break; 2044317019Sdim 2045317019Sdim case ToolChain::CST_Libstdcxx: 2046317019Sdim // Unfortunately, -lstdc++ doesn't always exist in the standard search path; 2047317019Sdim // it was previously found in the gcc lib dir. However, for all the Darwin 2048317019Sdim // platforms we care about it was -lstdc++.6, so we search for that 2049317019Sdim // explicitly if we can't see an obvious -lstdc++ candidate. 2050317019Sdim 2051317019Sdim // Check in the sysroot first. 2052317019Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 2053317019Sdim SmallString<128> P(A->getValue()); 2054317019Sdim llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib"); 2055317019Sdim 2056317019Sdim if (!getVFS().exists(P)) { 2057317019Sdim llvm::sys::path::remove_filename(P); 2058317019Sdim llvm::sys::path::append(P, "libstdc++.6.dylib"); 2059317019Sdim if (getVFS().exists(P)) { 2060317019Sdim CmdArgs.push_back(Args.MakeArgString(P)); 2061317019Sdim return; 2062317019Sdim } 2063317019Sdim } 2064317019Sdim } 2065317019Sdim 2066317019Sdim // Otherwise, look in the root. 2067317019Sdim // FIXME: This should be removed someday when we don't have to care about 2068317019Sdim // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist. 2069317019Sdim if (!getVFS().exists("/usr/lib/libstdc++.dylib") && 2070317019Sdim getVFS().exists("/usr/lib/libstdc++.6.dylib")) { 2071317019Sdim CmdArgs.push_back("/usr/lib/libstdc++.6.dylib"); 2072317019Sdim return; 2073317019Sdim } 2074317019Sdim 2075317019Sdim // Otherwise, let the linker search. 2076317019Sdim CmdArgs.push_back("-lstdc++"); 2077317019Sdim break; 2078317019Sdim } 2079317019Sdim} 2080317019Sdim 2081317019Sdimvoid DarwinClang::AddCCKextLibArgs(const ArgList &Args, 2082317019Sdim ArgStringList &CmdArgs) const { 2083317019Sdim // For Darwin platforms, use the compiler-rt-based support library 2084317019Sdim // instead of the gcc-provided one (which is also incidentally 2085317019Sdim // only present in the gcc lib dir, which makes it hard to find). 2086317019Sdim 2087317019Sdim SmallString<128> P(getDriver().ResourceDir); 2088317019Sdim llvm::sys::path::append(P, "lib", "darwin"); 2089317019Sdim 2090317019Sdim // Use the newer cc_kext for iOS ARM after 6.0. 2091317019Sdim if (isTargetWatchOS()) { 2092317019Sdim llvm::sys::path::append(P, "libclang_rt.cc_kext_watchos.a"); 2093317019Sdim } else if (isTargetTvOS()) { 2094317019Sdim llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a"); 2095317019Sdim } else if (isTargetIPhoneOS()) { 2096317019Sdim llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a"); 2097317019Sdim } else { 2098317019Sdim llvm::sys::path::append(P, "libclang_rt.cc_kext.a"); 2099317019Sdim } 2100317019Sdim 2101317019Sdim // For now, allow missing resource libraries to support developers who may 2102317019Sdim // not have compiler-rt checked out or integrated into their build. 2103317019Sdim if (getVFS().exists(P)) 2104317019Sdim CmdArgs.push_back(Args.MakeArgString(P)); 2105317019Sdim} 2106317019Sdim 2107317019SdimDerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args, 2108317019Sdim StringRef BoundArch, 2109317019Sdim Action::OffloadKind) const { 2110317019Sdim DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); 2111317019Sdim const OptTable &Opts = getDriver().getOpts(); 2112317019Sdim 2113317019Sdim // FIXME: We really want to get out of the tool chain level argument 2114317019Sdim // translation business, as it makes the driver functionality much 2115317019Sdim // more opaque. For now, we follow gcc closely solely for the 2116317019Sdim // purpose of easily achieving feature parity & testability. Once we 2117317019Sdim // have something that works, we should reevaluate each translation 2118317019Sdim // and try to push it down into tool specific logic. 2119317019Sdim 2120317019Sdim for (Arg *A : Args) { 2121317019Sdim if (A->getOption().matches(options::OPT_Xarch__)) { 2122317019Sdim // Skip this argument unless the architecture matches either the toolchain 2123317019Sdim // triple arch, or the arch being bound. 2124317019Sdim llvm::Triple::ArchType XarchArch = 2125317019Sdim tools::darwin::getArchTypeForMachOArchName(A->getValue(0)); 2126317019Sdim if (!(XarchArch == getArch() || 2127317019Sdim (!BoundArch.empty() && 2128317019Sdim XarchArch == 2129317019Sdim tools::darwin::getArchTypeForMachOArchName(BoundArch)))) 2130317019Sdim continue; 2131317019Sdim 2132317019Sdim Arg *OriginalArg = A; 2133317019Sdim unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1)); 2134317019Sdim unsigned Prev = Index; 2135317019Sdim std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index)); 2136317019Sdim 2137317019Sdim // If the argument parsing failed or more than one argument was 2138317019Sdim // consumed, the -Xarch_ argument's parameter tried to consume 2139317019Sdim // extra arguments. Emit an error and ignore. 2140317019Sdim // 2141317019Sdim // We also want to disallow any options which would alter the 2142317019Sdim // driver behavior; that isn't going to work in our model. We 2143317019Sdim // use isDriverOption() as an approximation, although things 2144317019Sdim // like -O4 are going to slip through. 2145317019Sdim if (!XarchArg || Index > Prev + 1) { 2146317019Sdim getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args) 2147317019Sdim << A->getAsString(Args); 2148317019Sdim continue; 2149317019Sdim } else if (XarchArg->getOption().hasFlag(options::DriverOption)) { 2150317019Sdim getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver) 2151317019Sdim << A->getAsString(Args); 2152317019Sdim continue; 2153317019Sdim } 2154317019Sdim 2155317019Sdim XarchArg->setBaseArg(A); 2156317019Sdim 2157317019Sdim A = XarchArg.release(); 2158317019Sdim DAL->AddSynthesizedArg(A); 2159317019Sdim 2160317019Sdim // Linker input arguments require custom handling. The problem is that we 2161317019Sdim // have already constructed the phase actions, so we can not treat them as 2162317019Sdim // "input arguments". 2163317019Sdim if (A->getOption().hasFlag(options::LinkerInput)) { 2164317019Sdim // Convert the argument into individual Zlinker_input_args. 2165317019Sdim for (const char *Value : A->getValues()) { 2166317019Sdim DAL->AddSeparateArg( 2167317019Sdim OriginalArg, Opts.getOption(options::OPT_Zlinker_input), Value); 2168317019Sdim } 2169317019Sdim continue; 2170317019Sdim } 2171317019Sdim } 2172317019Sdim 2173317019Sdim // Sob. These is strictly gcc compatible for the time being. Apple 2174317019Sdim // gcc translates options twice, which means that self-expanding 2175317019Sdim // options add duplicates. 2176317019Sdim switch ((options::ID)A->getOption().getID()) { 2177317019Sdim default: 2178317019Sdim DAL->append(A); 2179317019Sdim break; 2180317019Sdim 2181317019Sdim case options::OPT_mkernel: 2182317019Sdim case options::OPT_fapple_kext: 2183317019Sdim DAL->append(A); 2184317019Sdim DAL->AddFlagArg(A, Opts.getOption(options::OPT_static)); 2185317019Sdim break; 2186317019Sdim 2187317019Sdim case options::OPT_dependency_file: 2188317019Sdim DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue()); 2189317019Sdim break; 2190317019Sdim 2191317019Sdim case options::OPT_gfull: 2192317019Sdim DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); 2193317019Sdim DAL->AddFlagArg( 2194317019Sdim A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)); 2195317019Sdim break; 2196317019Sdim 2197317019Sdim case options::OPT_gused: 2198317019Sdim DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); 2199317019Sdim DAL->AddFlagArg( 2200317019Sdim A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols)); 2201317019Sdim break; 2202317019Sdim 2203317019Sdim case options::OPT_shared: 2204317019Sdim DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib)); 2205317019Sdim break; 2206317019Sdim 2207317019Sdim case options::OPT_fconstant_cfstrings: 2208317019Sdim DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings)); 2209317019Sdim break; 2210317019Sdim 2211317019Sdim case options::OPT_fno_constant_cfstrings: 2212317019Sdim DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings)); 2213317019Sdim break; 2214317019Sdim 2215317019Sdim case options::OPT_Wnonportable_cfstrings: 2216317019Sdim DAL->AddFlagArg(A, 2217317019Sdim Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)); 2218317019Sdim break; 2219317019Sdim 2220317019Sdim case options::OPT_Wno_nonportable_cfstrings: 2221317019Sdim DAL->AddFlagArg( 2222317019Sdim A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)); 2223317019Sdim break; 2224317019Sdim 2225317019Sdim case options::OPT_fpascal_strings: 2226317019Sdim DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings)); 2227317019Sdim break; 2228317019Sdim 2229317019Sdim case options::OPT_fno_pascal_strings: 2230317019Sdim DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings)); 2231317019Sdim break; 2232317019Sdim } 2233317019Sdim } 2234317019Sdim 2235360784Sdim if (getTriple().isX86()) 2236317019Sdim if (!Args.hasArgNoClaim(options::OPT_mtune_EQ)) 2237317019Sdim DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_mtune_EQ), 2238317019Sdim "core2"); 2239317019Sdim 2240317019Sdim // Add the arch options based on the particular spelling of -arch, to match 2241317019Sdim // how the driver driver works. 2242317019Sdim if (!BoundArch.empty()) { 2243317019Sdim StringRef Name = BoundArch; 2244317019Sdim const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ); 2245317019Sdim const Option MArch = Opts.getOption(clang::driver::options::OPT_march_EQ); 2246317019Sdim 2247317019Sdim // This code must be kept in sync with LLVM's getArchTypeForDarwinArch, 2248317019Sdim // which defines the list of which architectures we accept. 2249317019Sdim if (Name == "ppc") 2250317019Sdim ; 2251317019Sdim else if (Name == "ppc601") 2252317019Sdim DAL->AddJoinedArg(nullptr, MCpu, "601"); 2253317019Sdim else if (Name == "ppc603") 2254317019Sdim DAL->AddJoinedArg(nullptr, MCpu, "603"); 2255317019Sdim else if (Name == "ppc604") 2256317019Sdim DAL->AddJoinedArg(nullptr, MCpu, "604"); 2257317019Sdim else if (Name == "ppc604e") 2258317019Sdim DAL->AddJoinedArg(nullptr, MCpu, "604e"); 2259317019Sdim else if (Name == "ppc750") 2260317019Sdim DAL->AddJoinedArg(nullptr, MCpu, "750"); 2261317019Sdim else if (Name == "ppc7400") 2262317019Sdim DAL->AddJoinedArg(nullptr, MCpu, "7400"); 2263317019Sdim else if (Name == "ppc7450") 2264317019Sdim DAL->AddJoinedArg(nullptr, MCpu, "7450"); 2265317019Sdim else if (Name == "ppc970") 2266317019Sdim DAL->AddJoinedArg(nullptr, MCpu, "970"); 2267317019Sdim 2268317019Sdim else if (Name == "ppc64" || Name == "ppc64le") 2269317019Sdim DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64)); 2270317019Sdim 2271317019Sdim else if (Name == "i386") 2272317019Sdim ; 2273317019Sdim else if (Name == "i486") 2274317019Sdim DAL->AddJoinedArg(nullptr, MArch, "i486"); 2275317019Sdim else if (Name == "i586") 2276317019Sdim DAL->AddJoinedArg(nullptr, MArch, "i586"); 2277317019Sdim else if (Name == "i686") 2278317019Sdim DAL->AddJoinedArg(nullptr, MArch, "i686"); 2279317019Sdim else if (Name == "pentium") 2280317019Sdim DAL->AddJoinedArg(nullptr, MArch, "pentium"); 2281317019Sdim else if (Name == "pentium2") 2282317019Sdim DAL->AddJoinedArg(nullptr, MArch, "pentium2"); 2283317019Sdim else if (Name == "pentpro") 2284317019Sdim DAL->AddJoinedArg(nullptr, MArch, "pentiumpro"); 2285317019Sdim else if (Name == "pentIIm3") 2286317019Sdim DAL->AddJoinedArg(nullptr, MArch, "pentium2"); 2287317019Sdim 2288344779Sdim else if (Name == "x86_64" || Name == "x86_64h") 2289317019Sdim DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64)); 2290317019Sdim 2291317019Sdim else if (Name == "arm") 2292317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv4t"); 2293317019Sdim else if (Name == "armv4t") 2294317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv4t"); 2295317019Sdim else if (Name == "armv5") 2296317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv5tej"); 2297317019Sdim else if (Name == "xscale") 2298317019Sdim DAL->AddJoinedArg(nullptr, MArch, "xscale"); 2299317019Sdim else if (Name == "armv6") 2300317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv6k"); 2301317019Sdim else if (Name == "armv6m") 2302317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv6m"); 2303317019Sdim else if (Name == "armv7") 2304317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv7a"); 2305317019Sdim else if (Name == "armv7em") 2306317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv7em"); 2307317019Sdim else if (Name == "armv7k") 2308317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv7k"); 2309317019Sdim else if (Name == "armv7m") 2310317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv7m"); 2311317019Sdim else if (Name == "armv7s") 2312317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv7s"); 2313317019Sdim } 2314317019Sdim 2315317019Sdim return DAL; 2316317019Sdim} 2317317019Sdim 2318317019Sdimvoid MachO::AddLinkRuntimeLibArgs(const ArgList &Args, 2319353358Sdim ArgStringList &CmdArgs, 2320353358Sdim bool ForceLinkBuiltinRT) const { 2321317019Sdim // Embedded targets are simple at the moment, not supporting sanitizers and 2322317019Sdim // with different libraries for each member of the product { static, PIC } x 2323317019Sdim // { hard-float, soft-float } 2324344779Sdim llvm::SmallString<32> CompilerRT = StringRef(""); 2325317019Sdim CompilerRT += 2326317019Sdim (tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard) 2327317019Sdim ? "hard" 2328317019Sdim : "soft"; 2329344779Sdim CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic" : "_static"; 2330317019Sdim 2331327952Sdim AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, RLO_IsEmbedded); 2332317019Sdim} 2333317019Sdim 2334320572Sdimbool Darwin::isAlignedAllocationUnavailable() const { 2335327952Sdim llvm::Triple::OSType OS; 2336327952Sdim 2337320572Sdim switch (TargetPlatform) { 2338320572Sdim case MacOS: // Earlier than 10.13. 2339327952Sdim OS = llvm::Triple::MacOSX; 2340327952Sdim break; 2341320572Sdim case IPhoneOS: 2342327952Sdim OS = llvm::Triple::IOS; 2343327952Sdim break; 2344327952Sdim case TvOS: // Earlier than 11.0. 2345327952Sdim OS = llvm::Triple::TvOS; 2346327952Sdim break; 2347327952Sdim case WatchOS: // Earlier than 4.0. 2348327952Sdim OS = llvm::Triple::WatchOS; 2349327952Sdim break; 2350320572Sdim } 2351327952Sdim 2352327952Sdim return TargetVersion < alignedAllocMinVersion(OS); 2353320572Sdim} 2354320572Sdim 2355320572Sdimvoid Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 2356320970Sdim llvm::opt::ArgStringList &CC1Args, 2357320970Sdim Action::OffloadKind DeviceOffloadKind) const { 2358341825Sdim // Pass "-faligned-alloc-unavailable" only when the user hasn't manually 2359341825Sdim // enabled or disabled aligned allocations. 2360341825Sdim if (!DriverArgs.hasArgNoClaim(options::OPT_faligned_allocation, 2361341825Sdim options::OPT_fno_aligned_allocation) && 2362341825Sdim isAlignedAllocationUnavailable()) 2363320572Sdim CC1Args.push_back("-faligned-alloc-unavailable"); 2364344779Sdim 2365344779Sdim if (SDKInfo) { 2366344779Sdim /// Pass the SDK version to the compiler when the SDK information is 2367344779Sdim /// available. 2368344779Sdim std::string Arg; 2369344779Sdim llvm::raw_string_ostream OS(Arg); 2370344779Sdim OS << "-target-sdk-version=" << SDKInfo->getVersion(); 2371344779Sdim CC1Args.push_back(DriverArgs.MakeArgString(OS.str())); 2372344779Sdim } 2373320572Sdim} 2374320572Sdim 2375317019SdimDerivedArgList * 2376317019SdimDarwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch, 2377317019Sdim Action::OffloadKind DeviceOffloadKind) const { 2378317019Sdim // First get the generic Apple args, before moving onto Darwin-specific ones. 2379317019Sdim DerivedArgList *DAL = 2380317019Sdim MachO::TranslateArgs(Args, BoundArch, DeviceOffloadKind); 2381317019Sdim const OptTable &Opts = getDriver().getOpts(); 2382317019Sdim 2383317019Sdim // If no architecture is bound, none of the translations here are relevant. 2384317019Sdim if (BoundArch.empty()) 2385317019Sdim return DAL; 2386317019Sdim 2387317019Sdim // Add an explicit version min argument for the deployment target. We do this 2388317019Sdim // after argument translation because -Xarch_ arguments may add a version min 2389317019Sdim // argument. 2390317019Sdim AddDeploymentTarget(*DAL); 2391317019Sdim 2392317019Sdim // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext. 2393317019Sdim // FIXME: It would be far better to avoid inserting those -static arguments, 2394317019Sdim // but we can't check the deployment target in the translation code until 2395317019Sdim // it is set here. 2396317019Sdim if (isTargetWatchOSBased() || 2397317019Sdim (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) { 2398317019Sdim for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) { 2399317019Sdim Arg *A = *it; 2400317019Sdim ++it; 2401317019Sdim if (A->getOption().getID() != options::OPT_mkernel && 2402317019Sdim A->getOption().getID() != options::OPT_fapple_kext) 2403317019Sdim continue; 2404317019Sdim assert(it != ie && "unexpected argument translation"); 2405317019Sdim A = *it; 2406317019Sdim assert(A->getOption().getID() == options::OPT_static && 2407317019Sdim "missing expected -static argument"); 2408317019Sdim *it = nullptr; 2409317019Sdim ++it; 2410317019Sdim } 2411317019Sdim } 2412317019Sdim 2413317019Sdim if (!Args.getLastArg(options::OPT_stdlib_EQ) && 2414317019Sdim GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) 2415317019Sdim DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_stdlib_EQ), 2416317019Sdim "libc++"); 2417317019Sdim 2418317019Sdim // Validate the C++ standard library choice. 2419317019Sdim CXXStdlibType Type = GetCXXStdlibType(*DAL); 2420317019Sdim if (Type == ToolChain::CST_Libcxx) { 2421317019Sdim // Check whether the target provides libc++. 2422317019Sdim StringRef where; 2423317019Sdim 2424317019Sdim // Complain about targeting iOS < 5.0 in any way. 2425317019Sdim if (isTargetIOSBased() && isIPhoneOSVersionLT(5, 0)) 2426317019Sdim where = "iOS 5.0"; 2427317019Sdim 2428317019Sdim if (where != StringRef()) { 2429317019Sdim getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment) << where; 2430317019Sdim } 2431317019Sdim } 2432317019Sdim 2433317019Sdim auto Arch = tools::darwin::getArchTypeForMachOArchName(BoundArch); 2434317019Sdim if ((Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)) { 2435317019Sdim if (Args.hasFlag(options::OPT_fomit_frame_pointer, 2436317019Sdim options::OPT_fno_omit_frame_pointer, false)) 2437317019Sdim getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target) 2438317019Sdim << "-fomit-frame-pointer" << BoundArch; 2439317019Sdim } 2440317019Sdim 2441317019Sdim return DAL; 2442317019Sdim} 2443317019Sdim 2444322740Sdimbool MachO::IsUnwindTablesDefault(const ArgList &Args) const { 2445322855Sdim // Unwind tables are not emitted if -fno-exceptions is supplied (except when 2446322855Sdim // targeting x86_64). 2447322855Sdim return getArch() == llvm::Triple::x86_64 || 2448327952Sdim (GetExceptionModel(Args) != llvm::ExceptionHandling::SjLj && 2449322855Sdim Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, 2450322855Sdim true)); 2451317019Sdim} 2452317019Sdim 2453317019Sdimbool MachO::UseDwarfDebugFlags() const { 2454317019Sdim if (const char *S = ::getenv("RC_DEBUG_OPTIONS")) 2455317019Sdim return S[0] != '\0'; 2456317019Sdim return false; 2457317019Sdim} 2458317019Sdim 2459327952Sdimllvm::ExceptionHandling Darwin::GetExceptionModel(const ArgList &Args) const { 2460317019Sdim // Darwin uses SjLj exceptions on ARM. 2461317019Sdim if (getTriple().getArch() != llvm::Triple::arm && 2462317019Sdim getTriple().getArch() != llvm::Triple::thumb) 2463327952Sdim return llvm::ExceptionHandling::None; 2464317019Sdim 2465317019Sdim // Only watchOS uses the new DWARF/Compact unwinding method. 2466317019Sdim llvm::Triple Triple(ComputeLLVMTriple(Args)); 2467344779Sdim if (Triple.isWatchABI()) 2468327952Sdim return llvm::ExceptionHandling::DwarfCFI; 2469327952Sdim 2470327952Sdim return llvm::ExceptionHandling::SjLj; 2471317019Sdim} 2472317019Sdim 2473317019Sdimbool Darwin::SupportsEmbeddedBitcode() const { 2474317019Sdim assert(TargetInitialized && "Target not initialized!"); 2475317019Sdim if (isTargetIPhoneOS() && isIPhoneOSVersionLT(6, 0)) 2476317019Sdim return false; 2477317019Sdim return true; 2478317019Sdim} 2479317019Sdim 2480317019Sdimbool MachO::isPICDefault() const { return true; } 2481317019Sdim 2482317019Sdimbool MachO::isPIEDefault() const { return false; } 2483317019Sdim 2484317019Sdimbool MachO::isPICDefaultForced() const { 2485317019Sdim return (getArch() == llvm::Triple::x86_64 || 2486317019Sdim getArch() == llvm::Triple::aarch64); 2487317019Sdim} 2488317019Sdim 2489317019Sdimbool MachO::SupportsProfiling() const { 2490317019Sdim // Profiling instrumentation is only supported on x86. 2491360784Sdim return getTriple().isX86(); 2492317019Sdim} 2493317019Sdim 2494317019Sdimvoid Darwin::addMinVersionArgs(const ArgList &Args, 2495317019Sdim ArgStringList &CmdArgs) const { 2496317019Sdim VersionTuple TargetVersion = getTargetVersion(); 2497317019Sdim 2498317019Sdim if (isTargetWatchOS()) 2499317019Sdim CmdArgs.push_back("-watchos_version_min"); 2500317019Sdim else if (isTargetWatchOSSimulator()) 2501317019Sdim CmdArgs.push_back("-watchos_simulator_version_min"); 2502317019Sdim else if (isTargetTvOS()) 2503317019Sdim CmdArgs.push_back("-tvos_version_min"); 2504317019Sdim else if (isTargetTvOSSimulator()) 2505317019Sdim CmdArgs.push_back("-tvos_simulator_version_min"); 2506317019Sdim else if (isTargetIOSSimulator()) 2507317019Sdim CmdArgs.push_back("-ios_simulator_version_min"); 2508317019Sdim else if (isTargetIOSBased()) 2509317019Sdim CmdArgs.push_back("-iphoneos_version_min"); 2510317019Sdim else { 2511317019Sdim assert(isTargetMacOS() && "unexpected target"); 2512317019Sdim CmdArgs.push_back("-macosx_version_min"); 2513317019Sdim } 2514317019Sdim 2515317019Sdim CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); 2516317019Sdim} 2517317019Sdim 2518360784Sdimstatic const char *getPlatformName(Darwin::DarwinPlatformKind Platform, 2519360784Sdim Darwin::DarwinEnvironmentKind Environment) { 2520360784Sdim switch (Platform) { 2521360784Sdim case Darwin::MacOS: 2522360784Sdim return "macos"; 2523360784Sdim case Darwin::IPhoneOS: 2524360784Sdim if (Environment == Darwin::NativeEnvironment || 2525360784Sdim Environment == Darwin::Simulator) 2526360784Sdim return "ios"; 2527360784Sdim // FIXME: Add macCatalyst support here ("\"mac catalyst\""). 2528360784Sdim llvm_unreachable("macCatalyst isn't yet supported"); 2529360784Sdim case Darwin::TvOS: 2530360784Sdim return "tvos"; 2531360784Sdim case Darwin::WatchOS: 2532360784Sdim return "watchos"; 2533360784Sdim } 2534360784Sdim llvm_unreachable("invalid platform"); 2535360784Sdim} 2536360784Sdim 2537360784Sdimvoid Darwin::addPlatformVersionArgs(const llvm::opt::ArgList &Args, 2538360784Sdim llvm::opt::ArgStringList &CmdArgs) const { 2539360784Sdim // -platform_version <platform> <target_version> <sdk_version> 2540360784Sdim // Both the target and SDK version support only up to 3 components. 2541360784Sdim CmdArgs.push_back("-platform_version"); 2542360784Sdim std::string PlatformName = getPlatformName(TargetPlatform, TargetEnvironment); 2543360784Sdim if (TargetEnvironment == Darwin::Simulator) 2544360784Sdim PlatformName += "-simulator"; 2545360784Sdim CmdArgs.push_back(Args.MakeArgString(PlatformName)); 2546360784Sdim VersionTuple TargetVersion = getTargetVersion().withoutBuild(); 2547360784Sdim CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); 2548360784Sdim if (SDKInfo) { 2549360784Sdim VersionTuple SDKVersion = SDKInfo->getVersion().withoutBuild(); 2550360784Sdim CmdArgs.push_back(Args.MakeArgString(SDKVersion.getAsString())); 2551360784Sdim } else { 2552360784Sdim // Use a blank SDK version if it's not present. 2553360784Sdim CmdArgs.push_back("0.0.0"); 2554360784Sdim } 2555360784Sdim} 2556360784Sdim 2557317019Sdimvoid Darwin::addStartObjectFileArgs(const ArgList &Args, 2558317019Sdim ArgStringList &CmdArgs) const { 2559317019Sdim // Derived from startfile spec. 2560317019Sdim if (Args.hasArg(options::OPT_dynamiclib)) { 2561317019Sdim // Derived from darwin_dylib1 spec. 2562317019Sdim if (isTargetWatchOSBased()) { 2563317019Sdim ; // watchOS does not need dylib1.o. 2564317019Sdim } else if (isTargetIOSSimulator()) { 2565317019Sdim ; // iOS simulator does not need dylib1.o. 2566317019Sdim } else if (isTargetIPhoneOS()) { 2567317019Sdim if (isIPhoneOSVersionLT(3, 1)) 2568317019Sdim CmdArgs.push_back("-ldylib1.o"); 2569317019Sdim } else { 2570317019Sdim if (isMacosxVersionLT(10, 5)) 2571317019Sdim CmdArgs.push_back("-ldylib1.o"); 2572317019Sdim else if (isMacosxVersionLT(10, 6)) 2573317019Sdim CmdArgs.push_back("-ldylib1.10.5.o"); 2574317019Sdim } 2575317019Sdim } else { 2576317019Sdim if (Args.hasArg(options::OPT_bundle)) { 2577317019Sdim if (!Args.hasArg(options::OPT_static)) { 2578317019Sdim // Derived from darwin_bundle1 spec. 2579317019Sdim if (isTargetWatchOSBased()) { 2580317019Sdim ; // watchOS does not need bundle1.o. 2581317019Sdim } else if (isTargetIOSSimulator()) { 2582317019Sdim ; // iOS simulator does not need bundle1.o. 2583317019Sdim } else if (isTargetIPhoneOS()) { 2584317019Sdim if (isIPhoneOSVersionLT(3, 1)) 2585317019Sdim CmdArgs.push_back("-lbundle1.o"); 2586317019Sdim } else { 2587317019Sdim if (isMacosxVersionLT(10, 6)) 2588317019Sdim CmdArgs.push_back("-lbundle1.o"); 2589317019Sdim } 2590317019Sdim } 2591317019Sdim } else { 2592317019Sdim if (Args.hasArg(options::OPT_pg) && SupportsProfiling()) { 2593353358Sdim if (isTargetMacOS() && isMacosxVersionLT(10, 9)) { 2594353358Sdim if (Args.hasArg(options::OPT_static) || 2595353358Sdim Args.hasArg(options::OPT_object) || 2596353358Sdim Args.hasArg(options::OPT_preload)) { 2597353358Sdim CmdArgs.push_back("-lgcrt0.o"); 2598353358Sdim } else { 2599353358Sdim CmdArgs.push_back("-lgcrt1.o"); 2600353358Sdim 2601353358Sdim // darwin_crt2 spec is empty. 2602353358Sdim } 2603353358Sdim // By default on OS X 10.8 and later, we don't link with a crt1.o 2604353358Sdim // file and the linker knows to use _main as the entry point. But, 2605353358Sdim // when compiling with -pg, we need to link with the gcrt1.o file, 2606353358Sdim // so pass the -no_new_main option to tell the linker to use the 2607353358Sdim // "start" symbol as the entry point. 2608353358Sdim if (isTargetMacOS() && !isMacosxVersionLT(10, 8)) 2609353358Sdim CmdArgs.push_back("-no_new_main"); 2610317019Sdim } else { 2611353358Sdim getDriver().Diag(diag::err_drv_clang_unsupported_opt_pg_darwin) 2612353358Sdim << isTargetMacOS(); 2613317019Sdim } 2614317019Sdim } else { 2615317019Sdim if (Args.hasArg(options::OPT_static) || 2616317019Sdim Args.hasArg(options::OPT_object) || 2617317019Sdim Args.hasArg(options::OPT_preload)) { 2618317019Sdim CmdArgs.push_back("-lcrt0.o"); 2619317019Sdim } else { 2620317019Sdim // Derived from darwin_crt1 spec. 2621317019Sdim if (isTargetWatchOSBased()) { 2622317019Sdim ; // watchOS does not need crt1.o. 2623317019Sdim } else if (isTargetIOSSimulator()) { 2624317019Sdim ; // iOS simulator does not need crt1.o. 2625317019Sdim } else if (isTargetIPhoneOS()) { 2626317019Sdim if (getArch() == llvm::Triple::aarch64) 2627317019Sdim ; // iOS does not need any crt1 files for arm64 2628317019Sdim else if (isIPhoneOSVersionLT(3, 1)) 2629317019Sdim CmdArgs.push_back("-lcrt1.o"); 2630317019Sdim else if (isIPhoneOSVersionLT(6, 0)) 2631317019Sdim CmdArgs.push_back("-lcrt1.3.1.o"); 2632317019Sdim } else { 2633317019Sdim if (isMacosxVersionLT(10, 5)) 2634317019Sdim CmdArgs.push_back("-lcrt1.o"); 2635317019Sdim else if (isMacosxVersionLT(10, 6)) 2636317019Sdim CmdArgs.push_back("-lcrt1.10.5.o"); 2637317019Sdim else if (isMacosxVersionLT(10, 8)) 2638317019Sdim CmdArgs.push_back("-lcrt1.10.6.o"); 2639317019Sdim 2640317019Sdim // darwin_crt2 spec is empty. 2641317019Sdim } 2642317019Sdim } 2643317019Sdim } 2644317019Sdim } 2645317019Sdim } 2646317019Sdim 2647317019Sdim if (!isTargetIPhoneOS() && Args.hasArg(options::OPT_shared_libgcc) && 2648344779Sdim !isTargetWatchOS() && isMacosxVersionLT(10, 5)) { 2649317019Sdim const char *Str = Args.MakeArgString(GetFilePath("crt3.o")); 2650317019Sdim CmdArgs.push_back(Str); 2651317019Sdim } 2652317019Sdim} 2653317019Sdim 2654317019Sdimvoid Darwin::CheckObjCARC() const { 2655317019Sdim if (isTargetIOSBased() || isTargetWatchOSBased() || 2656317019Sdim (isTargetMacOS() && !isMacosxVersionLT(10, 6))) 2657317019Sdim return; 2658317019Sdim getDriver().Diag(diag::err_arc_unsupported_on_toolchain); 2659317019Sdim} 2660317019Sdim 2661317019SdimSanitizerMask Darwin::getSupportedSanitizers() const { 2662317019Sdim const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; 2663317019Sdim SanitizerMask Res = ToolChain::getSupportedSanitizers(); 2664317019Sdim Res |= SanitizerKind::Address; 2665353358Sdim Res |= SanitizerKind::PointerCompare; 2666353358Sdim Res |= SanitizerKind::PointerSubtract; 2667317472Sdim Res |= SanitizerKind::Leak; 2668317472Sdim Res |= SanitizerKind::Fuzzer; 2669327952Sdim Res |= SanitizerKind::FuzzerNoLink; 2670327952Sdim Res |= SanitizerKind::Function; 2671344779Sdim 2672344779Sdim // Prior to 10.9, macOS shipped a version of the C++ standard library without 2673344779Sdim // C++11 support. The same is true of iOS prior to version 5. These OS'es are 2674344779Sdim // incompatible with -fsanitize=vptr. 2675344779Sdim if (!(isTargetMacOS() && isMacosxVersionLT(10, 9)) 2676344779Sdim && !(isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0))) 2677344779Sdim Res |= SanitizerKind::Vptr; 2678344779Sdim 2679317019Sdim if (isTargetMacOS()) { 2680317019Sdim if (IsX86_64) 2681317019Sdim Res |= SanitizerKind::Thread; 2682317019Sdim } else if (isTargetIOSSimulator() || isTargetTvOSSimulator()) { 2683317019Sdim if (IsX86_64) 2684317019Sdim Res |= SanitizerKind::Thread; 2685317019Sdim } 2686317019Sdim return Res; 2687317019Sdim} 2688317019Sdim 2689317019Sdimvoid Darwin::printVerboseInfo(raw_ostream &OS) const { 2690317019Sdim CudaInstallation.print(OS); 2691317019Sdim} 2692