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