10b57cec5SDimitry Andric //===--- Darwin.h - Darwin ToolChain Implementations ------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H 100b57cec5SDimitry Andric #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "Cuda.h" 135ffd83dbSDimitry Andric #include "ROCm.h" 14fe6060f1SDimitry Andric #include "clang/Basic/DarwinSDKInfo.h" 15e8d8bef9SDimitry Andric #include "clang/Basic/LangOptions.h" 160b57cec5SDimitry Andric #include "clang/Driver/Tool.h" 170b57cec5SDimitry Andric #include "clang/Driver/ToolChain.h" 180b57cec5SDimitry Andric #include "clang/Driver/XRayArgs.h" 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric namespace clang { 210b57cec5SDimitry Andric namespace driver { 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric namespace toolchains { 240b57cec5SDimitry Andric class MachO; 250b57cec5SDimitry Andric } // end namespace toolchains 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric namespace tools { 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric namespace darwin { 300b57cec5SDimitry Andric llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str); 310b57cec5SDimitry Andric void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str); 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MachOTool : public Tool { 340b57cec5SDimitry Andric virtual void anchor(); 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric protected: 370b57cec5SDimitry Andric void AddMachOArch(const llvm::opt::ArgList &Args, 380b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric const toolchains::MachO &getMachOToolChain() const { 410b57cec5SDimitry Andric return reinterpret_cast<const toolchains::MachO &>(getToolChain()); 420b57cec5SDimitry Andric } 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric public: 455ffd83dbSDimitry Andric MachOTool(const char *Name, const char *ShortName, const ToolChain &TC) 465ffd83dbSDimitry Andric : Tool(Name, ShortName, TC) {} 470b57cec5SDimitry Andric }; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Assembler : public MachOTool { 500b57cec5SDimitry Andric public: 510b57cec5SDimitry Andric Assembler(const ToolChain &TC) 520b57cec5SDimitry Andric : MachOTool("darwin::Assembler", "assembler", TC) {} 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 570b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 580b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 590b57cec5SDimitry Andric const char *LinkingOutput) const override; 600b57cec5SDimitry Andric }; 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool { 630b57cec5SDimitry Andric bool NeedsTempPath(const InputInfoList &Inputs) const; 640b57cec5SDimitry Andric void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args, 650b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 6681ad6265SDimitry Andric const InputInfoList &Inputs, VersionTuple Version, 670eae32dcSDimitry Andric bool LinkerIsLLD) const; 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric public: 705ffd83dbSDimitry Andric Linker(const ToolChain &TC) : MachOTool("darwin::Linker", "linker", TC) {} 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 730b57cec5SDimitry Andric bool isLinkJob() const override { return true; } 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 760b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 770b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 780b57cec5SDimitry Andric const char *LinkingOutput) const override; 790b57cec5SDimitry Andric }; 800b57cec5SDimitry Andric 81349cc55cSDimitry Andric class LLVM_LIBRARY_VISIBILITY StaticLibTool : public MachOTool { 82349cc55cSDimitry Andric public: 83349cc55cSDimitry Andric StaticLibTool(const ToolChain &TC) 84349cc55cSDimitry Andric : MachOTool("darwin::StaticLibTool", "static-lib-linker", TC) {} 85349cc55cSDimitry Andric 86349cc55cSDimitry Andric bool hasIntegratedCPP() const override { return false; } 87349cc55cSDimitry Andric bool isLinkJob() const override { return true; } 88349cc55cSDimitry Andric 89349cc55cSDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 90349cc55cSDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 91349cc55cSDimitry Andric const llvm::opt::ArgList &TCArgs, 92349cc55cSDimitry Andric const char *LinkingOutput) const override; 93349cc55cSDimitry Andric }; 94349cc55cSDimitry Andric 950b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Lipo : public MachOTool { 960b57cec5SDimitry Andric public: 970b57cec5SDimitry Andric Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {} 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 1020b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 1030b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 1040b57cec5SDimitry Andric const char *LinkingOutput) const override; 1050b57cec5SDimitry Andric }; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Dsymutil : public MachOTool { 1080b57cec5SDimitry Andric public: 1090b57cec5SDimitry Andric Dsymutil(const ToolChain &TC) 1100b57cec5SDimitry Andric : MachOTool("darwin::Dsymutil", "dsymutil", TC) {} 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 1130b57cec5SDimitry Andric bool isDsymutilJob() const override { return true; } 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 1160b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 1170b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 1180b57cec5SDimitry Andric const char *LinkingOutput) const override; 1190b57cec5SDimitry Andric }; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY VerifyDebug : public MachOTool { 1220b57cec5SDimitry Andric public: 1230b57cec5SDimitry Andric VerifyDebug(const ToolChain &TC) 1240b57cec5SDimitry Andric : MachOTool("darwin::VerifyDebug", "dwarfdump", TC) {} 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 1290b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 1300b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 1310b57cec5SDimitry Andric const char *LinkingOutput) const override; 1320b57cec5SDimitry Andric }; 1330b57cec5SDimitry Andric } // end namespace darwin 1340b57cec5SDimitry Andric } // end namespace tools 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric namespace toolchains { 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain { 1390b57cec5SDimitry Andric protected: 1400b57cec5SDimitry Andric Tool *buildAssembler() const override; 1410b57cec5SDimitry Andric Tool *buildLinker() const override; 142349cc55cSDimitry Andric Tool *buildStaticLibTool() const override; 1430b57cec5SDimitry Andric Tool *getTool(Action::ActionClass AC) const override; 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric private: 1460b57cec5SDimitry Andric mutable std::unique_ptr<tools::darwin::Lipo> Lipo; 1470b57cec5SDimitry Andric mutable std::unique_ptr<tools::darwin::Dsymutil> Dsymutil; 1480b57cec5SDimitry Andric mutable std::unique_ptr<tools::darwin::VerifyDebug> VerifyDebug; 1490b57cec5SDimitry Andric 15081ad6265SDimitry Andric /// The version of the linker known to be available in the tool chain. 151*bdd1243dSDimitry Andric mutable std::optional<VersionTuple> LinkerVersion; 15281ad6265SDimitry Andric 1530b57cec5SDimitry Andric public: 1540b57cec5SDimitry Andric MachO(const Driver &D, const llvm::Triple &Triple, 1550b57cec5SDimitry Andric const llvm::opt::ArgList &Args); 1560b57cec5SDimitry Andric ~MachO() override; 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric /// @name MachO specific toolchain API 1590b57cec5SDimitry Andric /// { 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric /// Get the "MachO" arch name for a particular compiler invocation. For 1620b57cec5SDimitry Andric /// example, Apple treats different ARM variations as distinct architectures. 1630b57cec5SDimitry Andric StringRef getMachOArchName(const llvm::opt::ArgList &Args) const; 1640b57cec5SDimitry Andric 16581ad6265SDimitry Andric /// Get the version of the linker known to be available for a particular 16681ad6265SDimitry Andric /// compiler invocation (via the `-mlinker-version=` arg). 16781ad6265SDimitry Andric VersionTuple getLinkerVersion(const llvm::opt::ArgList &Args) const; 16881ad6265SDimitry Andric 1690b57cec5SDimitry Andric /// Add the linker arguments to link the ARC runtime library. 1700b57cec5SDimitry Andric virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args, 1710b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const {} 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric /// Add the linker arguments to link the compiler runtime library. 1740b57cec5SDimitry Andric /// 1750b57cec5SDimitry Andric /// FIXME: This API is intended for use with embedded libraries only, and is 1760b57cec5SDimitry Andric /// misleadingly named. 1770b57cec5SDimitry Andric virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, 1780b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 1790b57cec5SDimitry Andric bool ForceLinkBuiltinRT = false) const; 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args, 1820b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const { 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric virtual void addMinVersionArgs(const llvm::opt::ArgList &Args, 1860b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const {} 1870b57cec5SDimitry Andric 188480093f4SDimitry Andric virtual void addPlatformVersionArgs(const llvm::opt::ArgList &Args, 189480093f4SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const { 190480093f4SDimitry Andric } 191480093f4SDimitry Andric 1920b57cec5SDimitry Andric /// On some iOS platforms, kernel and kernel modules were built statically. Is 1930b57cec5SDimitry Andric /// this such a target? 1940b57cec5SDimitry Andric virtual bool isKernelStatic() const { return false; } 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric /// Is the target either iOS or an iOS simulator? 1970b57cec5SDimitry Andric bool isTargetIOSBased() const { return false; } 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric /// Options to control how a runtime library is linked. 2000b57cec5SDimitry Andric enum RuntimeLinkOptions : unsigned { 2010b57cec5SDimitry Andric /// Link the library in even if it can't be found in the VFS. 2020b57cec5SDimitry Andric RLO_AlwaysLink = 1 << 0, 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric /// Use the embedded runtime from the macho_embedded directory. 2050b57cec5SDimitry Andric RLO_IsEmbedded = 1 << 1, 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric /// Emit rpaths for @executable_path as well as the resource directory. 2080b57cec5SDimitry Andric RLO_AddRPath = 1 << 2, 2090b57cec5SDimitry Andric }; 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric /// Add a runtime library to the list of items to link. 2120b57cec5SDimitry Andric void AddLinkRuntimeLib(const llvm::opt::ArgList &Args, 2130b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, StringRef Component, 2140b57cec5SDimitry Andric RuntimeLinkOptions Opts = RuntimeLinkOptions(), 2150b57cec5SDimitry Andric bool IsShared = false) const; 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric /// Add any profiling runtime libraries that are needed. This is essentially a 2180b57cec5SDimitry Andric /// MachO specific version of addProfileRT in Tools.cpp. 2190b57cec5SDimitry Andric void addProfileRTLibs(const llvm::opt::ArgList &Args, 2200b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override { 2210b57cec5SDimitry Andric // There aren't any profiling libs for embedded targets currently. 2220b57cec5SDimitry Andric } 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric /// } 2250b57cec5SDimitry Andric /// @name ToolChain Implementation 2260b57cec5SDimitry Andric /// { 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric types::ID LookupTypeForExtension(StringRef Ext) const override; 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric bool HasNativeLLVMSupport() const override; 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric llvm::opt::DerivedArgList * 2330b57cec5SDimitry Andric TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 2340b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric bool IsBlocksDefault() const override { 2370b57cec5SDimitry Andric // Always allow blocks on Apple; users interested in versioning are 2380b57cec5SDimitry Andric // expected to use /usr/include/Block.h. 2390b57cec5SDimitry Andric return true; 2400b57cec5SDimitry Andric } 2410b57cec5SDimitry Andric bool IsIntegratedAssemblerDefault() const override { 2420b57cec5SDimitry Andric // Default integrated assembler to on for Apple's MachO targets. 2430b57cec5SDimitry Andric return true; 2440b57cec5SDimitry Andric } 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric bool IsMathErrnoDefault() const override { return false; } 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric bool IsEncodeExtendedBlockSignatureDefault() const override { return true; } 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric bool IsObjCNonFragileABIDefault() const override { 2510b57cec5SDimitry Andric // Non-fragile ABI is default for everything but i386. 2520b57cec5SDimitry Andric return getTriple().getArch() != llvm::Triple::x86; 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric bool UseObjCMixedDispatch() const override { return true; } 2560b57cec5SDimitry Andric 257*bdd1243dSDimitry Andric UnwindTableLevel 258*bdd1243dSDimitry Andric getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override; 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric RuntimeLibType GetDefaultRuntimeLibType() const override { 2610b57cec5SDimitry Andric return ToolChain::RLT_CompilerRT; 2620b57cec5SDimitry Andric } 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric bool isPICDefault() const override; 265349cc55cSDimitry Andric bool isPIEDefault(const llvm::opt::ArgList &Args) const override; 2660b57cec5SDimitry Andric bool isPICDefaultForced() const override; 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric bool SupportsProfiling() const override; 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric bool UseDwarfDebugFlags() const override; 27181ad6265SDimitry Andric std::string GetGlobalDebugPathRemapping() const override; 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andric llvm::ExceptionHandling 2740b57cec5SDimitry Andric GetExceptionModel(const llvm::opt::ArgList &Args) const override { 2750b57cec5SDimitry Andric return llvm::ExceptionHandling::None; 2760b57cec5SDimitry Andric } 2770b57cec5SDimitry Andric 2780b57cec5SDimitry Andric virtual StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const { 2790b57cec5SDimitry Andric return ""; 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric 282480093f4SDimitry Andric // Darwin toolchain uses legacy thin LTO API, which is not 283480093f4SDimitry Andric // capable of unit splitting. 284480093f4SDimitry Andric bool canSplitThinLTOUnit() const override { return false; } 2850b57cec5SDimitry Andric /// } 2860b57cec5SDimitry Andric }; 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric /// Darwin - The base Darwin tool chain. 2890b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { 2900b57cec5SDimitry Andric public: 2910b57cec5SDimitry Andric /// Whether the information on the target has been initialized. 2920b57cec5SDimitry Andric // 2930b57cec5SDimitry Andric // FIXME: This should be eliminated. What we want to do is make this part of 2940b57cec5SDimitry Andric // the "default target for arguments" selection process, once we get out of 2950b57cec5SDimitry Andric // the argument translation business. 2960b57cec5SDimitry Andric mutable bool TargetInitialized; 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric enum DarwinPlatformKind { 2990b57cec5SDimitry Andric MacOS, 3000b57cec5SDimitry Andric IPhoneOS, 3010b57cec5SDimitry Andric TvOS, 3020b57cec5SDimitry Andric WatchOS, 30381ad6265SDimitry Andric DriverKit, 30481ad6265SDimitry Andric LastDarwinPlatform = DriverKit 3050b57cec5SDimitry Andric }; 3060b57cec5SDimitry Andric enum DarwinEnvironmentKind { 3070b57cec5SDimitry Andric NativeEnvironment, 3080b57cec5SDimitry Andric Simulator, 309fe6060f1SDimitry Andric MacCatalyst, 3100b57cec5SDimitry Andric }; 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric mutable DarwinPlatformKind TargetPlatform; 3130b57cec5SDimitry Andric mutable DarwinEnvironmentKind TargetEnvironment; 3140b57cec5SDimitry Andric 315fe6060f1SDimitry Andric /// The native OS version we are targeting. 3160b57cec5SDimitry Andric mutable VersionTuple TargetVersion; 317fe6060f1SDimitry Andric /// The OS version we are targeting as specified in the triple. 318fe6060f1SDimitry Andric mutable VersionTuple OSTargetVersion; 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric /// The information about the darwin SDK that was used. 321*bdd1243dSDimitry Andric mutable std::optional<DarwinSDKInfo> SDKInfo; 3220b57cec5SDimitry Andric 32381ad6265SDimitry Andric /// The target variant triple that was specified (if any). 324*bdd1243dSDimitry Andric mutable std::optional<llvm::Triple> TargetVariantTriple; 32581ad6265SDimitry Andric 3260b57cec5SDimitry Andric CudaInstallationDetector CudaInstallation; 3275ffd83dbSDimitry Andric RocmInstallationDetector RocmInstallation; 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric private: 3300b57cec5SDimitry Andric void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const; 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric public: 3330b57cec5SDimitry Andric Darwin(const Driver &D, const llvm::Triple &Triple, 3340b57cec5SDimitry Andric const llvm::opt::ArgList &Args); 3350b57cec5SDimitry Andric ~Darwin() override; 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, 3380b57cec5SDimitry Andric types::ID InputType) const override; 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric /// @name Apple Specific Toolchain Implementation 3410b57cec5SDimitry Andric /// { 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric void addMinVersionArgs(const llvm::opt::ArgList &Args, 3440b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 3450b57cec5SDimitry Andric 346480093f4SDimitry Andric void addPlatformVersionArgs(const llvm::opt::ArgList &Args, 347480093f4SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 348480093f4SDimitry Andric 3490b57cec5SDimitry Andric void addStartObjectFileArgs(const llvm::opt::ArgList &Args, 3500b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric bool isKernelStatic() const override { 3530b57cec5SDimitry Andric return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) && 35481ad6265SDimitry Andric !isTargetWatchOS() && !isTargetDriverKit()); 3550b57cec5SDimitry Andric } 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric void addProfileRTLibs(const llvm::opt::ArgList &Args, 3580b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric protected: 3610b57cec5SDimitry Andric /// } 3620b57cec5SDimitry Andric /// @name Darwin specific Toolchain functions 3630b57cec5SDimitry Andric /// { 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric // FIXME: Eliminate these ...Target functions and derive separate tool chains 3660b57cec5SDimitry Andric // for these targets and put version in constructor. 3670b57cec5SDimitry Andric void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment, 368fe6060f1SDimitry Andric unsigned Major, unsigned Minor, unsigned Micro, 369fe6060f1SDimitry Andric VersionTuple NativeTargetVersion) const { 3700b57cec5SDimitry Andric // FIXME: For now, allow reinitialization as long as values don't 3710b57cec5SDimitry Andric // change. This will go away when we move away from argument translation. 3720b57cec5SDimitry Andric if (TargetInitialized && TargetPlatform == Platform && 3730b57cec5SDimitry Andric TargetEnvironment == Environment && 374fe6060f1SDimitry Andric (Environment == MacCatalyst ? OSTargetVersion : TargetVersion) == 375fe6060f1SDimitry Andric VersionTuple(Major, Minor, Micro)) 3760b57cec5SDimitry Andric return; 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric assert(!TargetInitialized && "Target already initialized!"); 3790b57cec5SDimitry Andric TargetInitialized = true; 3800b57cec5SDimitry Andric TargetPlatform = Platform; 3810b57cec5SDimitry Andric TargetEnvironment = Environment; 3820b57cec5SDimitry Andric TargetVersion = VersionTuple(Major, Minor, Micro); 3830b57cec5SDimitry Andric if (Environment == Simulator) 3840b57cec5SDimitry Andric const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::Simulator); 385fe6060f1SDimitry Andric else if (Environment == MacCatalyst) { 386fe6060f1SDimitry Andric const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::MacABI); 387fe6060f1SDimitry Andric TargetVersion = NativeTargetVersion; 388fe6060f1SDimitry Andric OSTargetVersion = VersionTuple(Major, Minor, Micro); 389fe6060f1SDimitry Andric } 3900b57cec5SDimitry Andric } 3910b57cec5SDimitry Andric 3925ffd83dbSDimitry Andric public: 3930b57cec5SDimitry Andric bool isTargetIPhoneOS() const { 3940b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 3950b57cec5SDimitry Andric return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && 3960b57cec5SDimitry Andric TargetEnvironment == NativeEnvironment; 3970b57cec5SDimitry Andric } 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric bool isTargetIOSSimulator() const { 4000b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4010b57cec5SDimitry Andric return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && 4020b57cec5SDimitry Andric TargetEnvironment == Simulator; 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric bool isTargetIOSBased() const { 4060b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4070b57cec5SDimitry Andric return isTargetIPhoneOS() || isTargetIOSSimulator(); 4080b57cec5SDimitry Andric } 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric bool isTargetTvOS() const { 4110b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4120b57cec5SDimitry Andric return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment; 4130b57cec5SDimitry Andric } 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric bool isTargetTvOSSimulator() const { 4160b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4170b57cec5SDimitry Andric return TargetPlatform == TvOS && TargetEnvironment == Simulator; 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric bool isTargetTvOSBased() const { 4210b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4220b57cec5SDimitry Andric return TargetPlatform == TvOS; 4230b57cec5SDimitry Andric } 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric bool isTargetWatchOS() const { 4260b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4270b57cec5SDimitry Andric return TargetPlatform == WatchOS && TargetEnvironment == NativeEnvironment; 4280b57cec5SDimitry Andric } 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric bool isTargetWatchOSSimulator() const { 4310b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4320b57cec5SDimitry Andric return TargetPlatform == WatchOS && TargetEnvironment == Simulator; 4330b57cec5SDimitry Andric } 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric bool isTargetWatchOSBased() const { 4360b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4370b57cec5SDimitry Andric return TargetPlatform == WatchOS; 4380b57cec5SDimitry Andric } 4390b57cec5SDimitry Andric 44081ad6265SDimitry Andric bool isTargetDriverKit() const { 44181ad6265SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 44281ad6265SDimitry Andric return TargetPlatform == DriverKit; 44381ad6265SDimitry Andric } 44481ad6265SDimitry Andric 445fe6060f1SDimitry Andric bool isTargetMacCatalyst() const { 446fe6060f1SDimitry Andric return TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst; 447fe6060f1SDimitry Andric } 448fe6060f1SDimitry Andric 4490b57cec5SDimitry Andric bool isTargetMacOS() const { 4500b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4510b57cec5SDimitry Andric return TargetPlatform == MacOS; 4520b57cec5SDimitry Andric } 4530b57cec5SDimitry Andric 4545ffd83dbSDimitry Andric bool isTargetMacOSBased() const { 4555ffd83dbSDimitry Andric assert(TargetInitialized && "Target not initialized!"); 456fe6060f1SDimitry Andric return TargetPlatform == MacOS || isTargetMacCatalyst(); 4575ffd83dbSDimitry Andric } 4585ffd83dbSDimitry Andric 4595ffd83dbSDimitry Andric bool isTargetAppleSiliconMac() const { 4605ffd83dbSDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4615ffd83dbSDimitry Andric return isTargetMacOSBased() && getArch() == llvm::Triple::aarch64; 4625ffd83dbSDimitry Andric } 4635ffd83dbSDimitry Andric 4640b57cec5SDimitry Andric bool isTargetInitialized() const { return TargetInitialized; } 4650b57cec5SDimitry Andric 466fe6060f1SDimitry Andric /// The version of the OS that's used by the OS specified in the target 467fe6060f1SDimitry Andric /// triple. It might be different from the actual target OS on which the 468fe6060f1SDimitry Andric /// program will run, e.g. MacCatalyst code runs on a macOS target, but its 469fe6060f1SDimitry Andric /// target triple is iOS. 470fe6060f1SDimitry Andric VersionTuple getTripleTargetVersion() const { 4710b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 472fe6060f1SDimitry Andric return isTargetMacCatalyst() ? OSTargetVersion : TargetVersion; 4730b57cec5SDimitry Andric } 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0, 4760b57cec5SDimitry Andric unsigned V2 = 0) const { 4770b57cec5SDimitry Andric assert(isTargetIOSBased() && "Unexpected call for non iOS target!"); 4780b57cec5SDimitry Andric return TargetVersion < VersionTuple(V0, V1, V2); 4790b57cec5SDimitry Andric } 4800b57cec5SDimitry Andric 4815ffd83dbSDimitry Andric /// Returns true if the minimum supported macOS version for the slice that's 4825ffd83dbSDimitry Andric /// being built is less than the specified version. If there's no minimum 4835ffd83dbSDimitry Andric /// supported macOS version, the deployment target version is compared to the 4845ffd83dbSDimitry Andric /// specifed version instead. 4850b57cec5SDimitry Andric bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const { 486fe6060f1SDimitry Andric assert(isTargetMacOSBased() && 487fe6060f1SDimitry Andric (getTriple().isMacOSX() || getTriple().isMacCatalystEnvironment()) && 4885ffd83dbSDimitry Andric "Unexpected call for non OS X target!"); 489e8d8bef9SDimitry Andric // The effective triple might not be initialized yet, so construct a 490e8d8bef9SDimitry Andric // pseudo-effective triple to get the minimum supported OS version. 491e8d8bef9SDimitry Andric VersionTuple MinVers = 492e8d8bef9SDimitry Andric llvm::Triple(getTriple().getArchName(), "apple", "macos") 493e8d8bef9SDimitry Andric .getMinimumSupportedOSVersion(); 4945ffd83dbSDimitry Andric return (!MinVers.empty() && MinVers > TargetVersion 4955ffd83dbSDimitry Andric ? MinVers 4965ffd83dbSDimitry Andric : TargetVersion) < VersionTuple(V0, V1, V2); 4970b57cec5SDimitry Andric } 4980b57cec5SDimitry Andric 4995ffd83dbSDimitry Andric protected: 5000b57cec5SDimitry Andric /// Return true if c++17 aligned allocation/deallocation functions are not 5010b57cec5SDimitry Andric /// implemented in the c++ standard library of the deployment target we are 5020b57cec5SDimitry Andric /// targeting. 5030b57cec5SDimitry Andric bool isAlignedAllocationUnavailable() const; 5040b57cec5SDimitry Andric 5050b57cec5SDimitry Andric void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 5060b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args, 5070b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 5080b57cec5SDimitry Andric 509*bdd1243dSDimitry Andric void addClangCC1ASTargetOptions( 510*bdd1243dSDimitry Andric const llvm::opt::ArgList &Args, 511*bdd1243dSDimitry Andric llvm::opt::ArgStringList &CC1ASArgs) const override; 512*bdd1243dSDimitry Andric 5130b57cec5SDimitry Andric StringRef getPlatformFamily() const; 5140b57cec5SDimitry Andric StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const override; 5150b57cec5SDimitry Andric 5160b57cec5SDimitry Andric public: 5170b57cec5SDimitry Andric static StringRef getSDKName(StringRef isysroot); 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric /// } 5200b57cec5SDimitry Andric /// @name ToolChain Implementation 5210b57cec5SDimitry Andric /// { 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andric // Darwin tools support multiple architecture (e.g., i386 and x86_64) and 5240b57cec5SDimitry Andric // most development is done against SDKs, so compiling for a different 5250b57cec5SDimitry Andric // architecture should not get any special treatment. 5260b57cec5SDimitry Andric bool isCrossCompiling() const override { return false; } 5270b57cec5SDimitry Andric 5280b57cec5SDimitry Andric llvm::opt::DerivedArgList * 5290b57cec5SDimitry Andric TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 5300b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric CXXStdlibType GetDefaultCXXStdlibType() const override; 5330b57cec5SDimitry Andric ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override; 5340b57cec5SDimitry Andric bool hasBlocksRuntime() const override; 5350b57cec5SDimitry Andric 5360b57cec5SDimitry Andric void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, 5370b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 5385ffd83dbSDimitry Andric void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, 5395ffd83dbSDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andric bool UseObjCMixedDispatch() const override { 5420b57cec5SDimitry Andric // This is only used with the non-fragile ABI and non-legacy dispatch. 5430b57cec5SDimitry Andric 5440b57cec5SDimitry Andric // Mixed dispatch is used everywhere except OS X before 10.6. 545fe6060f1SDimitry Andric return !(isTargetMacOSBased() && isMacosxVersionLT(10, 6)); 5460b57cec5SDimitry Andric } 5470b57cec5SDimitry Andric 548e8d8bef9SDimitry Andric LangOptions::StackProtectorMode 549e8d8bef9SDimitry Andric GetDefaultStackProtectorLevel(bool KernelOrKext) const override { 5500b57cec5SDimitry Andric // Stack protectors default to on for user code on 10.5, 5510b57cec5SDimitry Andric // and for everything in 10.6 and beyond 55281ad6265SDimitry Andric if (isTargetIOSBased() || isTargetWatchOSBased() || isTargetDriverKit()) 553e8d8bef9SDimitry Andric return LangOptions::SSPOn; 554fe6060f1SDimitry Andric else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 6)) 555e8d8bef9SDimitry Andric return LangOptions::SSPOn; 556fe6060f1SDimitry Andric else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 5) && !KernelOrKext) 557e8d8bef9SDimitry Andric return LangOptions::SSPOn; 5580b57cec5SDimitry Andric 559e8d8bef9SDimitry Andric return LangOptions::SSPOff; 5600b57cec5SDimitry Andric } 5610b57cec5SDimitry Andric 5620b57cec5SDimitry Andric void CheckObjCARC() const override; 5630b57cec5SDimitry Andric 5640b57cec5SDimitry Andric llvm::ExceptionHandling GetExceptionModel( 5650b57cec5SDimitry Andric const llvm::opt::ArgList &Args) const override; 5660b57cec5SDimitry Andric 5670b57cec5SDimitry Andric bool SupportsEmbeddedBitcode() const override; 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric SanitizerMask getSupportedSanitizers() const override; 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric void printVerboseInfo(raw_ostream &OS) const override; 5720b57cec5SDimitry Andric }; 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric /// DarwinClang - The Darwin toolchain used by Clang. 5750b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { 5760b57cec5SDimitry Andric public: 5770b57cec5SDimitry Andric DarwinClang(const Driver &D, const llvm::Triple &Triple, 5780b57cec5SDimitry Andric const llvm::opt::ArgList &Args); 5790b57cec5SDimitry Andric 5800b57cec5SDimitry Andric /// @name Apple ToolChain Implementation 5810b57cec5SDimitry Andric /// { 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andric RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override; 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andric void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, 5860b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 5870b57cec5SDimitry Andric bool ForceLinkBuiltinRT = false) const override; 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric void AddClangCXXStdlibIncludeArgs( 5900b57cec5SDimitry Andric const llvm::opt::ArgList &DriverArgs, 5910b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 5920b57cec5SDimitry Andric 5930b57cec5SDimitry Andric void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 5940b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 5950b57cec5SDimitry Andric 5960b57cec5SDimitry Andric void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, 5970b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 5980b57cec5SDimitry Andric 5990b57cec5SDimitry Andric void AddCCKextLibArgs(const llvm::opt::ArgList &Args, 6000b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 6010b57cec5SDimitry Andric 6020b57cec5SDimitry Andric void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override; 6030b57cec5SDimitry Andric 6040b57cec5SDimitry Andric void AddLinkARCArgs(const llvm::opt::ArgList &Args, 6050b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 6060b57cec5SDimitry Andric 6070b57cec5SDimitry Andric unsigned GetDefaultDwarfVersion() const override; 6080b57cec5SDimitry Andric // Until dtrace (via CTF) and LLDB can deal with distributed debug info, 6090b57cec5SDimitry Andric // Darwin defaults to standalone/full debug info. 6100b57cec5SDimitry Andric bool GetDefaultStandaloneDebug() const override { return true; } 6110b57cec5SDimitry Andric llvm::DebuggerKind getDefaultDebuggerTuning() const override { 6120b57cec5SDimitry Andric return llvm::DebuggerKind::LLDB; 6130b57cec5SDimitry Andric } 6140b57cec5SDimitry Andric 6150b57cec5SDimitry Andric /// } 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric private: 6180b57cec5SDimitry Andric void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args, 6190b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 6200b57cec5SDimitry Andric StringRef Sanitizer, 6210b57cec5SDimitry Andric bool shared = true) const; 6220b57cec5SDimitry Andric 6230b57cec5SDimitry Andric bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, 6240b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args, 6250b57cec5SDimitry Andric llvm::SmallString<128> Base, 6260b57cec5SDimitry Andric llvm::StringRef Version, 6270b57cec5SDimitry Andric llvm::StringRef ArchDir, 6280b57cec5SDimitry Andric llvm::StringRef BitDir) const; 6290b57cec5SDimitry Andric 630*bdd1243dSDimitry Andric llvm::SmallString<128> 631*bdd1243dSDimitry Andric GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const; 6320b57cec5SDimitry Andric }; 6330b57cec5SDimitry Andric 6340b57cec5SDimitry Andric } // end namespace toolchains 6350b57cec5SDimitry Andric } // end namespace driver 6360b57cec5SDimitry Andric } // end namespace clang 6370b57cec5SDimitry Andric 6380b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H 639