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 // Return the full path of the compiler-rt library on a non-Darwin MachO 227 // system. Those are under 228 // <resourcedir>/lib/darwin/macho_embedded/<...>(.dylib|.a). 229 std::string 230 getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, 231 FileType Type = ToolChain::FT_Static) const override; 232 233 /// } 234 /// @name ToolChain Implementation 235 /// { 236 237 types::ID LookupTypeForExtension(StringRef Ext) const override; 238 239 bool HasNativeLLVMSupport() const override; 240 241 llvm::opt::DerivedArgList * 242 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 243 Action::OffloadKind DeviceOffloadKind) const override; 244 IsBlocksDefault()245 bool IsBlocksDefault() const override { 246 // Always allow blocks on Apple; users interested in versioning are 247 // expected to use /usr/include/Block.h. 248 return true; 249 } 250 IsMathErrnoDefault()251 bool IsMathErrnoDefault() const override { return false; } 252 IsEncodeExtendedBlockSignatureDefault()253 bool IsEncodeExtendedBlockSignatureDefault() const override { return true; } 254 IsObjCNonFragileABIDefault()255 bool IsObjCNonFragileABIDefault() const override { 256 // Non-fragile ABI is default for everything but i386. 257 return getTriple().getArch() != llvm::Triple::x86; 258 } 259 UseObjCMixedDispatch()260 bool UseObjCMixedDispatch() const override { return true; } 261 262 UnwindTableLevel 263 getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override; 264 GetDefaultRuntimeLibType()265 RuntimeLibType GetDefaultRuntimeLibType() const override { 266 return ToolChain::RLT_CompilerRT; 267 } 268 269 bool isPICDefault() const override; 270 bool isPIEDefault(const llvm::opt::ArgList &Args) const override; 271 bool isPICDefaultForced() const override; 272 273 bool SupportsProfiling() const override; 274 275 bool UseDwarfDebugFlags() const override; 276 std::string GetGlobalDebugPathRemapping() const override; 277 278 llvm::ExceptionHandling GetExceptionModel(const llvm::opt::ArgList & Args)279 GetExceptionModel(const llvm::opt::ArgList &Args) const override { 280 return llvm::ExceptionHandling::None; 281 } 282 283 virtual StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const { 284 return ""; 285 } 286 287 // Darwin toolchain uses legacy thin LTO API, which is not 288 // capable of unit splitting. canSplitThinLTOUnit()289 bool canSplitThinLTOUnit() const override { return false; } 290 /// } 291 }; 292 293 /// Darwin - The base Darwin tool chain. 294 class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { 295 public: 296 /// Whether the information on the target has been initialized. 297 // 298 // FIXME: This should be eliminated. What we want to do is make this part of 299 // the "default target for arguments" selection process, once we get out of 300 // the argument translation business. 301 mutable bool TargetInitialized; 302 303 enum DarwinPlatformKind { 304 MacOS, 305 IPhoneOS, 306 TvOS, 307 WatchOS, 308 DriverKit, 309 XROS, 310 LastDarwinPlatform = XROS 311 }; 312 enum DarwinEnvironmentKind { 313 NativeEnvironment, 314 Simulator, 315 MacCatalyst, 316 }; 317 318 mutable DarwinPlatformKind TargetPlatform; 319 mutable DarwinEnvironmentKind TargetEnvironment; 320 321 /// The native OS version we are targeting. 322 mutable VersionTuple TargetVersion; 323 /// The OS version we are targeting as specified in the triple. 324 mutable VersionTuple OSTargetVersion; 325 326 /// The information about the darwin SDK that was used. 327 mutable std::optional<DarwinSDKInfo> SDKInfo; 328 329 /// The target variant triple that was specified (if any). 330 mutable std::optional<llvm::Triple> TargetVariantTriple; 331 332 LazyDetector<CudaInstallationDetector> CudaInstallation; 333 LazyDetector<RocmInstallationDetector> RocmInstallation; 334 335 private: 336 void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const; 337 338 public: 339 Darwin(const Driver &D, const llvm::Triple &Triple, 340 const llvm::opt::ArgList &Args); 341 ~Darwin() override; 342 343 std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, 344 types::ID InputType) const override; 345 346 /// @name Apple Specific Toolchain Implementation 347 /// { 348 349 void addMinVersionArgs(const llvm::opt::ArgList &Args, 350 llvm::opt::ArgStringList &CmdArgs) const override; 351 352 void addPlatformVersionArgs(const llvm::opt::ArgList &Args, 353 llvm::opt::ArgStringList &CmdArgs) const override; 354 355 void addStartObjectFileArgs(const llvm::opt::ArgList &Args, 356 llvm::opt::ArgStringList &CmdArgs) const override; 357 isKernelStatic()358 bool isKernelStatic() const override { 359 return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) && 360 !isTargetWatchOS() && !isTargetDriverKit()); 361 } 362 363 void addProfileRTLibs(const llvm::opt::ArgList &Args, 364 llvm::opt::ArgStringList &CmdArgs) const override; 365 366 // Return the full path of the compiler-rt library on a Darwin MachO system. 367 // Those are under <resourcedir>/lib/darwin/<...>(.dylib|.a). 368 std::string 369 getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, 370 FileType Type = ToolChain::FT_Static) const override; 371 372 protected: 373 /// } 374 /// @name Darwin specific Toolchain functions 375 /// { 376 377 // FIXME: Eliminate these ...Target functions and derive separate tool chains 378 // for these targets and put version in constructor. setTarget(DarwinPlatformKind Platform,DarwinEnvironmentKind Environment,unsigned Major,unsigned Minor,unsigned Micro,VersionTuple NativeTargetVersion)379 void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment, 380 unsigned Major, unsigned Minor, unsigned Micro, 381 VersionTuple NativeTargetVersion) const { 382 // FIXME: For now, allow reinitialization as long as values don't 383 // change. This will go away when we move away from argument translation. 384 if (TargetInitialized && TargetPlatform == Platform && 385 TargetEnvironment == Environment && 386 (Environment == MacCatalyst ? OSTargetVersion : TargetVersion) == 387 VersionTuple(Major, Minor, Micro)) 388 return; 389 390 assert(!TargetInitialized && "Target already initialized!"); 391 TargetInitialized = true; 392 TargetPlatform = Platform; 393 TargetEnvironment = Environment; 394 TargetVersion = VersionTuple(Major, Minor, Micro); 395 if (Environment == Simulator) 396 const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::Simulator); 397 else if (Environment == MacCatalyst) { 398 const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::MacABI); 399 TargetVersion = NativeTargetVersion; 400 OSTargetVersion = VersionTuple(Major, Minor, Micro); 401 } 402 } 403 404 public: isTargetIPhoneOS()405 bool isTargetIPhoneOS() const { 406 assert(TargetInitialized && "Target not initialized!"); 407 return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && 408 TargetEnvironment == NativeEnvironment; 409 } 410 isTargetIOSSimulator()411 bool isTargetIOSSimulator() const { 412 assert(TargetInitialized && "Target not initialized!"); 413 return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && 414 TargetEnvironment == Simulator; 415 } 416 isTargetIOSBased()417 bool isTargetIOSBased() const { 418 assert(TargetInitialized && "Target not initialized!"); 419 return isTargetIPhoneOS() || isTargetIOSSimulator(); 420 } 421 isTargetXROSDevice()422 bool isTargetXROSDevice() const { 423 return TargetPlatform == XROS && TargetEnvironment == NativeEnvironment; 424 } 425 isTargetXROSSimulator()426 bool isTargetXROSSimulator() const { 427 return TargetPlatform == XROS && TargetEnvironment == Simulator; 428 } 429 isTargetXROS()430 bool isTargetXROS() const { return TargetPlatform == XROS; } 431 isTargetTvOS()432 bool isTargetTvOS() const { 433 assert(TargetInitialized && "Target not initialized!"); 434 return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment; 435 } 436 isTargetTvOSSimulator()437 bool isTargetTvOSSimulator() const { 438 assert(TargetInitialized && "Target not initialized!"); 439 return TargetPlatform == TvOS && TargetEnvironment == Simulator; 440 } 441 isTargetTvOSBased()442 bool isTargetTvOSBased() const { 443 assert(TargetInitialized && "Target not initialized!"); 444 return TargetPlatform == TvOS; 445 } 446 isTargetWatchOS()447 bool isTargetWatchOS() const { 448 assert(TargetInitialized && "Target not initialized!"); 449 return TargetPlatform == WatchOS && TargetEnvironment == NativeEnvironment; 450 } 451 isTargetWatchOSSimulator()452 bool isTargetWatchOSSimulator() const { 453 assert(TargetInitialized && "Target not initialized!"); 454 return TargetPlatform == WatchOS && TargetEnvironment == Simulator; 455 } 456 isTargetWatchOSBased()457 bool isTargetWatchOSBased() const { 458 assert(TargetInitialized && "Target not initialized!"); 459 return TargetPlatform == WatchOS; 460 } 461 isTargetDriverKit()462 bool isTargetDriverKit() const { 463 assert(TargetInitialized && "Target not initialized!"); 464 return TargetPlatform == DriverKit; 465 } 466 isTargetMacCatalyst()467 bool isTargetMacCatalyst() const { 468 return TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst; 469 } 470 isTargetMacOS()471 bool isTargetMacOS() const { 472 assert(TargetInitialized && "Target not initialized!"); 473 return TargetPlatform == MacOS; 474 } 475 isTargetMacOSBased()476 bool isTargetMacOSBased() const { 477 assert(TargetInitialized && "Target not initialized!"); 478 return TargetPlatform == MacOS || isTargetMacCatalyst(); 479 } 480 isTargetAppleSiliconMac()481 bool isTargetAppleSiliconMac() const { 482 assert(TargetInitialized && "Target not initialized!"); 483 return isTargetMacOSBased() && getArch() == llvm::Triple::aarch64; 484 } 485 isTargetInitialized()486 bool isTargetInitialized() const { return TargetInitialized; } 487 488 /// The version of the OS that's used by the OS specified in the target 489 /// triple. It might be different from the actual target OS on which the 490 /// program will run, e.g. MacCatalyst code runs on a macOS target, but its 491 /// target triple is iOS. getTripleTargetVersion()492 VersionTuple getTripleTargetVersion() const { 493 assert(TargetInitialized && "Target not initialized!"); 494 return isTargetMacCatalyst() ? OSTargetVersion : TargetVersion; 495 } 496 497 bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0, 498 unsigned V2 = 0) const { 499 assert(isTargetIOSBased() && "Unexpected call for non iOS target!"); 500 return TargetVersion < VersionTuple(V0, V1, V2); 501 } 502 503 /// Returns true if the minimum supported macOS version for the slice that's 504 /// being built is less than the specified version. If there's no minimum 505 /// supported macOS version, the deployment target version is compared to the 506 /// specifed version instead. 507 bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const { 508 assert(isTargetMacOSBased() && 509 (getTriple().isMacOSX() || getTriple().isMacCatalystEnvironment()) && 510 "Unexpected call for non OS X target!"); 511 // The effective triple might not be initialized yet, so construct a 512 // pseudo-effective triple to get the minimum supported OS version. 513 VersionTuple MinVers = 514 llvm::Triple(getTriple().getArchName(), "apple", "macos") 515 .getMinimumSupportedOSVersion(); 516 return (!MinVers.empty() && MinVers > TargetVersion 517 ? MinVers 518 : TargetVersion) < VersionTuple(V0, V1, V2); 519 } 520 521 protected: 522 /// Return true if c++17 aligned allocation/deallocation functions are not 523 /// implemented in the c++ standard library of the deployment target we are 524 /// targeting. 525 bool isAlignedAllocationUnavailable() const; 526 527 /// Return true if c++14 sized deallocation functions are not implemented in 528 /// the c++ standard library of the deployment target we are targeting. 529 bool isSizedDeallocationUnavailable() const; 530 531 void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 532 llvm::opt::ArgStringList &CC1Args, 533 Action::OffloadKind DeviceOffloadKind) const override; 534 535 void addClangCC1ASTargetOptions( 536 const llvm::opt::ArgList &Args, 537 llvm::opt::ArgStringList &CC1ASArgs) const override; 538 539 StringRef getPlatformFamily() const; 540 StringRef getOSLibraryNameSuffix(bool IgnoreSim = false) const override; 541 542 public: 543 static StringRef getSDKName(StringRef isysroot); 544 545 /// } 546 /// @name ToolChain Implementation 547 /// { 548 549 // Darwin tools support multiple architecture (e.g., i386 and x86_64) and 550 // most development is done against SDKs, so compiling for a different 551 // architecture should not get any special treatment. isCrossCompiling()552 bool isCrossCompiling() const override { return false; } 553 554 llvm::opt::DerivedArgList * 555 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 556 Action::OffloadKind DeviceOffloadKind) const override; 557 558 CXXStdlibType GetDefaultCXXStdlibType() const override; 559 ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override; 560 bool hasBlocksRuntime() const override; 561 562 void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, 563 llvm::opt::ArgStringList &CC1Args) const override; 564 void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, 565 llvm::opt::ArgStringList &CC1Args) const override; 566 UseObjCMixedDispatch()567 bool UseObjCMixedDispatch() const override { 568 // This is only used with the non-fragile ABI and non-legacy dispatch. 569 570 // Mixed dispatch is used everywhere except OS X before 10.6. 571 return !(isTargetMacOSBased() && isMacosxVersionLT(10, 6)); 572 } 573 574 LangOptions::StackProtectorMode GetDefaultStackProtectorLevel(bool KernelOrKext)575 GetDefaultStackProtectorLevel(bool KernelOrKext) const override { 576 // Stack protectors default to on for user code on 10.5, 577 // and for everything in 10.6 and beyond 578 if (isTargetIOSBased() || isTargetWatchOSBased() || isTargetDriverKit() || 579 isTargetXROS()) 580 return LangOptions::SSPOn; 581 else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 6)) 582 return LangOptions::SSPOn; 583 else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 5) && !KernelOrKext) 584 return LangOptions::SSPOn; 585 586 return LangOptions::SSPOff; 587 } 588 589 void CheckObjCARC() const override; 590 591 llvm::ExceptionHandling GetExceptionModel( 592 const llvm::opt::ArgList &Args) const override; 593 594 bool SupportsEmbeddedBitcode() const override; 595 596 SanitizerMask getSupportedSanitizers() const override; 597 598 void printVerboseInfo(raw_ostream &OS) const override; 599 }; 600 601 /// DarwinClang - The Darwin toolchain used by Clang. 602 class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { 603 public: 604 DarwinClang(const Driver &D, const llvm::Triple &Triple, 605 const llvm::opt::ArgList &Args); 606 607 /// @name Apple ToolChain Implementation 608 /// { 609 610 RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override; 611 612 void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, 613 llvm::opt::ArgStringList &CmdArgs, 614 bool ForceLinkBuiltinRT = false) const override; 615 616 void AddClangCXXStdlibIncludeArgs( 617 const llvm::opt::ArgList &DriverArgs, 618 llvm::opt::ArgStringList &CC1Args) const override; 619 620 void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 621 llvm::opt::ArgStringList &CC1Args) const override; 622 623 void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, 624 llvm::opt::ArgStringList &CmdArgs) const override; 625 626 void AddCCKextLibArgs(const llvm::opt::ArgList &Args, 627 llvm::opt::ArgStringList &CmdArgs) const override; 628 629 void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override; 630 631 void AddLinkARCArgs(const llvm::opt::ArgList &Args, 632 llvm::opt::ArgStringList &CmdArgs) const override; 633 634 unsigned GetDefaultDwarfVersion() const override; 635 // Until dtrace (via CTF) and LLDB can deal with distributed debug info, 636 // Darwin defaults to standalone/full debug info. GetDefaultStandaloneDebug()637 bool GetDefaultStandaloneDebug() const override { return true; } getDefaultDebuggerTuning()638 llvm::DebuggerKind getDefaultDebuggerTuning() const override { 639 return llvm::DebuggerKind::LLDB; 640 } 641 642 /// } 643 644 private: 645 void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args, 646 llvm::opt::ArgStringList &CmdArgs, 647 StringRef Sanitizer, 648 bool shared = true) const; 649 650 bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, 651 llvm::opt::ArgStringList &CC1Args, 652 llvm::SmallString<128> Base, 653 llvm::StringRef Version, 654 llvm::StringRef ArchDir, 655 llvm::StringRef BitDir) const; 656 657 llvm::SmallString<128> 658 GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const; 659 }; 660 661 } // end namespace toolchains 662 } // end namespace driver 663 } // end namespace clang 664 665 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H 666