1 //===--- ToolChains.h - ToolChain Implementations ---------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_H 11 #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_H 12 13 #include "Tools.h" 14 #include "clang/Basic/VersionTuple.h" 15 #include "clang/Driver/Action.h" 16 #include "clang/Driver/Multilib.h" 17 #include "clang/Driver/ToolChain.h" 18 #include "llvm/ADT/DenseMap.h" 19 #include "llvm/ADT/Optional.h" 20 #include "llvm/Support/Compiler.h" 21 #include <set> 22 #include <vector> 23 24 namespace clang { 25 namespace driver { 26 namespace toolchains { 27 28 /// Generic_GCC - A tool chain using the 'gcc' command to perform 29 /// all subcommands; this relies on gcc translating the majority of 30 /// command line options. 31 class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain { 32 public: 33 /// \brief Struct to store and manipulate GCC versions. 34 /// 35 /// We rely on assumptions about the form and structure of GCC version 36 /// numbers: they consist of at most three '.'-separated components, and each 37 /// component is a non-negative integer except for the last component. For 38 /// the last component we are very flexible in order to tolerate release 39 /// candidates or 'x' wildcards. 40 /// 41 /// Note that the ordering established among GCCVersions is based on the 42 /// preferred version string to use. For example we prefer versions without 43 /// a hard-coded patch number to those with a hard coded patch number. 44 /// 45 /// Currently this doesn't provide any logic for textual suffixes to patches 46 /// in the way that (for example) Debian's version format does. If that ever 47 /// becomes necessary, it can be added. 48 struct GCCVersion { 49 /// \brief The unparsed text of the version. 50 std::string Text; 51 52 /// \brief The parsed major, minor, and patch numbers. 53 int Major, Minor, Patch; 54 55 /// \brief The text of the parsed major, and major+minor versions. 56 std::string MajorStr, MinorStr; 57 58 /// \brief Any textual suffix on the patch number. 59 std::string PatchSuffix; 60 61 static GCCVersion Parse(StringRef VersionText); 62 bool isOlderThan(int RHSMajor, int RHSMinor, int RHSPatch, 63 StringRef RHSPatchSuffix = StringRef()) const; 64 bool operator<(const GCCVersion &RHS) const { 65 return isOlderThan(RHS.Major, RHS.Minor, RHS.Patch, RHS.PatchSuffix); 66 } 67 bool operator>(const GCCVersion &RHS) const { return RHS < *this; } 68 bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); } 69 bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); } 70 }; 71 72 /// \brief This is a class to find a viable GCC installation for Clang to 73 /// use. 74 /// 75 /// This class tries to find a GCC installation on the system, and report 76 /// information about it. It starts from the host information provided to the 77 /// Driver, and has logic for fuzzing that where appropriate. 78 class GCCInstallationDetector { 79 bool IsValid; 80 llvm::Triple GCCTriple; 81 const Driver &D; 82 83 // FIXME: These might be better as path objects. 84 std::string GCCInstallPath; 85 std::string GCCParentLibPath; 86 87 /// The primary multilib appropriate for the given flags. 88 Multilib SelectedMultilib; 89 /// On Biarch systems, this corresponds to the default multilib when 90 /// targeting the non-default multilib. Otherwise, it is empty. 91 llvm::Optional<Multilib> BiarchSibling; 92 93 GCCVersion Version; 94 95 // We retain the list of install paths that were considered and rejected in 96 // order to print out detailed information in verbose mode. 97 std::set<std::string> CandidateGCCInstallPaths; 98 99 /// The set of multilibs that the detected installation supports. 100 MultilibSet Multilibs; 101 102 public: GCCInstallationDetector(const Driver & D)103 explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {} 104 void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args, 105 ArrayRef<std::string> ExtraTripleAliases = None); 106 107 /// \brief Check whether we detected a valid GCC install. isValid()108 bool isValid() const { return IsValid; } 109 110 /// \brief Get the GCC triple for the detected install. getTriple()111 const llvm::Triple &getTriple() const { return GCCTriple; } 112 113 /// \brief Get the detected GCC installation path. getInstallPath()114 StringRef getInstallPath() const { return GCCInstallPath; } 115 116 /// \brief Get the detected GCC parent lib path. getParentLibPath()117 StringRef getParentLibPath() const { return GCCParentLibPath; } 118 119 /// \brief Get the detected Multilib getMultilib()120 const Multilib &getMultilib() const { return SelectedMultilib; } 121 122 /// \brief Get the whole MultilibSet getMultilibs()123 const MultilibSet &getMultilibs() const { return Multilibs; } 124 125 /// Get the biarch sibling multilib (if it exists). 126 /// \return true iff such a sibling exists 127 bool getBiarchSibling(Multilib &M) const; 128 129 /// \brief Get the detected GCC version string. getVersion()130 const GCCVersion &getVersion() const { return Version; } 131 132 /// \brief Print information about the detected GCC installation. 133 void print(raw_ostream &OS) const; 134 135 private: 136 static void 137 CollectLibDirsAndTriples(const llvm::Triple &TargetTriple, 138 const llvm::Triple &BiarchTriple, 139 SmallVectorImpl<StringRef> &LibDirs, 140 SmallVectorImpl<StringRef> &TripleAliases, 141 SmallVectorImpl<StringRef> &BiarchLibDirs, 142 SmallVectorImpl<StringRef> &BiarchTripleAliases); 143 144 void ScanLibDirForGCCTriple(const llvm::Triple &TargetArch, 145 const llvm::opt::ArgList &Args, 146 const std::string &LibDir, 147 StringRef CandidateTriple, 148 bool NeedsBiarchSuffix = false); 149 150 void scanLibDirForGCCTripleSolaris(const llvm::Triple &TargetArch, 151 const llvm::opt::ArgList &Args, 152 const std::string &LibDir, 153 StringRef CandidateTriple, 154 bool NeedsBiarchSuffix = false); 155 }; 156 157 protected: 158 GCCInstallationDetector GCCInstallation; 159 160 // \brief A class to find a viable CUDA installation 161 162 class CudaInstallationDetector { 163 bool IsValid; 164 const Driver &D; 165 std::string CudaInstallPath; 166 std::string CudaLibPath; 167 std::string CudaLibDevicePath; 168 std::string CudaIncludePath; 169 llvm::StringMap<std::string> CudaLibDeviceMap; 170 171 public: CudaInstallationDetector(const Driver & D)172 CudaInstallationDetector(const Driver &D) : IsValid(false), D(D) {} 173 void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args); 174 175 /// \brief Check whether we detected a valid Cuda install. isValid()176 bool isValid() const { return IsValid; } 177 /// \brief Print information about the detected CUDA installation. 178 void print(raw_ostream &OS) const; 179 180 /// \brief Get the detected Cuda installation path. getInstallPath()181 StringRef getInstallPath() const { return CudaInstallPath; } 182 /// \brief Get the detected Cuda Include path. getIncludePath()183 StringRef getIncludePath() const { return CudaIncludePath; } 184 /// \brief Get the detected Cuda library path. getLibPath()185 StringRef getLibPath() const { return CudaLibPath; } 186 /// \brief Get the detected Cuda device library path. getLibDevicePath()187 StringRef getLibDevicePath() const { return CudaLibDevicePath; } 188 /// \brief Get libdevice file for given architecture getLibDeviceFile(StringRef Gpu)189 std::string getLibDeviceFile(StringRef Gpu) const { 190 return CudaLibDeviceMap.lookup(Gpu); 191 } 192 }; 193 194 CudaInstallationDetector CudaInstallation; 195 196 public: 197 Generic_GCC(const Driver &D, const llvm::Triple &Triple, 198 const llvm::opt::ArgList &Args); 199 ~Generic_GCC() override; 200 201 void printVerboseInfo(raw_ostream &OS) const override; 202 203 bool IsUnwindTablesDefault() const override; 204 bool isPICDefault() const override; 205 bool isPIEDefault() const override; 206 bool isPICDefaultForced() const override; 207 bool IsIntegratedAssemblerDefault() const override; 208 209 protected: 210 Tool *getTool(Action::ActionClass AC) const override; 211 Tool *buildAssembler() const override; 212 Tool *buildLinker() const override; 213 214 /// \name ToolChain Implementation Helper Functions 215 /// @{ 216 217 /// \brief Check whether the target triple's architecture is 64-bits. isTarget64Bit()218 bool isTarget64Bit() const { return getTriple().isArch64Bit(); } 219 220 /// \brief Check whether the target triple's architecture is 32-bits. isTarget32Bit()221 bool isTarget32Bit() const { return getTriple().isArch32Bit(); } 222 223 bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix, StringRef GCCTriple, 224 StringRef GCCMultiarchTriple, 225 StringRef TargetMultiarchTriple, 226 Twine IncludeSuffix, 227 const llvm::opt::ArgList &DriverArgs, 228 llvm::opt::ArgStringList &CC1Args) const; 229 230 /// @} 231 232 private: 233 mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocess; 234 mutable std::unique_ptr<tools::gcc::Compiler> Compile; 235 }; 236 237 class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain { 238 protected: 239 Tool *buildAssembler() const override; 240 Tool *buildLinker() const override; 241 Tool *getTool(Action::ActionClass AC) const override; 242 243 private: 244 mutable std::unique_ptr<tools::darwin::Lipo> Lipo; 245 mutable std::unique_ptr<tools::darwin::Dsymutil> Dsymutil; 246 mutable std::unique_ptr<tools::darwin::VerifyDebug> VerifyDebug; 247 248 public: 249 MachO(const Driver &D, const llvm::Triple &Triple, 250 const llvm::opt::ArgList &Args); 251 ~MachO() override; 252 253 /// @name MachO specific toolchain API 254 /// { 255 256 /// Get the "MachO" arch name for a particular compiler invocation. For 257 /// example, Apple treats different ARM variations as distinct architectures. 258 StringRef getMachOArchName(const llvm::opt::ArgList &Args) const; 259 260 /// Add the linker arguments to link the ARC runtime library. AddLinkARCArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)261 virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args, 262 llvm::opt::ArgStringList &CmdArgs) const {} 263 264 /// Add the linker arguments to link the compiler runtime library. 265 virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, 266 llvm::opt::ArgStringList &CmdArgs) const; 267 addStartObjectFileArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)268 virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args, 269 llvm::opt::ArgStringList &CmdArgs) const { 270 } 271 addMinVersionArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)272 virtual void addMinVersionArgs(const llvm::opt::ArgList &Args, 273 llvm::opt::ArgStringList &CmdArgs) const {} 274 275 /// On some iOS platforms, kernel and kernel modules were built statically. Is 276 /// this such a target? isKernelStatic()277 virtual bool isKernelStatic() const { return false; } 278 279 /// Is the target either iOS or an iOS simulator? isTargetIOSBased()280 bool isTargetIOSBased() const { return false; } 281 282 void AddLinkRuntimeLib(const llvm::opt::ArgList &Args, 283 llvm::opt::ArgStringList &CmdArgs, 284 StringRef DarwinLibName, bool AlwaysLink = false, 285 bool IsEmbedded = false, bool AddRPath = false) const; 286 287 /// Add any profiling runtime libraries that are needed. This is essentially a 288 /// MachO specific version of addProfileRT in Tools.cpp. addProfileRTLibs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs)289 void addProfileRTLibs(const llvm::opt::ArgList &Args, 290 llvm::opt::ArgStringList &CmdArgs) const override { 291 // There aren't any profiling libs for embedded targets currently. 292 } 293 294 /// } 295 /// @name ToolChain Implementation 296 /// { 297 298 std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, 299 types::ID InputType) const override; 300 301 types::ID LookupTypeForExtension(const char *Ext) const override; 302 303 bool HasNativeLLVMSupport() const override; 304 305 llvm::opt::DerivedArgList * 306 TranslateArgs(const llvm::opt::DerivedArgList &Args, 307 const char *BoundArch) const override; 308 IsBlocksDefault()309 bool IsBlocksDefault() const override { 310 // Always allow blocks on Apple; users interested in versioning are 311 // expected to use /usr/include/Block.h. 312 return true; 313 } IsIntegratedAssemblerDefault()314 bool IsIntegratedAssemblerDefault() const override { 315 // Default integrated assembler to on for Apple's MachO targets. 316 return true; 317 } 318 IsMathErrnoDefault()319 bool IsMathErrnoDefault() const override { return false; } 320 IsEncodeExtendedBlockSignatureDefault()321 bool IsEncodeExtendedBlockSignatureDefault() const override { return true; } 322 IsObjCNonFragileABIDefault()323 bool IsObjCNonFragileABIDefault() const override { 324 // Non-fragile ABI is default for everything but i386. 325 return getTriple().getArch() != llvm::Triple::x86; 326 } 327 UseObjCMixedDispatch()328 bool UseObjCMixedDispatch() const override { return true; } 329 330 bool IsUnwindTablesDefault() const override; 331 GetDefaultRuntimeLibType()332 RuntimeLibType GetDefaultRuntimeLibType() const override { 333 return ToolChain::RLT_CompilerRT; 334 } 335 336 bool isPICDefault() const override; 337 bool isPIEDefault() const override; 338 bool isPICDefaultForced() const override; 339 340 bool SupportsProfiling() const override; 341 SupportsObjCGC()342 bool SupportsObjCGC() const override { return false; } 343 344 bool UseDwarfDebugFlags() const override; 345 UseSjLjExceptions(const llvm::opt::ArgList & Args)346 bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override { 347 return false; 348 } 349 350 /// } 351 }; 352 353 /// Darwin - The base Darwin tool chain. 354 class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { 355 public: 356 /// Whether the information on the target has been initialized. 357 // 358 // FIXME: This should be eliminated. What we want to do is make this part of 359 // the "default target for arguments" selection process, once we get out of 360 // the argument translation business. 361 mutable bool TargetInitialized; 362 363 enum DarwinPlatformKind { 364 MacOS, 365 IPhoneOS, 366 IPhoneOSSimulator, 367 TvOS, 368 TvOSSimulator, 369 WatchOS, 370 WatchOSSimulator 371 }; 372 373 mutable DarwinPlatformKind TargetPlatform; 374 375 /// The OS version we are targeting. 376 mutable VersionTuple TargetVersion; 377 378 private: 379 void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const; 380 381 public: 382 Darwin(const Driver &D, const llvm::Triple &Triple, 383 const llvm::opt::ArgList &Args); 384 ~Darwin() override; 385 386 std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, 387 types::ID InputType) const override; 388 389 /// @name Apple Specific Toolchain Implementation 390 /// { 391 392 void addMinVersionArgs(const llvm::opt::ArgList &Args, 393 llvm::opt::ArgStringList &CmdArgs) const override; 394 395 void addStartObjectFileArgs(const llvm::opt::ArgList &Args, 396 llvm::opt::ArgStringList &CmdArgs) const override; 397 isKernelStatic()398 bool isKernelStatic() const override { 399 return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) && 400 !isTargetWatchOS()); 401 } 402 403 void addProfileRTLibs(const llvm::opt::ArgList &Args, 404 llvm::opt::ArgStringList &CmdArgs) const override; 405 406 protected: 407 /// } 408 /// @name Darwin specific Toolchain functions 409 /// { 410 411 // FIXME: Eliminate these ...Target functions and derive separate tool chains 412 // for these targets and put version in constructor. setTarget(DarwinPlatformKind Platform,unsigned Major,unsigned Minor,unsigned Micro)413 void setTarget(DarwinPlatformKind Platform, unsigned Major, unsigned Minor, 414 unsigned Micro) const { 415 // FIXME: For now, allow reinitialization as long as values don't 416 // change. This will go away when we move away from argument translation. 417 if (TargetInitialized && TargetPlatform == Platform && 418 TargetVersion == VersionTuple(Major, Minor, Micro)) 419 return; 420 421 assert(!TargetInitialized && "Target already initialized!"); 422 TargetInitialized = true; 423 TargetPlatform = Platform; 424 TargetVersion = VersionTuple(Major, Minor, Micro); 425 } 426 isTargetIPhoneOS()427 bool isTargetIPhoneOS() const { 428 assert(TargetInitialized && "Target not initialized!"); 429 return TargetPlatform == IPhoneOS || TargetPlatform == TvOS; 430 } 431 isTargetIOSSimulator()432 bool isTargetIOSSimulator() const { 433 assert(TargetInitialized && "Target not initialized!"); 434 return TargetPlatform == IPhoneOSSimulator || 435 TargetPlatform == TvOSSimulator; 436 } 437 isTargetIOSBased()438 bool isTargetIOSBased() const { 439 assert(TargetInitialized && "Target not initialized!"); 440 return isTargetIPhoneOS() || isTargetIOSSimulator(); 441 } 442 isTargetTvOS()443 bool isTargetTvOS() const { 444 assert(TargetInitialized && "Target not initialized!"); 445 return TargetPlatform == TvOS; 446 } 447 isTargetTvOSSimulator()448 bool isTargetTvOSSimulator() const { 449 assert(TargetInitialized && "Target not initialized!"); 450 return TargetPlatform == TvOSSimulator; 451 } 452 isTargetTvOSBased()453 bool isTargetTvOSBased() const { 454 assert(TargetInitialized && "Target not initialized!"); 455 return TargetPlatform == TvOS || TargetPlatform == TvOSSimulator; 456 } 457 isTargetWatchOS()458 bool isTargetWatchOS() const { 459 assert(TargetInitialized && "Target not initialized!"); 460 return TargetPlatform == WatchOS; 461 } 462 isTargetWatchOSSimulator()463 bool isTargetWatchOSSimulator() const { 464 assert(TargetInitialized && "Target not initialized!"); 465 return TargetPlatform == WatchOSSimulator; 466 } 467 isTargetWatchOSBased()468 bool isTargetWatchOSBased() const { 469 assert(TargetInitialized && "Target not initialized!"); 470 return TargetPlatform == WatchOS || TargetPlatform == WatchOSSimulator; 471 } 472 isTargetMacOS()473 bool isTargetMacOS() const { 474 assert(TargetInitialized && "Target not initialized!"); 475 return TargetPlatform == MacOS; 476 } 477 isTargetInitialized()478 bool isTargetInitialized() const { return TargetInitialized; } 479 getTargetVersion()480 VersionTuple getTargetVersion() const { 481 assert(TargetInitialized && "Target not initialized!"); 482 return TargetVersion; 483 } 484 485 bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0, 486 unsigned V2 = 0) const { 487 assert(isTargetIOSBased() && "Unexpected call for non iOS target!"); 488 return TargetVersion < VersionTuple(V0, V1, V2); 489 } 490 491 bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const { 492 assert(isTargetMacOS() && "Unexpected call for non OS X target!"); 493 return TargetVersion < VersionTuple(V0, V1, V2); 494 } 495 496 public: 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. isCrossCompiling()504 bool isCrossCompiling() const override { return false; } 505 506 llvm::opt::DerivedArgList * 507 TranslateArgs(const llvm::opt::DerivedArgList &Args, 508 const char *BoundArch) const override; 509 510 ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override; 511 bool hasBlocksRuntime() const override; 512 UseObjCMixedDispatch()513 bool UseObjCMixedDispatch() const override { 514 // This is only used with the non-fragile ABI and non-legacy dispatch. 515 516 // Mixed dispatch is used everywhere except OS X before 10.6. 517 return !(isTargetMacOS() && isMacosxVersionLT(10, 6)); 518 } 519 GetDefaultStackProtectorLevel(bool KernelOrKext)520 unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override { 521 // Stack protectors default to on for user code on 10.5, 522 // and for everything in 10.6 and beyond 523 if (isTargetIOSBased() || isTargetWatchOSBased()) 524 return 1; 525 else if (isTargetMacOS() && !isMacosxVersionLT(10, 6)) 526 return 1; 527 else if (isTargetMacOS() && !isMacosxVersionLT(10, 5) && !KernelOrKext) 528 return 1; 529 530 return 0; 531 } 532 533 bool SupportsObjCGC() const override; 534 535 void CheckObjCARC() const override; 536 537 bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override; 538 539 SanitizerMask getSupportedSanitizers() const override; 540 }; 541 542 /// DarwinClang - The Darwin toolchain used by Clang. 543 class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { 544 public: 545 DarwinClang(const Driver &D, const llvm::Triple &Triple, 546 const llvm::opt::ArgList &Args); 547 548 /// @name Apple ToolChain Implementation 549 /// { 550 551 void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, 552 llvm::opt::ArgStringList &CmdArgs) const override; 553 554 void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, 555 llvm::opt::ArgStringList &CmdArgs) const override; 556 557 void AddCCKextLibArgs(const llvm::opt::ArgList &Args, 558 llvm::opt::ArgStringList &CmdArgs) const override; 559 560 void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override; 561 562 void AddLinkARCArgs(const llvm::opt::ArgList &Args, 563 llvm::opt::ArgStringList &CmdArgs) const override; 564 GetDefaultDwarfVersion()565 unsigned GetDefaultDwarfVersion() const override { return 2; } 566 // Until dtrace (via CTF) and LLDB can deal with distributed debug info, 567 // Darwin defaults to standalone/full debug info. GetDefaultStandaloneDebug()568 bool GetDefaultStandaloneDebug() const override { return true; } getDefaultDebuggerTuning()569 llvm::DebuggerKind getDefaultDebuggerTuning() const override { 570 return llvm::DebuggerKind::LLDB; 571 } 572 573 /// } 574 575 private: 576 void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args, 577 llvm::opt::ArgStringList &CmdArgs, 578 StringRef Sanitizer) const; 579 }; 580 581 class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC { 582 virtual void anchor(); 583 584 public: Generic_ELF(const Driver & D,const llvm::Triple & Triple,const llvm::opt::ArgList & Args)585 Generic_ELF(const Driver &D, const llvm::Triple &Triple, 586 const llvm::opt::ArgList &Args) 587 : Generic_GCC(D, Triple, Args) {} 588 589 void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 590 llvm::opt::ArgStringList &CC1Args) const override; 591 }; 592 593 class LLVM_LIBRARY_VISIBILITY CloudABI : public Generic_ELF { 594 public: 595 CloudABI(const Driver &D, const llvm::Triple &Triple, 596 const llvm::opt::ArgList &Args); HasNativeLLVMSupport()597 bool HasNativeLLVMSupport() const override { return true; } 598 IsMathErrnoDefault()599 bool IsMathErrnoDefault() const override { return false; } IsObjCNonFragileABIDefault()600 bool IsObjCNonFragileABIDefault() const override { return true; } 601 602 CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList & Args)603 GetCXXStdlibType(const llvm::opt::ArgList &Args) const override { 604 return ToolChain::CST_Libcxx; 605 } 606 void AddClangCXXStdlibIncludeArgs( 607 const llvm::opt::ArgList &DriverArgs, 608 llvm::opt::ArgStringList &CC1Args) const override; 609 void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, 610 llvm::opt::ArgStringList &CmdArgs) const override; 611 isPIEDefault()612 bool isPIEDefault() const override { return false; } 613 614 protected: 615 Tool *buildLinker() const override; 616 }; 617 618 class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_GCC { 619 public: 620 Solaris(const Driver &D, const llvm::Triple &Triple, 621 const llvm::opt::ArgList &Args); 622 IsIntegratedAssemblerDefault()623 bool IsIntegratedAssemblerDefault() const override { return true; } 624 625 void AddClangCXXStdlibIncludeArgs( 626 const llvm::opt::ArgList &DriverArgs, 627 llvm::opt::ArgStringList &CC1Args) const override; 628 GetDefaultDwarfVersion()629 unsigned GetDefaultDwarfVersion() const override { return 2; } 630 631 protected: 632 Tool *buildAssembler() const override; 633 Tool *buildLinker() const override; 634 }; 635 636 class LLVM_LIBRARY_VISIBILITY MinGW : public ToolChain { 637 public: 638 MinGW(const Driver &D, const llvm::Triple &Triple, 639 const llvm::opt::ArgList &Args); 640 641 bool IsIntegratedAssemblerDefault() const override; 642 bool IsUnwindTablesDefault() const override; 643 bool isPICDefault() const override; 644 bool isPIEDefault() const override; 645 bool isPICDefaultForced() const override; 646 bool UseSEHExceptions() const; 647 648 void 649 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 650 llvm::opt::ArgStringList &CC1Args) const override; 651 void AddClangCXXStdlibIncludeArgs( 652 const llvm::opt::ArgList &DriverArgs, 653 llvm::opt::ArgStringList &CC1Args) const override; 654 655 protected: 656 Tool *getTool(Action::ActionClass AC) const override; 657 Tool *buildLinker() const override; 658 Tool *buildAssembler() const override; 659 660 private: 661 std::string Base; 662 std::string GccLibDir; 663 std::string Ver; 664 std::string Arch; 665 mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocessor; 666 mutable std::unique_ptr<tools::gcc::Compiler> Compiler; 667 void findGccLibDir(); 668 }; 669 670 class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic_ELF { 671 public: 672 OpenBSD(const Driver &D, const llvm::Triple &Triple, 673 const llvm::opt::ArgList &Args); 674 IsMathErrnoDefault()675 bool IsMathErrnoDefault() const override { return false; } IsObjCNonFragileABIDefault()676 bool IsObjCNonFragileABIDefault() const override { return true; } isPIEDefault()677 bool isPIEDefault() const override { return true; } 678 GetDefaultStackProtectorLevel(bool KernelOrKext)679 unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override { 680 return 2; 681 } GetDefaultDwarfVersion()682 unsigned GetDefaultDwarfVersion() const override { return 2; } 683 684 protected: 685 Tool *buildAssembler() const override; 686 Tool *buildLinker() const override; 687 }; 688 689 class LLVM_LIBRARY_VISIBILITY Bitrig : public Generic_ELF { 690 public: 691 Bitrig(const Driver &D, const llvm::Triple &Triple, 692 const llvm::opt::ArgList &Args); 693 IsMathErrnoDefault()694 bool IsMathErrnoDefault() const override { return false; } IsObjCNonFragileABIDefault()695 bool IsObjCNonFragileABIDefault() const override { return true; } 696 697 CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; 698 void AddClangCXXStdlibIncludeArgs( 699 const llvm::opt::ArgList &DriverArgs, 700 llvm::opt::ArgStringList &CC1Args) const override; 701 void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, 702 llvm::opt::ArgStringList &CmdArgs) const override; GetDefaultStackProtectorLevel(bool KernelOrKext)703 unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override { 704 return 1; 705 } 706 707 protected: 708 Tool *buildAssembler() const override; 709 Tool *buildLinker() const override; 710 }; 711 712 class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF { 713 public: 714 FreeBSD(const Driver &D, const llvm::Triple &Triple, 715 const llvm::opt::ArgList &Args); 716 bool HasNativeLLVMSupport() const override; 717 IsMathErrnoDefault()718 bool IsMathErrnoDefault() const override { return false; } IsObjCNonFragileABIDefault()719 bool IsObjCNonFragileABIDefault() const override { return true; } 720 721 CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; 722 void AddClangCXXStdlibIncludeArgs( 723 const llvm::opt::ArgList &DriverArgs, 724 llvm::opt::ArgStringList &CC1Args) const override; 725 726 bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override; 727 bool isPIEDefault() const override; 728 SanitizerMask getSupportedSanitizers() const override; GetDefaultDwarfVersion()729 unsigned GetDefaultDwarfVersion() const override { return 2; } 730 // Until dtrace (via CTF) and LLDB can deal with distributed debug info, 731 // FreeBSD defaults to standalone/full debug info. GetDefaultStandaloneDebug()732 bool GetDefaultStandaloneDebug() const override { return true; } getDefaultDebuggerTuning()733 llvm::DebuggerKind getDefaultDebuggerTuning() const override { 734 return llvm::DebuggerKind::LLDB; 735 } 736 737 protected: 738 Tool *buildAssembler() const override; 739 Tool *buildLinker() const override; 740 }; 741 742 class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF { 743 public: 744 NetBSD(const Driver &D, const llvm::Triple &Triple, 745 const llvm::opt::ArgList &Args); 746 IsMathErrnoDefault()747 bool IsMathErrnoDefault() const override { return false; } IsObjCNonFragileABIDefault()748 bool IsObjCNonFragileABIDefault() const override { return true; } 749 750 CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; 751 752 void AddClangCXXStdlibIncludeArgs( 753 const llvm::opt::ArgList &DriverArgs, 754 llvm::opt::ArgStringList &CC1Args) const override; IsUnwindTablesDefault()755 bool IsUnwindTablesDefault() const override { return true; } 756 757 protected: 758 Tool *buildAssembler() const override; 759 Tool *buildLinker() const override; 760 }; 761 762 class LLVM_LIBRARY_VISIBILITY Minix : public Generic_ELF { 763 public: 764 Minix(const Driver &D, const llvm::Triple &Triple, 765 const llvm::opt::ArgList &Args); 766 767 protected: 768 Tool *buildAssembler() const override; 769 Tool *buildLinker() const override; 770 }; 771 772 class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_ELF { 773 public: 774 DragonFly(const Driver &D, const llvm::Triple &Triple, 775 const llvm::opt::ArgList &Args); 776 IsMathErrnoDefault()777 bool IsMathErrnoDefault() const override { return false; } 778 779 protected: 780 Tool *buildAssembler() const override; 781 Tool *buildLinker() const override; 782 }; 783 784 class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF { 785 public: 786 Linux(const Driver &D, const llvm::Triple &Triple, 787 const llvm::opt::ArgList &Args); 788 789 bool HasNativeLLVMSupport() const override; 790 791 void 792 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 793 llvm::opt::ArgStringList &CC1Args) const override; 794 void AddClangCXXStdlibIncludeArgs( 795 const llvm::opt::ArgList &DriverArgs, 796 llvm::opt::ArgStringList &CC1Args) const override; 797 void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, 798 llvm::opt::ArgStringList &CC1Args) const override; 799 bool isPIEDefault() const override; 800 SanitizerMask getSupportedSanitizers() const override; 801 void addProfileRTLibs(const llvm::opt::ArgList &Args, 802 llvm::opt::ArgStringList &CmdArgs) const override; 803 virtual std::string computeSysRoot() const; 804 805 std::vector<std::string> ExtraOpts; 806 807 protected: 808 Tool *buildAssembler() const override; 809 Tool *buildLinker() const override; 810 }; 811 812 class LLVM_LIBRARY_VISIBILITY CudaToolChain : public Linux { 813 public: 814 CudaToolChain(const Driver &D, const llvm::Triple &Triple, 815 const llvm::opt::ArgList &Args); 816 817 llvm::opt::DerivedArgList * 818 TranslateArgs(const llvm::opt::DerivedArgList &Args, 819 const char *BoundArch) const override; 820 void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 821 llvm::opt::ArgStringList &CC1Args) const override; 822 }; 823 824 class LLVM_LIBRARY_VISIBILITY MipsLLVMToolChain : public Linux { 825 protected: 826 Tool *buildLinker() const override; 827 828 public: 829 MipsLLVMToolChain(const Driver &D, const llvm::Triple &Triple, 830 const llvm::opt::ArgList &Args); 831 832 void 833 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 834 llvm::opt::ArgStringList &CC1Args) const override; 835 836 CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; 837 838 void AddClangCXXStdlibIncludeArgs( 839 const llvm::opt::ArgList &DriverArgs, 840 llvm::opt::ArgStringList &CC1Args) const override; 841 842 void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, 843 llvm::opt::ArgStringList &CmdArgs) const override; 844 845 std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, 846 bool Shared = false) const override; 847 848 std::string computeSysRoot() const override; 849 GetDefaultRuntimeLibType()850 RuntimeLibType GetDefaultRuntimeLibType() const override { 851 return GCCInstallation.isValid() ? RuntimeLibType::RLT_Libgcc 852 : RuntimeLibType::RLT_CompilerRT; 853 } 854 855 private: 856 Multilib SelectedMultilib; 857 std::string LibSuffix; 858 }; 859 860 class LLVM_LIBRARY_VISIBILITY HexagonToolChain : public Linux { 861 protected: 862 GCCVersion GCCLibAndIncVersion; 863 Tool *buildAssembler() const override; 864 Tool *buildLinker() const override; 865 866 public: 867 HexagonToolChain(const Driver &D, const llvm::Triple &Triple, 868 const llvm::opt::ArgList &Args); 869 ~HexagonToolChain() override; 870 871 void 872 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 873 llvm::opt::ArgStringList &CC1Args) const override; 874 void AddClangCXXStdlibIncludeArgs( 875 const llvm::opt::ArgList &DriverArgs, 876 llvm::opt::ArgStringList &CC1Args) const override; 877 CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; 878 GetGCCLibAndIncVersion()879 StringRef GetGCCLibAndIncVersion() const { return GCCLibAndIncVersion.Text; } IsIntegratedAssemblerDefault()880 bool IsIntegratedAssemblerDefault() const override { 881 return true; 882 } 883 884 std::string getHexagonTargetDir( 885 const std::string &InstalledDir, 886 const SmallVectorImpl<std::string> &PrefixDirs) const; 887 void getHexagonLibraryPaths(const llvm::opt::ArgList &Args, 888 ToolChain::path_list &LibPaths) const; 889 890 static const StringRef GetDefaultCPU(); 891 static const StringRef GetTargetCPUVersion(const llvm::opt::ArgList &Args); 892 893 static Optional<unsigned> getSmallDataThreshold( 894 const llvm::opt::ArgList &Args); 895 }; 896 897 class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF { 898 protected: 899 Tool *buildLinker() const override; 900 901 public: 902 AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple, 903 const llvm::opt::ArgList &Args); IsIntegratedAssemblerDefault()904 bool IsIntegratedAssemblerDefault() const override { return true; } 905 }; 906 907 class LLVM_LIBRARY_VISIBILITY NaClToolChain : public Generic_ELF { 908 public: 909 NaClToolChain(const Driver &D, const llvm::Triple &Triple, 910 const llvm::opt::ArgList &Args); 911 912 void 913 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 914 llvm::opt::ArgStringList &CC1Args) const override; 915 void AddClangCXXStdlibIncludeArgs( 916 const llvm::opt::ArgList &DriverArgs, 917 llvm::opt::ArgStringList &CC1Args) const override; 918 919 CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; 920 921 void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, 922 llvm::opt::ArgStringList &CmdArgs) const override; 923 IsIntegratedAssemblerDefault()924 bool IsIntegratedAssemblerDefault() const override { 925 return getTriple().getArch() == llvm::Triple::mipsel; 926 } 927 928 // Get the path to the file containing NaCl's ARM macros. 929 // It lives in NaClToolChain because the ARMAssembler tool needs a 930 // const char * that it can pass around, GetNaClArmMacrosPath()931 const char *GetNaClArmMacrosPath() const { return NaClArmMacrosPath.c_str(); } 932 933 std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, 934 types::ID InputType) const override; 935 936 protected: 937 Tool *buildLinker() const override; 938 Tool *buildAssembler() const override; 939 940 private: 941 std::string NaClArmMacrosPath; 942 }; 943 944 /// TCEToolChain - A tool chain using the llvm bitcode tools to perform 945 /// all subcommands. See http://tce.cs.tut.fi for our peculiar target. 946 class LLVM_LIBRARY_VISIBILITY TCEToolChain : public ToolChain { 947 public: 948 TCEToolChain(const Driver &D, const llvm::Triple &Triple, 949 const llvm::opt::ArgList &Args); 950 ~TCEToolChain() override; 951 952 bool IsMathErrnoDefault() const override; 953 bool isPICDefault() const override; 954 bool isPIEDefault() const override; 955 bool isPICDefaultForced() const override; 956 }; 957 958 class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain { 959 public: 960 MSVCToolChain(const Driver &D, const llvm::Triple &Triple, 961 const llvm::opt::ArgList &Args); 962 963 llvm::opt::DerivedArgList * 964 TranslateArgs(const llvm::opt::DerivedArgList &Args, 965 const char *BoundArch) const override; 966 967 bool IsIntegratedAssemblerDefault() const override; 968 bool IsUnwindTablesDefault() const override; 969 bool isPICDefault() const override; 970 bool isPIEDefault() const override; 971 bool isPICDefaultForced() const override; 972 973 void 974 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 975 llvm::opt::ArgStringList &CC1Args) const override; 976 void AddClangCXXStdlibIncludeArgs( 977 const llvm::opt::ArgList &DriverArgs, 978 llvm::opt::ArgStringList &CC1Args) const override; 979 980 bool getWindowsSDKDir(std::string &path, int &major, 981 std::string &windowsSDKIncludeVersion, 982 std::string &windowsSDKLibVersion) const; 983 bool getWindowsSDKLibraryPath(std::string &path) const; 984 /// \brief Check if Universal CRT should be used if available 985 bool useUniversalCRT(std::string &visualStudioDir) const; 986 bool getUniversalCRTSdkDir(std::string &path, std::string &ucrtVersion) const; 987 bool getUniversalCRTLibraryPath(std::string &path) const; 988 bool getVisualStudioInstallDir(std::string &path) const; 989 bool getVisualStudioBinariesFolder(const char *clangProgramPath, 990 std::string &path) const; 991 992 std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, 993 types::ID InputType) const override; 994 SanitizerMask getSupportedSanitizers() const override; 995 996 protected: 997 void AddSystemIncludeWithSubfolder(const llvm::opt::ArgList &DriverArgs, 998 llvm::opt::ArgStringList &CC1Args, 999 const std::string &folder, 1000 const Twine &subfolder1, 1001 const Twine &subfolder2 = "", 1002 const Twine &subfolder3 = "") const; 1003 1004 Tool *buildLinker() const override; 1005 Tool *buildAssembler() const override; 1006 }; 1007 1008 class LLVM_LIBRARY_VISIBILITY CrossWindowsToolChain : public Generic_GCC { 1009 public: 1010 CrossWindowsToolChain(const Driver &D, const llvm::Triple &T, 1011 const llvm::opt::ArgList &Args); 1012 IsIntegratedAssemblerDefault()1013 bool IsIntegratedAssemblerDefault() const override { return true; } 1014 bool IsUnwindTablesDefault() const override; 1015 bool isPICDefault() const override; 1016 bool isPIEDefault() const override; 1017 bool isPICDefaultForced() const override; 1018 GetDefaultStackProtectorLevel(bool KernelOrKext)1019 unsigned int GetDefaultStackProtectorLevel(bool KernelOrKext) const override { 1020 return 0; 1021 } 1022 1023 void 1024 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 1025 llvm::opt::ArgStringList &CC1Args) const override; 1026 void AddClangCXXStdlibIncludeArgs( 1027 const llvm::opt::ArgList &DriverArgs, 1028 llvm::opt::ArgStringList &CC1Args) const override; 1029 void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, 1030 llvm::opt::ArgStringList &CmdArgs) const override; 1031 1032 SanitizerMask getSupportedSanitizers() const override; 1033 1034 protected: 1035 Tool *buildLinker() const override; 1036 Tool *buildAssembler() const override; 1037 }; 1038 1039 class LLVM_LIBRARY_VISIBILITY XCoreToolChain : public ToolChain { 1040 public: 1041 XCoreToolChain(const Driver &D, const llvm::Triple &Triple, 1042 const llvm::opt::ArgList &Args); 1043 1044 protected: 1045 Tool *buildAssembler() const override; 1046 Tool *buildLinker() const override; 1047 1048 public: 1049 bool isPICDefault() const override; 1050 bool isPIEDefault() const override; 1051 bool isPICDefaultForced() const override; 1052 bool SupportsProfiling() const override; 1053 bool hasBlocksRuntime() const override; 1054 void 1055 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 1056 llvm::opt::ArgStringList &CC1Args) const override; 1057 void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 1058 llvm::opt::ArgStringList &CC1Args) const override; 1059 void AddClangCXXStdlibIncludeArgs( 1060 const llvm::opt::ArgList &DriverArgs, 1061 llvm::opt::ArgStringList &CC1Args) const override; 1062 void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, 1063 llvm::opt::ArgStringList &CmdArgs) const override; 1064 }; 1065 1066 /// MyriadToolChain - A tool chain using either clang or the external compiler 1067 /// installed by the Movidius SDK to perform all subcommands. 1068 class LLVM_LIBRARY_VISIBILITY MyriadToolChain : public Generic_GCC { 1069 public: 1070 MyriadToolChain(const Driver &D, const llvm::Triple &Triple, 1071 const llvm::opt::ArgList &Args); 1072 ~MyriadToolChain() override; 1073 1074 void 1075 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 1076 llvm::opt::ArgStringList &CC1Args) const override; 1077 void AddClangCXXStdlibIncludeArgs( 1078 const llvm::opt::ArgList &DriverArgs, 1079 llvm::opt::ArgStringList &CC1Args) const override; 1080 Tool *SelectTool(const JobAction &JA) const override; GetDefaultDwarfVersion()1081 unsigned GetDefaultDwarfVersion() const override { return 2; } 1082 1083 protected: 1084 Tool *buildLinker() const override; isShaveCompilation(const llvm::Triple & T)1085 bool isShaveCompilation(const llvm::Triple &T) const { 1086 return T.getArch() == llvm::Triple::shave; 1087 } 1088 1089 private: 1090 mutable std::unique_ptr<Tool> Compiler; 1091 mutable std::unique_ptr<Tool> Assembler; 1092 }; 1093 1094 class LLVM_LIBRARY_VISIBILITY WebAssembly final : public ToolChain { 1095 public: 1096 WebAssembly(const Driver &D, const llvm::Triple &Triple, 1097 const llvm::opt::ArgList &Args); 1098 1099 private: 1100 bool IsMathErrnoDefault() const override; 1101 bool IsObjCNonFragileABIDefault() const override; 1102 bool UseObjCMixedDispatch() const override; 1103 bool isPICDefault() const override; 1104 bool isPIEDefault() const override; 1105 bool isPICDefaultForced() const override; 1106 bool IsIntegratedAssemblerDefault() const override; 1107 bool hasBlocksRuntime() const override; 1108 bool SupportsObjCGC() const override; 1109 bool SupportsProfiling() const override; 1110 bool HasNativeLLVMSupport() const override; 1111 void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 1112 llvm::opt::ArgStringList &CC1Args) const override; 1113 1114 Tool *buildLinker() const override; 1115 }; 1116 1117 class LLVM_LIBRARY_VISIBILITY PS4CPU : public Generic_ELF { 1118 public: 1119 PS4CPU(const Driver &D, const llvm::Triple &Triple, 1120 const llvm::opt::ArgList &Args); 1121 IsMathErrnoDefault()1122 bool IsMathErrnoDefault() const override { return false; } IsObjCNonFragileABIDefault()1123 bool IsObjCNonFragileABIDefault() const override { return true; } 1124 bool HasNativeLLVMSupport() const override; 1125 bool isPICDefault() const override; 1126 GetDefaultStackProtectorLevel(bool KernelOrKext)1127 unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override { 1128 return 2; // SSPStrong 1129 } 1130 getDefaultDebuggerTuning()1131 llvm::DebuggerKind getDefaultDebuggerTuning() const override { 1132 return llvm::DebuggerKind::SCE; 1133 } 1134 1135 SanitizerMask getSupportedSanitizers() const override; 1136 1137 protected: 1138 Tool *buildAssembler() const override; 1139 Tool *buildLinker() const override; 1140 }; 1141 1142 } // end namespace toolchains 1143 } // end namespace driver 1144 } // end namespace clang 1145 1146 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_H 1147