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