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, 66e8d8bef9SDimitry Andric const InputInfoList &Inputs, unsigned Version[5], 67*0eae32dcSDimitry 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 1500b57cec5SDimitry Andric public: 1510b57cec5SDimitry Andric MachO(const Driver &D, const llvm::Triple &Triple, 1520b57cec5SDimitry Andric const llvm::opt::ArgList &Args); 1530b57cec5SDimitry Andric ~MachO() override; 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric /// @name MachO specific toolchain API 1560b57cec5SDimitry Andric /// { 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric /// Get the "MachO" arch name for a particular compiler invocation. For 1590b57cec5SDimitry Andric /// example, Apple treats different ARM variations as distinct architectures. 1600b57cec5SDimitry Andric StringRef getMachOArchName(const llvm::opt::ArgList &Args) const; 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric /// Add the linker arguments to link the ARC runtime library. 1630b57cec5SDimitry Andric virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args, 1640b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const {} 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric /// Add the linker arguments to link the compiler runtime library. 1670b57cec5SDimitry Andric /// 1680b57cec5SDimitry Andric /// FIXME: This API is intended for use with embedded libraries only, and is 1690b57cec5SDimitry Andric /// misleadingly named. 1700b57cec5SDimitry Andric virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, 1710b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 1720b57cec5SDimitry Andric bool ForceLinkBuiltinRT = false) const; 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args, 1750b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const { 1760b57cec5SDimitry Andric } 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric virtual void addMinVersionArgs(const llvm::opt::ArgList &Args, 1790b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const {} 1800b57cec5SDimitry Andric 181480093f4SDimitry Andric virtual void addPlatformVersionArgs(const llvm::opt::ArgList &Args, 182480093f4SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const { 183480093f4SDimitry Andric } 184480093f4SDimitry Andric 1850b57cec5SDimitry Andric /// On some iOS platforms, kernel and kernel modules were built statically. Is 1860b57cec5SDimitry Andric /// this such a target? 1870b57cec5SDimitry Andric virtual bool isKernelStatic() const { return false; } 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric /// Is the target either iOS or an iOS simulator? 1900b57cec5SDimitry Andric bool isTargetIOSBased() const { return false; } 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric /// Options to control how a runtime library is linked. 1930b57cec5SDimitry Andric enum RuntimeLinkOptions : unsigned { 1940b57cec5SDimitry Andric /// Link the library in even if it can't be found in the VFS. 1950b57cec5SDimitry Andric RLO_AlwaysLink = 1 << 0, 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric /// Use the embedded runtime from the macho_embedded directory. 1980b57cec5SDimitry Andric RLO_IsEmbedded = 1 << 1, 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric /// Emit rpaths for @executable_path as well as the resource directory. 2010b57cec5SDimitry Andric RLO_AddRPath = 1 << 2, 2020b57cec5SDimitry Andric }; 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric /// Add a runtime library to the list of items to link. 2050b57cec5SDimitry Andric void AddLinkRuntimeLib(const llvm::opt::ArgList &Args, 2060b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, StringRef Component, 2070b57cec5SDimitry Andric RuntimeLinkOptions Opts = RuntimeLinkOptions(), 2080b57cec5SDimitry Andric bool IsShared = false) const; 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric /// Add any profiling runtime libraries that are needed. This is essentially a 2110b57cec5SDimitry Andric /// MachO specific version of addProfileRT in Tools.cpp. 2120b57cec5SDimitry Andric void addProfileRTLibs(const llvm::opt::ArgList &Args, 2130b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override { 2140b57cec5SDimitry Andric // There aren't any profiling libs for embedded targets currently. 2150b57cec5SDimitry Andric } 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric /// } 2180b57cec5SDimitry Andric /// @name ToolChain Implementation 2190b57cec5SDimitry Andric /// { 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric types::ID LookupTypeForExtension(StringRef Ext) const override; 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric bool HasNativeLLVMSupport() const override; 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric llvm::opt::DerivedArgList * 2260b57cec5SDimitry Andric TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 2270b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric bool IsBlocksDefault() const override { 2300b57cec5SDimitry Andric // Always allow blocks on Apple; users interested in versioning are 2310b57cec5SDimitry Andric // expected to use /usr/include/Block.h. 2320b57cec5SDimitry Andric return true; 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric bool IsIntegratedAssemblerDefault() const override { 2350b57cec5SDimitry Andric // Default integrated assembler to on for Apple's MachO targets. 2360b57cec5SDimitry Andric return true; 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric bool IsMathErrnoDefault() const override { return false; } 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric bool IsEncodeExtendedBlockSignatureDefault() const override { return true; } 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric bool IsObjCNonFragileABIDefault() const override { 2440b57cec5SDimitry Andric // Non-fragile ABI is default for everything but i386. 2450b57cec5SDimitry Andric return getTriple().getArch() != llvm::Triple::x86; 2460b57cec5SDimitry Andric } 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric bool UseObjCMixedDispatch() const override { return true; } 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override; 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric RuntimeLibType GetDefaultRuntimeLibType() const override { 2530b57cec5SDimitry Andric return ToolChain::RLT_CompilerRT; 2540b57cec5SDimitry Andric } 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric bool isPICDefault() const override; 257349cc55cSDimitry Andric bool isPIEDefault(const llvm::opt::ArgList &Args) const override; 2580b57cec5SDimitry Andric bool isPICDefaultForced() const override; 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric bool SupportsProfiling() const override; 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric bool UseDwarfDebugFlags() const override; 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric llvm::ExceptionHandling 2650b57cec5SDimitry Andric GetExceptionModel(const llvm::opt::ArgList &Args) const override { 2660b57cec5SDimitry Andric return llvm::ExceptionHandling::None; 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric virtual StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const { 2700b57cec5SDimitry Andric return ""; 2710b57cec5SDimitry Andric } 2720b57cec5SDimitry Andric 273480093f4SDimitry Andric // Darwin toolchain uses legacy thin LTO API, which is not 274480093f4SDimitry Andric // capable of unit splitting. 275480093f4SDimitry Andric bool canSplitThinLTOUnit() const override { return false; } 2760b57cec5SDimitry Andric /// } 2770b57cec5SDimitry Andric }; 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric /// Darwin - The base Darwin tool chain. 2800b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { 2810b57cec5SDimitry Andric public: 2820b57cec5SDimitry Andric /// Whether the information on the target has been initialized. 2830b57cec5SDimitry Andric // 2840b57cec5SDimitry Andric // FIXME: This should be eliminated. What we want to do is make this part of 2850b57cec5SDimitry Andric // the "default target for arguments" selection process, once we get out of 2860b57cec5SDimitry Andric // the argument translation business. 2870b57cec5SDimitry Andric mutable bool TargetInitialized; 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric enum DarwinPlatformKind { 2900b57cec5SDimitry Andric MacOS, 2910b57cec5SDimitry Andric IPhoneOS, 2920b57cec5SDimitry Andric TvOS, 2930b57cec5SDimitry Andric WatchOS, 2940b57cec5SDimitry Andric LastDarwinPlatform = WatchOS 2950b57cec5SDimitry Andric }; 2960b57cec5SDimitry Andric enum DarwinEnvironmentKind { 2970b57cec5SDimitry Andric NativeEnvironment, 2980b57cec5SDimitry Andric Simulator, 299fe6060f1SDimitry Andric MacCatalyst, 3000b57cec5SDimitry Andric }; 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric mutable DarwinPlatformKind TargetPlatform; 3030b57cec5SDimitry Andric mutable DarwinEnvironmentKind TargetEnvironment; 3040b57cec5SDimitry Andric 305fe6060f1SDimitry Andric /// The native OS version we are targeting. 3060b57cec5SDimitry Andric mutable VersionTuple TargetVersion; 307fe6060f1SDimitry Andric /// The OS version we are targeting as specified in the triple. 308fe6060f1SDimitry Andric mutable VersionTuple OSTargetVersion; 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric /// The information about the darwin SDK that was used. 3110b57cec5SDimitry Andric mutable Optional<DarwinSDKInfo> SDKInfo; 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric CudaInstallationDetector CudaInstallation; 3145ffd83dbSDimitry Andric RocmInstallationDetector RocmInstallation; 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric private: 3170b57cec5SDimitry Andric void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const; 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric public: 3200b57cec5SDimitry Andric Darwin(const Driver &D, const llvm::Triple &Triple, 3210b57cec5SDimitry Andric const llvm::opt::ArgList &Args); 3220b57cec5SDimitry Andric ~Darwin() override; 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, 3250b57cec5SDimitry Andric types::ID InputType) const override; 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric /// @name Apple Specific Toolchain Implementation 3280b57cec5SDimitry Andric /// { 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric void addMinVersionArgs(const llvm::opt::ArgList &Args, 3310b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 3320b57cec5SDimitry Andric 333480093f4SDimitry Andric void addPlatformVersionArgs(const llvm::opt::ArgList &Args, 334480093f4SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 335480093f4SDimitry Andric 3360b57cec5SDimitry Andric void addStartObjectFileArgs(const llvm::opt::ArgList &Args, 3370b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric bool isKernelStatic() const override { 3400b57cec5SDimitry Andric return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) && 3410b57cec5SDimitry Andric !isTargetWatchOS()); 3420b57cec5SDimitry Andric } 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric void addProfileRTLibs(const llvm::opt::ArgList &Args, 3450b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric protected: 3480b57cec5SDimitry Andric /// } 3490b57cec5SDimitry Andric /// @name Darwin specific Toolchain functions 3500b57cec5SDimitry Andric /// { 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric // FIXME: Eliminate these ...Target functions and derive separate tool chains 3530b57cec5SDimitry Andric // for these targets and put version in constructor. 3540b57cec5SDimitry Andric void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment, 355fe6060f1SDimitry Andric unsigned Major, unsigned Minor, unsigned Micro, 356fe6060f1SDimitry Andric VersionTuple NativeTargetVersion) const { 3570b57cec5SDimitry Andric // FIXME: For now, allow reinitialization as long as values don't 3580b57cec5SDimitry Andric // change. This will go away when we move away from argument translation. 3590b57cec5SDimitry Andric if (TargetInitialized && TargetPlatform == Platform && 3600b57cec5SDimitry Andric TargetEnvironment == Environment && 361fe6060f1SDimitry Andric (Environment == MacCatalyst ? OSTargetVersion : TargetVersion) == 362fe6060f1SDimitry Andric VersionTuple(Major, Minor, Micro)) 3630b57cec5SDimitry Andric return; 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric assert(!TargetInitialized && "Target already initialized!"); 3660b57cec5SDimitry Andric TargetInitialized = true; 3670b57cec5SDimitry Andric TargetPlatform = Platform; 3680b57cec5SDimitry Andric TargetEnvironment = Environment; 3690b57cec5SDimitry Andric TargetVersion = VersionTuple(Major, Minor, Micro); 3700b57cec5SDimitry Andric if (Environment == Simulator) 3710b57cec5SDimitry Andric const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::Simulator); 372fe6060f1SDimitry Andric else if (Environment == MacCatalyst) { 373fe6060f1SDimitry Andric const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::MacABI); 374fe6060f1SDimitry Andric TargetVersion = NativeTargetVersion; 375fe6060f1SDimitry Andric OSTargetVersion = VersionTuple(Major, Minor, Micro); 376fe6060f1SDimitry Andric } 3770b57cec5SDimitry Andric } 3780b57cec5SDimitry Andric 3795ffd83dbSDimitry Andric public: 3800b57cec5SDimitry Andric bool isTargetIPhoneOS() const { 3810b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 3820b57cec5SDimitry Andric return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && 3830b57cec5SDimitry Andric TargetEnvironment == NativeEnvironment; 3840b57cec5SDimitry Andric } 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andric bool isTargetIOSSimulator() const { 3870b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 3880b57cec5SDimitry Andric return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && 3890b57cec5SDimitry Andric TargetEnvironment == Simulator; 3900b57cec5SDimitry Andric } 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric bool isTargetIOSBased() const { 3930b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 3940b57cec5SDimitry Andric return isTargetIPhoneOS() || isTargetIOSSimulator(); 3950b57cec5SDimitry Andric } 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric bool isTargetTvOS() const { 3980b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 3990b57cec5SDimitry Andric return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment; 4000b57cec5SDimitry Andric } 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric bool isTargetTvOSSimulator() const { 4030b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4040b57cec5SDimitry Andric return TargetPlatform == TvOS && TargetEnvironment == Simulator; 4050b57cec5SDimitry Andric } 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric bool isTargetTvOSBased() const { 4080b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4090b57cec5SDimitry Andric return TargetPlatform == TvOS; 4100b57cec5SDimitry Andric } 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andric bool isTargetWatchOS() const { 4130b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4140b57cec5SDimitry Andric return TargetPlatform == WatchOS && TargetEnvironment == NativeEnvironment; 4150b57cec5SDimitry Andric } 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric bool isTargetWatchOSSimulator() const { 4180b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4190b57cec5SDimitry Andric return TargetPlatform == WatchOS && TargetEnvironment == Simulator; 4200b57cec5SDimitry Andric } 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric bool isTargetWatchOSBased() const { 4230b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4240b57cec5SDimitry Andric return TargetPlatform == WatchOS; 4250b57cec5SDimitry Andric } 4260b57cec5SDimitry Andric 427fe6060f1SDimitry Andric bool isTargetMacCatalyst() const { 428fe6060f1SDimitry Andric return TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst; 429fe6060f1SDimitry Andric } 430fe6060f1SDimitry Andric 4310b57cec5SDimitry Andric bool isTargetMacOS() const { 4320b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4330b57cec5SDimitry Andric return TargetPlatform == MacOS; 4340b57cec5SDimitry Andric } 4350b57cec5SDimitry Andric 4365ffd83dbSDimitry Andric bool isTargetMacOSBased() const { 4375ffd83dbSDimitry Andric assert(TargetInitialized && "Target not initialized!"); 438fe6060f1SDimitry Andric return TargetPlatform == MacOS || isTargetMacCatalyst(); 4395ffd83dbSDimitry Andric } 4405ffd83dbSDimitry Andric 4415ffd83dbSDimitry Andric bool isTargetAppleSiliconMac() const { 4425ffd83dbSDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4435ffd83dbSDimitry Andric return isTargetMacOSBased() && getArch() == llvm::Triple::aarch64; 4445ffd83dbSDimitry Andric } 4455ffd83dbSDimitry Andric 4460b57cec5SDimitry Andric bool isTargetInitialized() const { return TargetInitialized; } 4470b57cec5SDimitry Andric 448fe6060f1SDimitry Andric /// The version of the OS that's used by the OS specified in the target 449fe6060f1SDimitry Andric /// triple. It might be different from the actual target OS on which the 450fe6060f1SDimitry Andric /// program will run, e.g. MacCatalyst code runs on a macOS target, but its 451fe6060f1SDimitry Andric /// target triple is iOS. 452fe6060f1SDimitry Andric VersionTuple getTripleTargetVersion() const { 4530b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 454fe6060f1SDimitry Andric return isTargetMacCatalyst() ? OSTargetVersion : TargetVersion; 4550b57cec5SDimitry Andric } 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andric bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0, 4580b57cec5SDimitry Andric unsigned V2 = 0) const { 4590b57cec5SDimitry Andric assert(isTargetIOSBased() && "Unexpected call for non iOS target!"); 4600b57cec5SDimitry Andric return TargetVersion < VersionTuple(V0, V1, V2); 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric 4635ffd83dbSDimitry Andric /// Returns true if the minimum supported macOS version for the slice that's 4645ffd83dbSDimitry Andric /// being built is less than the specified version. If there's no minimum 4655ffd83dbSDimitry Andric /// supported macOS version, the deployment target version is compared to the 4665ffd83dbSDimitry Andric /// specifed version instead. 4670b57cec5SDimitry Andric bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const { 468fe6060f1SDimitry Andric assert(isTargetMacOSBased() && 469fe6060f1SDimitry Andric (getTriple().isMacOSX() || getTriple().isMacCatalystEnvironment()) && 4705ffd83dbSDimitry Andric "Unexpected call for non OS X target!"); 471e8d8bef9SDimitry Andric // The effective triple might not be initialized yet, so construct a 472e8d8bef9SDimitry Andric // pseudo-effective triple to get the minimum supported OS version. 473e8d8bef9SDimitry Andric VersionTuple MinVers = 474e8d8bef9SDimitry Andric llvm::Triple(getTriple().getArchName(), "apple", "macos") 475e8d8bef9SDimitry Andric .getMinimumSupportedOSVersion(); 4765ffd83dbSDimitry Andric return (!MinVers.empty() && MinVers > TargetVersion 4775ffd83dbSDimitry Andric ? MinVers 4785ffd83dbSDimitry Andric : TargetVersion) < VersionTuple(V0, V1, V2); 4790b57cec5SDimitry Andric } 4800b57cec5SDimitry Andric 4815ffd83dbSDimitry Andric protected: 4820b57cec5SDimitry Andric /// Return true if c++17 aligned allocation/deallocation functions are not 4830b57cec5SDimitry Andric /// implemented in the c++ standard library of the deployment target we are 4840b57cec5SDimitry Andric /// targeting. 4850b57cec5SDimitry Andric bool isAlignedAllocationUnavailable() const; 4860b57cec5SDimitry Andric 4870b57cec5SDimitry Andric void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 4880b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args, 4890b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andric StringRef getPlatformFamily() const; 4920b57cec5SDimitry Andric StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const override; 4930b57cec5SDimitry Andric 4940b57cec5SDimitry Andric public: 4950b57cec5SDimitry Andric static StringRef getSDKName(StringRef isysroot); 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric /// } 4980b57cec5SDimitry Andric /// @name ToolChain Implementation 4990b57cec5SDimitry Andric /// { 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric // Darwin tools support multiple architecture (e.g., i386 and x86_64) and 5020b57cec5SDimitry Andric // most development is done against SDKs, so compiling for a different 5030b57cec5SDimitry Andric // architecture should not get any special treatment. 5040b57cec5SDimitry Andric bool isCrossCompiling() const override { return false; } 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric llvm::opt::DerivedArgList * 5070b57cec5SDimitry Andric TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 5080b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric CXXStdlibType GetDefaultCXXStdlibType() const override; 5110b57cec5SDimitry Andric ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override; 5120b57cec5SDimitry Andric bool hasBlocksRuntime() const override; 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, 5150b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 5165ffd83dbSDimitry Andric void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, 5175ffd83dbSDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric bool UseObjCMixedDispatch() const override { 5200b57cec5SDimitry Andric // This is only used with the non-fragile ABI and non-legacy dispatch. 5210b57cec5SDimitry Andric 5220b57cec5SDimitry Andric // Mixed dispatch is used everywhere except OS X before 10.6. 523fe6060f1SDimitry Andric return !(isTargetMacOSBased() && isMacosxVersionLT(10, 6)); 5240b57cec5SDimitry Andric } 5250b57cec5SDimitry Andric 526e8d8bef9SDimitry Andric LangOptions::StackProtectorMode 527e8d8bef9SDimitry Andric GetDefaultStackProtectorLevel(bool KernelOrKext) const override { 5280b57cec5SDimitry Andric // Stack protectors default to on for user code on 10.5, 5290b57cec5SDimitry Andric // and for everything in 10.6 and beyond 5300b57cec5SDimitry Andric if (isTargetIOSBased() || isTargetWatchOSBased()) 531e8d8bef9SDimitry Andric return LangOptions::SSPOn; 532fe6060f1SDimitry Andric else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 6)) 533e8d8bef9SDimitry Andric return LangOptions::SSPOn; 534fe6060f1SDimitry Andric else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 5) && !KernelOrKext) 535e8d8bef9SDimitry Andric return LangOptions::SSPOn; 5360b57cec5SDimitry Andric 537e8d8bef9SDimitry Andric return LangOptions::SSPOff; 5380b57cec5SDimitry Andric } 5390b57cec5SDimitry Andric 5400b57cec5SDimitry Andric void CheckObjCARC() const override; 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric llvm::ExceptionHandling GetExceptionModel( 5430b57cec5SDimitry Andric const llvm::opt::ArgList &Args) const override; 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric bool SupportsEmbeddedBitcode() const override; 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andric SanitizerMask getSupportedSanitizers() const override; 5480b57cec5SDimitry Andric 5490b57cec5SDimitry Andric void printVerboseInfo(raw_ostream &OS) const override; 5500b57cec5SDimitry Andric }; 5510b57cec5SDimitry Andric 5520b57cec5SDimitry Andric /// DarwinClang - The Darwin toolchain used by Clang. 5530b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { 5540b57cec5SDimitry Andric public: 5550b57cec5SDimitry Andric DarwinClang(const Driver &D, const llvm::Triple &Triple, 5560b57cec5SDimitry Andric const llvm::opt::ArgList &Args); 5570b57cec5SDimitry Andric 5580b57cec5SDimitry Andric /// @name Apple ToolChain Implementation 5590b57cec5SDimitry Andric /// { 5600b57cec5SDimitry Andric 5610b57cec5SDimitry Andric RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override; 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, 5640b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 5650b57cec5SDimitry Andric bool ForceLinkBuiltinRT = false) const override; 5660b57cec5SDimitry Andric 5670b57cec5SDimitry Andric void AddClangCXXStdlibIncludeArgs( 5680b57cec5SDimitry Andric const llvm::opt::ArgList &DriverArgs, 5690b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 5720b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, 5750b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric void AddCCKextLibArgs(const llvm::opt::ArgList &Args, 5780b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 5790b57cec5SDimitry Andric 5800b57cec5SDimitry Andric void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override; 5810b57cec5SDimitry Andric 5820b57cec5SDimitry Andric void AddLinkARCArgs(const llvm::opt::ArgList &Args, 5830b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andric unsigned GetDefaultDwarfVersion() const override; 5860b57cec5SDimitry Andric // Until dtrace (via CTF) and LLDB can deal with distributed debug info, 5870b57cec5SDimitry Andric // Darwin defaults to standalone/full debug info. 5880b57cec5SDimitry Andric bool GetDefaultStandaloneDebug() const override { return true; } 5890b57cec5SDimitry Andric llvm::DebuggerKind getDefaultDebuggerTuning() const override { 5900b57cec5SDimitry Andric return llvm::DebuggerKind::LLDB; 5910b57cec5SDimitry Andric } 5920b57cec5SDimitry Andric 5930b57cec5SDimitry Andric /// } 5940b57cec5SDimitry Andric 5950b57cec5SDimitry Andric private: 5960b57cec5SDimitry Andric void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args, 5970b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 5980b57cec5SDimitry Andric StringRef Sanitizer, 5990b57cec5SDimitry Andric bool shared = true) const; 6000b57cec5SDimitry Andric 6010b57cec5SDimitry Andric bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, 6020b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args, 6030b57cec5SDimitry Andric llvm::SmallString<128> Base, 6040b57cec5SDimitry Andric llvm::StringRef Version, 6050b57cec5SDimitry Andric llvm::StringRef ArchDir, 6060b57cec5SDimitry Andric llvm::StringRef BitDir) const; 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric llvm::StringRef GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const; 6090b57cec5SDimitry Andric }; 6100b57cec5SDimitry Andric 6110b57cec5SDimitry Andric } // end namespace toolchains 6120b57cec5SDimitry Andric } // end namespace driver 6130b57cec5SDimitry Andric } // end namespace clang 6140b57cec5SDimitry Andric 6150b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H 616