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" 13*7a6dacacSDimitry Andric #include "LazyDetector.h" 145ffd83dbSDimitry Andric #include "ROCm.h" 15fe6060f1SDimitry Andric #include "clang/Basic/DarwinSDKInfo.h" 16e8d8bef9SDimitry Andric #include "clang/Basic/LangOptions.h" 170b57cec5SDimitry Andric #include "clang/Driver/Tool.h" 180b57cec5SDimitry Andric #include "clang/Driver/ToolChain.h" 190b57cec5SDimitry Andric #include "clang/Driver/XRayArgs.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace clang { 220b57cec5SDimitry Andric namespace driver { 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric namespace toolchains { 250b57cec5SDimitry Andric class MachO; 260b57cec5SDimitry Andric } // end namespace toolchains 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric namespace tools { 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric namespace darwin { 310b57cec5SDimitry Andric llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str); 3206c3fb27SDimitry Andric void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str, 3306c3fb27SDimitry Andric const llvm::opt::ArgList &Args); 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MachOTool : public Tool { 360b57cec5SDimitry Andric virtual void anchor(); 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric protected: 390b57cec5SDimitry Andric void AddMachOArch(const llvm::opt::ArgList &Args, 400b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric const toolchains::MachO &getMachOToolChain() const { 430b57cec5SDimitry Andric return reinterpret_cast<const toolchains::MachO &>(getToolChain()); 440b57cec5SDimitry Andric } 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric public: 475ffd83dbSDimitry Andric MachOTool(const char *Name, const char *ShortName, const ToolChain &TC) 485ffd83dbSDimitry Andric : Tool(Name, ShortName, TC) {} 490b57cec5SDimitry Andric }; 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Assembler : public MachOTool { 520b57cec5SDimitry Andric public: 530b57cec5SDimitry Andric Assembler(const ToolChain &TC) 540b57cec5SDimitry Andric : MachOTool("darwin::Assembler", "assembler", TC) {} 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 590b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 600b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 610b57cec5SDimitry Andric const char *LinkingOutput) const override; 620b57cec5SDimitry Andric }; 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool { 650b57cec5SDimitry Andric bool NeedsTempPath(const InputInfoList &Inputs) const; 660b57cec5SDimitry Andric void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args, 670b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 6881ad6265SDimitry Andric const InputInfoList &Inputs, VersionTuple Version, 69*7a6dacacSDimitry Andric bool LinkerIsLLD, bool UsePlatformVersion) const; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric public: 725ffd83dbSDimitry Andric Linker(const ToolChain &TC) : MachOTool("darwin::Linker", "linker", TC) {} 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 750b57cec5SDimitry Andric bool isLinkJob() const override { return true; } 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 780b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 790b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 800b57cec5SDimitry Andric const char *LinkingOutput) const override; 810b57cec5SDimitry Andric }; 820b57cec5SDimitry Andric 83349cc55cSDimitry Andric class LLVM_LIBRARY_VISIBILITY StaticLibTool : public MachOTool { 84349cc55cSDimitry Andric public: 85349cc55cSDimitry Andric StaticLibTool(const ToolChain &TC) 86349cc55cSDimitry Andric : MachOTool("darwin::StaticLibTool", "static-lib-linker", TC) {} 87349cc55cSDimitry Andric 88349cc55cSDimitry Andric bool hasIntegratedCPP() const override { return false; } 89349cc55cSDimitry Andric bool isLinkJob() const override { return true; } 90349cc55cSDimitry Andric 91349cc55cSDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 92349cc55cSDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 93349cc55cSDimitry Andric const llvm::opt::ArgList &TCArgs, 94349cc55cSDimitry Andric const char *LinkingOutput) const override; 95349cc55cSDimitry Andric }; 96349cc55cSDimitry Andric 970b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Lipo : public MachOTool { 980b57cec5SDimitry Andric public: 990b57cec5SDimitry Andric Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {} 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 1040b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 1050b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 1060b57cec5SDimitry Andric const char *LinkingOutput) const override; 1070b57cec5SDimitry Andric }; 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Dsymutil : public MachOTool { 1100b57cec5SDimitry Andric public: 1110b57cec5SDimitry Andric Dsymutil(const ToolChain &TC) 1120b57cec5SDimitry Andric : MachOTool("darwin::Dsymutil", "dsymutil", TC) {} 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 1150b57cec5SDimitry Andric bool isDsymutilJob() const override { return true; } 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 1180b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 1190b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 1200b57cec5SDimitry Andric const char *LinkingOutput) const override; 1210b57cec5SDimitry Andric }; 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY VerifyDebug : public MachOTool { 1240b57cec5SDimitry Andric public: 1250b57cec5SDimitry Andric VerifyDebug(const ToolChain &TC) 1260b57cec5SDimitry Andric : MachOTool("darwin::VerifyDebug", "dwarfdump", TC) {} 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 1310b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 1320b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 1330b57cec5SDimitry Andric const char *LinkingOutput) const override; 1340b57cec5SDimitry Andric }; 1350b57cec5SDimitry Andric } // end namespace darwin 1360b57cec5SDimitry Andric } // end namespace tools 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric namespace toolchains { 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain { 1410b57cec5SDimitry Andric protected: 1420b57cec5SDimitry Andric Tool *buildAssembler() const override; 1430b57cec5SDimitry Andric Tool *buildLinker() const override; 144349cc55cSDimitry Andric Tool *buildStaticLibTool() const override; 1450b57cec5SDimitry Andric Tool *getTool(Action::ActionClass AC) const override; 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric private: 1480b57cec5SDimitry Andric mutable std::unique_ptr<tools::darwin::Lipo> Lipo; 1490b57cec5SDimitry Andric mutable std::unique_ptr<tools::darwin::Dsymutil> Dsymutil; 1500b57cec5SDimitry Andric mutable std::unique_ptr<tools::darwin::VerifyDebug> VerifyDebug; 1510b57cec5SDimitry Andric 15281ad6265SDimitry Andric /// The version of the linker known to be available in the tool chain. 153bdd1243dSDimitry Andric mutable std::optional<VersionTuple> LinkerVersion; 15481ad6265SDimitry Andric 1550b57cec5SDimitry Andric public: 1560b57cec5SDimitry Andric MachO(const Driver &D, const llvm::Triple &Triple, 1570b57cec5SDimitry Andric const llvm::opt::ArgList &Args); 1580b57cec5SDimitry Andric ~MachO() override; 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric /// @name MachO specific toolchain API 1610b57cec5SDimitry Andric /// { 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric /// Get the "MachO" arch name for a particular compiler invocation. For 1640b57cec5SDimitry Andric /// example, Apple treats different ARM variations as distinct architectures. 1650b57cec5SDimitry Andric StringRef getMachOArchName(const llvm::opt::ArgList &Args) const; 1660b57cec5SDimitry Andric 16781ad6265SDimitry Andric /// Get the version of the linker known to be available for a particular 16881ad6265SDimitry Andric /// compiler invocation (via the `-mlinker-version=` arg). 16981ad6265SDimitry Andric VersionTuple getLinkerVersion(const llvm::opt::ArgList &Args) const; 17081ad6265SDimitry Andric 1710b57cec5SDimitry Andric /// Add the linker arguments to link the ARC runtime library. 1720b57cec5SDimitry Andric virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args, 1730b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const {} 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric /// Add the linker arguments to link the compiler runtime library. 1760b57cec5SDimitry Andric /// 1770b57cec5SDimitry Andric /// FIXME: This API is intended for use with embedded libraries only, and is 1780b57cec5SDimitry Andric /// misleadingly named. 1790b57cec5SDimitry Andric virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, 1800b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 1810b57cec5SDimitry Andric bool ForceLinkBuiltinRT = false) const; 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args, 1840b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const { 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric virtual void addMinVersionArgs(const llvm::opt::ArgList &Args, 1880b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const {} 1890b57cec5SDimitry Andric 190480093f4SDimitry Andric virtual void addPlatformVersionArgs(const llvm::opt::ArgList &Args, 191480093f4SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const { 192480093f4SDimitry Andric } 193480093f4SDimitry Andric 1940b57cec5SDimitry Andric /// On some iOS platforms, kernel and kernel modules were built statically. Is 1950b57cec5SDimitry Andric /// this such a target? 1960b57cec5SDimitry Andric virtual bool isKernelStatic() const { return false; } 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric /// Is the target either iOS or an iOS simulator? 1990b57cec5SDimitry Andric bool isTargetIOSBased() const { return false; } 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric /// Options to control how a runtime library is linked. 2020b57cec5SDimitry Andric enum RuntimeLinkOptions : unsigned { 2030b57cec5SDimitry Andric /// Link the library in even if it can't be found in the VFS. 2040b57cec5SDimitry Andric RLO_AlwaysLink = 1 << 0, 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric /// Use the embedded runtime from the macho_embedded directory. 2070b57cec5SDimitry Andric RLO_IsEmbedded = 1 << 1, 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric /// Emit rpaths for @executable_path as well as the resource directory. 2100b57cec5SDimitry Andric RLO_AddRPath = 1 << 2, 2110b57cec5SDimitry Andric }; 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric /// Add a runtime library to the list of items to link. 2140b57cec5SDimitry Andric void AddLinkRuntimeLib(const llvm::opt::ArgList &Args, 2150b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, StringRef Component, 2160b57cec5SDimitry Andric RuntimeLinkOptions Opts = RuntimeLinkOptions(), 2170b57cec5SDimitry Andric bool IsShared = false) const; 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric /// Add any profiling runtime libraries that are needed. This is essentially a 2200b57cec5SDimitry Andric /// MachO specific version of addProfileRT in Tools.cpp. 2210b57cec5SDimitry Andric void addProfileRTLibs(const llvm::opt::ArgList &Args, 2220b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override { 2230b57cec5SDimitry Andric // There aren't any profiling libs for embedded targets currently. 2240b57cec5SDimitry Andric } 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric /// } 2270b57cec5SDimitry Andric /// @name ToolChain Implementation 2280b57cec5SDimitry Andric /// { 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric types::ID LookupTypeForExtension(StringRef Ext) const override; 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric bool HasNativeLLVMSupport() const override; 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric llvm::opt::DerivedArgList * 2350b57cec5SDimitry Andric TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 2360b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric bool IsBlocksDefault() const override { 2390b57cec5SDimitry Andric // Always allow blocks on Apple; users interested in versioning are 2400b57cec5SDimitry Andric // expected to use /usr/include/Block.h. 2410b57cec5SDimitry Andric return true; 2420b57cec5SDimitry Andric } 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric bool IsMathErrnoDefault() const override { return false; } 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric bool IsEncodeExtendedBlockSignatureDefault() const override { return true; } 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric bool IsObjCNonFragileABIDefault() const override { 2490b57cec5SDimitry Andric // Non-fragile ABI is default for everything but i386. 2500b57cec5SDimitry Andric return getTriple().getArch() != llvm::Triple::x86; 2510b57cec5SDimitry Andric } 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric bool UseObjCMixedDispatch() const override { return true; } 2540b57cec5SDimitry Andric 255bdd1243dSDimitry Andric UnwindTableLevel 256bdd1243dSDimitry Andric getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override; 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric RuntimeLibType GetDefaultRuntimeLibType() const override { 2590b57cec5SDimitry Andric return ToolChain::RLT_CompilerRT; 2600b57cec5SDimitry Andric } 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric bool isPICDefault() const override; 263349cc55cSDimitry Andric bool isPIEDefault(const llvm::opt::ArgList &Args) const override; 2640b57cec5SDimitry Andric bool isPICDefaultForced() const override; 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric bool SupportsProfiling() const override; 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric bool UseDwarfDebugFlags() const override; 26981ad6265SDimitry Andric std::string GetGlobalDebugPathRemapping() const override; 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric llvm::ExceptionHandling 2720b57cec5SDimitry Andric GetExceptionModel(const llvm::opt::ArgList &Args) const override { 2730b57cec5SDimitry Andric return llvm::ExceptionHandling::None; 2740b57cec5SDimitry Andric } 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric virtual StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const { 2770b57cec5SDimitry Andric return ""; 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric 280480093f4SDimitry Andric // Darwin toolchain uses legacy thin LTO API, which is not 281480093f4SDimitry Andric // capable of unit splitting. 282480093f4SDimitry Andric bool canSplitThinLTOUnit() const override { return false; } 2830b57cec5SDimitry Andric /// } 2840b57cec5SDimitry Andric }; 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric /// Darwin - The base Darwin tool chain. 2870b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { 2880b57cec5SDimitry Andric public: 2890b57cec5SDimitry Andric /// Whether the information on the target has been initialized. 2900b57cec5SDimitry Andric // 2910b57cec5SDimitry Andric // FIXME: This should be eliminated. What we want to do is make this part of 2920b57cec5SDimitry Andric // the "default target for arguments" selection process, once we get out of 2930b57cec5SDimitry Andric // the argument translation business. 2940b57cec5SDimitry Andric mutable bool TargetInitialized; 2950b57cec5SDimitry Andric 2960b57cec5SDimitry Andric enum DarwinPlatformKind { 2970b57cec5SDimitry Andric MacOS, 2980b57cec5SDimitry Andric IPhoneOS, 2990b57cec5SDimitry Andric TvOS, 3000b57cec5SDimitry Andric WatchOS, 30181ad6265SDimitry Andric DriverKit, 302*7a6dacacSDimitry Andric XROS, 30381ad6265SDimitry Andric LastDarwinPlatform = DriverKit 3040b57cec5SDimitry Andric }; 3050b57cec5SDimitry Andric enum DarwinEnvironmentKind { 3060b57cec5SDimitry Andric NativeEnvironment, 3070b57cec5SDimitry Andric Simulator, 308fe6060f1SDimitry Andric MacCatalyst, 3090b57cec5SDimitry Andric }; 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric mutable DarwinPlatformKind TargetPlatform; 3120b57cec5SDimitry Andric mutable DarwinEnvironmentKind TargetEnvironment; 3130b57cec5SDimitry Andric 314fe6060f1SDimitry Andric /// The native OS version we are targeting. 3150b57cec5SDimitry Andric mutable VersionTuple TargetVersion; 316fe6060f1SDimitry Andric /// The OS version we are targeting as specified in the triple. 317fe6060f1SDimitry Andric mutable VersionTuple OSTargetVersion; 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric /// The information about the darwin SDK that was used. 320bdd1243dSDimitry Andric mutable std::optional<DarwinSDKInfo> SDKInfo; 3210b57cec5SDimitry Andric 32281ad6265SDimitry Andric /// The target variant triple that was specified (if any). 323bdd1243dSDimitry Andric mutable std::optional<llvm::Triple> TargetVariantTriple; 32481ad6265SDimitry Andric 325*7a6dacacSDimitry Andric LazyDetector<CudaInstallationDetector> CudaInstallation; 326*7a6dacacSDimitry Andric LazyDetector<RocmInstallationDetector> RocmInstallation; 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric private: 3290b57cec5SDimitry Andric void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const; 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric public: 3320b57cec5SDimitry Andric Darwin(const Driver &D, const llvm::Triple &Triple, 3330b57cec5SDimitry Andric const llvm::opt::ArgList &Args); 3340b57cec5SDimitry Andric ~Darwin() override; 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, 3370b57cec5SDimitry Andric types::ID InputType) const override; 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric /// @name Apple Specific Toolchain Implementation 3400b57cec5SDimitry Andric /// { 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric void addMinVersionArgs(const llvm::opt::ArgList &Args, 3430b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 3440b57cec5SDimitry Andric 345480093f4SDimitry Andric void addPlatformVersionArgs(const llvm::opt::ArgList &Args, 346480093f4SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 347480093f4SDimitry Andric 3480b57cec5SDimitry Andric void addStartObjectFileArgs(const llvm::opt::ArgList &Args, 3490b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric bool isKernelStatic() const override { 3520b57cec5SDimitry Andric return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) && 35381ad6265SDimitry Andric !isTargetWatchOS() && !isTargetDriverKit()); 3540b57cec5SDimitry Andric } 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric void addProfileRTLibs(const llvm::opt::ArgList &Args, 3570b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric protected: 3600b57cec5SDimitry Andric /// } 3610b57cec5SDimitry Andric /// @name Darwin specific Toolchain functions 3620b57cec5SDimitry Andric /// { 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andric // FIXME: Eliminate these ...Target functions and derive separate tool chains 3650b57cec5SDimitry Andric // for these targets and put version in constructor. 3660b57cec5SDimitry Andric void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment, 367fe6060f1SDimitry Andric unsigned Major, unsigned Minor, unsigned Micro, 368fe6060f1SDimitry Andric VersionTuple NativeTargetVersion) const { 3690b57cec5SDimitry Andric // FIXME: For now, allow reinitialization as long as values don't 3700b57cec5SDimitry Andric // change. This will go away when we move away from argument translation. 3710b57cec5SDimitry Andric if (TargetInitialized && TargetPlatform == Platform && 3720b57cec5SDimitry Andric TargetEnvironment == Environment && 373fe6060f1SDimitry Andric (Environment == MacCatalyst ? OSTargetVersion : TargetVersion) == 374fe6060f1SDimitry Andric VersionTuple(Major, Minor, Micro)) 3750b57cec5SDimitry Andric return; 3760b57cec5SDimitry Andric 3770b57cec5SDimitry Andric assert(!TargetInitialized && "Target already initialized!"); 3780b57cec5SDimitry Andric TargetInitialized = true; 3790b57cec5SDimitry Andric TargetPlatform = Platform; 3800b57cec5SDimitry Andric TargetEnvironment = Environment; 3810b57cec5SDimitry Andric TargetVersion = VersionTuple(Major, Minor, Micro); 3820b57cec5SDimitry Andric if (Environment == Simulator) 3830b57cec5SDimitry Andric const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::Simulator); 384fe6060f1SDimitry Andric else if (Environment == MacCatalyst) { 385fe6060f1SDimitry Andric const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::MacABI); 386fe6060f1SDimitry Andric TargetVersion = NativeTargetVersion; 387fe6060f1SDimitry Andric OSTargetVersion = VersionTuple(Major, Minor, Micro); 388fe6060f1SDimitry Andric } 3890b57cec5SDimitry Andric } 3900b57cec5SDimitry Andric 3915ffd83dbSDimitry Andric public: 3920b57cec5SDimitry Andric bool isTargetIPhoneOS() const { 3930b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 3940b57cec5SDimitry Andric return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && 3950b57cec5SDimitry Andric TargetEnvironment == NativeEnvironment; 3960b57cec5SDimitry Andric } 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric bool isTargetIOSSimulator() const { 3990b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4000b57cec5SDimitry Andric return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && 4010b57cec5SDimitry Andric TargetEnvironment == Simulator; 4020b57cec5SDimitry Andric } 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric bool isTargetIOSBased() const { 4050b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4060b57cec5SDimitry Andric return isTargetIPhoneOS() || isTargetIOSSimulator(); 4070b57cec5SDimitry Andric } 4080b57cec5SDimitry Andric 409*7a6dacacSDimitry Andric bool isTargetXROSDevice() const { 410*7a6dacacSDimitry Andric return TargetPlatform == XROS && TargetEnvironment == NativeEnvironment; 411*7a6dacacSDimitry Andric } 412*7a6dacacSDimitry Andric 413*7a6dacacSDimitry Andric bool isTargetXROSSimulator() const { 414*7a6dacacSDimitry Andric return TargetPlatform == XROS && TargetEnvironment == Simulator; 415*7a6dacacSDimitry Andric } 416*7a6dacacSDimitry Andric 417*7a6dacacSDimitry Andric bool isTargetXROS() const { return TargetPlatform == XROS; } 418*7a6dacacSDimitry Andric 4190b57cec5SDimitry Andric bool isTargetTvOS() const { 4200b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4210b57cec5SDimitry Andric return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment; 4220b57cec5SDimitry Andric } 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric bool isTargetTvOSSimulator() const { 4250b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4260b57cec5SDimitry Andric return TargetPlatform == TvOS && TargetEnvironment == Simulator; 4270b57cec5SDimitry Andric } 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric bool isTargetTvOSBased() const { 4300b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4310b57cec5SDimitry Andric return TargetPlatform == TvOS; 4320b57cec5SDimitry Andric } 4330b57cec5SDimitry Andric 4340b57cec5SDimitry Andric bool isTargetWatchOS() const { 4350b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4360b57cec5SDimitry Andric return TargetPlatform == WatchOS && TargetEnvironment == NativeEnvironment; 4370b57cec5SDimitry Andric } 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric bool isTargetWatchOSSimulator() const { 4400b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4410b57cec5SDimitry Andric return TargetPlatform == WatchOS && TargetEnvironment == Simulator; 4420b57cec5SDimitry Andric } 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric bool isTargetWatchOSBased() const { 4450b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4460b57cec5SDimitry Andric return TargetPlatform == WatchOS; 4470b57cec5SDimitry Andric } 4480b57cec5SDimitry Andric 44981ad6265SDimitry Andric bool isTargetDriverKit() const { 45081ad6265SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 45181ad6265SDimitry Andric return TargetPlatform == DriverKit; 45281ad6265SDimitry Andric } 45381ad6265SDimitry Andric 454fe6060f1SDimitry Andric bool isTargetMacCatalyst() const { 455fe6060f1SDimitry Andric return TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst; 456fe6060f1SDimitry Andric } 457fe6060f1SDimitry Andric 4580b57cec5SDimitry Andric bool isTargetMacOS() const { 4590b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4600b57cec5SDimitry Andric return TargetPlatform == MacOS; 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric 4635ffd83dbSDimitry Andric bool isTargetMacOSBased() const { 4645ffd83dbSDimitry Andric assert(TargetInitialized && "Target not initialized!"); 465fe6060f1SDimitry Andric return TargetPlatform == MacOS || isTargetMacCatalyst(); 4665ffd83dbSDimitry Andric } 4675ffd83dbSDimitry Andric 4685ffd83dbSDimitry Andric bool isTargetAppleSiliconMac() const { 4695ffd83dbSDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4705ffd83dbSDimitry Andric return isTargetMacOSBased() && getArch() == llvm::Triple::aarch64; 4715ffd83dbSDimitry Andric } 4725ffd83dbSDimitry Andric 4730b57cec5SDimitry Andric bool isTargetInitialized() const { return TargetInitialized; } 4740b57cec5SDimitry Andric 475fe6060f1SDimitry Andric /// The version of the OS that's used by the OS specified in the target 476fe6060f1SDimitry Andric /// triple. It might be different from the actual target OS on which the 477fe6060f1SDimitry Andric /// program will run, e.g. MacCatalyst code runs on a macOS target, but its 478fe6060f1SDimitry Andric /// target triple is iOS. 479fe6060f1SDimitry Andric VersionTuple getTripleTargetVersion() const { 4800b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 481fe6060f1SDimitry Andric return isTargetMacCatalyst() ? OSTargetVersion : TargetVersion; 4820b57cec5SDimitry Andric } 4830b57cec5SDimitry Andric 4840b57cec5SDimitry Andric bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0, 4850b57cec5SDimitry Andric unsigned V2 = 0) const { 4860b57cec5SDimitry Andric assert(isTargetIOSBased() && "Unexpected call for non iOS target!"); 4870b57cec5SDimitry Andric return TargetVersion < VersionTuple(V0, V1, V2); 4880b57cec5SDimitry Andric } 4890b57cec5SDimitry Andric 4905ffd83dbSDimitry Andric /// Returns true if the minimum supported macOS version for the slice that's 4915ffd83dbSDimitry Andric /// being built is less than the specified version. If there's no minimum 4925ffd83dbSDimitry Andric /// supported macOS version, the deployment target version is compared to the 4935ffd83dbSDimitry Andric /// specifed version instead. 4940b57cec5SDimitry Andric bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const { 495fe6060f1SDimitry Andric assert(isTargetMacOSBased() && 496fe6060f1SDimitry Andric (getTriple().isMacOSX() || getTriple().isMacCatalystEnvironment()) && 4975ffd83dbSDimitry Andric "Unexpected call for non OS X target!"); 498e8d8bef9SDimitry Andric // The effective triple might not be initialized yet, so construct a 499e8d8bef9SDimitry Andric // pseudo-effective triple to get the minimum supported OS version. 500e8d8bef9SDimitry Andric VersionTuple MinVers = 501e8d8bef9SDimitry Andric llvm::Triple(getTriple().getArchName(), "apple", "macos") 502e8d8bef9SDimitry Andric .getMinimumSupportedOSVersion(); 5035ffd83dbSDimitry Andric return (!MinVers.empty() && MinVers > TargetVersion 5045ffd83dbSDimitry Andric ? MinVers 5055ffd83dbSDimitry Andric : TargetVersion) < VersionTuple(V0, V1, V2); 5060b57cec5SDimitry Andric } 5070b57cec5SDimitry Andric 5085ffd83dbSDimitry Andric protected: 5090b57cec5SDimitry Andric /// Return true if c++17 aligned allocation/deallocation functions are not 5100b57cec5SDimitry Andric /// implemented in the c++ standard library of the deployment target we are 5110b57cec5SDimitry Andric /// targeting. 5120b57cec5SDimitry Andric bool isAlignedAllocationUnavailable() const; 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 5150b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args, 5160b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 5170b57cec5SDimitry Andric 518bdd1243dSDimitry Andric void addClangCC1ASTargetOptions( 519bdd1243dSDimitry Andric const llvm::opt::ArgList &Args, 520bdd1243dSDimitry Andric llvm::opt::ArgStringList &CC1ASArgs) const override; 521bdd1243dSDimitry Andric 5220b57cec5SDimitry Andric StringRef getPlatformFamily() const; 5230b57cec5SDimitry Andric StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const override; 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andric public: 5260b57cec5SDimitry Andric static StringRef getSDKName(StringRef isysroot); 5270b57cec5SDimitry Andric 5280b57cec5SDimitry Andric /// } 5290b57cec5SDimitry Andric /// @name ToolChain Implementation 5300b57cec5SDimitry Andric /// { 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric // Darwin tools support multiple architecture (e.g., i386 and x86_64) and 5330b57cec5SDimitry Andric // most development is done against SDKs, so compiling for a different 5340b57cec5SDimitry Andric // architecture should not get any special treatment. 5350b57cec5SDimitry Andric bool isCrossCompiling() const override { return false; } 5360b57cec5SDimitry Andric 5370b57cec5SDimitry Andric llvm::opt::DerivedArgList * 5380b57cec5SDimitry Andric TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 5390b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andric CXXStdlibType GetDefaultCXXStdlibType() const override; 5420b57cec5SDimitry Andric ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override; 5430b57cec5SDimitry Andric bool hasBlocksRuntime() const override; 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, 5460b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 5475ffd83dbSDimitry Andric void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, 5485ffd83dbSDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric bool UseObjCMixedDispatch() const override { 5510b57cec5SDimitry Andric // This is only used with the non-fragile ABI and non-legacy dispatch. 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andric // Mixed dispatch is used everywhere except OS X before 10.6. 554fe6060f1SDimitry Andric return !(isTargetMacOSBased() && isMacosxVersionLT(10, 6)); 5550b57cec5SDimitry Andric } 5560b57cec5SDimitry Andric 557e8d8bef9SDimitry Andric LangOptions::StackProtectorMode 558e8d8bef9SDimitry Andric GetDefaultStackProtectorLevel(bool KernelOrKext) const override { 5590b57cec5SDimitry Andric // Stack protectors default to on for user code on 10.5, 5600b57cec5SDimitry Andric // and for everything in 10.6 and beyond 561*7a6dacacSDimitry Andric if (isTargetIOSBased() || isTargetWatchOSBased() || isTargetDriverKit() || 562*7a6dacacSDimitry Andric isTargetXROS()) 563e8d8bef9SDimitry Andric return LangOptions::SSPOn; 564fe6060f1SDimitry Andric else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 6)) 565e8d8bef9SDimitry Andric return LangOptions::SSPOn; 566fe6060f1SDimitry Andric else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 5) && !KernelOrKext) 567e8d8bef9SDimitry Andric return LangOptions::SSPOn; 5680b57cec5SDimitry Andric 569e8d8bef9SDimitry Andric return LangOptions::SSPOff; 5700b57cec5SDimitry Andric } 5710b57cec5SDimitry Andric 5720b57cec5SDimitry Andric void CheckObjCARC() const override; 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric llvm::ExceptionHandling GetExceptionModel( 5750b57cec5SDimitry Andric const llvm::opt::ArgList &Args) const override; 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric bool SupportsEmbeddedBitcode() const override; 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andric SanitizerMask getSupportedSanitizers() const override; 5800b57cec5SDimitry Andric 5810b57cec5SDimitry Andric void printVerboseInfo(raw_ostream &OS) const override; 5820b57cec5SDimitry Andric }; 5830b57cec5SDimitry Andric 5840b57cec5SDimitry Andric /// DarwinClang - The Darwin toolchain used by Clang. 5850b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { 5860b57cec5SDimitry Andric public: 5870b57cec5SDimitry Andric DarwinClang(const Driver &D, const llvm::Triple &Triple, 5880b57cec5SDimitry Andric const llvm::opt::ArgList &Args); 5890b57cec5SDimitry Andric 5900b57cec5SDimitry Andric /// @name Apple ToolChain Implementation 5910b57cec5SDimitry Andric /// { 5920b57cec5SDimitry Andric 5930b57cec5SDimitry Andric RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override; 5940b57cec5SDimitry Andric 5950b57cec5SDimitry Andric void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, 5960b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 5970b57cec5SDimitry Andric bool ForceLinkBuiltinRT = false) const override; 5980b57cec5SDimitry Andric 5990b57cec5SDimitry Andric void AddClangCXXStdlibIncludeArgs( 6000b57cec5SDimitry Andric const llvm::opt::ArgList &DriverArgs, 6010b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 6020b57cec5SDimitry Andric 6030b57cec5SDimitry Andric void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 6040b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, 6070b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 6080b57cec5SDimitry Andric 6090b57cec5SDimitry Andric void AddCCKextLibArgs(const llvm::opt::ArgList &Args, 6100b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 6110b57cec5SDimitry Andric 6120b57cec5SDimitry Andric void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override; 6130b57cec5SDimitry Andric 6140b57cec5SDimitry Andric void AddLinkARCArgs(const llvm::opt::ArgList &Args, 6150b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric unsigned GetDefaultDwarfVersion() const override; 6180b57cec5SDimitry Andric // Until dtrace (via CTF) and LLDB can deal with distributed debug info, 6190b57cec5SDimitry Andric // Darwin defaults to standalone/full debug info. 6200b57cec5SDimitry Andric bool GetDefaultStandaloneDebug() const override { return true; } 6210b57cec5SDimitry Andric llvm::DebuggerKind getDefaultDebuggerTuning() const override { 6220b57cec5SDimitry Andric return llvm::DebuggerKind::LLDB; 6230b57cec5SDimitry Andric } 6240b57cec5SDimitry Andric 6250b57cec5SDimitry Andric /// } 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric private: 6280b57cec5SDimitry Andric void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args, 6290b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 6300b57cec5SDimitry Andric StringRef Sanitizer, 6310b57cec5SDimitry Andric bool shared = true) const; 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, 6340b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args, 6350b57cec5SDimitry Andric llvm::SmallString<128> Base, 6360b57cec5SDimitry Andric llvm::StringRef Version, 6370b57cec5SDimitry Andric llvm::StringRef ArchDir, 6380b57cec5SDimitry Andric llvm::StringRef BitDir) const; 6390b57cec5SDimitry Andric 640bdd1243dSDimitry Andric llvm::SmallString<128> 641bdd1243dSDimitry Andric GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const; 6420b57cec5SDimitry Andric }; 6430b57cec5SDimitry Andric 6440b57cec5SDimitry Andric } // end namespace toolchains 6450b57cec5SDimitry Andric } // end namespace driver 6460b57cec5SDimitry Andric } // end namespace clang 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H 649