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