1*0b57cec5SDimitry Andric //===--- Darwin.h - Darwin ToolChain Implementations ------------*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H 10*0b57cec5SDimitry Andric #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H 11*0b57cec5SDimitry Andric 12*0b57cec5SDimitry Andric #include "Cuda.h" 13*0b57cec5SDimitry Andric #include "clang/Driver/DarwinSDKInfo.h" 14*0b57cec5SDimitry Andric #include "clang/Driver/Tool.h" 15*0b57cec5SDimitry Andric #include "clang/Driver/ToolChain.h" 16*0b57cec5SDimitry Andric #include "clang/Driver/XRayArgs.h" 17*0b57cec5SDimitry Andric 18*0b57cec5SDimitry Andric namespace clang { 19*0b57cec5SDimitry Andric namespace driver { 20*0b57cec5SDimitry Andric 21*0b57cec5SDimitry Andric namespace toolchains { 22*0b57cec5SDimitry Andric class MachO; 23*0b57cec5SDimitry Andric } // end namespace toolchains 24*0b57cec5SDimitry Andric 25*0b57cec5SDimitry Andric namespace tools { 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric namespace darwin { 28*0b57cec5SDimitry Andric llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str); 29*0b57cec5SDimitry Andric void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str); 30*0b57cec5SDimitry Andric 31*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MachOTool : public Tool { 32*0b57cec5SDimitry Andric virtual void anchor(); 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric protected: 35*0b57cec5SDimitry Andric void AddMachOArch(const llvm::opt::ArgList &Args, 36*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 37*0b57cec5SDimitry Andric 38*0b57cec5SDimitry Andric const toolchains::MachO &getMachOToolChain() const { 39*0b57cec5SDimitry Andric return reinterpret_cast<const toolchains::MachO &>(getToolChain()); 40*0b57cec5SDimitry Andric } 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric public: 43*0b57cec5SDimitry Andric MachOTool( 44*0b57cec5SDimitry Andric const char *Name, const char *ShortName, const ToolChain &TC, 45*0b57cec5SDimitry Andric ResponseFileSupport ResponseSupport = RF_None, 46*0b57cec5SDimitry Andric llvm::sys::WindowsEncodingMethod ResponseEncoding = llvm::sys::WEM_UTF8, 47*0b57cec5SDimitry Andric const char *ResponseFlag = "@") 48*0b57cec5SDimitry Andric : Tool(Name, ShortName, TC, ResponseSupport, ResponseEncoding, 49*0b57cec5SDimitry Andric ResponseFlag) {} 50*0b57cec5SDimitry Andric }; 51*0b57cec5SDimitry Andric 52*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Assembler : public MachOTool { 53*0b57cec5SDimitry Andric public: 54*0b57cec5SDimitry Andric Assembler(const ToolChain &TC) 55*0b57cec5SDimitry Andric : MachOTool("darwin::Assembler", "assembler", TC) {} 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 60*0b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 61*0b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 62*0b57cec5SDimitry Andric const char *LinkingOutput) const override; 63*0b57cec5SDimitry Andric }; 64*0b57cec5SDimitry Andric 65*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool { 66*0b57cec5SDimitry Andric bool NeedsTempPath(const InputInfoList &Inputs) const; 67*0b57cec5SDimitry Andric void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args, 68*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 69*0b57cec5SDimitry Andric const InputInfoList &Inputs) const; 70*0b57cec5SDimitry Andric 71*0b57cec5SDimitry Andric public: 72*0b57cec5SDimitry Andric Linker(const ToolChain &TC) 73*0b57cec5SDimitry Andric : MachOTool("darwin::Linker", "linker", TC, RF_FileList, 74*0b57cec5SDimitry Andric llvm::sys::WEM_UTF8, "-filelist") {} 75*0b57cec5SDimitry Andric 76*0b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 77*0b57cec5SDimitry Andric bool isLinkJob() const override { return true; } 78*0b57cec5SDimitry Andric 79*0b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 80*0b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 81*0b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 82*0b57cec5SDimitry Andric const char *LinkingOutput) const override; 83*0b57cec5SDimitry Andric }; 84*0b57cec5SDimitry Andric 85*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Lipo : public MachOTool { 86*0b57cec5SDimitry Andric public: 87*0b57cec5SDimitry Andric Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {} 88*0b57cec5SDimitry Andric 89*0b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 90*0b57cec5SDimitry Andric 91*0b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 92*0b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 93*0b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 94*0b57cec5SDimitry Andric const char *LinkingOutput) const override; 95*0b57cec5SDimitry Andric }; 96*0b57cec5SDimitry Andric 97*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Dsymutil : public MachOTool { 98*0b57cec5SDimitry Andric public: 99*0b57cec5SDimitry Andric Dsymutil(const ToolChain &TC) 100*0b57cec5SDimitry Andric : MachOTool("darwin::Dsymutil", "dsymutil", TC) {} 101*0b57cec5SDimitry Andric 102*0b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 103*0b57cec5SDimitry Andric bool isDsymutilJob() const override { return true; } 104*0b57cec5SDimitry Andric 105*0b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 106*0b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 107*0b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 108*0b57cec5SDimitry Andric const char *LinkingOutput) const override; 109*0b57cec5SDimitry Andric }; 110*0b57cec5SDimitry Andric 111*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY VerifyDebug : public MachOTool { 112*0b57cec5SDimitry Andric public: 113*0b57cec5SDimitry Andric VerifyDebug(const ToolChain &TC) 114*0b57cec5SDimitry Andric : MachOTool("darwin::VerifyDebug", "dwarfdump", TC) {} 115*0b57cec5SDimitry Andric 116*0b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 117*0b57cec5SDimitry Andric 118*0b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 119*0b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 120*0b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 121*0b57cec5SDimitry Andric const char *LinkingOutput) const override; 122*0b57cec5SDimitry Andric }; 123*0b57cec5SDimitry Andric } // end namespace darwin 124*0b57cec5SDimitry Andric } // end namespace tools 125*0b57cec5SDimitry Andric 126*0b57cec5SDimitry Andric namespace toolchains { 127*0b57cec5SDimitry Andric 128*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain { 129*0b57cec5SDimitry Andric protected: 130*0b57cec5SDimitry Andric Tool *buildAssembler() const override; 131*0b57cec5SDimitry Andric Tool *buildLinker() const override; 132*0b57cec5SDimitry Andric Tool *getTool(Action::ActionClass AC) const override; 133*0b57cec5SDimitry Andric 134*0b57cec5SDimitry Andric private: 135*0b57cec5SDimitry Andric mutable std::unique_ptr<tools::darwin::Lipo> Lipo; 136*0b57cec5SDimitry Andric mutable std::unique_ptr<tools::darwin::Dsymutil> Dsymutil; 137*0b57cec5SDimitry Andric mutable std::unique_ptr<tools::darwin::VerifyDebug> VerifyDebug; 138*0b57cec5SDimitry Andric 139*0b57cec5SDimitry Andric public: 140*0b57cec5SDimitry Andric MachO(const Driver &D, const llvm::Triple &Triple, 141*0b57cec5SDimitry Andric const llvm::opt::ArgList &Args); 142*0b57cec5SDimitry Andric ~MachO() override; 143*0b57cec5SDimitry Andric 144*0b57cec5SDimitry Andric /// @name MachO specific toolchain API 145*0b57cec5SDimitry Andric /// { 146*0b57cec5SDimitry Andric 147*0b57cec5SDimitry Andric /// Get the "MachO" arch name for a particular compiler invocation. For 148*0b57cec5SDimitry Andric /// example, Apple treats different ARM variations as distinct architectures. 149*0b57cec5SDimitry Andric StringRef getMachOArchName(const llvm::opt::ArgList &Args) const; 150*0b57cec5SDimitry Andric 151*0b57cec5SDimitry Andric /// Add the linker arguments to link the ARC runtime library. 152*0b57cec5SDimitry Andric virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args, 153*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const {} 154*0b57cec5SDimitry Andric 155*0b57cec5SDimitry Andric /// Add the linker arguments to link the compiler runtime library. 156*0b57cec5SDimitry Andric /// 157*0b57cec5SDimitry Andric /// FIXME: This API is intended for use with embedded libraries only, and is 158*0b57cec5SDimitry Andric /// misleadingly named. 159*0b57cec5SDimitry Andric virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, 160*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 161*0b57cec5SDimitry Andric bool ForceLinkBuiltinRT = false) const; 162*0b57cec5SDimitry Andric 163*0b57cec5SDimitry Andric virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args, 164*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const { 165*0b57cec5SDimitry Andric } 166*0b57cec5SDimitry Andric 167*0b57cec5SDimitry Andric virtual void addMinVersionArgs(const llvm::opt::ArgList &Args, 168*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const {} 169*0b57cec5SDimitry Andric 170*0b57cec5SDimitry Andric /// On some iOS platforms, kernel and kernel modules were built statically. Is 171*0b57cec5SDimitry Andric /// this such a target? 172*0b57cec5SDimitry Andric virtual bool isKernelStatic() const { return false; } 173*0b57cec5SDimitry Andric 174*0b57cec5SDimitry Andric /// Is the target either iOS or an iOS simulator? 175*0b57cec5SDimitry Andric bool isTargetIOSBased() const { return false; } 176*0b57cec5SDimitry Andric 177*0b57cec5SDimitry Andric /// Options to control how a runtime library is linked. 178*0b57cec5SDimitry Andric enum RuntimeLinkOptions : unsigned { 179*0b57cec5SDimitry Andric /// Link the library in even if it can't be found in the VFS. 180*0b57cec5SDimitry Andric RLO_AlwaysLink = 1 << 0, 181*0b57cec5SDimitry Andric 182*0b57cec5SDimitry Andric /// Use the embedded runtime from the macho_embedded directory. 183*0b57cec5SDimitry Andric RLO_IsEmbedded = 1 << 1, 184*0b57cec5SDimitry Andric 185*0b57cec5SDimitry Andric /// Emit rpaths for @executable_path as well as the resource directory. 186*0b57cec5SDimitry Andric RLO_AddRPath = 1 << 2, 187*0b57cec5SDimitry Andric 188*0b57cec5SDimitry Andric /// Link the library in before any others. 189*0b57cec5SDimitry Andric RLO_FirstLink = 1 << 3, 190*0b57cec5SDimitry Andric }; 191*0b57cec5SDimitry Andric 192*0b57cec5SDimitry Andric /// Add a runtime library to the list of items to link. 193*0b57cec5SDimitry Andric void AddLinkRuntimeLib(const llvm::opt::ArgList &Args, 194*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, StringRef Component, 195*0b57cec5SDimitry Andric RuntimeLinkOptions Opts = RuntimeLinkOptions(), 196*0b57cec5SDimitry Andric bool IsShared = false) const; 197*0b57cec5SDimitry Andric 198*0b57cec5SDimitry Andric /// Add any profiling runtime libraries that are needed. This is essentially a 199*0b57cec5SDimitry Andric /// MachO specific version of addProfileRT in Tools.cpp. 200*0b57cec5SDimitry Andric void addProfileRTLibs(const llvm::opt::ArgList &Args, 201*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override { 202*0b57cec5SDimitry Andric // There aren't any profiling libs for embedded targets currently. 203*0b57cec5SDimitry Andric } 204*0b57cec5SDimitry Andric 205*0b57cec5SDimitry Andric /// } 206*0b57cec5SDimitry Andric /// @name ToolChain Implementation 207*0b57cec5SDimitry Andric /// { 208*0b57cec5SDimitry Andric 209*0b57cec5SDimitry Andric types::ID LookupTypeForExtension(StringRef Ext) const override; 210*0b57cec5SDimitry Andric 211*0b57cec5SDimitry Andric bool HasNativeLLVMSupport() const override; 212*0b57cec5SDimitry Andric 213*0b57cec5SDimitry Andric llvm::opt::DerivedArgList * 214*0b57cec5SDimitry Andric TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 215*0b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 216*0b57cec5SDimitry Andric 217*0b57cec5SDimitry Andric bool IsBlocksDefault() const override { 218*0b57cec5SDimitry Andric // Always allow blocks on Apple; users interested in versioning are 219*0b57cec5SDimitry Andric // expected to use /usr/include/Block.h. 220*0b57cec5SDimitry Andric return true; 221*0b57cec5SDimitry Andric } 222*0b57cec5SDimitry Andric bool IsIntegratedAssemblerDefault() const override { 223*0b57cec5SDimitry Andric // Default integrated assembler to on for Apple's MachO targets. 224*0b57cec5SDimitry Andric return true; 225*0b57cec5SDimitry Andric } 226*0b57cec5SDimitry Andric 227*0b57cec5SDimitry Andric bool IsMathErrnoDefault() const override { return false; } 228*0b57cec5SDimitry Andric 229*0b57cec5SDimitry Andric bool IsEncodeExtendedBlockSignatureDefault() const override { return true; } 230*0b57cec5SDimitry Andric 231*0b57cec5SDimitry Andric bool IsObjCNonFragileABIDefault() const override { 232*0b57cec5SDimitry Andric // Non-fragile ABI is default for everything but i386. 233*0b57cec5SDimitry Andric return getTriple().getArch() != llvm::Triple::x86; 234*0b57cec5SDimitry Andric } 235*0b57cec5SDimitry Andric 236*0b57cec5SDimitry Andric bool UseObjCMixedDispatch() const override { return true; } 237*0b57cec5SDimitry Andric 238*0b57cec5SDimitry Andric bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override; 239*0b57cec5SDimitry Andric 240*0b57cec5SDimitry Andric RuntimeLibType GetDefaultRuntimeLibType() const override { 241*0b57cec5SDimitry Andric return ToolChain::RLT_CompilerRT; 242*0b57cec5SDimitry Andric } 243*0b57cec5SDimitry Andric 244*0b57cec5SDimitry Andric bool isPICDefault() const override; 245*0b57cec5SDimitry Andric bool isPIEDefault() const override; 246*0b57cec5SDimitry Andric bool isPICDefaultForced() const override; 247*0b57cec5SDimitry Andric 248*0b57cec5SDimitry Andric bool SupportsProfiling() const override; 249*0b57cec5SDimitry Andric 250*0b57cec5SDimitry Andric bool UseDwarfDebugFlags() const override; 251*0b57cec5SDimitry Andric 252*0b57cec5SDimitry Andric llvm::ExceptionHandling 253*0b57cec5SDimitry Andric GetExceptionModel(const llvm::opt::ArgList &Args) const override { 254*0b57cec5SDimitry Andric return llvm::ExceptionHandling::None; 255*0b57cec5SDimitry Andric } 256*0b57cec5SDimitry Andric 257*0b57cec5SDimitry Andric virtual StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const { 258*0b57cec5SDimitry Andric return ""; 259*0b57cec5SDimitry Andric } 260*0b57cec5SDimitry Andric 261*0b57cec5SDimitry Andric /// } 262*0b57cec5SDimitry Andric }; 263*0b57cec5SDimitry Andric 264*0b57cec5SDimitry Andric /// Darwin - The base Darwin tool chain. 265*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { 266*0b57cec5SDimitry Andric public: 267*0b57cec5SDimitry Andric /// Whether the information on the target has been initialized. 268*0b57cec5SDimitry Andric // 269*0b57cec5SDimitry Andric // FIXME: This should be eliminated. What we want to do is make this part of 270*0b57cec5SDimitry Andric // the "default target for arguments" selection process, once we get out of 271*0b57cec5SDimitry Andric // the argument translation business. 272*0b57cec5SDimitry Andric mutable bool TargetInitialized; 273*0b57cec5SDimitry Andric 274*0b57cec5SDimitry Andric enum DarwinPlatformKind { 275*0b57cec5SDimitry Andric MacOS, 276*0b57cec5SDimitry Andric IPhoneOS, 277*0b57cec5SDimitry Andric TvOS, 278*0b57cec5SDimitry Andric WatchOS, 279*0b57cec5SDimitry Andric LastDarwinPlatform = WatchOS 280*0b57cec5SDimitry Andric }; 281*0b57cec5SDimitry Andric enum DarwinEnvironmentKind { 282*0b57cec5SDimitry Andric NativeEnvironment, 283*0b57cec5SDimitry Andric Simulator, 284*0b57cec5SDimitry Andric }; 285*0b57cec5SDimitry Andric 286*0b57cec5SDimitry Andric mutable DarwinPlatformKind TargetPlatform; 287*0b57cec5SDimitry Andric mutable DarwinEnvironmentKind TargetEnvironment; 288*0b57cec5SDimitry Andric 289*0b57cec5SDimitry Andric /// The OS version we are targeting. 290*0b57cec5SDimitry Andric mutable VersionTuple TargetVersion; 291*0b57cec5SDimitry Andric 292*0b57cec5SDimitry Andric /// The information about the darwin SDK that was used. 293*0b57cec5SDimitry Andric mutable Optional<DarwinSDKInfo> SDKInfo; 294*0b57cec5SDimitry Andric 295*0b57cec5SDimitry Andric CudaInstallationDetector CudaInstallation; 296*0b57cec5SDimitry Andric 297*0b57cec5SDimitry Andric private: 298*0b57cec5SDimitry Andric void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const; 299*0b57cec5SDimitry Andric 300*0b57cec5SDimitry Andric public: 301*0b57cec5SDimitry Andric Darwin(const Driver &D, const llvm::Triple &Triple, 302*0b57cec5SDimitry Andric const llvm::opt::ArgList &Args); 303*0b57cec5SDimitry Andric ~Darwin() override; 304*0b57cec5SDimitry Andric 305*0b57cec5SDimitry Andric std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, 306*0b57cec5SDimitry Andric types::ID InputType) const override; 307*0b57cec5SDimitry Andric 308*0b57cec5SDimitry Andric /// @name Apple Specific Toolchain Implementation 309*0b57cec5SDimitry Andric /// { 310*0b57cec5SDimitry Andric 311*0b57cec5SDimitry Andric void addMinVersionArgs(const llvm::opt::ArgList &Args, 312*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 313*0b57cec5SDimitry Andric 314*0b57cec5SDimitry Andric void addStartObjectFileArgs(const llvm::opt::ArgList &Args, 315*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 316*0b57cec5SDimitry Andric 317*0b57cec5SDimitry Andric bool isKernelStatic() const override { 318*0b57cec5SDimitry Andric return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) && 319*0b57cec5SDimitry Andric !isTargetWatchOS()); 320*0b57cec5SDimitry Andric } 321*0b57cec5SDimitry Andric 322*0b57cec5SDimitry Andric void addProfileRTLibs(const llvm::opt::ArgList &Args, 323*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 324*0b57cec5SDimitry Andric 325*0b57cec5SDimitry Andric protected: 326*0b57cec5SDimitry Andric /// } 327*0b57cec5SDimitry Andric /// @name Darwin specific Toolchain functions 328*0b57cec5SDimitry Andric /// { 329*0b57cec5SDimitry Andric 330*0b57cec5SDimitry Andric // FIXME: Eliminate these ...Target functions and derive separate tool chains 331*0b57cec5SDimitry Andric // for these targets and put version in constructor. 332*0b57cec5SDimitry Andric void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment, 333*0b57cec5SDimitry Andric unsigned Major, unsigned Minor, unsigned Micro) const { 334*0b57cec5SDimitry Andric // FIXME: For now, allow reinitialization as long as values don't 335*0b57cec5SDimitry Andric // change. This will go away when we move away from argument translation. 336*0b57cec5SDimitry Andric if (TargetInitialized && TargetPlatform == Platform && 337*0b57cec5SDimitry Andric TargetEnvironment == Environment && 338*0b57cec5SDimitry Andric TargetVersion == VersionTuple(Major, Minor, Micro)) 339*0b57cec5SDimitry Andric return; 340*0b57cec5SDimitry Andric 341*0b57cec5SDimitry Andric assert(!TargetInitialized && "Target already initialized!"); 342*0b57cec5SDimitry Andric TargetInitialized = true; 343*0b57cec5SDimitry Andric TargetPlatform = Platform; 344*0b57cec5SDimitry Andric TargetEnvironment = Environment; 345*0b57cec5SDimitry Andric TargetVersion = VersionTuple(Major, Minor, Micro); 346*0b57cec5SDimitry Andric if (Environment == Simulator) 347*0b57cec5SDimitry Andric const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::Simulator); 348*0b57cec5SDimitry Andric } 349*0b57cec5SDimitry Andric 350*0b57cec5SDimitry Andric bool isTargetIPhoneOS() const { 351*0b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 352*0b57cec5SDimitry Andric return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && 353*0b57cec5SDimitry Andric TargetEnvironment == NativeEnvironment; 354*0b57cec5SDimitry Andric } 355*0b57cec5SDimitry Andric 356*0b57cec5SDimitry Andric bool isTargetIOSSimulator() const { 357*0b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 358*0b57cec5SDimitry Andric return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && 359*0b57cec5SDimitry Andric TargetEnvironment == Simulator; 360*0b57cec5SDimitry Andric } 361*0b57cec5SDimitry Andric 362*0b57cec5SDimitry Andric bool isTargetIOSBased() const { 363*0b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 364*0b57cec5SDimitry Andric return isTargetIPhoneOS() || isTargetIOSSimulator(); 365*0b57cec5SDimitry Andric } 366*0b57cec5SDimitry Andric 367*0b57cec5SDimitry Andric bool isTargetTvOS() const { 368*0b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 369*0b57cec5SDimitry Andric return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment; 370*0b57cec5SDimitry Andric } 371*0b57cec5SDimitry Andric 372*0b57cec5SDimitry Andric bool isTargetTvOSSimulator() const { 373*0b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 374*0b57cec5SDimitry Andric return TargetPlatform == TvOS && TargetEnvironment == Simulator; 375*0b57cec5SDimitry Andric } 376*0b57cec5SDimitry Andric 377*0b57cec5SDimitry Andric bool isTargetTvOSBased() const { 378*0b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 379*0b57cec5SDimitry Andric return TargetPlatform == TvOS; 380*0b57cec5SDimitry Andric } 381*0b57cec5SDimitry Andric 382*0b57cec5SDimitry Andric bool isTargetWatchOS() const { 383*0b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 384*0b57cec5SDimitry Andric return TargetPlatform == WatchOS && TargetEnvironment == NativeEnvironment; 385*0b57cec5SDimitry Andric } 386*0b57cec5SDimitry Andric 387*0b57cec5SDimitry Andric bool isTargetWatchOSSimulator() const { 388*0b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 389*0b57cec5SDimitry Andric return TargetPlatform == WatchOS && TargetEnvironment == Simulator; 390*0b57cec5SDimitry Andric } 391*0b57cec5SDimitry Andric 392*0b57cec5SDimitry Andric bool isTargetWatchOSBased() const { 393*0b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 394*0b57cec5SDimitry Andric return TargetPlatform == WatchOS; 395*0b57cec5SDimitry Andric } 396*0b57cec5SDimitry Andric 397*0b57cec5SDimitry Andric bool isTargetMacOS() const { 398*0b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 399*0b57cec5SDimitry Andric return TargetPlatform == MacOS; 400*0b57cec5SDimitry Andric } 401*0b57cec5SDimitry Andric 402*0b57cec5SDimitry Andric bool isTargetInitialized() const { return TargetInitialized; } 403*0b57cec5SDimitry Andric 404*0b57cec5SDimitry Andric VersionTuple getTargetVersion() const { 405*0b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 406*0b57cec5SDimitry Andric return TargetVersion; 407*0b57cec5SDimitry Andric } 408*0b57cec5SDimitry Andric 409*0b57cec5SDimitry Andric bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0, 410*0b57cec5SDimitry Andric unsigned V2 = 0) const { 411*0b57cec5SDimitry Andric assert(isTargetIOSBased() && "Unexpected call for non iOS target!"); 412*0b57cec5SDimitry Andric return TargetVersion < VersionTuple(V0, V1, V2); 413*0b57cec5SDimitry Andric } 414*0b57cec5SDimitry Andric 415*0b57cec5SDimitry Andric bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const { 416*0b57cec5SDimitry Andric assert(isTargetMacOS() && "Unexpected call for non OS X target!"); 417*0b57cec5SDimitry Andric return TargetVersion < VersionTuple(V0, V1, V2); 418*0b57cec5SDimitry Andric } 419*0b57cec5SDimitry Andric 420*0b57cec5SDimitry Andric /// Return true if c++17 aligned allocation/deallocation functions are not 421*0b57cec5SDimitry Andric /// implemented in the c++ standard library of the deployment target we are 422*0b57cec5SDimitry Andric /// targeting. 423*0b57cec5SDimitry Andric bool isAlignedAllocationUnavailable() const; 424*0b57cec5SDimitry Andric 425*0b57cec5SDimitry Andric void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 426*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args, 427*0b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 428*0b57cec5SDimitry Andric 429*0b57cec5SDimitry Andric StringRef getPlatformFamily() const; 430*0b57cec5SDimitry Andric StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const override; 431*0b57cec5SDimitry Andric 432*0b57cec5SDimitry Andric public: 433*0b57cec5SDimitry Andric static StringRef getSDKName(StringRef isysroot); 434*0b57cec5SDimitry Andric 435*0b57cec5SDimitry Andric /// } 436*0b57cec5SDimitry Andric /// @name ToolChain Implementation 437*0b57cec5SDimitry Andric /// { 438*0b57cec5SDimitry Andric 439*0b57cec5SDimitry Andric // Darwin tools support multiple architecture (e.g., i386 and x86_64) and 440*0b57cec5SDimitry Andric // most development is done against SDKs, so compiling for a different 441*0b57cec5SDimitry Andric // architecture should not get any special treatment. 442*0b57cec5SDimitry Andric bool isCrossCompiling() const override { return false; } 443*0b57cec5SDimitry Andric 444*0b57cec5SDimitry Andric llvm::opt::DerivedArgList * 445*0b57cec5SDimitry Andric TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 446*0b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 447*0b57cec5SDimitry Andric 448*0b57cec5SDimitry Andric CXXStdlibType GetDefaultCXXStdlibType() const override; 449*0b57cec5SDimitry Andric ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override; 450*0b57cec5SDimitry Andric bool hasBlocksRuntime() const override; 451*0b57cec5SDimitry Andric 452*0b57cec5SDimitry Andric void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, 453*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 454*0b57cec5SDimitry Andric 455*0b57cec5SDimitry Andric bool UseObjCMixedDispatch() const override { 456*0b57cec5SDimitry Andric // This is only used with the non-fragile ABI and non-legacy dispatch. 457*0b57cec5SDimitry Andric 458*0b57cec5SDimitry Andric // Mixed dispatch is used everywhere except OS X before 10.6. 459*0b57cec5SDimitry Andric return !(isTargetMacOS() && isMacosxVersionLT(10, 6)); 460*0b57cec5SDimitry Andric } 461*0b57cec5SDimitry Andric 462*0b57cec5SDimitry Andric unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override { 463*0b57cec5SDimitry Andric // Stack protectors default to on for user code on 10.5, 464*0b57cec5SDimitry Andric // and for everything in 10.6 and beyond 465*0b57cec5SDimitry Andric if (isTargetIOSBased() || isTargetWatchOSBased()) 466*0b57cec5SDimitry Andric return 1; 467*0b57cec5SDimitry Andric else if (isTargetMacOS() && !isMacosxVersionLT(10, 6)) 468*0b57cec5SDimitry Andric return 1; 469*0b57cec5SDimitry Andric else if (isTargetMacOS() && !isMacosxVersionLT(10, 5) && !KernelOrKext) 470*0b57cec5SDimitry Andric return 1; 471*0b57cec5SDimitry Andric 472*0b57cec5SDimitry Andric return 0; 473*0b57cec5SDimitry Andric } 474*0b57cec5SDimitry Andric 475*0b57cec5SDimitry Andric void CheckObjCARC() const override; 476*0b57cec5SDimitry Andric 477*0b57cec5SDimitry Andric llvm::ExceptionHandling GetExceptionModel( 478*0b57cec5SDimitry Andric const llvm::opt::ArgList &Args) const override; 479*0b57cec5SDimitry Andric 480*0b57cec5SDimitry Andric bool SupportsEmbeddedBitcode() const override; 481*0b57cec5SDimitry Andric 482*0b57cec5SDimitry Andric SanitizerMask getSupportedSanitizers() const override; 483*0b57cec5SDimitry Andric 484*0b57cec5SDimitry Andric void printVerboseInfo(raw_ostream &OS) const override; 485*0b57cec5SDimitry Andric }; 486*0b57cec5SDimitry Andric 487*0b57cec5SDimitry Andric /// DarwinClang - The Darwin toolchain used by Clang. 488*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { 489*0b57cec5SDimitry Andric public: 490*0b57cec5SDimitry Andric DarwinClang(const Driver &D, const llvm::Triple &Triple, 491*0b57cec5SDimitry Andric const llvm::opt::ArgList &Args); 492*0b57cec5SDimitry Andric 493*0b57cec5SDimitry Andric /// @name Apple ToolChain Implementation 494*0b57cec5SDimitry Andric /// { 495*0b57cec5SDimitry Andric 496*0b57cec5SDimitry Andric RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override; 497*0b57cec5SDimitry Andric 498*0b57cec5SDimitry Andric void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, 499*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 500*0b57cec5SDimitry Andric bool ForceLinkBuiltinRT = false) const override; 501*0b57cec5SDimitry Andric 502*0b57cec5SDimitry Andric void AddClangCXXStdlibIncludeArgs( 503*0b57cec5SDimitry Andric const llvm::opt::ArgList &DriverArgs, 504*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 505*0b57cec5SDimitry Andric 506*0b57cec5SDimitry Andric void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 507*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 508*0b57cec5SDimitry Andric 509*0b57cec5SDimitry Andric void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, 510*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 511*0b57cec5SDimitry Andric 512*0b57cec5SDimitry Andric void AddCCKextLibArgs(const llvm::opt::ArgList &Args, 513*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 514*0b57cec5SDimitry Andric 515*0b57cec5SDimitry Andric void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override; 516*0b57cec5SDimitry Andric 517*0b57cec5SDimitry Andric void AddLinkARCArgs(const llvm::opt::ArgList &Args, 518*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 519*0b57cec5SDimitry Andric 520*0b57cec5SDimitry Andric unsigned GetDefaultDwarfVersion() const override; 521*0b57cec5SDimitry Andric // Until dtrace (via CTF) and LLDB can deal with distributed debug info, 522*0b57cec5SDimitry Andric // Darwin defaults to standalone/full debug info. 523*0b57cec5SDimitry Andric bool GetDefaultStandaloneDebug() const override { return true; } 524*0b57cec5SDimitry Andric llvm::DebuggerKind getDefaultDebuggerTuning() const override { 525*0b57cec5SDimitry Andric return llvm::DebuggerKind::LLDB; 526*0b57cec5SDimitry Andric } 527*0b57cec5SDimitry Andric 528*0b57cec5SDimitry Andric /// } 529*0b57cec5SDimitry Andric 530*0b57cec5SDimitry Andric private: 531*0b57cec5SDimitry Andric void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args, 532*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 533*0b57cec5SDimitry Andric StringRef Sanitizer, 534*0b57cec5SDimitry Andric bool shared = true) const; 535*0b57cec5SDimitry Andric 536*0b57cec5SDimitry Andric bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, 537*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args, 538*0b57cec5SDimitry Andric llvm::SmallString<128> Base, 539*0b57cec5SDimitry Andric llvm::StringRef Version, 540*0b57cec5SDimitry Andric llvm::StringRef ArchDir, 541*0b57cec5SDimitry Andric llvm::StringRef BitDir) const; 542*0b57cec5SDimitry Andric 543*0b57cec5SDimitry Andric llvm::StringRef GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const; 544*0b57cec5SDimitry Andric }; 545*0b57cec5SDimitry Andric 546*0b57cec5SDimitry Andric } // end namespace toolchains 547*0b57cec5SDimitry Andric } // end namespace driver 548*0b57cec5SDimitry Andric } // end namespace clang 549*0b57cec5SDimitry Andric 550*0b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H 551