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