1 //===--- Darwin.h - Darwin ToolChain Implementations ------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H 10 #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H 11 12 #include "Cuda.h" 13 #include "LazyDetector.h" 14 #include "ROCm.h" 15 #include "SYCL.h" 16 #include "clang/Basic/DarwinSDKInfo.h" 17 #include "clang/Basic/LangOptions.h" 18 #include "clang/Driver/Tool.h" 19 #include "clang/Driver/ToolChain.h" 20 #include "clang/Driver/XRayArgs.h" 21 22 namespace clang { 23 namespace driver { 24 25 namespace toolchains { 26 class MachO; 27 } // end namespace toolchains 28 29 namespace tools { 30 31 namespace darwin { 32 llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str); 33 void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str, 34 const llvm::opt::ArgList &Args); 35 36 class LLVM_LIBRARY_VISIBILITY MachOTool : public Tool { 37 virtual void anchor(); 38 39 protected: 40 void AddMachOArch(const llvm::opt::ArgList &Args, 41 llvm::opt::ArgStringList &CmdArgs) const; 42 getMachOToolChain()43 const toolchains::MachO &getMachOToolChain() const { 44 return reinterpret_cast<const toolchains::MachO &>(getToolChain()); 45 } 46 47 public: MachOTool(const char * Name,const char * ShortName,const ToolChain & TC)48 MachOTool(const char *Name, const char *ShortName, const ToolChain &TC) 49 : Tool(Name, ShortName, TC) {} 50 }; 51 52 class LLVM_LIBRARY_VISIBILITY Assembler : public MachOTool { 53 public: Assembler(const ToolChain & TC)54 Assembler(const ToolChain &TC) 55 : MachOTool("darwin::Assembler", "assembler", TC) {} 56 hasIntegratedCPP()57 bool hasIntegratedCPP() const override { return false; } 58 59 void ConstructJob(Compilation &C, const JobAction &JA, 60 const InputInfo &Output, const InputInfoList &Inputs, 61 const llvm::opt::ArgList &TCArgs, 62 const char *LinkingOutput) const override; 63 }; 64 65 class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool { 66 bool NeedsTempPath(const InputInfoList &Inputs) const; 67 void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args, 68 llvm::opt::ArgStringList &CmdArgs, 69 const InputInfoList &Inputs, VersionTuple Version, 70 bool LinkerIsLLD, bool UsePlatformVersion) const; 71 72 public: Linker(const ToolChain & TC)73 Linker(const ToolChain &TC) : MachOTool("darwin::Linker", "linker", TC) {} 74 hasIntegratedCPP()75 bool hasIntegratedCPP() const override { return false; } isLinkJob()76 bool isLinkJob() const override { return true; } 77 78 void ConstructJob(Compilation &C, const JobAction &JA, 79 const InputInfo &Output, const InputInfoList &Inputs, 80 const llvm::opt::ArgList &TCArgs, 81 const char *LinkingOutput) const override; 82 }; 83 84 class LLVM_LIBRARY_VISIBILITY StaticLibTool : public MachOTool { 85 public: StaticLibTool(const ToolChain & TC)86 StaticLibTool(const ToolChain &TC) 87 : MachOTool("darwin::StaticLibTool", "static-lib-linker", TC) {} 88 hasIntegratedCPP()89 bool hasIntegratedCPP() const override { return false; } isLinkJob()90 bool isLinkJob() const override { return true; } 91 92 void ConstructJob(Compilation &C, const JobAction &JA, 93 const InputInfo &Output, const InputInfoList &Inputs, 94 const llvm::opt::ArgList &TCArgs, 95 const char *LinkingOutput) const override; 96 }; 97 98 class LLVM_LIBRARY_VISIBILITY Lipo : public MachOTool { 99 public: Lipo(const ToolChain & TC)100 Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {} 101 hasIntegratedCPP()102 bool hasIntegratedCPP() const override { return false; } 103 104 void ConstructJob(Compilation &C, const JobAction &JA, 105 const InputInfo &Output, const InputInfoList &Inputs, 106 const llvm::opt::ArgList &TCArgs, 107 const char *LinkingOutput) const override; 108 }; 109 110 class LLVM_LIBRARY_VISIBILITY Dsymutil : public MachOTool { 111 public: Dsymutil(const ToolChain & TC)112 Dsymutil(const ToolChain &TC) 113 : MachOTool("darwin::Dsymutil", "dsymutil", TC) {} 114 hasIntegratedCPP()115 bool hasIntegratedCPP() const override { return false; } isDsymutilJob()116 bool isDsymutilJob() const override { return true; } 117 118 void ConstructJob(Compilation &C, const JobAction &JA, 119 const InputInfo &Output, const InputInfoList &Inputs, 120 const llvm::opt::ArgList &TCArgs, 121 const char *LinkingOutput) const override; 122 }; 123 124 class LLVM_LIBRARY_VISIBILITY VerifyDebug : public MachOTool { 125 public: VerifyDebug(const ToolChain & TC)126 VerifyDebug(const ToolChain &TC) 127 : MachOTool("darwin::VerifyDebug", "dwarfdump", TC) {} 128 hasIntegratedCPP()129 bool hasIntegratedCPP() const override { return false; } 130 131 void ConstructJob(Compilation &C, const JobAction &JA, 132 const InputInfo &Output, const InputInfoList &Inputs, 133 const llvm::opt::ArgList &TCArgs, 134 const char *LinkingOutput) const override; 135 }; 136 } // end namespace darwin 137 } // end namespace tools 138 139 namespace toolchains { 140 141 class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain { 142 protected: 143 Tool *buildAssembler() const override; 144 Tool *buildLinker() const override; 145 Tool *buildStaticLibTool() const override; 146 Tool *getTool(Action::ActionClass AC) const override; 147 148 void 149 addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 150 llvm::opt::ArgStringList &CC1Args, 151 Action::OffloadKind DeviceOffloadKind) const override; 152 153 private: 154 mutable std::unique_ptr<tools::darwin::Lipo> Lipo; 155 mutable std::unique_ptr<tools::darwin::Dsymutil> Dsymutil; 156 mutable std::unique_ptr<tools::darwin::VerifyDebug> VerifyDebug; 157 158 /// The version of the linker known to be available in the tool chain. 159 mutable std::optional<VersionTuple> LinkerVersion; 160 161 public: 162 MachO(const Driver &D, const llvm::Triple &Triple, 163 const llvm::opt::ArgList &Args); 164 ~MachO() override; 165 166 /// @name MachO specific toolchain API 167 /// { 168 169 /// Get the "MachO" arch name for a particular compiler invocation. For 170 /// example, Apple treats different ARM variations as distinct architectures. 171 StringRef getMachOArchName(const llvm::opt::ArgList &Args) const; 172 173 /// Get the version of the linker known to be available for a particular 174 /// compiler invocation (via the `-mlinker-version=` arg). 175 VersionTuple getLinkerVersion(const llvm::opt::ArgList &Args) const; 176 177 /// Add the linker arguments to link the ARC runtime library. AddLinkARCArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)178 virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args, 179 llvm::opt::ArgStringList &CmdArgs) const {} 180 181 /// Add the linker arguments to link the compiler runtime library. 182 /// 183 /// FIXME: This API is intended for use with embedded libraries only, and is 184 /// misleadingly named. 185 virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, 186 llvm::opt::ArgStringList &CmdArgs, 187 bool ForceLinkBuiltinRT = false) const; 188 addStartObjectFileArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)189 virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args, 190 llvm::opt::ArgStringList &CmdArgs) const { 191 } 192 addMinVersionArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)193 virtual void addMinVersionArgs(const llvm::opt::ArgList &Args, 194 llvm::opt::ArgStringList &CmdArgs) const {} 195 addPlatformVersionArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)196 virtual void addPlatformVersionArgs(const llvm::opt::ArgList &Args, 197 llvm::opt::ArgStringList &CmdArgs) const { 198 } 199 200 /// On some iOS platforms, kernel and kernel modules were built statically. Is 201 /// this such a target? isKernelStatic()202 virtual bool isKernelStatic() const { return false; } 203 204 /// Is the target either iOS or an iOS simulator? isTargetIOSBased()205 bool isTargetIOSBased() const { return false; } 206 207 /// Options to control how a runtime library is linked. 208 enum RuntimeLinkOptions : unsigned { 209 /// Link the library in even if it can't be found in the VFS. 210 RLO_AlwaysLink = 1 << 0, 211 212 /// Use the embedded runtime from the macho_embedded directory. 213 RLO_IsEmbedded = 1 << 1, 214 215 /// Emit rpaths for @executable_path as well as the resource directory. 216 RLO_AddRPath = 1 << 2, 217 }; 218 219 /// Add a runtime library to the list of items to link. 220 void AddLinkRuntimeLib(const llvm::opt::ArgList &Args, 221 llvm::opt::ArgStringList &CmdArgs, StringRef Component, 222 RuntimeLinkOptions Opts = RuntimeLinkOptions(), 223 bool IsShared = false) const; 224 225 /// Add any profiling runtime libraries that are needed. This is essentially a 226 /// MachO specific version of addProfileRT in Tools.cpp. addProfileRTLibs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)227 void addProfileRTLibs(const llvm::opt::ArgList &Args, 228 llvm::opt::ArgStringList &CmdArgs) const override { 229 // There aren't any profiling libs for embedded targets currently. 230 } 231 232 // Return the full path of the compiler-rt library on a non-Darwin MachO 233 // system. Those are under 234 // <resourcedir>/lib/darwin/macho_embedded/<...>(.dylib|.a). 235 std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, 236 FileType Type = ToolChain::FT_Static, 237 bool IsFortran = false) const override; 238 239 /// } 240 /// @name ToolChain Implementation 241 /// { 242 243 types::ID LookupTypeForExtension(StringRef Ext) const override; 244 245 bool HasNativeLLVMSupport() const override; 246 247 llvm::opt::DerivedArgList * 248 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 249 Action::OffloadKind DeviceOffloadKind) const override; 250 IsBlocksDefault()251 bool IsBlocksDefault() const override { 252 // Always allow blocks on Apple; users interested in versioning are 253 // expected to use /usr/include/Block.h. 254 return true; 255 } 256 IsMathErrnoDefault()257 bool IsMathErrnoDefault() const override { return false; } 258 IsEncodeExtendedBlockSignatureDefault()259 bool IsEncodeExtendedBlockSignatureDefault() const override { return true; } 260 IsObjCNonFragileABIDefault()261 bool IsObjCNonFragileABIDefault() const override { 262 // Non-fragile ABI is default for everything but i386. 263 return getTriple().getArch() != llvm::Triple::x86; 264 } 265 UseObjCMixedDispatch()266 bool UseObjCMixedDispatch() const override { return true; } 267 268 UnwindTableLevel 269 getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override; 270 GetDefaultRuntimeLibType()271 RuntimeLibType GetDefaultRuntimeLibType() const override { 272 return ToolChain::RLT_CompilerRT; 273 } 274 275 bool isPICDefault() const override; 276 bool isPIEDefault(const llvm::opt::ArgList &Args) const override; 277 bool isPICDefaultForced() const override; 278 279 bool SupportsProfiling() const override; 280 281 bool UseDwarfDebugFlags() const override; 282 std::string GetGlobalDebugPathRemapping() const override; 283 284 llvm::ExceptionHandling GetExceptionModel(const llvm::opt::ArgList & Args)285 GetExceptionModel(const llvm::opt::ArgList &Args) const override { 286 return llvm::ExceptionHandling::None; 287 } 288 289 virtual StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const { 290 return ""; 291 } 292 293 // Darwin toolchain uses legacy thin LTO API, which is not 294 // capable of unit splitting. canSplitThinLTOUnit()295 bool canSplitThinLTOUnit() const override { return false; } 296 /// } 297 }; 298 299 /// Apple specific MachO extensions 300 class LLVM_LIBRARY_VISIBILITY AppleMachO : public MachO { 301 public: 302 AppleMachO(const Driver &D, const llvm::Triple &Triple, 303 const llvm::opt::ArgList &Args); 304 ~AppleMachO() override; 305 306 /// } 307 /// @name Apple Specific ToolChain Implementation 308 /// { 309 void 310 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 311 llvm::opt::ArgStringList &CC1Args) const override; 312 313 void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, 314 llvm::opt::ArgStringList &CC1Args) const override; 315 void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, 316 llvm::opt::ArgStringList &CC1Args) const override; 317 void addSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs, 318 llvm::opt::ArgStringList &CC1Args) const override; 319 320 void AddClangCXXStdlibIncludeArgs( 321 const llvm::opt::ArgList &DriverArgs, 322 llvm::opt::ArgStringList &CC1Args) const override; 323 void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, 324 llvm::opt::ArgStringList &CmdArgs) const override; 325 326 void printVerboseInfo(raw_ostream &OS) const override; 327 /// } 328 329 LazyDetector<CudaInstallationDetector> CudaInstallation; 330 LazyDetector<RocmInstallationDetector> RocmInstallation; 331 LazyDetector<SYCLInstallationDetector> SYCLInstallation; 332 333 protected: 334 llvm::SmallString<128> 335 GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const; 336 337 private: 338 virtual void 339 AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, 340 llvm::opt::ArgStringList &CC1Args) const; 341 }; 342 343 /// Darwin - The base Darwin tool chain. 344 class LLVM_LIBRARY_VISIBILITY Darwin : public AppleMachO { 345 public: 346 /// Whether the information on the target has been initialized. 347 // 348 // FIXME: This should be eliminated. What we want to do is make this part of 349 // the "default target for arguments" selection process, once we get out of 350 // the argument translation business. 351 mutable bool TargetInitialized; 352 353 enum DarwinPlatformKind { 354 MacOS, 355 IPhoneOS, 356 TvOS, 357 WatchOS, 358 DriverKit, 359 XROS, 360 LastDarwinPlatform = XROS 361 }; 362 enum DarwinEnvironmentKind { 363 NativeEnvironment, 364 Simulator, 365 MacCatalyst, 366 }; 367 368 mutable DarwinPlatformKind TargetPlatform; 369 mutable DarwinEnvironmentKind TargetEnvironment; 370 371 /// The native OS version we are targeting. 372 mutable VersionTuple TargetVersion; 373 /// The OS version we are targeting as specified in the triple. 374 mutable VersionTuple OSTargetVersion; 375 376 /// The information about the darwin SDK that was used. 377 mutable std::optional<DarwinSDKInfo> SDKInfo; 378 379 /// The target variant triple that was specified (if any). 380 mutable std::optional<llvm::Triple> TargetVariantTriple; 381 382 private: 383 void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const; 384 385 public: 386 Darwin(const Driver &D, const llvm::Triple &Triple, 387 const llvm::opt::ArgList &Args); 388 ~Darwin() override; 389 390 std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, 391 types::ID InputType) const override; 392 393 /// @name Darwin Specific Toolchain Implementation 394 /// { 395 396 void addMinVersionArgs(const llvm::opt::ArgList &Args, 397 llvm::opt::ArgStringList &CmdArgs) const override; 398 399 void addPlatformVersionArgs(const llvm::opt::ArgList &Args, 400 llvm::opt::ArgStringList &CmdArgs) const override; 401 402 void addStartObjectFileArgs(const llvm::opt::ArgList &Args, 403 llvm::opt::ArgStringList &CmdArgs) const override; 404 isKernelStatic()405 bool isKernelStatic() const override { 406 return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) && 407 !isTargetWatchOS() && !isTargetDriverKit()); 408 } 409 410 void addProfileRTLibs(const llvm::opt::ArgList &Args, 411 llvm::opt::ArgStringList &CmdArgs) const override; 412 413 // Return the full path of the compiler-rt library on a Darwin MachO system. 414 // Those are under <resourcedir>/lib/darwin/<...>(.dylib|.a). 415 std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, 416 FileType Type = ToolChain::FT_Static, 417 bool IsFortran = false) const override; 418 419 protected: 420 /// } 421 /// @name Darwin specific Toolchain functions 422 /// { 423 424 // FIXME: Eliminate these ...Target functions and derive separate tool chains 425 // for these targets and put version in constructor. setTarget(DarwinPlatformKind Platform,DarwinEnvironmentKind Environment,unsigned Major,unsigned Minor,unsigned Micro,VersionTuple NativeTargetVersion)426 void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment, 427 unsigned Major, unsigned Minor, unsigned Micro, 428 VersionTuple NativeTargetVersion) const { 429 // FIXME: For now, allow reinitialization as long as values don't 430 // change. This will go away when we move away from argument translation. 431 if (TargetInitialized && TargetPlatform == Platform && 432 TargetEnvironment == Environment && 433 (Environment == MacCatalyst ? OSTargetVersion : TargetVersion) == 434 VersionTuple(Major, Minor, Micro)) 435 return; 436 437 assert(!TargetInitialized && "Target already initialized!"); 438 TargetInitialized = true; 439 TargetPlatform = Platform; 440 TargetEnvironment = Environment; 441 TargetVersion = VersionTuple(Major, Minor, Micro); 442 if (Environment == Simulator) 443 const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::Simulator); 444 else if (Environment == MacCatalyst) { 445 const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::MacABI); 446 TargetVersion = NativeTargetVersion; 447 OSTargetVersion = VersionTuple(Major, Minor, Micro); 448 } 449 } 450 451 public: isTargetIPhoneOS()452 bool isTargetIPhoneOS() const { 453 assert(TargetInitialized && "Target not initialized!"); 454 return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && 455 TargetEnvironment == NativeEnvironment; 456 } 457 isTargetIOSSimulator()458 bool isTargetIOSSimulator() const { 459 assert(TargetInitialized && "Target not initialized!"); 460 return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && 461 TargetEnvironment == Simulator; 462 } 463 isTargetIOSBased()464 bool isTargetIOSBased() const { 465 assert(TargetInitialized && "Target not initialized!"); 466 return isTargetIPhoneOS() || isTargetIOSSimulator(); 467 } 468 isTargetXROSDevice()469 bool isTargetXROSDevice() const { 470 return TargetPlatform == XROS && TargetEnvironment == NativeEnvironment; 471 } 472 isTargetXROSSimulator()473 bool isTargetXROSSimulator() const { 474 return TargetPlatform == XROS && TargetEnvironment == Simulator; 475 } 476 isTargetXROS()477 bool isTargetXROS() const { return TargetPlatform == XROS; } 478 isTargetTvOS()479 bool isTargetTvOS() const { 480 assert(TargetInitialized && "Target not initialized!"); 481 return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment; 482 } 483 isTargetTvOSSimulator()484 bool isTargetTvOSSimulator() const { 485 assert(TargetInitialized && "Target not initialized!"); 486 return TargetPlatform == TvOS && TargetEnvironment == Simulator; 487 } 488 isTargetTvOSBased()489 bool isTargetTvOSBased() const { 490 assert(TargetInitialized && "Target not initialized!"); 491 return TargetPlatform == TvOS; 492 } 493 isTargetWatchOS()494 bool isTargetWatchOS() const { 495 assert(TargetInitialized && "Target not initialized!"); 496 return TargetPlatform == WatchOS && TargetEnvironment == NativeEnvironment; 497 } 498 isTargetWatchOSSimulator()499 bool isTargetWatchOSSimulator() const { 500 assert(TargetInitialized && "Target not initialized!"); 501 return TargetPlatform == WatchOS && TargetEnvironment == Simulator; 502 } 503 isTargetWatchOSBased()504 bool isTargetWatchOSBased() const { 505 assert(TargetInitialized && "Target not initialized!"); 506 return TargetPlatform == WatchOS; 507 } 508 isTargetDriverKit()509 bool isTargetDriverKit() const { 510 assert(TargetInitialized && "Target not initialized!"); 511 return TargetPlatform == DriverKit; 512 } 513 isTargetMacCatalyst()514 bool isTargetMacCatalyst() const { 515 return TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst; 516 } 517 isTargetMacOS()518 bool isTargetMacOS() const { 519 assert(TargetInitialized && "Target not initialized!"); 520 return TargetPlatform == MacOS; 521 } 522 isTargetMacOSBased()523 bool isTargetMacOSBased() const { 524 assert(TargetInitialized && "Target not initialized!"); 525 return TargetPlatform == MacOS || isTargetMacCatalyst(); 526 } 527 isTargetAppleSiliconMac()528 bool isTargetAppleSiliconMac() const { 529 assert(TargetInitialized && "Target not initialized!"); 530 return isTargetMacOSBased() && getArch() == llvm::Triple::aarch64; 531 } 532 isTargetInitialized()533 bool isTargetInitialized() const { return TargetInitialized; } 534 535 /// The version of the OS that's used by the OS specified in the target 536 /// triple. It might be different from the actual target OS on which the 537 /// program will run, e.g. MacCatalyst code runs on a macOS target, but its 538 /// target triple is iOS. getTripleTargetVersion()539 VersionTuple getTripleTargetVersion() const { 540 assert(TargetInitialized && "Target not initialized!"); 541 return isTargetMacCatalyst() ? OSTargetVersion : TargetVersion; 542 } 543 544 bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0, 545 unsigned V2 = 0) const { 546 assert(isTargetIOSBased() && "Unexpected call for non iOS target!"); 547 return TargetVersion < VersionTuple(V0, V1, V2); 548 } 549 550 /// Returns true if the minimum supported macOS version for the slice that's 551 /// being built is less than the specified version. If there's no minimum 552 /// supported macOS version, the deployment target version is compared to the 553 /// specifed version instead. 554 bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const { 555 assert(isTargetMacOSBased() && 556 (getTriple().isMacOSX() || getTriple().isMacCatalystEnvironment()) && 557 "Unexpected call for non OS X target!"); 558 // The effective triple might not be initialized yet, so construct a 559 // pseudo-effective triple to get the minimum supported OS version. 560 VersionTuple MinVers = 561 llvm::Triple(getTriple().getArchName(), "apple", "macos") 562 .getMinimumSupportedOSVersion(); 563 return (!MinVers.empty() && MinVers > TargetVersion 564 ? MinVers 565 : TargetVersion) < VersionTuple(V0, V1, V2); 566 } 567 568 protected: 569 /// Return true if c++17 aligned allocation/deallocation functions are not 570 /// implemented in the c++ standard library of the deployment target we are 571 /// targeting. 572 bool isAlignedAllocationUnavailable() const; 573 574 /// Return true if c++14 sized deallocation functions are not implemented in 575 /// the c++ standard library of the deployment target we are targeting. 576 bool isSizedDeallocationUnavailable() const; 577 578 void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 579 llvm::opt::ArgStringList &CC1Args, 580 Action::OffloadKind DeviceOffloadKind) const override; 581 582 void addClangCC1ASTargetOptions( 583 const llvm::opt::ArgList &Args, 584 llvm::opt::ArgStringList &CC1ASArgs) const override; 585 586 StringRef getPlatformFamily() const; 587 StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const override; 588 589 public: 590 static StringRef getSDKName(StringRef isysroot); 591 592 /// } 593 /// @name ToolChain Implementation 594 /// { 595 596 // Darwin tools support multiple architecture (e.g., i386 and x86_64) and 597 // most development is done against SDKs, so compiling for a different 598 // architecture should not get any special treatment. isCrossCompiling()599 bool isCrossCompiling() const override { return false; } 600 601 llvm::opt::DerivedArgList * 602 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 603 Action::OffloadKind DeviceOffloadKind) const override; 604 605 CXXStdlibType GetDefaultCXXStdlibType() const override; 606 ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override; 607 bool hasBlocksRuntime() const override; 608 UseObjCMixedDispatch()609 bool UseObjCMixedDispatch() const override { 610 // This is only used with the non-fragile ABI and non-legacy dispatch. 611 612 // Mixed dispatch is used everywhere except OS X before 10.6. 613 return !(isTargetMacOSBased() && isMacosxVersionLT(10, 6)); 614 } 615 616 LangOptions::StackProtectorMode GetDefaultStackProtectorLevel(bool KernelOrKext)617 GetDefaultStackProtectorLevel(bool KernelOrKext) const override { 618 // Stack protectors default to on for user code on 10.5, 619 // and for everything in 10.6 and beyond 620 if (isTargetIOSBased() || isTargetWatchOSBased() || isTargetDriverKit() || 621 isTargetXROS()) 622 return LangOptions::SSPOn; 623 else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 6)) 624 return LangOptions::SSPOn; 625 else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 5) && !KernelOrKext) 626 return LangOptions::SSPOn; 627 628 return LangOptions::SSPOff; 629 } 630 631 void CheckObjCARC() const override; 632 633 llvm::ExceptionHandling GetExceptionModel( 634 const llvm::opt::ArgList &Args) const override; 635 636 bool SupportsEmbeddedBitcode() const override; 637 638 SanitizerMask getSupportedSanitizers() const override; 639 }; 640 641 /// DarwinClang - The Darwin toolchain used by Clang. 642 class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { 643 public: 644 DarwinClang(const Driver &D, const llvm::Triple &Triple, 645 const llvm::opt::ArgList &Args); 646 647 /// @name Apple ToolChain Implementation 648 /// { 649 650 void 651 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 652 llvm::opt::ArgStringList &CC1Args) const override; 653 654 RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override; 655 656 void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, 657 llvm::opt::ArgStringList &CmdArgs, 658 bool ForceLinkBuiltinRT = false) const override; 659 660 void AddCCKextLibArgs(const llvm::opt::ArgList &Args, 661 llvm::opt::ArgStringList &CmdArgs) const override; 662 663 void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override; 664 665 void 666 addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 667 llvm::opt::ArgStringList &CC1Args, 668 Action::OffloadKind DeviceOffloadKind) const override; 669 670 void AddLinkARCArgs(const llvm::opt::ArgList &Args, 671 llvm::opt::ArgStringList &CmdArgs) const override; 672 673 unsigned GetDefaultDwarfVersion() const override; 674 // Until dtrace (via CTF) and LLDB can deal with distributed debug info, 675 // Darwin defaults to standalone/full debug info. GetDefaultStandaloneDebug()676 bool GetDefaultStandaloneDebug() const override { return true; } getDefaultDebuggerTuning()677 llvm::DebuggerKind getDefaultDebuggerTuning() const override { 678 return llvm::DebuggerKind::LLDB; 679 } 680 681 /// } 682 683 private: 684 void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args, 685 llvm::opt::ArgStringList &CmdArgs, 686 StringRef Sanitizer, 687 bool shared = true) const; 688 689 void 690 AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, 691 llvm::opt::ArgStringList &CC1Args) const override; 692 693 bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, 694 llvm::opt::ArgStringList &CC1Args, 695 llvm::SmallString<128> Base, 696 llvm::StringRef Version, 697 llvm::StringRef ArchDir, 698 llvm::StringRef BitDir) const; 699 }; 700 701 } // end namespace toolchains 702 } // end namespace driver 703 } // end namespace clang 704 705 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H 706