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