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