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*5ffd83dbSDimitry Andric #include "ROCm.h" 140b57cec5SDimitry Andric #include "clang/Driver/DarwinSDKInfo.h" 150b57cec5SDimitry Andric #include "clang/Driver/Tool.h" 160b57cec5SDimitry Andric #include "clang/Driver/ToolChain.h" 170b57cec5SDimitry Andric #include "clang/Driver/XRayArgs.h" 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric namespace clang { 200b57cec5SDimitry Andric namespace driver { 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric namespace toolchains { 230b57cec5SDimitry Andric class MachO; 240b57cec5SDimitry Andric } // end namespace toolchains 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric namespace tools { 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric namespace darwin { 290b57cec5SDimitry Andric llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str); 300b57cec5SDimitry Andric void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str); 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MachOTool : public Tool { 330b57cec5SDimitry Andric virtual void anchor(); 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric protected: 360b57cec5SDimitry Andric void AddMachOArch(const llvm::opt::ArgList &Args, 370b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric const toolchains::MachO &getMachOToolChain() const { 400b57cec5SDimitry Andric return reinterpret_cast<const toolchains::MachO &>(getToolChain()); 410b57cec5SDimitry Andric } 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric public: 44*5ffd83dbSDimitry Andric MachOTool(const char *Name, const char *ShortName, const ToolChain &TC) 45*5ffd83dbSDimitry Andric : Tool(Name, ShortName, TC) {} 460b57cec5SDimitry Andric }; 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Assembler : public MachOTool { 490b57cec5SDimitry Andric public: 500b57cec5SDimitry Andric Assembler(const ToolChain &TC) 510b57cec5SDimitry Andric : MachOTool("darwin::Assembler", "assembler", TC) {} 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 560b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 570b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 580b57cec5SDimitry Andric const char *LinkingOutput) const override; 590b57cec5SDimitry Andric }; 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool { 620b57cec5SDimitry Andric bool NeedsTempPath(const InputInfoList &Inputs) const; 630b57cec5SDimitry Andric void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args, 640b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 65*5ffd83dbSDimitry Andric const InputInfoList &Inputs, unsigned Version[5]) const; 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric public: 68*5ffd83dbSDimitry Andric Linker(const ToolChain &TC) : MachOTool("darwin::Linker", "linker", TC) {} 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 710b57cec5SDimitry Andric bool isLinkJob() const override { return true; } 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 740b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 750b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 760b57cec5SDimitry Andric const char *LinkingOutput) const override; 770b57cec5SDimitry Andric }; 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Lipo : public MachOTool { 800b57cec5SDimitry Andric public: 810b57cec5SDimitry Andric Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {} 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 860b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 870b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 880b57cec5SDimitry Andric const char *LinkingOutput) const override; 890b57cec5SDimitry Andric }; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Dsymutil : public MachOTool { 920b57cec5SDimitry Andric public: 930b57cec5SDimitry Andric Dsymutil(const ToolChain &TC) 940b57cec5SDimitry Andric : MachOTool("darwin::Dsymutil", "dsymutil", TC) {} 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 970b57cec5SDimitry Andric bool isDsymutilJob() const override { return true; } 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 1000b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 1010b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 1020b57cec5SDimitry Andric const char *LinkingOutput) const override; 1030b57cec5SDimitry Andric }; 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY VerifyDebug : public MachOTool { 1060b57cec5SDimitry Andric public: 1070b57cec5SDimitry Andric VerifyDebug(const ToolChain &TC) 1080b57cec5SDimitry Andric : MachOTool("darwin::VerifyDebug", "dwarfdump", TC) {} 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 1130b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 1140b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 1150b57cec5SDimitry Andric const char *LinkingOutput) const override; 1160b57cec5SDimitry Andric }; 1170b57cec5SDimitry Andric } // end namespace darwin 1180b57cec5SDimitry Andric } // end namespace tools 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric namespace toolchains { 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain { 1230b57cec5SDimitry Andric protected: 1240b57cec5SDimitry Andric Tool *buildAssembler() const override; 1250b57cec5SDimitry Andric Tool *buildLinker() const override; 1260b57cec5SDimitry Andric Tool *getTool(Action::ActionClass AC) const override; 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric private: 1290b57cec5SDimitry Andric mutable std::unique_ptr<tools::darwin::Lipo> Lipo; 1300b57cec5SDimitry Andric mutable std::unique_ptr<tools::darwin::Dsymutil> Dsymutil; 1310b57cec5SDimitry Andric mutable std::unique_ptr<tools::darwin::VerifyDebug> VerifyDebug; 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric public: 1340b57cec5SDimitry Andric MachO(const Driver &D, const llvm::Triple &Triple, 1350b57cec5SDimitry Andric const llvm::opt::ArgList &Args); 1360b57cec5SDimitry Andric ~MachO() override; 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric /// @name MachO specific toolchain API 1390b57cec5SDimitry Andric /// { 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric /// Get the "MachO" arch name for a particular compiler invocation. For 1420b57cec5SDimitry Andric /// example, Apple treats different ARM variations as distinct architectures. 1430b57cec5SDimitry Andric StringRef getMachOArchName(const llvm::opt::ArgList &Args) const; 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric /// Add the linker arguments to link the ARC runtime library. 1460b57cec5SDimitry Andric virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args, 1470b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const {} 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric /// Add the linker arguments to link the compiler runtime library. 1500b57cec5SDimitry Andric /// 1510b57cec5SDimitry Andric /// FIXME: This API is intended for use with embedded libraries only, and is 1520b57cec5SDimitry Andric /// misleadingly named. 1530b57cec5SDimitry Andric virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, 1540b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 1550b57cec5SDimitry Andric bool ForceLinkBuiltinRT = false) const; 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args, 1580b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const { 1590b57cec5SDimitry Andric } 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric virtual void addMinVersionArgs(const llvm::opt::ArgList &Args, 1620b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const {} 1630b57cec5SDimitry Andric 164480093f4SDimitry Andric virtual void addPlatformVersionArgs(const llvm::opt::ArgList &Args, 165480093f4SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const { 166480093f4SDimitry Andric } 167480093f4SDimitry Andric 1680b57cec5SDimitry Andric /// On some iOS platforms, kernel and kernel modules were built statically. Is 1690b57cec5SDimitry Andric /// this such a target? 1700b57cec5SDimitry Andric virtual bool isKernelStatic() const { return false; } 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric /// Is the target either iOS or an iOS simulator? 1730b57cec5SDimitry Andric bool isTargetIOSBased() const { return false; } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric /// Options to control how a runtime library is linked. 1760b57cec5SDimitry Andric enum RuntimeLinkOptions : unsigned { 1770b57cec5SDimitry Andric /// Link the library in even if it can't be found in the VFS. 1780b57cec5SDimitry Andric RLO_AlwaysLink = 1 << 0, 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric /// Use the embedded runtime from the macho_embedded directory. 1810b57cec5SDimitry Andric RLO_IsEmbedded = 1 << 1, 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric /// Emit rpaths for @executable_path as well as the resource directory. 1840b57cec5SDimitry Andric RLO_AddRPath = 1 << 2, 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric /// Link the library in before any others. 1870b57cec5SDimitry Andric RLO_FirstLink = 1 << 3, 1880b57cec5SDimitry Andric }; 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric /// Add a runtime library to the list of items to link. 1910b57cec5SDimitry Andric void AddLinkRuntimeLib(const llvm::opt::ArgList &Args, 1920b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, StringRef Component, 1930b57cec5SDimitry Andric RuntimeLinkOptions Opts = RuntimeLinkOptions(), 1940b57cec5SDimitry Andric bool IsShared = false) const; 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric /// Add any profiling runtime libraries that are needed. This is essentially a 1970b57cec5SDimitry Andric /// MachO specific version of addProfileRT in Tools.cpp. 1980b57cec5SDimitry Andric void addProfileRTLibs(const llvm::opt::ArgList &Args, 1990b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override { 2000b57cec5SDimitry Andric // There aren't any profiling libs for embedded targets currently. 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric /// } 2040b57cec5SDimitry Andric /// @name ToolChain Implementation 2050b57cec5SDimitry Andric /// { 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric types::ID LookupTypeForExtension(StringRef Ext) const override; 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric bool HasNativeLLVMSupport() const override; 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric llvm::opt::DerivedArgList * 2120b57cec5SDimitry Andric TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 2130b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric bool IsBlocksDefault() const override { 2160b57cec5SDimitry Andric // Always allow blocks on Apple; users interested in versioning are 2170b57cec5SDimitry Andric // expected to use /usr/include/Block.h. 2180b57cec5SDimitry Andric return true; 2190b57cec5SDimitry Andric } 2200b57cec5SDimitry Andric bool IsIntegratedAssemblerDefault() const override { 2210b57cec5SDimitry Andric // Default integrated assembler to on for Apple's MachO targets. 2220b57cec5SDimitry Andric return true; 2230b57cec5SDimitry Andric } 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric bool IsMathErrnoDefault() const override { return false; } 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric bool IsEncodeExtendedBlockSignatureDefault() const override { return true; } 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric bool IsObjCNonFragileABIDefault() const override { 2300b57cec5SDimitry Andric // Non-fragile ABI is default for everything but i386. 2310b57cec5SDimitry Andric return getTriple().getArch() != llvm::Triple::x86; 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric bool UseObjCMixedDispatch() const override { return true; } 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override; 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric RuntimeLibType GetDefaultRuntimeLibType() const override { 2390b57cec5SDimitry Andric return ToolChain::RLT_CompilerRT; 2400b57cec5SDimitry Andric } 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric bool isPICDefault() const override; 2430b57cec5SDimitry Andric bool isPIEDefault() const override; 2440b57cec5SDimitry Andric bool isPICDefaultForced() const override; 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric bool SupportsProfiling() const override; 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric bool UseDwarfDebugFlags() const override; 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric llvm::ExceptionHandling 2510b57cec5SDimitry Andric GetExceptionModel(const llvm::opt::ArgList &Args) const override { 2520b57cec5SDimitry Andric return llvm::ExceptionHandling::None; 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric virtual StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const { 2560b57cec5SDimitry Andric return ""; 2570b57cec5SDimitry Andric } 2580b57cec5SDimitry Andric 259480093f4SDimitry Andric // Darwin toolchain uses legacy thin LTO API, which is not 260480093f4SDimitry Andric // capable of unit splitting. 261480093f4SDimitry Andric bool canSplitThinLTOUnit() const override { return false; } 2620b57cec5SDimitry Andric /// } 2630b57cec5SDimitry Andric }; 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric /// Darwin - The base Darwin tool chain. 2660b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { 2670b57cec5SDimitry Andric public: 2680b57cec5SDimitry Andric /// Whether the information on the target has been initialized. 2690b57cec5SDimitry Andric // 2700b57cec5SDimitry Andric // FIXME: This should be eliminated. What we want to do is make this part of 2710b57cec5SDimitry Andric // the "default target for arguments" selection process, once we get out of 2720b57cec5SDimitry Andric // the argument translation business. 2730b57cec5SDimitry Andric mutable bool TargetInitialized; 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric enum DarwinPlatformKind { 2760b57cec5SDimitry Andric MacOS, 2770b57cec5SDimitry Andric IPhoneOS, 2780b57cec5SDimitry Andric TvOS, 2790b57cec5SDimitry Andric WatchOS, 2800b57cec5SDimitry Andric LastDarwinPlatform = WatchOS 2810b57cec5SDimitry Andric }; 2820b57cec5SDimitry Andric enum DarwinEnvironmentKind { 2830b57cec5SDimitry Andric NativeEnvironment, 2840b57cec5SDimitry Andric Simulator, 2850b57cec5SDimitry Andric }; 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric mutable DarwinPlatformKind TargetPlatform; 2880b57cec5SDimitry Andric mutable DarwinEnvironmentKind TargetEnvironment; 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric /// The OS version we are targeting. 2910b57cec5SDimitry Andric mutable VersionTuple TargetVersion; 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric /// The information about the darwin SDK that was used. 2940b57cec5SDimitry Andric mutable Optional<DarwinSDKInfo> SDKInfo; 2950b57cec5SDimitry Andric 2960b57cec5SDimitry Andric CudaInstallationDetector CudaInstallation; 297*5ffd83dbSDimitry Andric RocmInstallationDetector RocmInstallation; 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric private: 3000b57cec5SDimitry Andric void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const; 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric public: 3030b57cec5SDimitry Andric Darwin(const Driver &D, const llvm::Triple &Triple, 3040b57cec5SDimitry Andric const llvm::opt::ArgList &Args); 3050b57cec5SDimitry Andric ~Darwin() override; 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, 3080b57cec5SDimitry Andric types::ID InputType) const override; 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric /// @name Apple Specific Toolchain Implementation 3110b57cec5SDimitry Andric /// { 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric void addMinVersionArgs(const llvm::opt::ArgList &Args, 3140b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 3150b57cec5SDimitry Andric 316480093f4SDimitry Andric void addPlatformVersionArgs(const llvm::opt::ArgList &Args, 317480093f4SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 318480093f4SDimitry Andric 3190b57cec5SDimitry Andric void addStartObjectFileArgs(const llvm::opt::ArgList &Args, 3200b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric bool isKernelStatic() const override { 3230b57cec5SDimitry Andric return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) && 3240b57cec5SDimitry Andric !isTargetWatchOS()); 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric void addProfileRTLibs(const llvm::opt::ArgList &Args, 3280b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric protected: 3310b57cec5SDimitry Andric /// } 3320b57cec5SDimitry Andric /// @name Darwin specific Toolchain functions 3330b57cec5SDimitry Andric /// { 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric // FIXME: Eliminate these ...Target functions and derive separate tool chains 3360b57cec5SDimitry Andric // for these targets and put version in constructor. 3370b57cec5SDimitry Andric void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment, 3380b57cec5SDimitry Andric unsigned Major, unsigned Minor, unsigned Micro) const { 3390b57cec5SDimitry Andric // FIXME: For now, allow reinitialization as long as values don't 3400b57cec5SDimitry Andric // change. This will go away when we move away from argument translation. 3410b57cec5SDimitry Andric if (TargetInitialized && TargetPlatform == Platform && 3420b57cec5SDimitry Andric TargetEnvironment == Environment && 3430b57cec5SDimitry Andric TargetVersion == VersionTuple(Major, Minor, Micro)) 3440b57cec5SDimitry Andric return; 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric assert(!TargetInitialized && "Target already initialized!"); 3470b57cec5SDimitry Andric TargetInitialized = true; 3480b57cec5SDimitry Andric TargetPlatform = Platform; 3490b57cec5SDimitry Andric TargetEnvironment = Environment; 3500b57cec5SDimitry Andric TargetVersion = VersionTuple(Major, Minor, Micro); 3510b57cec5SDimitry Andric if (Environment == Simulator) 3520b57cec5SDimitry Andric const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::Simulator); 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric 355*5ffd83dbSDimitry Andric public: 3560b57cec5SDimitry Andric bool isTargetIPhoneOS() const { 3570b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 3580b57cec5SDimitry Andric return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && 3590b57cec5SDimitry Andric TargetEnvironment == NativeEnvironment; 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric bool isTargetIOSSimulator() const { 3630b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 3640b57cec5SDimitry Andric return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && 3650b57cec5SDimitry Andric TargetEnvironment == Simulator; 3660b57cec5SDimitry Andric } 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric bool isTargetIOSBased() const { 3690b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 3700b57cec5SDimitry Andric return isTargetIPhoneOS() || isTargetIOSSimulator(); 3710b57cec5SDimitry Andric } 3720b57cec5SDimitry Andric 3730b57cec5SDimitry Andric bool isTargetTvOS() const { 3740b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 3750b57cec5SDimitry Andric return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment; 3760b57cec5SDimitry Andric } 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric bool isTargetTvOSSimulator() const { 3790b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 3800b57cec5SDimitry Andric return TargetPlatform == TvOS && TargetEnvironment == Simulator; 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric bool isTargetTvOSBased() const { 3840b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 3850b57cec5SDimitry Andric return TargetPlatform == TvOS; 3860b57cec5SDimitry Andric } 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric bool isTargetWatchOS() const { 3890b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 3900b57cec5SDimitry Andric return TargetPlatform == WatchOS && TargetEnvironment == NativeEnvironment; 3910b57cec5SDimitry Andric } 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric bool isTargetWatchOSSimulator() const { 3940b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 3950b57cec5SDimitry Andric return TargetPlatform == WatchOS && TargetEnvironment == Simulator; 3960b57cec5SDimitry Andric } 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric bool isTargetWatchOSBased() const { 3990b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4000b57cec5SDimitry Andric return TargetPlatform == WatchOS; 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric bool isTargetMacOS() const { 4040b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4050b57cec5SDimitry Andric return TargetPlatform == MacOS; 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric 408*5ffd83dbSDimitry Andric bool isTargetMacOSBased() const { 409*5ffd83dbSDimitry Andric assert(TargetInitialized && "Target not initialized!"); 410*5ffd83dbSDimitry Andric // FIXME (Alex L): Add remaining MacCatalyst suppport. 411*5ffd83dbSDimitry Andric return TargetPlatform == MacOS; 412*5ffd83dbSDimitry Andric } 413*5ffd83dbSDimitry Andric 414*5ffd83dbSDimitry Andric bool isTargetAppleSiliconMac() const { 415*5ffd83dbSDimitry Andric assert(TargetInitialized && "Target not initialized!"); 416*5ffd83dbSDimitry Andric return isTargetMacOSBased() && getArch() == llvm::Triple::aarch64; 417*5ffd83dbSDimitry Andric } 418*5ffd83dbSDimitry Andric 4190b57cec5SDimitry Andric bool isTargetInitialized() const { return TargetInitialized; } 4200b57cec5SDimitry Andric 4210b57cec5SDimitry Andric VersionTuple getTargetVersion() const { 4220b57cec5SDimitry Andric assert(TargetInitialized && "Target not initialized!"); 4230b57cec5SDimitry Andric return TargetVersion; 4240b57cec5SDimitry Andric } 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0, 4270b57cec5SDimitry Andric unsigned V2 = 0) const { 4280b57cec5SDimitry Andric assert(isTargetIOSBased() && "Unexpected call for non iOS target!"); 4290b57cec5SDimitry Andric return TargetVersion < VersionTuple(V0, V1, V2); 4300b57cec5SDimitry Andric } 4310b57cec5SDimitry Andric 432*5ffd83dbSDimitry Andric /// Returns true if the minimum supported macOS version for the slice that's 433*5ffd83dbSDimitry Andric /// being built is less than the specified version. If there's no minimum 434*5ffd83dbSDimitry Andric /// supported macOS version, the deployment target version is compared to the 435*5ffd83dbSDimitry Andric /// specifed version instead. 4360b57cec5SDimitry Andric bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const { 437*5ffd83dbSDimitry Andric assert(isTargetMacOS() && getTriple().isMacOSX() && 438*5ffd83dbSDimitry Andric "Unexpected call for non OS X target!"); 439*5ffd83dbSDimitry Andric VersionTuple MinVers = getTriple().getMinimumSupportedOSVersion(); 440*5ffd83dbSDimitry Andric return (!MinVers.empty() && MinVers > TargetVersion 441*5ffd83dbSDimitry Andric ? MinVers 442*5ffd83dbSDimitry Andric : TargetVersion) < VersionTuple(V0, V1, V2); 4430b57cec5SDimitry Andric } 4440b57cec5SDimitry Andric 445*5ffd83dbSDimitry Andric protected: 4460b57cec5SDimitry Andric /// Return true if c++17 aligned allocation/deallocation functions are not 4470b57cec5SDimitry Andric /// implemented in the c++ standard library of the deployment target we are 4480b57cec5SDimitry Andric /// targeting. 4490b57cec5SDimitry Andric bool isAlignedAllocationUnavailable() const; 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 4520b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args, 4530b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric StringRef getPlatformFamily() const; 4560b57cec5SDimitry Andric StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const override; 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric public: 4590b57cec5SDimitry Andric static StringRef getSDKName(StringRef isysroot); 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric /// } 4620b57cec5SDimitry Andric /// @name ToolChain Implementation 4630b57cec5SDimitry Andric /// { 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric // Darwin tools support multiple architecture (e.g., i386 and x86_64) and 4660b57cec5SDimitry Andric // most development is done against SDKs, so compiling for a different 4670b57cec5SDimitry Andric // architecture should not get any special treatment. 4680b57cec5SDimitry Andric bool isCrossCompiling() const override { return false; } 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric llvm::opt::DerivedArgList * 4710b57cec5SDimitry Andric TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 4720b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 4730b57cec5SDimitry Andric 4740b57cec5SDimitry Andric CXXStdlibType GetDefaultCXXStdlibType() const override; 4750b57cec5SDimitry Andric ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override; 4760b57cec5SDimitry Andric bool hasBlocksRuntime() const override; 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, 4790b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 480*5ffd83dbSDimitry Andric void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, 481*5ffd83dbSDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric bool UseObjCMixedDispatch() const override { 4840b57cec5SDimitry Andric // This is only used with the non-fragile ABI and non-legacy dispatch. 4850b57cec5SDimitry Andric 4860b57cec5SDimitry Andric // Mixed dispatch is used everywhere except OS X before 10.6. 4870b57cec5SDimitry Andric return !(isTargetMacOS() && isMacosxVersionLT(10, 6)); 4880b57cec5SDimitry Andric } 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override { 4910b57cec5SDimitry Andric // Stack protectors default to on for user code on 10.5, 4920b57cec5SDimitry Andric // and for everything in 10.6 and beyond 4930b57cec5SDimitry Andric if (isTargetIOSBased() || isTargetWatchOSBased()) 4940b57cec5SDimitry Andric return 1; 4950b57cec5SDimitry Andric else if (isTargetMacOS() && !isMacosxVersionLT(10, 6)) 4960b57cec5SDimitry Andric return 1; 4970b57cec5SDimitry Andric else if (isTargetMacOS() && !isMacosxVersionLT(10, 5) && !KernelOrKext) 4980b57cec5SDimitry Andric return 1; 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric return 0; 5010b57cec5SDimitry Andric } 5020b57cec5SDimitry Andric 5030b57cec5SDimitry Andric void CheckObjCARC() const override; 5040b57cec5SDimitry Andric 5050b57cec5SDimitry Andric llvm::ExceptionHandling GetExceptionModel( 5060b57cec5SDimitry Andric const llvm::opt::ArgList &Args) const override; 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric bool SupportsEmbeddedBitcode() const override; 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric SanitizerMask getSupportedSanitizers() const override; 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric void printVerboseInfo(raw_ostream &OS) const override; 5130b57cec5SDimitry Andric }; 5140b57cec5SDimitry Andric 5150b57cec5SDimitry Andric /// DarwinClang - The Darwin toolchain used by Clang. 5160b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { 5170b57cec5SDimitry Andric public: 5180b57cec5SDimitry Andric DarwinClang(const Driver &D, const llvm::Triple &Triple, 5190b57cec5SDimitry Andric const llvm::opt::ArgList &Args); 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric /// @name Apple ToolChain Implementation 5220b57cec5SDimitry Andric /// { 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override; 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andric void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, 5270b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 5280b57cec5SDimitry Andric bool ForceLinkBuiltinRT = false) const override; 5290b57cec5SDimitry Andric 5300b57cec5SDimitry Andric void AddClangCXXStdlibIncludeArgs( 5310b57cec5SDimitry Andric const llvm::opt::ArgList &DriverArgs, 5320b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 5330b57cec5SDimitry Andric 5340b57cec5SDimitry Andric void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 5350b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const override; 5360b57cec5SDimitry Andric 5370b57cec5SDimitry Andric void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, 5380b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 5390b57cec5SDimitry Andric 5400b57cec5SDimitry Andric void AddCCKextLibArgs(const llvm::opt::ArgList &Args, 5410b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andric void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override; 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric void AddLinkARCArgs(const llvm::opt::ArgList &Args, 5460b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const override; 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric unsigned GetDefaultDwarfVersion() const override; 5490b57cec5SDimitry Andric // Until dtrace (via CTF) and LLDB can deal with distributed debug info, 5500b57cec5SDimitry Andric // Darwin defaults to standalone/full debug info. 5510b57cec5SDimitry Andric bool GetDefaultStandaloneDebug() const override { return true; } 5520b57cec5SDimitry Andric llvm::DebuggerKind getDefaultDebuggerTuning() const override { 5530b57cec5SDimitry Andric return llvm::DebuggerKind::LLDB; 5540b57cec5SDimitry Andric } 5550b57cec5SDimitry Andric 5560b57cec5SDimitry Andric /// } 5570b57cec5SDimitry Andric 5580b57cec5SDimitry Andric private: 5590b57cec5SDimitry Andric void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args, 5600b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 5610b57cec5SDimitry Andric StringRef Sanitizer, 5620b57cec5SDimitry Andric bool shared = true) const; 5630b57cec5SDimitry Andric 5640b57cec5SDimitry Andric bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, 5650b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args, 5660b57cec5SDimitry Andric llvm::SmallString<128> Base, 5670b57cec5SDimitry Andric llvm::StringRef Version, 5680b57cec5SDimitry Andric llvm::StringRef ArchDir, 5690b57cec5SDimitry Andric llvm::StringRef BitDir) const; 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric llvm::StringRef GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const; 5720b57cec5SDimitry Andric }; 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric } // end namespace toolchains 5750b57cec5SDimitry Andric } // end namespace driver 5760b57cec5SDimitry Andric } // end namespace clang 5770b57cec5SDimitry Andric 5780b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H 579