Darwin.cpp revision 317019
1317019Sdim//===--- Darwin.cpp - Darwin Tool and ToolChain Implementations -*- C++ -*-===// 2317019Sdim// 3317019Sdim// The LLVM Compiler Infrastructure 4317019Sdim// 5317019Sdim// This file is distributed under the University of Illinois Open Source 6317019Sdim// License. See LICENSE.TXT for details. 7317019Sdim// 8317019Sdim//===----------------------------------------------------------------------===// 9317019Sdim 10317019Sdim#include "Darwin.h" 11317019Sdim#include "Arch/ARM.h" 12317019Sdim#include "CommonArgs.h" 13317019Sdim#include "clang/Basic/ObjCRuntime.h" 14317019Sdim#include "clang/Basic/VirtualFileSystem.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" 22317019Sdim#include "llvm/Support/Path.h" 23317019Sdim#include "llvm/Support/ScopedPrinter.h" 24317019Sdim#include "llvm/Support/TargetParser.h" 25317019Sdim#include <cstdlib> // ::getenv 26317019Sdim 27317019Sdimusing namespace clang::driver; 28317019Sdimusing namespace clang::driver::tools; 29317019Sdimusing namespace clang::driver::toolchains; 30317019Sdimusing namespace clang; 31317019Sdimusing namespace llvm::opt; 32317019Sdim 33317019Sdimllvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) { 34317019Sdim // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for 35317019Sdim // archs which Darwin doesn't use. 36317019Sdim 37317019Sdim // The matching this routine does is fairly pointless, since it is neither the 38317019Sdim // complete architecture list, nor a reasonable subset. The problem is that 39317019Sdim // historically the driver driver accepts this and also ties its -march= 40317019Sdim // handling to the architecture name, so we need to be careful before removing 41317019Sdim // support for it. 42317019Sdim 43317019Sdim // This code must be kept in sync with Clang's Darwin specific argument 44317019Sdim // translation. 45317019Sdim 46317019Sdim return llvm::StringSwitch<llvm::Triple::ArchType>(Str) 47317019Sdim .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc) 48317019Sdim .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc) 49317019Sdim .Case("ppc64", llvm::Triple::ppc64) 50317019Sdim .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86) 51317019Sdim .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4", 52317019Sdim llvm::Triple::x86) 53317019Sdim .Cases("x86_64", "x86_64h", llvm::Triple::x86_64) 54317019Sdim // This is derived from the driver driver. 55317019Sdim .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm) 56317019Sdim .Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm) 57317019Sdim .Cases("armv7s", "xscale", llvm::Triple::arm) 58317019Sdim .Case("arm64", llvm::Triple::aarch64) 59317019Sdim .Case("r600", llvm::Triple::r600) 60317019Sdim .Case("amdgcn", llvm::Triple::amdgcn) 61317019Sdim .Case("nvptx", llvm::Triple::nvptx) 62317019Sdim .Case("nvptx64", llvm::Triple::nvptx64) 63317019Sdim .Case("amdil", llvm::Triple::amdil) 64317019Sdim .Case("spir", llvm::Triple::spir) 65317019Sdim .Default(llvm::Triple::UnknownArch); 66317019Sdim} 67317019Sdim 68317019Sdimvoid darwin::setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str) { 69317019Sdim const llvm::Triple::ArchType Arch = getArchTypeForMachOArchName(Str); 70317019Sdim unsigned ArchKind = llvm::ARM::parseArch(Str); 71317019Sdim T.setArch(Arch); 72317019Sdim 73317019Sdim if (Str == "x86_64h") 74317019Sdim T.setArchName(Str); 75317019Sdim else if (ArchKind == llvm::ARM::AK_ARMV6M || 76317019Sdim ArchKind == llvm::ARM::AK_ARMV7M || 77317019Sdim ArchKind == llvm::ARM::AK_ARMV7EM) { 78317019Sdim T.setOS(llvm::Triple::UnknownOS); 79317019Sdim T.setObjectFormat(llvm::Triple::MachO); 80317019Sdim } 81317019Sdim} 82317019Sdim 83317019Sdimvoid darwin::Assembler::ConstructJob(Compilation &C, const JobAction &JA, 84317019Sdim const InputInfo &Output, 85317019Sdim const InputInfoList &Inputs, 86317019Sdim const ArgList &Args, 87317019Sdim const char *LinkingOutput) const { 88317019Sdim ArgStringList CmdArgs; 89317019Sdim 90317019Sdim assert(Inputs.size() == 1 && "Unexpected number of inputs."); 91317019Sdim const InputInfo &Input = Inputs[0]; 92317019Sdim 93317019Sdim // Determine the original source input. 94317019Sdim const Action *SourceAction = &JA; 95317019Sdim while (SourceAction->getKind() != Action::InputClass) { 96317019Sdim assert(!SourceAction->getInputs().empty() && "unexpected root action!"); 97317019Sdim SourceAction = SourceAction->getInputs()[0]; 98317019Sdim } 99317019Sdim 100317019Sdim // If -fno-integrated-as is used add -Q to the darwin assember driver to make 101317019Sdim // sure it runs its system assembler not clang's integrated assembler. 102317019Sdim // Applicable to darwin11+ and Xcode 4+. darwin<10 lacked integrated-as. 103317019Sdim // FIXME: at run-time detect assembler capabilities or rely on version 104317019Sdim // information forwarded by -target-assembler-version. 105317019Sdim if (Args.hasArg(options::OPT_fno_integrated_as)) { 106317019Sdim const llvm::Triple &T(getToolChain().getTriple()); 107317019Sdim if (!(T.isMacOSX() && T.isMacOSXVersionLT(10, 7))) 108317019Sdim CmdArgs.push_back("-Q"); 109317019Sdim } 110317019Sdim 111317019Sdim // Forward -g, assuming we are dealing with an actual assembly file. 112317019Sdim if (SourceAction->getType() == types::TY_Asm || 113317019Sdim SourceAction->getType() == types::TY_PP_Asm) { 114317019Sdim if (Args.hasArg(options::OPT_gstabs)) 115317019Sdim CmdArgs.push_back("--gstabs"); 116317019Sdim else if (Args.hasArg(options::OPT_g_Group)) 117317019Sdim CmdArgs.push_back("-g"); 118317019Sdim } 119317019Sdim 120317019Sdim // Derived from asm spec. 121317019Sdim AddMachOArch(Args, CmdArgs); 122317019Sdim 123317019Sdim // Use -force_cpusubtype_ALL on x86 by default. 124317019Sdim if (getToolChain().getArch() == llvm::Triple::x86 || 125317019Sdim getToolChain().getArch() == llvm::Triple::x86_64 || 126317019Sdim Args.hasArg(options::OPT_force__cpusubtype__ALL)) 127317019Sdim CmdArgs.push_back("-force_cpusubtype_ALL"); 128317019Sdim 129317019Sdim if (getToolChain().getArch() != llvm::Triple::x86_64 && 130317019Sdim (((Args.hasArg(options::OPT_mkernel) || 131317019Sdim Args.hasArg(options::OPT_fapple_kext)) && 132317019Sdim getMachOToolChain().isKernelStatic()) || 133317019Sdim Args.hasArg(options::OPT_static))) 134317019Sdim CmdArgs.push_back("-static"); 135317019Sdim 136317019Sdim Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); 137317019Sdim 138317019Sdim assert(Output.isFilename() && "Unexpected lipo output."); 139317019Sdim CmdArgs.push_back("-o"); 140317019Sdim CmdArgs.push_back(Output.getFilename()); 141317019Sdim 142317019Sdim assert(Input.isFilename() && "Invalid input."); 143317019Sdim CmdArgs.push_back(Input.getFilename()); 144317019Sdim 145317019Sdim // asm_final spec is empty. 146317019Sdim 147317019Sdim const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); 148317019Sdim C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 149317019Sdim} 150317019Sdim 151317019Sdimvoid darwin::MachOTool::anchor() {} 152317019Sdim 153317019Sdimvoid darwin::MachOTool::AddMachOArch(const ArgList &Args, 154317019Sdim ArgStringList &CmdArgs) const { 155317019Sdim StringRef ArchName = getMachOToolChain().getMachOArchName(Args); 156317019Sdim 157317019Sdim // Derived from darwin_arch spec. 158317019Sdim CmdArgs.push_back("-arch"); 159317019Sdim CmdArgs.push_back(Args.MakeArgString(ArchName)); 160317019Sdim 161317019Sdim // FIXME: Is this needed anymore? 162317019Sdim if (ArchName == "arm") 163317019Sdim CmdArgs.push_back("-force_cpusubtype_ALL"); 164317019Sdim} 165317019Sdim 166317019Sdimbool darwin::Linker::NeedsTempPath(const InputInfoList &Inputs) const { 167317019Sdim // We only need to generate a temp path for LTO if we aren't compiling object 168317019Sdim // files. When compiling source files, we run 'dsymutil' after linking. We 169317019Sdim // don't run 'dsymutil' when compiling object files. 170317019Sdim for (const auto &Input : Inputs) 171317019Sdim if (Input.getType() != types::TY_Object) 172317019Sdim return true; 173317019Sdim 174317019Sdim return false; 175317019Sdim} 176317019Sdim 177317019Sdim/// \brief Pass -no_deduplicate to ld64 under certain conditions: 178317019Sdim/// 179317019Sdim/// - Either -O0 or -O1 is explicitly specified 180317019Sdim/// - No -O option is specified *and* this is a compile+link (implicit -O0) 181317019Sdim/// 182317019Sdim/// Also do *not* add -no_deduplicate when no -O option is specified and this 183317019Sdim/// is just a link (we can't imply -O0) 184317019Sdimstatic bool shouldLinkerNotDedup(bool IsLinkerOnlyAction, const ArgList &Args) { 185317019Sdim if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { 186317019Sdim if (A->getOption().matches(options::OPT_O0)) 187317019Sdim return true; 188317019Sdim if (A->getOption().matches(options::OPT_O)) 189317019Sdim return llvm::StringSwitch<bool>(A->getValue()) 190317019Sdim .Case("1", true) 191317019Sdim .Default(false); 192317019Sdim return false; // OPT_Ofast & OPT_O4 193317019Sdim } 194317019Sdim 195317019Sdim if (!IsLinkerOnlyAction) // Implicit -O0 for compile+linker only. 196317019Sdim return true; 197317019Sdim return false; 198317019Sdim} 199317019Sdim 200317019Sdimvoid darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args, 201317019Sdim ArgStringList &CmdArgs, 202317019Sdim const InputInfoList &Inputs) const { 203317019Sdim const Driver &D = getToolChain().getDriver(); 204317019Sdim const toolchains::MachO &MachOTC = getMachOToolChain(); 205317019Sdim 206317019Sdim unsigned Version[5] = {0, 0, 0, 0, 0}; 207317019Sdim if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) { 208317019Sdim if (!Driver::GetReleaseVersion(A->getValue(), Version)) 209317019Sdim D.Diag(diag::err_drv_invalid_version_number) << A->getAsString(Args); 210317019Sdim } 211317019Sdim 212317019Sdim // Newer linkers support -demangle. Pass it if supported and not disabled by 213317019Sdim // the user. 214317019Sdim if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) 215317019Sdim CmdArgs.push_back("-demangle"); 216317019Sdim 217317019Sdim if (Args.hasArg(options::OPT_rdynamic) && Version[0] >= 137) 218317019Sdim CmdArgs.push_back("-export_dynamic"); 219317019Sdim 220317019Sdim // If we are using App Extension restrictions, pass a flag to the linker 221317019Sdim // telling it that the compiled code has been audited. 222317019Sdim if (Args.hasFlag(options::OPT_fapplication_extension, 223317019Sdim options::OPT_fno_application_extension, false)) 224317019Sdim CmdArgs.push_back("-application_extension"); 225317019Sdim 226317019Sdim if (D.isUsingLTO()) { 227317019Sdim // If we are using LTO, then automatically create a temporary file path for 228317019Sdim // the linker to use, so that it's lifetime will extend past a possible 229317019Sdim // dsymutil step. 230317019Sdim if (Version[0] >= 116 && NeedsTempPath(Inputs)) { 231317019Sdim const char *TmpPath = C.getArgs().MakeArgString( 232317019Sdim D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object))); 233317019Sdim C.addTempFile(TmpPath); 234317019Sdim CmdArgs.push_back("-object_path_lto"); 235317019Sdim CmdArgs.push_back(TmpPath); 236317019Sdim } 237317019Sdim } 238317019Sdim 239317019Sdim // Use -lto_library option to specify the libLTO.dylib path. Try to find 240317019Sdim // it in clang installed libraries. ld64 will only look at this argument 241317019Sdim // when it actually uses LTO, so libLTO.dylib only needs to exist at link 242317019Sdim // time if ld64 decides that it needs to use LTO. 243317019Sdim // Since this is passed unconditionally, ld64 will never look for libLTO.dylib 244317019Sdim // next to it. That's ok since ld64 using a libLTO.dylib not matching the 245317019Sdim // clang version won't work anyways. 246317019Sdim if (Version[0] >= 133) { 247317019Sdim // Search for libLTO in <InstalledDir>/../lib/libLTO.dylib 248317019Sdim StringRef P = llvm::sys::path::parent_path(D.Dir); 249317019Sdim SmallString<128> LibLTOPath(P); 250317019Sdim llvm::sys::path::append(LibLTOPath, "lib"); 251317019Sdim llvm::sys::path::append(LibLTOPath, "libLTO.dylib"); 252317019Sdim CmdArgs.push_back("-lto_library"); 253317019Sdim CmdArgs.push_back(C.getArgs().MakeArgString(LibLTOPath)); 254317019Sdim } 255317019Sdim 256317019Sdim // ld64 version 262 and above run the deduplicate pass by default. 257317019Sdim if (Version[0] >= 262 && shouldLinkerNotDedup(C.getJobs().empty(), Args)) 258317019Sdim CmdArgs.push_back("-no_deduplicate"); 259317019Sdim 260317019Sdim // Derived from the "link" spec. 261317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_static); 262317019Sdim if (!Args.hasArg(options::OPT_static)) 263317019Sdim CmdArgs.push_back("-dynamic"); 264317019Sdim if (Args.hasArg(options::OPT_fgnu_runtime)) { 265317019Sdim // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu 266317019Sdim // here. How do we wish to handle such things? 267317019Sdim } 268317019Sdim 269317019Sdim if (!Args.hasArg(options::OPT_dynamiclib)) { 270317019Sdim AddMachOArch(Args, CmdArgs); 271317019Sdim // FIXME: Why do this only on this path? 272317019Sdim Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL); 273317019Sdim 274317019Sdim Args.AddLastArg(CmdArgs, options::OPT_bundle); 275317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader); 276317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_client__name); 277317019Sdim 278317019Sdim Arg *A; 279317019Sdim if ((A = Args.getLastArg(options::OPT_compatibility__version)) || 280317019Sdim (A = Args.getLastArg(options::OPT_current__version)) || 281317019Sdim (A = Args.getLastArg(options::OPT_install__name))) 282317019Sdim D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args) 283317019Sdim << "-dynamiclib"; 284317019Sdim 285317019Sdim Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace); 286317019Sdim Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs); 287317019Sdim Args.AddLastArg(CmdArgs, options::OPT_private__bundle); 288317019Sdim } else { 289317019Sdim CmdArgs.push_back("-dylib"); 290317019Sdim 291317019Sdim Arg *A; 292317019Sdim if ((A = Args.getLastArg(options::OPT_bundle)) || 293317019Sdim (A = Args.getLastArg(options::OPT_bundle__loader)) || 294317019Sdim (A = Args.getLastArg(options::OPT_client__name)) || 295317019Sdim (A = Args.getLastArg(options::OPT_force__flat__namespace)) || 296317019Sdim (A = Args.getLastArg(options::OPT_keep__private__externs)) || 297317019Sdim (A = Args.getLastArg(options::OPT_private__bundle))) 298317019Sdim D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args) 299317019Sdim << "-dynamiclib"; 300317019Sdim 301317019Sdim Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version, 302317019Sdim "-dylib_compatibility_version"); 303317019Sdim Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version, 304317019Sdim "-dylib_current_version"); 305317019Sdim 306317019Sdim AddMachOArch(Args, CmdArgs); 307317019Sdim 308317019Sdim Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name, 309317019Sdim "-dylib_install_name"); 310317019Sdim } 311317019Sdim 312317019Sdim Args.AddLastArg(CmdArgs, options::OPT_all__load); 313317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_allowable__client); 314317019Sdim Args.AddLastArg(CmdArgs, options::OPT_bind__at__load); 315317019Sdim if (MachOTC.isTargetIOSBased()) 316317019Sdim Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal); 317317019Sdim Args.AddLastArg(CmdArgs, options::OPT_dead__strip); 318317019Sdim Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms); 319317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_dylib__file); 320317019Sdim Args.AddLastArg(CmdArgs, options::OPT_dynamic); 321317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list); 322317019Sdim Args.AddLastArg(CmdArgs, options::OPT_flat__namespace); 323317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_force__load); 324317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names); 325317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_image__base); 326317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_init); 327317019Sdim 328317019Sdim // Add the deployment target. 329317019Sdim MachOTC.addMinVersionArgs(Args, CmdArgs); 330317019Sdim 331317019Sdim Args.AddLastArg(CmdArgs, options::OPT_nomultidefs); 332317019Sdim Args.AddLastArg(CmdArgs, options::OPT_multi__module); 333317019Sdim Args.AddLastArg(CmdArgs, options::OPT_single__module); 334317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined); 335317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused); 336317019Sdim 337317019Sdim if (const Arg *A = 338317019Sdim Args.getLastArg(options::OPT_fpie, options::OPT_fPIE, 339317019Sdim options::OPT_fno_pie, options::OPT_fno_PIE)) { 340317019Sdim if (A->getOption().matches(options::OPT_fpie) || 341317019Sdim A->getOption().matches(options::OPT_fPIE)) 342317019Sdim CmdArgs.push_back("-pie"); 343317019Sdim else 344317019Sdim CmdArgs.push_back("-no_pie"); 345317019Sdim } 346317019Sdim 347317019Sdim // for embed-bitcode, use -bitcode_bundle in linker command 348317019Sdim if (C.getDriver().embedBitcodeEnabled()) { 349317019Sdim // Check if the toolchain supports bitcode build flow. 350317019Sdim if (MachOTC.SupportsEmbeddedBitcode()) { 351317019Sdim CmdArgs.push_back("-bitcode_bundle"); 352317019Sdim if (C.getDriver().embedBitcodeMarkerOnly() && Version[0] >= 278) { 353317019Sdim CmdArgs.push_back("-bitcode_process_mode"); 354317019Sdim CmdArgs.push_back("marker"); 355317019Sdim } 356317019Sdim } else 357317019Sdim D.Diag(diag::err_drv_bitcode_unsupported_on_toolchain); 358317019Sdim } 359317019Sdim 360317019Sdim Args.AddLastArg(CmdArgs, options::OPT_prebind); 361317019Sdim Args.AddLastArg(CmdArgs, options::OPT_noprebind); 362317019Sdim Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding); 363317019Sdim Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules); 364317019Sdim Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs); 365317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_sectcreate); 366317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_sectorder); 367317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_seg1addr); 368317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_segprot); 369317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_segaddr); 370317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr); 371317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr); 372317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table); 373317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename); 374317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_sub__library); 375317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella); 376317019Sdim 377317019Sdim // Give --sysroot= preference, over the Apple specific behavior to also use 378317019Sdim // --isysroot as the syslibroot. 379317019Sdim StringRef sysroot = C.getSysRoot(); 380317019Sdim if (sysroot != "") { 381317019Sdim CmdArgs.push_back("-syslibroot"); 382317019Sdim CmdArgs.push_back(C.getArgs().MakeArgString(sysroot)); 383317019Sdim } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 384317019Sdim CmdArgs.push_back("-syslibroot"); 385317019Sdim CmdArgs.push_back(A->getValue()); 386317019Sdim } 387317019Sdim 388317019Sdim Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace); 389317019Sdim Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints); 390317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_umbrella); 391317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_undefined); 392317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list); 393317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches); 394317019Sdim Args.AddLastArg(CmdArgs, options::OPT_X_Flag); 395317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_y); 396317019Sdim Args.AddLastArg(CmdArgs, options::OPT_w); 397317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size); 398317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_segs__read__); 399317019Sdim Args.AddLastArg(CmdArgs, options::OPT_seglinkedit); 400317019Sdim Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit); 401317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_sectalign); 402317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols); 403317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_segcreate); 404317019Sdim Args.AddLastArg(CmdArgs, options::OPT_whyload); 405317019Sdim Args.AddLastArg(CmdArgs, options::OPT_whatsloaded); 406317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name); 407317019Sdim Args.AddLastArg(CmdArgs, options::OPT_dylinker); 408317019Sdim Args.AddLastArg(CmdArgs, options::OPT_Mach); 409317019Sdim} 410317019Sdim 411317019Sdim/// \brief Determine whether we are linking the ObjC runtime. 412317019Sdimstatic bool isObjCRuntimeLinked(const ArgList &Args) { 413317019Sdim if (isObjCAutoRefCount(Args)) { 414317019Sdim Args.ClaimAllArgs(options::OPT_fobjc_link_runtime); 415317019Sdim return true; 416317019Sdim } 417317019Sdim return Args.hasArg(options::OPT_fobjc_link_runtime); 418317019Sdim} 419317019Sdim 420317019Sdimvoid darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, 421317019Sdim const InputInfo &Output, 422317019Sdim const InputInfoList &Inputs, 423317019Sdim const ArgList &Args, 424317019Sdim const char *LinkingOutput) const { 425317019Sdim assert(Output.getType() == types::TY_Image && "Invalid linker output type."); 426317019Sdim 427317019Sdim // If the number of arguments surpasses the system limits, we will encode the 428317019Sdim // input files in a separate file, shortening the command line. To this end, 429317019Sdim // build a list of input file names that can be passed via a file with the 430317019Sdim // -filelist linker option. 431317019Sdim llvm::opt::ArgStringList InputFileList; 432317019Sdim 433317019Sdim // The logic here is derived from gcc's behavior; most of which 434317019Sdim // comes from specs (starting with link_command). Consult gcc for 435317019Sdim // more information. 436317019Sdim ArgStringList CmdArgs; 437317019Sdim 438317019Sdim /// Hack(tm) to ignore linking errors when we are doing ARC migration. 439317019Sdim if (Args.hasArg(options::OPT_ccc_arcmt_check, 440317019Sdim options::OPT_ccc_arcmt_migrate)) { 441317019Sdim for (const auto &Arg : Args) 442317019Sdim Arg->claim(); 443317019Sdim const char *Exec = 444317019Sdim Args.MakeArgString(getToolChain().GetProgramPath("touch")); 445317019Sdim CmdArgs.push_back(Output.getFilename()); 446317019Sdim C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, None)); 447317019Sdim return; 448317019Sdim } 449317019Sdim 450317019Sdim // I'm not sure why this particular decomposition exists in gcc, but 451317019Sdim // we follow suite for ease of comparison. 452317019Sdim AddLinkArgs(C, Args, CmdArgs, Inputs); 453317019Sdim 454317019Sdim // For LTO, pass the name of the optimization record file. 455317019Sdim if (Args.hasFlag(options::OPT_fsave_optimization_record, 456317019Sdim options::OPT_fno_save_optimization_record, false)) { 457317019Sdim CmdArgs.push_back("-mllvm"); 458317019Sdim CmdArgs.push_back("-lto-pass-remarks-output"); 459317019Sdim CmdArgs.push_back("-mllvm"); 460317019Sdim 461317019Sdim SmallString<128> F; 462317019Sdim F = Output.getFilename(); 463317019Sdim F += ".opt.yaml"; 464317019Sdim CmdArgs.push_back(Args.MakeArgString(F)); 465317019Sdim 466317019Sdim if (getLastProfileUseArg(Args)) { 467317019Sdim CmdArgs.push_back("-mllvm"); 468317019Sdim CmdArgs.push_back("-lto-pass-remarks-with-hotness"); 469317019Sdim } 470317019Sdim } 471317019Sdim 472317019Sdim // It seems that the 'e' option is completely ignored for dynamic executables 473317019Sdim // (the default), and with static executables, the last one wins, as expected. 474317019Sdim Args.AddAllArgs(CmdArgs, {options::OPT_d_Flag, options::OPT_s, options::OPT_t, 475317019Sdim options::OPT_Z_Flag, options::OPT_u_Group, 476317019Sdim options::OPT_e, options::OPT_r}); 477317019Sdim 478317019Sdim // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading 479317019Sdim // members of static archive libraries which implement Objective-C classes or 480317019Sdim // categories. 481317019Sdim if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX)) 482317019Sdim CmdArgs.push_back("-ObjC"); 483317019Sdim 484317019Sdim CmdArgs.push_back("-o"); 485317019Sdim CmdArgs.push_back(Output.getFilename()); 486317019Sdim 487317019Sdim if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) 488317019Sdim getMachOToolChain().addStartObjectFileArgs(Args, CmdArgs); 489317019Sdim 490317019Sdim // SafeStack requires its own runtime libraries 491317019Sdim // These libraries should be linked first, to make sure the 492317019Sdim // __safestack_init constructor executes before everything else 493317019Sdim if (getToolChain().getSanitizerArgs().needsSafeStackRt()) { 494317019Sdim getMachOToolChain().AddLinkRuntimeLib(Args, CmdArgs, 495317019Sdim "libclang_rt.safestack_osx.a", 496317019Sdim /*AlwaysLink=*/true); 497317019Sdim } 498317019Sdim 499317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_L); 500317019Sdim 501317019Sdim AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); 502317019Sdim // Build the input file for -filelist (list of linker input files) in case we 503317019Sdim // need it later 504317019Sdim for (const auto &II : Inputs) { 505317019Sdim if (!II.isFilename()) { 506317019Sdim // This is a linker input argument. 507317019Sdim // We cannot mix input arguments and file names in a -filelist input, thus 508317019Sdim // we prematurely stop our list (remaining files shall be passed as 509317019Sdim // arguments). 510317019Sdim if (InputFileList.size() > 0) 511317019Sdim break; 512317019Sdim 513317019Sdim continue; 514317019Sdim } 515317019Sdim 516317019Sdim InputFileList.push_back(II.getFilename()); 517317019Sdim } 518317019Sdim 519317019Sdim if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) 520317019Sdim addOpenMPRuntime(CmdArgs, getToolChain(), Args); 521317019Sdim 522317019Sdim if (isObjCRuntimeLinked(Args) && 523317019Sdim !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { 524317019Sdim // We use arclite library for both ARC and subscripting support. 525317019Sdim getMachOToolChain().AddLinkARCArgs(Args, CmdArgs); 526317019Sdim 527317019Sdim CmdArgs.push_back("-framework"); 528317019Sdim CmdArgs.push_back("Foundation"); 529317019Sdim // Link libobj. 530317019Sdim CmdArgs.push_back("-lobjc"); 531317019Sdim } 532317019Sdim 533317019Sdim if (LinkingOutput) { 534317019Sdim CmdArgs.push_back("-arch_multiple"); 535317019Sdim CmdArgs.push_back("-final_output"); 536317019Sdim CmdArgs.push_back(LinkingOutput); 537317019Sdim } 538317019Sdim 539317019Sdim if (Args.hasArg(options::OPT_fnested_functions)) 540317019Sdim CmdArgs.push_back("-allow_stack_execute"); 541317019Sdim 542317019Sdim getMachOToolChain().addProfileRTLibs(Args, CmdArgs); 543317019Sdim 544317019Sdim if (unsigned Parallelism = 545317019Sdim getLTOParallelism(Args, getToolChain().getDriver())) { 546317019Sdim CmdArgs.push_back("-mllvm"); 547317019Sdim CmdArgs.push_back( 548317019Sdim Args.MakeArgString(Twine("-threads=") + llvm::to_string(Parallelism))); 549317019Sdim } 550317019Sdim 551317019Sdim if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { 552317019Sdim if (getToolChain().getDriver().CCCIsCXX()) 553317019Sdim getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 554317019Sdim 555317019Sdim // link_ssp spec is empty. 556317019Sdim 557317019Sdim // Let the tool chain choose which runtime library to link. 558317019Sdim getMachOToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs); 559317019Sdim 560317019Sdim // No need to do anything for pthreads. Claim argument to avoid warning. 561317019Sdim Args.ClaimAllArgs(options::OPT_pthread); 562317019Sdim Args.ClaimAllArgs(options::OPT_pthreads); 563317019Sdim } 564317019Sdim 565317019Sdim if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { 566317019Sdim // endfile_spec is empty. 567317019Sdim } 568317019Sdim 569317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 570317019Sdim Args.AddAllArgs(CmdArgs, options::OPT_F); 571317019Sdim 572317019Sdim // -iframework should be forwarded as -F. 573317019Sdim for (const Arg *A : Args.filtered(options::OPT_iframework)) 574317019Sdim CmdArgs.push_back(Args.MakeArgString(std::string("-F") + A->getValue())); 575317019Sdim 576317019Sdim if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { 577317019Sdim if (Arg *A = Args.getLastArg(options::OPT_fveclib)) { 578317019Sdim if (A->getValue() == StringRef("Accelerate")) { 579317019Sdim CmdArgs.push_back("-framework"); 580317019Sdim CmdArgs.push_back("Accelerate"); 581317019Sdim } 582317019Sdim } 583317019Sdim } 584317019Sdim 585317019Sdim const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); 586317019Sdim std::unique_ptr<Command> Cmd = 587317019Sdim llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs); 588317019Sdim Cmd->setInputFileList(std::move(InputFileList)); 589317019Sdim C.addCommand(std::move(Cmd)); 590317019Sdim} 591317019Sdim 592317019Sdimvoid darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA, 593317019Sdim const InputInfo &Output, 594317019Sdim const InputInfoList &Inputs, 595317019Sdim const ArgList &Args, 596317019Sdim const char *LinkingOutput) const { 597317019Sdim ArgStringList CmdArgs; 598317019Sdim 599317019Sdim CmdArgs.push_back("-create"); 600317019Sdim assert(Output.isFilename() && "Unexpected lipo output."); 601317019Sdim 602317019Sdim CmdArgs.push_back("-output"); 603317019Sdim CmdArgs.push_back(Output.getFilename()); 604317019Sdim 605317019Sdim for (const auto &II : Inputs) { 606317019Sdim assert(II.isFilename() && "Unexpected lipo input."); 607317019Sdim CmdArgs.push_back(II.getFilename()); 608317019Sdim } 609317019Sdim 610317019Sdim const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("lipo")); 611317019Sdim C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 612317019Sdim} 613317019Sdim 614317019Sdimvoid darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA, 615317019Sdim const InputInfo &Output, 616317019Sdim const InputInfoList &Inputs, 617317019Sdim const ArgList &Args, 618317019Sdim const char *LinkingOutput) const { 619317019Sdim ArgStringList CmdArgs; 620317019Sdim 621317019Sdim CmdArgs.push_back("-o"); 622317019Sdim CmdArgs.push_back(Output.getFilename()); 623317019Sdim 624317019Sdim assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); 625317019Sdim const InputInfo &Input = Inputs[0]; 626317019Sdim assert(Input.isFilename() && "Unexpected dsymutil input."); 627317019Sdim CmdArgs.push_back(Input.getFilename()); 628317019Sdim 629317019Sdim const char *Exec = 630317019Sdim Args.MakeArgString(getToolChain().GetProgramPath("dsymutil")); 631317019Sdim C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 632317019Sdim} 633317019Sdim 634317019Sdimvoid darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA, 635317019Sdim const InputInfo &Output, 636317019Sdim const InputInfoList &Inputs, 637317019Sdim const ArgList &Args, 638317019Sdim const char *LinkingOutput) const { 639317019Sdim ArgStringList CmdArgs; 640317019Sdim CmdArgs.push_back("--verify"); 641317019Sdim CmdArgs.push_back("--debug-info"); 642317019Sdim CmdArgs.push_back("--eh-frame"); 643317019Sdim CmdArgs.push_back("--quiet"); 644317019Sdim 645317019Sdim assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); 646317019Sdim const InputInfo &Input = Inputs[0]; 647317019Sdim assert(Input.isFilename() && "Unexpected verify input"); 648317019Sdim 649317019Sdim // Grabbing the output of the earlier dsymutil run. 650317019Sdim CmdArgs.push_back(Input.getFilename()); 651317019Sdim 652317019Sdim const char *Exec = 653317019Sdim Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump")); 654317019Sdim C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 655317019Sdim} 656317019Sdim 657317019SdimMachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 658317019Sdim : ToolChain(D, Triple, Args) { 659317019Sdim // We expect 'as', 'ld', etc. to be adjacent to our install dir. 660317019Sdim getProgramPaths().push_back(getDriver().getInstalledDir()); 661317019Sdim if (getDriver().getInstalledDir() != getDriver().Dir) 662317019Sdim getProgramPaths().push_back(getDriver().Dir); 663317019Sdim} 664317019Sdim 665317019Sdim/// Darwin - Darwin tool chain for i386 and x86_64. 666317019SdimDarwin::Darwin(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 667317019Sdim : MachO(D, Triple, Args), TargetInitialized(false), 668317019Sdim CudaInstallation(D, Triple, Args) {} 669317019Sdim 670317019Sdimtypes::ID MachO::LookupTypeForExtension(StringRef Ext) const { 671317019Sdim types::ID Ty = types::lookupTypeForExtension(Ext); 672317019Sdim 673317019Sdim // Darwin always preprocesses assembly files (unless -x is used explicitly). 674317019Sdim if (Ty == types::TY_PP_Asm) 675317019Sdim return types::TY_Asm; 676317019Sdim 677317019Sdim return Ty; 678317019Sdim} 679317019Sdim 680317019Sdimbool MachO::HasNativeLLVMSupport() const { return true; } 681317019Sdim 682317019SdimToolChain::CXXStdlibType Darwin::GetDefaultCXXStdlibType() const { 683317019Sdim // Default to use libc++ on OS X 10.9+ and iOS 7+. 684317019Sdim if ((isTargetMacOS() && !isMacosxVersionLT(10, 9)) || 685317019Sdim (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0)) || 686317019Sdim isTargetWatchOSBased()) 687317019Sdim return ToolChain::CST_Libcxx; 688317019Sdim 689317019Sdim return ToolChain::CST_Libstdcxx; 690317019Sdim} 691317019Sdim 692317019Sdim/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0. 693317019SdimObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const { 694317019Sdim if (isTargetWatchOSBased()) 695317019Sdim return ObjCRuntime(ObjCRuntime::WatchOS, TargetVersion); 696317019Sdim if (isTargetIOSBased()) 697317019Sdim return ObjCRuntime(ObjCRuntime::iOS, TargetVersion); 698317019Sdim if (isNonFragile) 699317019Sdim return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion); 700317019Sdim return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion); 701317019Sdim} 702317019Sdim 703317019Sdim/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2. 704317019Sdimbool Darwin::hasBlocksRuntime() const { 705317019Sdim if (isTargetWatchOSBased()) 706317019Sdim return true; 707317019Sdim else if (isTargetIOSBased()) 708317019Sdim return !isIPhoneOSVersionLT(3, 2); 709317019Sdim else { 710317019Sdim assert(isTargetMacOS() && "unexpected darwin target"); 711317019Sdim return !isMacosxVersionLT(10, 6); 712317019Sdim } 713317019Sdim} 714317019Sdim 715317019Sdimvoid Darwin::AddCudaIncludeArgs(const ArgList &DriverArgs, 716317019Sdim ArgStringList &CC1Args) const { 717317019Sdim CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); 718317019Sdim} 719317019Sdim 720317019Sdim// This is just a MachO name translation routine and there's no 721317019Sdim// way to join this into ARMTargetParser without breaking all 722317019Sdim// other assumptions. Maybe MachO should consider standardising 723317019Sdim// their nomenclature. 724317019Sdimstatic const char *ArmMachOArchName(StringRef Arch) { 725317019Sdim return llvm::StringSwitch<const char *>(Arch) 726317019Sdim .Case("armv6k", "armv6") 727317019Sdim .Case("armv6m", "armv6m") 728317019Sdim .Case("armv5tej", "armv5") 729317019Sdim .Case("xscale", "xscale") 730317019Sdim .Case("armv4t", "armv4t") 731317019Sdim .Case("armv7", "armv7") 732317019Sdim .Cases("armv7a", "armv7-a", "armv7") 733317019Sdim .Cases("armv7r", "armv7-r", "armv7") 734317019Sdim .Cases("armv7em", "armv7e-m", "armv7em") 735317019Sdim .Cases("armv7k", "armv7-k", "armv7k") 736317019Sdim .Cases("armv7m", "armv7-m", "armv7m") 737317019Sdim .Cases("armv7s", "armv7-s", "armv7s") 738317019Sdim .Default(nullptr); 739317019Sdim} 740317019Sdim 741317019Sdimstatic const char *ArmMachOArchNameCPU(StringRef CPU) { 742317019Sdim unsigned ArchKind = llvm::ARM::parseCPUArch(CPU); 743317019Sdim if (ArchKind == llvm::ARM::AK_INVALID) 744317019Sdim return nullptr; 745317019Sdim StringRef Arch = llvm::ARM::getArchName(ArchKind); 746317019Sdim 747317019Sdim // FIXME: Make sure this MachO triple mangling is really necessary. 748317019Sdim // ARMv5* normalises to ARMv5. 749317019Sdim if (Arch.startswith("armv5")) 750317019Sdim Arch = Arch.substr(0, 5); 751317019Sdim // ARMv6*, except ARMv6M, normalises to ARMv6. 752317019Sdim else if (Arch.startswith("armv6") && !Arch.endswith("6m")) 753317019Sdim Arch = Arch.substr(0, 5); 754317019Sdim // ARMv7A normalises to ARMv7. 755317019Sdim else if (Arch.endswith("v7a")) 756317019Sdim Arch = Arch.substr(0, 5); 757317019Sdim return Arch.data(); 758317019Sdim} 759317019Sdim 760317019SdimStringRef MachO::getMachOArchName(const ArgList &Args) const { 761317019Sdim switch (getTriple().getArch()) { 762317019Sdim default: 763317019Sdim return getDefaultUniversalArchName(); 764317019Sdim 765317019Sdim case llvm::Triple::aarch64: 766317019Sdim return "arm64"; 767317019Sdim 768317019Sdim case llvm::Triple::thumb: 769317019Sdim case llvm::Triple::arm: 770317019Sdim if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) 771317019Sdim if (const char *Arch = ArmMachOArchName(A->getValue())) 772317019Sdim return Arch; 773317019Sdim 774317019Sdim if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 775317019Sdim if (const char *Arch = ArmMachOArchNameCPU(A->getValue())) 776317019Sdim return Arch; 777317019Sdim 778317019Sdim return "arm"; 779317019Sdim } 780317019Sdim} 781317019Sdim 782317019SdimDarwin::~Darwin() {} 783317019Sdim 784317019SdimMachO::~MachO() {} 785317019Sdim 786317019Sdimstd::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args, 787317019Sdim types::ID InputType) const { 788317019Sdim llvm::Triple Triple(ComputeLLVMTriple(Args, InputType)); 789317019Sdim 790317019Sdim // If the target isn't initialized (e.g., an unknown Darwin platform, return 791317019Sdim // the default triple). 792317019Sdim if (!isTargetInitialized()) 793317019Sdim return Triple.getTriple(); 794317019Sdim 795317019Sdim SmallString<16> Str; 796317019Sdim if (isTargetWatchOSBased()) 797317019Sdim Str += "watchos"; 798317019Sdim else if (isTargetTvOSBased()) 799317019Sdim Str += "tvos"; 800317019Sdim else if (isTargetIOSBased()) 801317019Sdim Str += "ios"; 802317019Sdim else 803317019Sdim Str += "macosx"; 804317019Sdim Str += getTargetVersion().getAsString(); 805317019Sdim Triple.setOSName(Str); 806317019Sdim 807317019Sdim return Triple.getTriple(); 808317019Sdim} 809317019Sdim 810317019SdimTool *MachO::getTool(Action::ActionClass AC) const { 811317019Sdim switch (AC) { 812317019Sdim case Action::LipoJobClass: 813317019Sdim if (!Lipo) 814317019Sdim Lipo.reset(new tools::darwin::Lipo(*this)); 815317019Sdim return Lipo.get(); 816317019Sdim case Action::DsymutilJobClass: 817317019Sdim if (!Dsymutil) 818317019Sdim Dsymutil.reset(new tools::darwin::Dsymutil(*this)); 819317019Sdim return Dsymutil.get(); 820317019Sdim case Action::VerifyDebugInfoJobClass: 821317019Sdim if (!VerifyDebug) 822317019Sdim VerifyDebug.reset(new tools::darwin::VerifyDebug(*this)); 823317019Sdim return VerifyDebug.get(); 824317019Sdim default: 825317019Sdim return ToolChain::getTool(AC); 826317019Sdim } 827317019Sdim} 828317019Sdim 829317019SdimTool *MachO::buildLinker() const { return new tools::darwin::Linker(*this); } 830317019Sdim 831317019SdimTool *MachO::buildAssembler() const { 832317019Sdim return new tools::darwin::Assembler(*this); 833317019Sdim} 834317019Sdim 835317019SdimDarwinClang::DarwinClang(const Driver &D, const llvm::Triple &Triple, 836317019Sdim const ArgList &Args) 837317019Sdim : Darwin(D, Triple, Args) {} 838317019Sdim 839317019Sdimvoid DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const { 840317019Sdim // For modern targets, promote certain warnings to errors. 841317019Sdim if (isTargetWatchOSBased() || getTriple().isArch64Bit()) { 842317019Sdim // Always enable -Wdeprecated-objc-isa-usage and promote it 843317019Sdim // to an error. 844317019Sdim CC1Args.push_back("-Wdeprecated-objc-isa-usage"); 845317019Sdim CC1Args.push_back("-Werror=deprecated-objc-isa-usage"); 846317019Sdim 847317019Sdim // For iOS and watchOS, also error about implicit function declarations, 848317019Sdim // as that can impact calling conventions. 849317019Sdim if (!isTargetMacOS()) 850317019Sdim CC1Args.push_back("-Werror=implicit-function-declaration"); 851317019Sdim } 852317019Sdim} 853317019Sdim 854317019Sdimvoid DarwinClang::AddLinkARCArgs(const ArgList &Args, 855317019Sdim ArgStringList &CmdArgs) const { 856317019Sdim // Avoid linking compatibility stubs on i386 mac. 857317019Sdim if (isTargetMacOS() && getArch() == llvm::Triple::x86) 858317019Sdim return; 859317019Sdim 860317019Sdim ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true); 861317019Sdim 862317019Sdim if ((runtime.hasNativeARC() || !isObjCAutoRefCount(Args)) && 863317019Sdim runtime.hasSubscripting()) 864317019Sdim return; 865317019Sdim 866317019Sdim CmdArgs.push_back("-force_load"); 867317019Sdim SmallString<128> P(getDriver().ClangExecutable); 868317019Sdim llvm::sys::path::remove_filename(P); // 'clang' 869317019Sdim llvm::sys::path::remove_filename(P); // 'bin' 870317019Sdim llvm::sys::path::append(P, "lib", "arc", "libarclite_"); 871317019Sdim // Mash in the platform. 872317019Sdim if (isTargetWatchOSSimulator()) 873317019Sdim P += "watchsimulator"; 874317019Sdim else if (isTargetWatchOS()) 875317019Sdim P += "watchos"; 876317019Sdim else if (isTargetTvOSSimulator()) 877317019Sdim P += "appletvsimulator"; 878317019Sdim else if (isTargetTvOS()) 879317019Sdim P += "appletvos"; 880317019Sdim else if (isTargetIOSSimulator()) 881317019Sdim P += "iphonesimulator"; 882317019Sdim else if (isTargetIPhoneOS()) 883317019Sdim P += "iphoneos"; 884317019Sdim else 885317019Sdim P += "macosx"; 886317019Sdim P += ".a"; 887317019Sdim 888317019Sdim CmdArgs.push_back(Args.MakeArgString(P)); 889317019Sdim} 890317019Sdim 891317019Sdimunsigned DarwinClang::GetDefaultDwarfVersion() const { 892317019Sdim // Default to use DWARF 2 on OS X 10.10 / iOS 8 and lower. 893317019Sdim if ((isTargetMacOS() && isMacosxVersionLT(10, 11)) || 894317019Sdim (isTargetIOSBased() && isIPhoneOSVersionLT(9))) 895317019Sdim return 2; 896317019Sdim return 4; 897317019Sdim} 898317019Sdim 899317019Sdimvoid MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs, 900317019Sdim StringRef DarwinLibName, bool AlwaysLink, 901317019Sdim bool IsEmbedded, bool AddRPath) const { 902317019Sdim SmallString<128> Dir(getDriver().ResourceDir); 903317019Sdim llvm::sys::path::append(Dir, "lib", IsEmbedded ? "macho_embedded" : "darwin"); 904317019Sdim 905317019Sdim SmallString<128> P(Dir); 906317019Sdim llvm::sys::path::append(P, DarwinLibName); 907317019Sdim 908317019Sdim // For now, allow missing resource libraries to support developers who may 909317019Sdim // not have compiler-rt checked out or integrated into their build (unless 910317019Sdim // we explicitly force linking with this library). 911317019Sdim if (AlwaysLink || getVFS().exists(P)) 912317019Sdim CmdArgs.push_back(Args.MakeArgString(P)); 913317019Sdim 914317019Sdim // Adding the rpaths might negatively interact when other rpaths are involved, 915317019Sdim // so we should make sure we add the rpaths last, after all user-specified 916317019Sdim // rpaths. This is currently true from this place, but we need to be 917317019Sdim // careful if this function is ever called before user's rpaths are emitted. 918317019Sdim if (AddRPath) { 919317019Sdim assert(DarwinLibName.endswith(".dylib") && "must be a dynamic library"); 920317019Sdim 921317019Sdim // Add @executable_path to rpath to support having the dylib copied with 922317019Sdim // the executable. 923317019Sdim CmdArgs.push_back("-rpath"); 924317019Sdim CmdArgs.push_back("@executable_path"); 925317019Sdim 926317019Sdim // Add the path to the resource dir to rpath to support using the dylib 927317019Sdim // from the default location without copying. 928317019Sdim CmdArgs.push_back("-rpath"); 929317019Sdim CmdArgs.push_back(Args.MakeArgString(Dir)); 930317019Sdim } 931317019Sdim} 932317019Sdim 933317019SdimStringRef Darwin::getPlatformFamily() const { 934317019Sdim switch (TargetPlatform) { 935317019Sdim case DarwinPlatformKind::MacOS: 936317019Sdim return "MacOSX"; 937317019Sdim case DarwinPlatformKind::IPhoneOS: 938317019Sdim case DarwinPlatformKind::IPhoneOSSimulator: 939317019Sdim return "iPhone"; 940317019Sdim case DarwinPlatformKind::TvOS: 941317019Sdim case DarwinPlatformKind::TvOSSimulator: 942317019Sdim return "AppleTV"; 943317019Sdim case DarwinPlatformKind::WatchOS: 944317019Sdim case DarwinPlatformKind::WatchOSSimulator: 945317019Sdim return "Watch"; 946317019Sdim } 947317019Sdim llvm_unreachable("Unsupported platform"); 948317019Sdim} 949317019Sdim 950317019SdimStringRef Darwin::getSDKName(StringRef isysroot) { 951317019Sdim // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk 952317019Sdim llvm::sys::path::const_iterator SDKDir; 953317019Sdim auto BeginSDK = llvm::sys::path::begin(isysroot); 954317019Sdim auto EndSDK = llvm::sys::path::end(isysroot); 955317019Sdim for (auto IT = BeginSDK; IT != EndSDK; ++IT) { 956317019Sdim StringRef SDK = *IT; 957317019Sdim if (SDK.endswith(".sdk")) 958317019Sdim return SDK.slice(0, SDK.size() - 4); 959317019Sdim } 960317019Sdim return ""; 961317019Sdim} 962317019Sdim 963317019SdimStringRef Darwin::getOSLibraryNameSuffix() const { 964317019Sdim switch(TargetPlatform) { 965317019Sdim case DarwinPlatformKind::MacOS: 966317019Sdim return "osx"; 967317019Sdim case DarwinPlatformKind::IPhoneOS: 968317019Sdim return "ios"; 969317019Sdim case DarwinPlatformKind::IPhoneOSSimulator: 970317019Sdim return "iossim"; 971317019Sdim case DarwinPlatformKind::TvOS: 972317019Sdim return "tvos"; 973317019Sdim case DarwinPlatformKind::TvOSSimulator: 974317019Sdim return "tvossim"; 975317019Sdim case DarwinPlatformKind::WatchOS: 976317019Sdim return "watchos"; 977317019Sdim case DarwinPlatformKind::WatchOSSimulator: 978317019Sdim return "watchossim"; 979317019Sdim } 980317019Sdim llvm_unreachable("Unsupported platform"); 981317019Sdim} 982317019Sdim 983317019Sdimvoid Darwin::addProfileRTLibs(const ArgList &Args, 984317019Sdim ArgStringList &CmdArgs) const { 985317019Sdim if (!needsProfileRT(Args)) return; 986317019Sdim 987317019Sdim AddLinkRuntimeLib(Args, CmdArgs, (Twine("libclang_rt.profile_") + 988317019Sdim getOSLibraryNameSuffix() + ".a").str(), 989317019Sdim /*AlwaysLink*/ true); 990317019Sdim} 991317019Sdim 992317019Sdimvoid DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args, 993317019Sdim ArgStringList &CmdArgs, 994317019Sdim StringRef Sanitizer) const { 995317019Sdim AddLinkRuntimeLib( 996317019Sdim Args, CmdArgs, 997317019Sdim (Twine("libclang_rt.") + Sanitizer + "_" + 998317019Sdim getOSLibraryNameSuffix() + "_dynamic.dylib").str(), 999317019Sdim /*AlwaysLink*/ true, /*IsEmbedded*/ false, 1000317019Sdim /*AddRPath*/ true); 1001317019Sdim} 1002317019Sdim 1003317019SdimToolChain::RuntimeLibType DarwinClang::GetRuntimeLibType( 1004317019Sdim const ArgList &Args) const { 1005317019Sdim if (Arg* A = Args.getLastArg(options::OPT_rtlib_EQ)) { 1006317019Sdim StringRef Value = A->getValue(); 1007317019Sdim if (Value != "compiler-rt") 1008317019Sdim getDriver().Diag(clang::diag::err_drv_unsupported_rtlib_for_platform) 1009317019Sdim << Value << "darwin"; 1010317019Sdim } 1011317019Sdim 1012317019Sdim return ToolChain::RLT_CompilerRT; 1013317019Sdim} 1014317019Sdim 1015317019Sdimvoid DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, 1016317019Sdim ArgStringList &CmdArgs) const { 1017317019Sdim // Call once to ensure diagnostic is printed if wrong value was specified 1018317019Sdim GetRuntimeLibType(Args); 1019317019Sdim 1020317019Sdim // Darwin doesn't support real static executables, don't link any runtime 1021317019Sdim // libraries with -static. 1022317019Sdim if (Args.hasArg(options::OPT_static) || 1023317019Sdim Args.hasArg(options::OPT_fapple_kext) || 1024317019Sdim Args.hasArg(options::OPT_mkernel)) 1025317019Sdim return; 1026317019Sdim 1027317019Sdim // Reject -static-libgcc for now, we can deal with this when and if someone 1028317019Sdim // cares. This is useful in situations where someone wants to statically link 1029317019Sdim // something like libstdc++, and needs its runtime support routines. 1030317019Sdim if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) { 1031317019Sdim getDriver().Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args); 1032317019Sdim return; 1033317019Sdim } 1034317019Sdim 1035317019Sdim const SanitizerArgs &Sanitize = getSanitizerArgs(); 1036317019Sdim if (Sanitize.needsAsanRt()) 1037317019Sdim AddLinkSanitizerLibArgs(Args, CmdArgs, "asan"); 1038317019Sdim if (Sanitize.needsUbsanRt()) 1039317019Sdim AddLinkSanitizerLibArgs(Args, CmdArgs, "ubsan"); 1040317019Sdim if (Sanitize.needsTsanRt()) 1041317019Sdim AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan"); 1042317019Sdim if (Sanitize.needsStatsRt()) { 1043317019Sdim StringRef OS = isTargetMacOS() ? "osx" : "iossim"; 1044317019Sdim AddLinkRuntimeLib(Args, CmdArgs, 1045317019Sdim (Twine("libclang_rt.stats_client_") + OS + ".a").str(), 1046317019Sdim /*AlwaysLink=*/true); 1047317019Sdim AddLinkSanitizerLibArgs(Args, CmdArgs, "stats"); 1048317019Sdim } 1049317019Sdim if (Sanitize.needsEsanRt()) 1050317019Sdim AddLinkSanitizerLibArgs(Args, CmdArgs, "esan"); 1051317019Sdim 1052317019Sdim // Otherwise link libSystem, then the dynamic runtime library, and finally any 1053317019Sdim // target specific static runtime library. 1054317019Sdim CmdArgs.push_back("-lSystem"); 1055317019Sdim 1056317019Sdim // Select the dynamic runtime library and the target specific static library. 1057317019Sdim if (isTargetWatchOSBased()) { 1058317019Sdim // We currently always need a static runtime library for watchOS. 1059317019Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.watchos.a"); 1060317019Sdim } else if (isTargetTvOSBased()) { 1061317019Sdim // We currently always need a static runtime library for tvOS. 1062317019Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.tvos.a"); 1063317019Sdim } else if (isTargetIOSBased()) { 1064317019Sdim // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1, 1065317019Sdim // it never went into the SDK. 1066317019Sdim // Linking against libgcc_s.1 isn't needed for iOS 5.0+ 1067317019Sdim if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator() && 1068317019Sdim getTriple().getArch() != llvm::Triple::aarch64) 1069317019Sdim CmdArgs.push_back("-lgcc_s.1"); 1070317019Sdim 1071317019Sdim // We currently always need a static runtime library for iOS. 1072317019Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ios.a"); 1073317019Sdim } else { 1074317019Sdim assert(isTargetMacOS() && "unexpected non MacOS platform"); 1075317019Sdim // The dynamic runtime library was merged with libSystem for 10.6 and 1076317019Sdim // beyond; only 10.4 and 10.5 need an additional runtime library. 1077317019Sdim if (isMacosxVersionLT(10, 5)) 1078317019Sdim CmdArgs.push_back("-lgcc_s.10.4"); 1079317019Sdim else if (isMacosxVersionLT(10, 6)) 1080317019Sdim CmdArgs.push_back("-lgcc_s.10.5"); 1081317019Sdim 1082317019Sdim // Originally for OS X, we thought we would only need a static runtime 1083317019Sdim // library when targeting 10.4, to provide versions of the static functions 1084317019Sdim // which were omitted from 10.4.dylib. This led to the creation of the 10.4 1085317019Sdim // builtins library. 1086317019Sdim // 1087317019Sdim // Unfortunately, that turned out to not be true, because Darwin system 1088317019Sdim // headers can still use eprintf on i386, and it is not exported from 1089317019Sdim // libSystem. Therefore, we still must provide a runtime library just for 1090317019Sdim // the tiny tiny handful of projects that *might* use that symbol. 1091317019Sdim // 1092317019Sdim // Then over time, we figured out it was useful to add more things to the 1093317019Sdim // runtime so we created libclang_rt.osx.a to provide new functions when 1094317019Sdim // deploying to old OS builds, and for a long time we had both eprintf and 1095317019Sdim // osx builtin libraries. Which just seems excessive. So with PR 28855, we 1096317019Sdim // are removing the eprintf library and expecting eprintf to be provided by 1097317019Sdim // the OS X builtins library. 1098317019Sdim if (isMacosxVersionLT(10, 5)) 1099317019Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.10.4.a"); 1100317019Sdim else 1101317019Sdim AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.osx.a"); 1102317019Sdim } 1103317019Sdim} 1104317019Sdim 1105317019Sdimvoid Darwin::AddDeploymentTarget(DerivedArgList &Args) const { 1106317019Sdim const OptTable &Opts = getDriver().getOpts(); 1107317019Sdim 1108317019Sdim // Support allowing the SDKROOT environment variable used by xcrun and other 1109317019Sdim // Xcode tools to define the default sysroot, by making it the default for 1110317019Sdim // isysroot. 1111317019Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 1112317019Sdim // Warn if the path does not exist. 1113317019Sdim if (!getVFS().exists(A->getValue())) 1114317019Sdim getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue(); 1115317019Sdim } else { 1116317019Sdim if (char *env = ::getenv("SDKROOT")) { 1117317019Sdim // We only use this value as the default if it is an absolute path, 1118317019Sdim // exists, and it is not the root path. 1119317019Sdim if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) && 1120317019Sdim StringRef(env) != "/") { 1121317019Sdim Args.append(Args.MakeSeparateArg( 1122317019Sdim nullptr, Opts.getOption(options::OPT_isysroot), env)); 1123317019Sdim } 1124317019Sdim } 1125317019Sdim } 1126317019Sdim 1127317019Sdim Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ); 1128317019Sdim Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ, 1129317019Sdim options::OPT_mios_simulator_version_min_EQ); 1130317019Sdim Arg *TvOSVersion = 1131317019Sdim Args.getLastArg(options::OPT_mtvos_version_min_EQ, 1132317019Sdim options::OPT_mtvos_simulator_version_min_EQ); 1133317019Sdim Arg *WatchOSVersion = 1134317019Sdim Args.getLastArg(options::OPT_mwatchos_version_min_EQ, 1135317019Sdim options::OPT_mwatchos_simulator_version_min_EQ); 1136317019Sdim 1137317019Sdim // Add a macro to differentiate between m(iphone|tv|watch)os-version-min=X.Y and 1138317019Sdim // -m(iphone|tv|watch)simulator-version-min=X.Y. 1139317019Sdim if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ) || 1140317019Sdim Args.hasArg(options::OPT_mtvos_simulator_version_min_EQ) || 1141317019Sdim Args.hasArg(options::OPT_mwatchos_simulator_version_min_EQ)) 1142317019Sdim Args.append(Args.MakeSeparateArg(nullptr, Opts.getOption(options::OPT_D), 1143317019Sdim " __APPLE_EMBEDDED_SIMULATOR__=1")); 1144317019Sdim 1145317019Sdim if (OSXVersion && (iOSVersion || TvOSVersion || WatchOSVersion)) { 1146317019Sdim getDriver().Diag(diag::err_drv_argument_not_allowed_with) 1147317019Sdim << OSXVersion->getAsString(Args) 1148317019Sdim << (iOSVersion ? iOSVersion : 1149317019Sdim TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args); 1150317019Sdim iOSVersion = TvOSVersion = WatchOSVersion = nullptr; 1151317019Sdim } else if (iOSVersion && (TvOSVersion || WatchOSVersion)) { 1152317019Sdim getDriver().Diag(diag::err_drv_argument_not_allowed_with) 1153317019Sdim << iOSVersion->getAsString(Args) 1154317019Sdim << (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args); 1155317019Sdim TvOSVersion = WatchOSVersion = nullptr; 1156317019Sdim } else if (TvOSVersion && WatchOSVersion) { 1157317019Sdim getDriver().Diag(diag::err_drv_argument_not_allowed_with) 1158317019Sdim << TvOSVersion->getAsString(Args) 1159317019Sdim << WatchOSVersion->getAsString(Args); 1160317019Sdim WatchOSVersion = nullptr; 1161317019Sdim } else if (!OSXVersion && !iOSVersion && !TvOSVersion && !WatchOSVersion) { 1162317019Sdim // If no deployment target was specified on the command line, check for 1163317019Sdim // environment defines. 1164317019Sdim std::string OSXTarget; 1165317019Sdim std::string iOSTarget; 1166317019Sdim std::string TvOSTarget; 1167317019Sdim std::string WatchOSTarget; 1168317019Sdim 1169317019Sdim if (char *env = ::getenv("MACOSX_DEPLOYMENT_TARGET")) 1170317019Sdim OSXTarget = env; 1171317019Sdim if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET")) 1172317019Sdim iOSTarget = env; 1173317019Sdim if (char *env = ::getenv("TVOS_DEPLOYMENT_TARGET")) 1174317019Sdim TvOSTarget = env; 1175317019Sdim if (char *env = ::getenv("WATCHOS_DEPLOYMENT_TARGET")) 1176317019Sdim WatchOSTarget = env; 1177317019Sdim 1178317019Sdim // If there is no command-line argument to specify the Target version and 1179317019Sdim // no environment variable defined, see if we can set the default based 1180317019Sdim // on -isysroot. 1181317019Sdim if (OSXTarget.empty() && iOSTarget.empty() && WatchOSTarget.empty() && 1182317019Sdim TvOSTarget.empty() && Args.hasArg(options::OPT_isysroot)) { 1183317019Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 1184317019Sdim StringRef isysroot = A->getValue(); 1185317019Sdim StringRef SDK = getSDKName(isysroot); 1186317019Sdim if (SDK.size() > 0) { 1187317019Sdim // Slice the version number out. 1188317019Sdim // Version number is between the first and the last number. 1189317019Sdim size_t StartVer = SDK.find_first_of("0123456789"); 1190317019Sdim size_t EndVer = SDK.find_last_of("0123456789"); 1191317019Sdim if (StartVer != StringRef::npos && EndVer > StartVer) { 1192317019Sdim StringRef Version = SDK.slice(StartVer, EndVer + 1); 1193317019Sdim if (SDK.startswith("iPhoneOS") || 1194317019Sdim SDK.startswith("iPhoneSimulator")) 1195317019Sdim iOSTarget = Version; 1196317019Sdim else if (SDK.startswith("MacOSX")) 1197317019Sdim OSXTarget = Version; 1198317019Sdim else if (SDK.startswith("WatchOS") || 1199317019Sdim SDK.startswith("WatchSimulator")) 1200317019Sdim WatchOSTarget = Version; 1201317019Sdim else if (SDK.startswith("AppleTVOS") || 1202317019Sdim SDK.startswith("AppleTVSimulator")) 1203317019Sdim TvOSTarget = Version; 1204317019Sdim } 1205317019Sdim } 1206317019Sdim } 1207317019Sdim } 1208317019Sdim 1209317019Sdim // If no OSX or iOS target has been specified, try to guess platform 1210317019Sdim // from arch name and compute the version from the triple. 1211317019Sdim if (OSXTarget.empty() && iOSTarget.empty() && TvOSTarget.empty() && 1212317019Sdim WatchOSTarget.empty()) { 1213317019Sdim StringRef MachOArchName = getMachOArchName(Args); 1214317019Sdim unsigned Major, Minor, Micro; 1215317019Sdim if (MachOArchName == "armv7" || MachOArchName == "armv7s" || 1216317019Sdim MachOArchName == "arm64") { 1217317019Sdim getTriple().getiOSVersion(Major, Minor, Micro); 1218317019Sdim llvm::raw_string_ostream(iOSTarget) << Major << '.' << Minor << '.' 1219317019Sdim << Micro; 1220317019Sdim } else if (MachOArchName == "armv7k") { 1221317019Sdim getTriple().getWatchOSVersion(Major, Minor, Micro); 1222317019Sdim llvm::raw_string_ostream(WatchOSTarget) << Major << '.' << Minor << '.' 1223317019Sdim << Micro; 1224317019Sdim } else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" && 1225317019Sdim MachOArchName != "armv7em") { 1226317019Sdim if (!getTriple().getMacOSXVersion(Major, Minor, Micro)) { 1227317019Sdim getDriver().Diag(diag::err_drv_invalid_darwin_version) 1228317019Sdim << getTriple().getOSName(); 1229317019Sdim } 1230317019Sdim llvm::raw_string_ostream(OSXTarget) << Major << '.' << Minor << '.' 1231317019Sdim << Micro; 1232317019Sdim } 1233317019Sdim } 1234317019Sdim 1235317019Sdim // Do not allow conflicts with the watchOS target. 1236317019Sdim if (!WatchOSTarget.empty() && (!iOSTarget.empty() || !TvOSTarget.empty())) { 1237317019Sdim getDriver().Diag(diag::err_drv_conflicting_deployment_targets) 1238317019Sdim << "WATCHOS_DEPLOYMENT_TARGET" 1239317019Sdim << (!iOSTarget.empty() ? "IPHONEOS_DEPLOYMENT_TARGET" : 1240317019Sdim "TVOS_DEPLOYMENT_TARGET"); 1241317019Sdim } 1242317019Sdim 1243317019Sdim // Do not allow conflicts with the tvOS target. 1244317019Sdim if (!TvOSTarget.empty() && !iOSTarget.empty()) { 1245317019Sdim getDriver().Diag(diag::err_drv_conflicting_deployment_targets) 1246317019Sdim << "TVOS_DEPLOYMENT_TARGET" 1247317019Sdim << "IPHONEOS_DEPLOYMENT_TARGET"; 1248317019Sdim } 1249317019Sdim 1250317019Sdim // Allow conflicts among OSX and iOS for historical reasons, but choose the 1251317019Sdim // default platform. 1252317019Sdim if (!OSXTarget.empty() && (!iOSTarget.empty() || 1253317019Sdim !WatchOSTarget.empty() || 1254317019Sdim !TvOSTarget.empty())) { 1255317019Sdim if (getTriple().getArch() == llvm::Triple::arm || 1256317019Sdim getTriple().getArch() == llvm::Triple::aarch64 || 1257317019Sdim getTriple().getArch() == llvm::Triple::thumb) 1258317019Sdim OSXTarget = ""; 1259317019Sdim else 1260317019Sdim iOSTarget = WatchOSTarget = TvOSTarget = ""; 1261317019Sdim } 1262317019Sdim 1263317019Sdim if (!OSXTarget.empty()) { 1264317019Sdim const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); 1265317019Sdim OSXVersion = Args.MakeJoinedArg(nullptr, O, OSXTarget); 1266317019Sdim Args.append(OSXVersion); 1267317019Sdim } else if (!iOSTarget.empty()) { 1268317019Sdim const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ); 1269317019Sdim iOSVersion = Args.MakeJoinedArg(nullptr, O, iOSTarget); 1270317019Sdim Args.append(iOSVersion); 1271317019Sdim } else if (!TvOSTarget.empty()) { 1272317019Sdim const Option O = Opts.getOption(options::OPT_mtvos_version_min_EQ); 1273317019Sdim TvOSVersion = Args.MakeJoinedArg(nullptr, O, TvOSTarget); 1274317019Sdim Args.append(TvOSVersion); 1275317019Sdim } else if (!WatchOSTarget.empty()) { 1276317019Sdim const Option O = Opts.getOption(options::OPT_mwatchos_version_min_EQ); 1277317019Sdim WatchOSVersion = Args.MakeJoinedArg(nullptr, O, WatchOSTarget); 1278317019Sdim Args.append(WatchOSVersion); 1279317019Sdim } 1280317019Sdim } 1281317019Sdim 1282317019Sdim DarwinPlatformKind Platform; 1283317019Sdim if (OSXVersion) 1284317019Sdim Platform = MacOS; 1285317019Sdim else if (iOSVersion) 1286317019Sdim Platform = IPhoneOS; 1287317019Sdim else if (TvOSVersion) 1288317019Sdim Platform = TvOS; 1289317019Sdim else if (WatchOSVersion) 1290317019Sdim Platform = WatchOS; 1291317019Sdim else 1292317019Sdim llvm_unreachable("Unable to infer Darwin variant"); 1293317019Sdim 1294317019Sdim // Set the tool chain target information. 1295317019Sdim unsigned Major, Minor, Micro; 1296317019Sdim bool HadExtra; 1297317019Sdim if (Platform == MacOS) { 1298317019Sdim assert((!iOSVersion && !TvOSVersion && !WatchOSVersion) && 1299317019Sdim "Unknown target platform!"); 1300317019Sdim if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor, Micro, 1301317019Sdim HadExtra) || 1302317019Sdim HadExtra || Major != 10 || Minor >= 100 || Micro >= 100) 1303317019Sdim getDriver().Diag(diag::err_drv_invalid_version_number) 1304317019Sdim << OSXVersion->getAsString(Args); 1305317019Sdim } else if (Platform == IPhoneOS) { 1306317019Sdim assert(iOSVersion && "Unknown target platform!"); 1307317019Sdim if (!Driver::GetReleaseVersion(iOSVersion->getValue(), Major, Minor, Micro, 1308317019Sdim HadExtra) || 1309317019Sdim HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100) 1310317019Sdim getDriver().Diag(diag::err_drv_invalid_version_number) 1311317019Sdim << iOSVersion->getAsString(Args); 1312317019Sdim } else if (Platform == TvOS) { 1313317019Sdim if (!Driver::GetReleaseVersion(TvOSVersion->getValue(), Major, Minor, 1314317019Sdim Micro, HadExtra) || HadExtra || 1315317019Sdim Major >= 100 || Minor >= 100 || Micro >= 100) 1316317019Sdim getDriver().Diag(diag::err_drv_invalid_version_number) 1317317019Sdim << TvOSVersion->getAsString(Args); 1318317019Sdim } else if (Platform == WatchOS) { 1319317019Sdim if (!Driver::GetReleaseVersion(WatchOSVersion->getValue(), Major, Minor, 1320317019Sdim Micro, HadExtra) || HadExtra || 1321317019Sdim Major >= 10 || Minor >= 100 || Micro >= 100) 1322317019Sdim getDriver().Diag(diag::err_drv_invalid_version_number) 1323317019Sdim << WatchOSVersion->getAsString(Args); 1324317019Sdim } else 1325317019Sdim llvm_unreachable("unknown kind of Darwin platform"); 1326317019Sdim 1327317019Sdim // Recognize iOS targets with an x86 architecture as the iOS simulator. 1328317019Sdim if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 || 1329317019Sdim getTriple().getArch() == llvm::Triple::x86_64)) 1330317019Sdim Platform = IPhoneOSSimulator; 1331317019Sdim if (TvOSVersion && (getTriple().getArch() == llvm::Triple::x86 || 1332317019Sdim getTriple().getArch() == llvm::Triple::x86_64)) 1333317019Sdim Platform = TvOSSimulator; 1334317019Sdim if (WatchOSVersion && (getTriple().getArch() == llvm::Triple::x86 || 1335317019Sdim getTriple().getArch() == llvm::Triple::x86_64)) 1336317019Sdim Platform = WatchOSSimulator; 1337317019Sdim 1338317019Sdim setTarget(Platform, Major, Minor, Micro); 1339317019Sdim 1340317019Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 1341317019Sdim StringRef SDK = getSDKName(A->getValue()); 1342317019Sdim if (SDK.size() > 0) { 1343317019Sdim size_t StartVer = SDK.find_first_of("0123456789"); 1344317019Sdim StringRef SDKName = SDK.slice(0, StartVer); 1345317019Sdim if (!SDKName.startswith(getPlatformFamily())) 1346317019Sdim getDriver().Diag(diag::warn_incompatible_sysroot) 1347317019Sdim << SDKName << getPlatformFamily(); 1348317019Sdim } 1349317019Sdim } 1350317019Sdim} 1351317019Sdim 1352317019Sdimvoid DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args, 1353317019Sdim ArgStringList &CmdArgs) const { 1354317019Sdim CXXStdlibType Type = GetCXXStdlibType(Args); 1355317019Sdim 1356317019Sdim switch (Type) { 1357317019Sdim case ToolChain::CST_Libcxx: 1358317019Sdim CmdArgs.push_back("-lc++"); 1359317019Sdim break; 1360317019Sdim 1361317019Sdim case ToolChain::CST_Libstdcxx: 1362317019Sdim // Unfortunately, -lstdc++ doesn't always exist in the standard search path; 1363317019Sdim // it was previously found in the gcc lib dir. However, for all the Darwin 1364317019Sdim // platforms we care about it was -lstdc++.6, so we search for that 1365317019Sdim // explicitly if we can't see an obvious -lstdc++ candidate. 1366317019Sdim 1367317019Sdim // Check in the sysroot first. 1368317019Sdim if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 1369317019Sdim SmallString<128> P(A->getValue()); 1370317019Sdim llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib"); 1371317019Sdim 1372317019Sdim if (!getVFS().exists(P)) { 1373317019Sdim llvm::sys::path::remove_filename(P); 1374317019Sdim llvm::sys::path::append(P, "libstdc++.6.dylib"); 1375317019Sdim if (getVFS().exists(P)) { 1376317019Sdim CmdArgs.push_back(Args.MakeArgString(P)); 1377317019Sdim return; 1378317019Sdim } 1379317019Sdim } 1380317019Sdim } 1381317019Sdim 1382317019Sdim // Otherwise, look in the root. 1383317019Sdim // FIXME: This should be removed someday when we don't have to care about 1384317019Sdim // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist. 1385317019Sdim if (!getVFS().exists("/usr/lib/libstdc++.dylib") && 1386317019Sdim getVFS().exists("/usr/lib/libstdc++.6.dylib")) { 1387317019Sdim CmdArgs.push_back("/usr/lib/libstdc++.6.dylib"); 1388317019Sdim return; 1389317019Sdim } 1390317019Sdim 1391317019Sdim // Otherwise, let the linker search. 1392317019Sdim CmdArgs.push_back("-lstdc++"); 1393317019Sdim break; 1394317019Sdim } 1395317019Sdim} 1396317019Sdim 1397317019Sdimvoid DarwinClang::AddCCKextLibArgs(const ArgList &Args, 1398317019Sdim ArgStringList &CmdArgs) const { 1399317019Sdim // For Darwin platforms, use the compiler-rt-based support library 1400317019Sdim // instead of the gcc-provided one (which is also incidentally 1401317019Sdim // only present in the gcc lib dir, which makes it hard to find). 1402317019Sdim 1403317019Sdim SmallString<128> P(getDriver().ResourceDir); 1404317019Sdim llvm::sys::path::append(P, "lib", "darwin"); 1405317019Sdim 1406317019Sdim // Use the newer cc_kext for iOS ARM after 6.0. 1407317019Sdim if (isTargetWatchOS()) { 1408317019Sdim llvm::sys::path::append(P, "libclang_rt.cc_kext_watchos.a"); 1409317019Sdim } else if (isTargetTvOS()) { 1410317019Sdim llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a"); 1411317019Sdim } else if (isTargetIPhoneOS()) { 1412317019Sdim llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a"); 1413317019Sdim } else { 1414317019Sdim llvm::sys::path::append(P, "libclang_rt.cc_kext.a"); 1415317019Sdim } 1416317019Sdim 1417317019Sdim // For now, allow missing resource libraries to support developers who may 1418317019Sdim // not have compiler-rt checked out or integrated into their build. 1419317019Sdim if (getVFS().exists(P)) 1420317019Sdim CmdArgs.push_back(Args.MakeArgString(P)); 1421317019Sdim} 1422317019Sdim 1423317019SdimDerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args, 1424317019Sdim StringRef BoundArch, 1425317019Sdim Action::OffloadKind) const { 1426317019Sdim DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); 1427317019Sdim const OptTable &Opts = getDriver().getOpts(); 1428317019Sdim 1429317019Sdim // FIXME: We really want to get out of the tool chain level argument 1430317019Sdim // translation business, as it makes the driver functionality much 1431317019Sdim // more opaque. For now, we follow gcc closely solely for the 1432317019Sdim // purpose of easily achieving feature parity & testability. Once we 1433317019Sdim // have something that works, we should reevaluate each translation 1434317019Sdim // and try to push it down into tool specific logic. 1435317019Sdim 1436317019Sdim for (Arg *A : Args) { 1437317019Sdim if (A->getOption().matches(options::OPT_Xarch__)) { 1438317019Sdim // Skip this argument unless the architecture matches either the toolchain 1439317019Sdim // triple arch, or the arch being bound. 1440317019Sdim llvm::Triple::ArchType XarchArch = 1441317019Sdim tools::darwin::getArchTypeForMachOArchName(A->getValue(0)); 1442317019Sdim if (!(XarchArch == getArch() || 1443317019Sdim (!BoundArch.empty() && 1444317019Sdim XarchArch == 1445317019Sdim tools::darwin::getArchTypeForMachOArchName(BoundArch)))) 1446317019Sdim continue; 1447317019Sdim 1448317019Sdim Arg *OriginalArg = A; 1449317019Sdim unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1)); 1450317019Sdim unsigned Prev = Index; 1451317019Sdim std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index)); 1452317019Sdim 1453317019Sdim // If the argument parsing failed or more than one argument was 1454317019Sdim // consumed, the -Xarch_ argument's parameter tried to consume 1455317019Sdim // extra arguments. Emit an error and ignore. 1456317019Sdim // 1457317019Sdim // We also want to disallow any options which would alter the 1458317019Sdim // driver behavior; that isn't going to work in our model. We 1459317019Sdim // use isDriverOption() as an approximation, although things 1460317019Sdim // like -O4 are going to slip through. 1461317019Sdim if (!XarchArg || Index > Prev + 1) { 1462317019Sdim getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args) 1463317019Sdim << A->getAsString(Args); 1464317019Sdim continue; 1465317019Sdim } else if (XarchArg->getOption().hasFlag(options::DriverOption)) { 1466317019Sdim getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver) 1467317019Sdim << A->getAsString(Args); 1468317019Sdim continue; 1469317019Sdim } 1470317019Sdim 1471317019Sdim XarchArg->setBaseArg(A); 1472317019Sdim 1473317019Sdim A = XarchArg.release(); 1474317019Sdim DAL->AddSynthesizedArg(A); 1475317019Sdim 1476317019Sdim // Linker input arguments require custom handling. The problem is that we 1477317019Sdim // have already constructed the phase actions, so we can not treat them as 1478317019Sdim // "input arguments". 1479317019Sdim if (A->getOption().hasFlag(options::LinkerInput)) { 1480317019Sdim // Convert the argument into individual Zlinker_input_args. 1481317019Sdim for (const char *Value : A->getValues()) { 1482317019Sdim DAL->AddSeparateArg( 1483317019Sdim OriginalArg, Opts.getOption(options::OPT_Zlinker_input), Value); 1484317019Sdim } 1485317019Sdim continue; 1486317019Sdim } 1487317019Sdim } 1488317019Sdim 1489317019Sdim // Sob. These is strictly gcc compatible for the time being. Apple 1490317019Sdim // gcc translates options twice, which means that self-expanding 1491317019Sdim // options add duplicates. 1492317019Sdim switch ((options::ID)A->getOption().getID()) { 1493317019Sdim default: 1494317019Sdim DAL->append(A); 1495317019Sdim break; 1496317019Sdim 1497317019Sdim case options::OPT_mkernel: 1498317019Sdim case options::OPT_fapple_kext: 1499317019Sdim DAL->append(A); 1500317019Sdim DAL->AddFlagArg(A, Opts.getOption(options::OPT_static)); 1501317019Sdim break; 1502317019Sdim 1503317019Sdim case options::OPT_dependency_file: 1504317019Sdim DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue()); 1505317019Sdim break; 1506317019Sdim 1507317019Sdim case options::OPT_gfull: 1508317019Sdim DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); 1509317019Sdim DAL->AddFlagArg( 1510317019Sdim A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)); 1511317019Sdim break; 1512317019Sdim 1513317019Sdim case options::OPT_gused: 1514317019Sdim DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); 1515317019Sdim DAL->AddFlagArg( 1516317019Sdim A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols)); 1517317019Sdim break; 1518317019Sdim 1519317019Sdim case options::OPT_shared: 1520317019Sdim DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib)); 1521317019Sdim break; 1522317019Sdim 1523317019Sdim case options::OPT_fconstant_cfstrings: 1524317019Sdim DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings)); 1525317019Sdim break; 1526317019Sdim 1527317019Sdim case options::OPT_fno_constant_cfstrings: 1528317019Sdim DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings)); 1529317019Sdim break; 1530317019Sdim 1531317019Sdim case options::OPT_Wnonportable_cfstrings: 1532317019Sdim DAL->AddFlagArg(A, 1533317019Sdim Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)); 1534317019Sdim break; 1535317019Sdim 1536317019Sdim case options::OPT_Wno_nonportable_cfstrings: 1537317019Sdim DAL->AddFlagArg( 1538317019Sdim A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)); 1539317019Sdim break; 1540317019Sdim 1541317019Sdim case options::OPT_fpascal_strings: 1542317019Sdim DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings)); 1543317019Sdim break; 1544317019Sdim 1545317019Sdim case options::OPT_fno_pascal_strings: 1546317019Sdim DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings)); 1547317019Sdim break; 1548317019Sdim } 1549317019Sdim } 1550317019Sdim 1551317019Sdim if (getTriple().getArch() == llvm::Triple::x86 || 1552317019Sdim getTriple().getArch() == llvm::Triple::x86_64) 1553317019Sdim if (!Args.hasArgNoClaim(options::OPT_mtune_EQ)) 1554317019Sdim DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_mtune_EQ), 1555317019Sdim "core2"); 1556317019Sdim 1557317019Sdim // Add the arch options based on the particular spelling of -arch, to match 1558317019Sdim // how the driver driver works. 1559317019Sdim if (!BoundArch.empty()) { 1560317019Sdim StringRef Name = BoundArch; 1561317019Sdim const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ); 1562317019Sdim const Option MArch = Opts.getOption(clang::driver::options::OPT_march_EQ); 1563317019Sdim 1564317019Sdim // This code must be kept in sync with LLVM's getArchTypeForDarwinArch, 1565317019Sdim // which defines the list of which architectures we accept. 1566317019Sdim if (Name == "ppc") 1567317019Sdim ; 1568317019Sdim else if (Name == "ppc601") 1569317019Sdim DAL->AddJoinedArg(nullptr, MCpu, "601"); 1570317019Sdim else if (Name == "ppc603") 1571317019Sdim DAL->AddJoinedArg(nullptr, MCpu, "603"); 1572317019Sdim else if (Name == "ppc604") 1573317019Sdim DAL->AddJoinedArg(nullptr, MCpu, "604"); 1574317019Sdim else if (Name == "ppc604e") 1575317019Sdim DAL->AddJoinedArg(nullptr, MCpu, "604e"); 1576317019Sdim else if (Name == "ppc750") 1577317019Sdim DAL->AddJoinedArg(nullptr, MCpu, "750"); 1578317019Sdim else if (Name == "ppc7400") 1579317019Sdim DAL->AddJoinedArg(nullptr, MCpu, "7400"); 1580317019Sdim else if (Name == "ppc7450") 1581317019Sdim DAL->AddJoinedArg(nullptr, MCpu, "7450"); 1582317019Sdim else if (Name == "ppc970") 1583317019Sdim DAL->AddJoinedArg(nullptr, MCpu, "970"); 1584317019Sdim 1585317019Sdim else if (Name == "ppc64" || Name == "ppc64le") 1586317019Sdim DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64)); 1587317019Sdim 1588317019Sdim else if (Name == "i386") 1589317019Sdim ; 1590317019Sdim else if (Name == "i486") 1591317019Sdim DAL->AddJoinedArg(nullptr, MArch, "i486"); 1592317019Sdim else if (Name == "i586") 1593317019Sdim DAL->AddJoinedArg(nullptr, MArch, "i586"); 1594317019Sdim else if (Name == "i686") 1595317019Sdim DAL->AddJoinedArg(nullptr, MArch, "i686"); 1596317019Sdim else if (Name == "pentium") 1597317019Sdim DAL->AddJoinedArg(nullptr, MArch, "pentium"); 1598317019Sdim else if (Name == "pentium2") 1599317019Sdim DAL->AddJoinedArg(nullptr, MArch, "pentium2"); 1600317019Sdim else if (Name == "pentpro") 1601317019Sdim DAL->AddJoinedArg(nullptr, MArch, "pentiumpro"); 1602317019Sdim else if (Name == "pentIIm3") 1603317019Sdim DAL->AddJoinedArg(nullptr, MArch, "pentium2"); 1604317019Sdim 1605317019Sdim else if (Name == "x86_64") 1606317019Sdim DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64)); 1607317019Sdim else if (Name == "x86_64h") { 1608317019Sdim DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64)); 1609317019Sdim DAL->AddJoinedArg(nullptr, MArch, "x86_64h"); 1610317019Sdim } 1611317019Sdim 1612317019Sdim else if (Name == "arm") 1613317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv4t"); 1614317019Sdim else if (Name == "armv4t") 1615317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv4t"); 1616317019Sdim else if (Name == "armv5") 1617317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv5tej"); 1618317019Sdim else if (Name == "xscale") 1619317019Sdim DAL->AddJoinedArg(nullptr, MArch, "xscale"); 1620317019Sdim else if (Name == "armv6") 1621317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv6k"); 1622317019Sdim else if (Name == "armv6m") 1623317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv6m"); 1624317019Sdim else if (Name == "armv7") 1625317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv7a"); 1626317019Sdim else if (Name == "armv7em") 1627317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv7em"); 1628317019Sdim else if (Name == "armv7k") 1629317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv7k"); 1630317019Sdim else if (Name == "armv7m") 1631317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv7m"); 1632317019Sdim else if (Name == "armv7s") 1633317019Sdim DAL->AddJoinedArg(nullptr, MArch, "armv7s"); 1634317019Sdim } 1635317019Sdim 1636317019Sdim return DAL; 1637317019Sdim} 1638317019Sdim 1639317019Sdimvoid MachO::AddLinkRuntimeLibArgs(const ArgList &Args, 1640317019Sdim ArgStringList &CmdArgs) const { 1641317019Sdim // Embedded targets are simple at the moment, not supporting sanitizers and 1642317019Sdim // with different libraries for each member of the product { static, PIC } x 1643317019Sdim // { hard-float, soft-float } 1644317019Sdim llvm::SmallString<32> CompilerRT = StringRef("libclang_rt."); 1645317019Sdim CompilerRT += 1646317019Sdim (tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard) 1647317019Sdim ? "hard" 1648317019Sdim : "soft"; 1649317019Sdim CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic.a" : "_static.a"; 1650317019Sdim 1651317019Sdim AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, false, true); 1652317019Sdim} 1653317019Sdim 1654317019SdimDerivedArgList * 1655317019SdimDarwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch, 1656317019Sdim Action::OffloadKind DeviceOffloadKind) const { 1657317019Sdim // First get the generic Apple args, before moving onto Darwin-specific ones. 1658317019Sdim DerivedArgList *DAL = 1659317019Sdim MachO::TranslateArgs(Args, BoundArch, DeviceOffloadKind); 1660317019Sdim const OptTable &Opts = getDriver().getOpts(); 1661317019Sdim 1662317019Sdim // If no architecture is bound, none of the translations here are relevant. 1663317019Sdim if (BoundArch.empty()) 1664317019Sdim return DAL; 1665317019Sdim 1666317019Sdim // Add an explicit version min argument for the deployment target. We do this 1667317019Sdim // after argument translation because -Xarch_ arguments may add a version min 1668317019Sdim // argument. 1669317019Sdim AddDeploymentTarget(*DAL); 1670317019Sdim 1671317019Sdim // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext. 1672317019Sdim // FIXME: It would be far better to avoid inserting those -static arguments, 1673317019Sdim // but we can't check the deployment target in the translation code until 1674317019Sdim // it is set here. 1675317019Sdim if (isTargetWatchOSBased() || 1676317019Sdim (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) { 1677317019Sdim for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) { 1678317019Sdim Arg *A = *it; 1679317019Sdim ++it; 1680317019Sdim if (A->getOption().getID() != options::OPT_mkernel && 1681317019Sdim A->getOption().getID() != options::OPT_fapple_kext) 1682317019Sdim continue; 1683317019Sdim assert(it != ie && "unexpected argument translation"); 1684317019Sdim A = *it; 1685317019Sdim assert(A->getOption().getID() == options::OPT_static && 1686317019Sdim "missing expected -static argument"); 1687317019Sdim *it = nullptr; 1688317019Sdim ++it; 1689317019Sdim } 1690317019Sdim } 1691317019Sdim 1692317019Sdim if (!Args.getLastArg(options::OPT_stdlib_EQ) && 1693317019Sdim GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) 1694317019Sdim DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_stdlib_EQ), 1695317019Sdim "libc++"); 1696317019Sdim 1697317019Sdim // Validate the C++ standard library choice. 1698317019Sdim CXXStdlibType Type = GetCXXStdlibType(*DAL); 1699317019Sdim if (Type == ToolChain::CST_Libcxx) { 1700317019Sdim // Check whether the target provides libc++. 1701317019Sdim StringRef where; 1702317019Sdim 1703317019Sdim // Complain about targeting iOS < 5.0 in any way. 1704317019Sdim if (isTargetIOSBased() && isIPhoneOSVersionLT(5, 0)) 1705317019Sdim where = "iOS 5.0"; 1706317019Sdim 1707317019Sdim if (where != StringRef()) { 1708317019Sdim getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment) << where; 1709317019Sdim } 1710317019Sdim } 1711317019Sdim 1712317019Sdim auto Arch = tools::darwin::getArchTypeForMachOArchName(BoundArch); 1713317019Sdim if ((Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)) { 1714317019Sdim if (Args.hasFlag(options::OPT_fomit_frame_pointer, 1715317019Sdim options::OPT_fno_omit_frame_pointer, false)) 1716317019Sdim getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target) 1717317019Sdim << "-fomit-frame-pointer" << BoundArch; 1718317019Sdim } 1719317019Sdim 1720317019Sdim return DAL; 1721317019Sdim} 1722317019Sdim 1723317019Sdimbool MachO::IsUnwindTablesDefault() const { 1724317019Sdim return getArch() == llvm::Triple::x86_64; 1725317019Sdim} 1726317019Sdim 1727317019Sdimbool MachO::UseDwarfDebugFlags() const { 1728317019Sdim if (const char *S = ::getenv("RC_DEBUG_OPTIONS")) 1729317019Sdim return S[0] != '\0'; 1730317019Sdim return false; 1731317019Sdim} 1732317019Sdim 1733317019Sdimbool Darwin::UseSjLjExceptions(const ArgList &Args) const { 1734317019Sdim // Darwin uses SjLj exceptions on ARM. 1735317019Sdim if (getTriple().getArch() != llvm::Triple::arm && 1736317019Sdim getTriple().getArch() != llvm::Triple::thumb) 1737317019Sdim return false; 1738317019Sdim 1739317019Sdim // Only watchOS uses the new DWARF/Compact unwinding method. 1740317019Sdim llvm::Triple Triple(ComputeLLVMTriple(Args)); 1741317019Sdim return !Triple.isWatchABI(); 1742317019Sdim} 1743317019Sdim 1744317019Sdimbool Darwin::SupportsEmbeddedBitcode() const { 1745317019Sdim assert(TargetInitialized && "Target not initialized!"); 1746317019Sdim if (isTargetIPhoneOS() && isIPhoneOSVersionLT(6, 0)) 1747317019Sdim return false; 1748317019Sdim return true; 1749317019Sdim} 1750317019Sdim 1751317019Sdimbool MachO::isPICDefault() const { return true; } 1752317019Sdim 1753317019Sdimbool MachO::isPIEDefault() const { return false; } 1754317019Sdim 1755317019Sdimbool MachO::isPICDefaultForced() const { 1756317019Sdim return (getArch() == llvm::Triple::x86_64 || 1757317019Sdim getArch() == llvm::Triple::aarch64); 1758317019Sdim} 1759317019Sdim 1760317019Sdimbool MachO::SupportsProfiling() const { 1761317019Sdim // Profiling instrumentation is only supported on x86. 1762317019Sdim return getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64; 1763317019Sdim} 1764317019Sdim 1765317019Sdimvoid Darwin::addMinVersionArgs(const ArgList &Args, 1766317019Sdim ArgStringList &CmdArgs) const { 1767317019Sdim VersionTuple TargetVersion = getTargetVersion(); 1768317019Sdim 1769317019Sdim if (isTargetWatchOS()) 1770317019Sdim CmdArgs.push_back("-watchos_version_min"); 1771317019Sdim else if (isTargetWatchOSSimulator()) 1772317019Sdim CmdArgs.push_back("-watchos_simulator_version_min"); 1773317019Sdim else if (isTargetTvOS()) 1774317019Sdim CmdArgs.push_back("-tvos_version_min"); 1775317019Sdim else if (isTargetTvOSSimulator()) 1776317019Sdim CmdArgs.push_back("-tvos_simulator_version_min"); 1777317019Sdim else if (isTargetIOSSimulator()) 1778317019Sdim CmdArgs.push_back("-ios_simulator_version_min"); 1779317019Sdim else if (isTargetIOSBased()) 1780317019Sdim CmdArgs.push_back("-iphoneos_version_min"); 1781317019Sdim else { 1782317019Sdim assert(isTargetMacOS() && "unexpected target"); 1783317019Sdim CmdArgs.push_back("-macosx_version_min"); 1784317019Sdim } 1785317019Sdim 1786317019Sdim CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); 1787317019Sdim} 1788317019Sdim 1789317019Sdimvoid Darwin::addStartObjectFileArgs(const ArgList &Args, 1790317019Sdim ArgStringList &CmdArgs) const { 1791317019Sdim // Derived from startfile spec. 1792317019Sdim if (Args.hasArg(options::OPT_dynamiclib)) { 1793317019Sdim // Derived from darwin_dylib1 spec. 1794317019Sdim if (isTargetWatchOSBased()) { 1795317019Sdim ; // watchOS does not need dylib1.o. 1796317019Sdim } else if (isTargetIOSSimulator()) { 1797317019Sdim ; // iOS simulator does not need dylib1.o. 1798317019Sdim } else if (isTargetIPhoneOS()) { 1799317019Sdim if (isIPhoneOSVersionLT(3, 1)) 1800317019Sdim CmdArgs.push_back("-ldylib1.o"); 1801317019Sdim } else { 1802317019Sdim if (isMacosxVersionLT(10, 5)) 1803317019Sdim CmdArgs.push_back("-ldylib1.o"); 1804317019Sdim else if (isMacosxVersionLT(10, 6)) 1805317019Sdim CmdArgs.push_back("-ldylib1.10.5.o"); 1806317019Sdim } 1807317019Sdim } else { 1808317019Sdim if (Args.hasArg(options::OPT_bundle)) { 1809317019Sdim if (!Args.hasArg(options::OPT_static)) { 1810317019Sdim // Derived from darwin_bundle1 spec. 1811317019Sdim if (isTargetWatchOSBased()) { 1812317019Sdim ; // watchOS does not need bundle1.o. 1813317019Sdim } else if (isTargetIOSSimulator()) { 1814317019Sdim ; // iOS simulator does not need bundle1.o. 1815317019Sdim } else if (isTargetIPhoneOS()) { 1816317019Sdim if (isIPhoneOSVersionLT(3, 1)) 1817317019Sdim CmdArgs.push_back("-lbundle1.o"); 1818317019Sdim } else { 1819317019Sdim if (isMacosxVersionLT(10, 6)) 1820317019Sdim CmdArgs.push_back("-lbundle1.o"); 1821317019Sdim } 1822317019Sdim } 1823317019Sdim } else { 1824317019Sdim if (Args.hasArg(options::OPT_pg) && SupportsProfiling()) { 1825317019Sdim if (Args.hasArg(options::OPT_static) || 1826317019Sdim Args.hasArg(options::OPT_object) || 1827317019Sdim Args.hasArg(options::OPT_preload)) { 1828317019Sdim CmdArgs.push_back("-lgcrt0.o"); 1829317019Sdim } else { 1830317019Sdim CmdArgs.push_back("-lgcrt1.o"); 1831317019Sdim 1832317019Sdim // darwin_crt2 spec is empty. 1833317019Sdim } 1834317019Sdim // By default on OS X 10.8 and later, we don't link with a crt1.o 1835317019Sdim // file and the linker knows to use _main as the entry point. But, 1836317019Sdim // when compiling with -pg, we need to link with the gcrt1.o file, 1837317019Sdim // so pass the -no_new_main option to tell the linker to use the 1838317019Sdim // "start" symbol as the entry point. 1839317019Sdim if (isTargetMacOS() && !isMacosxVersionLT(10, 8)) 1840317019Sdim CmdArgs.push_back("-no_new_main"); 1841317019Sdim } else { 1842317019Sdim if (Args.hasArg(options::OPT_static) || 1843317019Sdim Args.hasArg(options::OPT_object) || 1844317019Sdim Args.hasArg(options::OPT_preload)) { 1845317019Sdim CmdArgs.push_back("-lcrt0.o"); 1846317019Sdim } else { 1847317019Sdim // Derived from darwin_crt1 spec. 1848317019Sdim if (isTargetWatchOSBased()) { 1849317019Sdim ; // watchOS does not need crt1.o. 1850317019Sdim } else if (isTargetIOSSimulator()) { 1851317019Sdim ; // iOS simulator does not need crt1.o. 1852317019Sdim } else if (isTargetIPhoneOS()) { 1853317019Sdim if (getArch() == llvm::Triple::aarch64) 1854317019Sdim ; // iOS does not need any crt1 files for arm64 1855317019Sdim else if (isIPhoneOSVersionLT(3, 1)) 1856317019Sdim CmdArgs.push_back("-lcrt1.o"); 1857317019Sdim else if (isIPhoneOSVersionLT(6, 0)) 1858317019Sdim CmdArgs.push_back("-lcrt1.3.1.o"); 1859317019Sdim } else { 1860317019Sdim if (isMacosxVersionLT(10, 5)) 1861317019Sdim CmdArgs.push_back("-lcrt1.o"); 1862317019Sdim else if (isMacosxVersionLT(10, 6)) 1863317019Sdim CmdArgs.push_back("-lcrt1.10.5.o"); 1864317019Sdim else if (isMacosxVersionLT(10, 8)) 1865317019Sdim CmdArgs.push_back("-lcrt1.10.6.o"); 1866317019Sdim 1867317019Sdim // darwin_crt2 spec is empty. 1868317019Sdim } 1869317019Sdim } 1870317019Sdim } 1871317019Sdim } 1872317019Sdim } 1873317019Sdim 1874317019Sdim if (!isTargetIPhoneOS() && Args.hasArg(options::OPT_shared_libgcc) && 1875317019Sdim !isTargetWatchOS() && 1876317019Sdim isMacosxVersionLT(10, 5)) { 1877317019Sdim const char *Str = Args.MakeArgString(GetFilePath("crt3.o")); 1878317019Sdim CmdArgs.push_back(Str); 1879317019Sdim } 1880317019Sdim} 1881317019Sdim 1882317019Sdimbool Darwin::SupportsObjCGC() const { return isTargetMacOS(); } 1883317019Sdim 1884317019Sdimvoid Darwin::CheckObjCARC() const { 1885317019Sdim if (isTargetIOSBased() || isTargetWatchOSBased() || 1886317019Sdim (isTargetMacOS() && !isMacosxVersionLT(10, 6))) 1887317019Sdim return; 1888317019Sdim getDriver().Diag(diag::err_arc_unsupported_on_toolchain); 1889317019Sdim} 1890317019Sdim 1891317019SdimSanitizerMask Darwin::getSupportedSanitizers() const { 1892317019Sdim const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; 1893317019Sdim SanitizerMask Res = ToolChain::getSupportedSanitizers(); 1894317019Sdim Res |= SanitizerKind::Address; 1895317019Sdim if (isTargetMacOS()) { 1896317019Sdim if (!isMacosxVersionLT(10, 9)) 1897317019Sdim Res |= SanitizerKind::Vptr; 1898317019Sdim Res |= SanitizerKind::SafeStack; 1899317019Sdim if (IsX86_64) 1900317019Sdim Res |= SanitizerKind::Thread; 1901317019Sdim } else if (isTargetIOSSimulator() || isTargetTvOSSimulator()) { 1902317019Sdim if (IsX86_64) 1903317019Sdim Res |= SanitizerKind::Thread; 1904317019Sdim } 1905317019Sdim return Res; 1906317019Sdim} 1907317019Sdim 1908317019Sdimvoid Darwin::printVerboseInfo(raw_ostream &OS) const { 1909317019Sdim CudaInstallation.print(OS); 1910317019Sdim} 1911