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 CLANG_LIB_DRIVER_TOOLCHAINS_H_ 11 #define CLANG_LIB_DRIVER_TOOLCHAINS_H_ 12 13 #include "clang/Driver/Action.h" 14 #include "clang/Driver/ToolChain.h" 15 16 #include "clang/Basic/VersionTuple.h" 17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/Support/Compiler.h" 19 20 #include "Tools.h" 21 22 namespace clang { 23 namespace driver { 24 namespace toolchains { 25 26 /// Generic_GCC - A tool chain using the 'gcc' command to perform 27 /// all subcommands; this relies on gcc translating the majority of 28 /// command line options. 29 class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain { 30 protected: 31 /// \brief Struct to store and manipulate GCC versions. 32 /// 33 /// We rely on assumptions about the form and structure of GCC version 34 /// numbers: they consist of at most three '.'-separated components, and each 35 /// component is a non-negative integer except for the last component. For 36 /// the last component we are very flexible in order to tolerate release 37 /// candidates or 'x' wildcards. 38 /// 39 /// Note that the ordering established among GCCVersions is based on the 40 /// preferred version string to use. For example we prefer versions without 41 /// a hard-coded patch number to those with a hard coded patch number. 42 /// 43 /// Currently this doesn't provide any logic for textual suffixes to patches 44 /// in the way that (for example) Debian's version format does. If that ever 45 /// becomes necessary, it can be added. 46 struct GCCVersion { 47 /// \brief The unparsed text of the version. 48 std::string Text; 49 50 /// \brief The parsed major, minor, and patch numbers. 51 int Major, Minor, Patch; 52 53 /// \brief Any textual suffix on the patch number. 54 std::string PatchSuffix; 55 56 static GCCVersion Parse(StringRef VersionText); 57 bool operator<(const GCCVersion &RHS) const; 58 bool operator>(const GCCVersion &RHS) const { return RHS < *this; } 59 bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); } 60 bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); } 61 }; 62 63 64 /// \brief This is a class to find a viable GCC installation for Clang to 65 /// use. 66 /// 67 /// This class tries to find a GCC installation on the system, and report 68 /// information about it. It starts from the host information provided to the 69 /// Driver, and has logic for fuzzing that where appropriate. 70 class GCCInstallationDetector { 71 72 bool IsValid; 73 llvm::Triple GCCTriple; 74 75 // FIXME: These might be better as path objects. 76 std::string GCCInstallPath; 77 std::string GCCMultiarchSuffix; 78 std::string GCCParentLibPath; 79 80 GCCVersion Version; 81 82 public: 83 GCCInstallationDetector(const Driver &D, const llvm::Triple &TargetTriple, 84 const ArgList &Args); 85 86 /// \brief Check whether we detected a valid GCC install. isValid()87 bool isValid() const { return IsValid; } 88 89 /// \brief Get the GCC triple for the detected install. getTriple()90 const llvm::Triple &getTriple() const { return GCCTriple; } 91 92 /// \brief Get the detected GCC installation path. getInstallPath()93 StringRef getInstallPath() const { return GCCInstallPath; } 94 95 /// \brief Get the detected GCC installation path suffix for multiarch GCCs. getMultiarchSuffix()96 StringRef getMultiarchSuffix() const { return GCCMultiarchSuffix; } 97 98 /// \brief Get the detected GCC parent lib path. getParentLibPath()99 StringRef getParentLibPath() const { return GCCParentLibPath; } 100 101 /// \brief Get the detected GCC version string. getVersion()102 const GCCVersion &getVersion() const { return Version; } 103 104 private: 105 static void CollectLibDirsAndTriples( 106 const llvm::Triple &TargetTriple, 107 const llvm::Triple &MultiarchTriple, 108 SmallVectorImpl<StringRef> &LibDirs, 109 SmallVectorImpl<StringRef> &TripleAliases, 110 SmallVectorImpl<StringRef> &MultiarchLibDirs, 111 SmallVectorImpl<StringRef> &MultiarchTripleAliases); 112 113 void ScanLibDirForGCCTriple(llvm::Triple::ArchType TargetArch, 114 const std::string &LibDir, 115 StringRef CandidateTriple, 116 bool NeedsMultiarchSuffix = false); 117 }; 118 119 GCCInstallationDetector GCCInstallation; 120 121 mutable llvm::DenseMap<unsigned, Tool*> Tools; 122 123 public: 124 Generic_GCC(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 125 ~Generic_GCC(); 126 127 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 128 const ActionList &Inputs) const; 129 130 virtual bool IsUnwindTablesDefault() const; 131 virtual const char *GetDefaultRelocationModel() const; 132 virtual const char *GetForcedPicModel() const; 133 134 protected: 135 /// \name ToolChain Implementation Helper Functions 136 /// @{ 137 138 /// \brief Check whether the target triple's architecture is 64-bits. isTarget64Bit()139 bool isTarget64Bit() const { return getTriple().isArch64Bit(); } 140 141 /// \brief Check whether the target triple's architecture is 32-bits. isTarget32Bit()142 bool isTarget32Bit() const { return getTriple().isArch32Bit(); } 143 144 /// @} 145 }; 146 147 class LLVM_LIBRARY_VISIBILITY Hexagon_TC : public ToolChain { 148 protected: 149 mutable llvm::DenseMap<unsigned, Tool*> Tools; 150 151 public: 152 Hexagon_TC(const Driver &D, const llvm::Triple& Triple); 153 ~Hexagon_TC(); 154 155 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 156 const ActionList &Inputs) const; 157 158 virtual bool IsUnwindTablesDefault() const; 159 virtual const char *GetDefaultRelocationModel() const; 160 virtual const char *GetForcedPicModel() const; 161 }; 162 163 /// Darwin - The base Darwin tool chain. 164 class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain { 165 public: 166 /// The host version. 167 unsigned DarwinVersion[3]; 168 169 private: 170 mutable llvm::DenseMap<unsigned, Tool*> Tools; 171 172 /// Whether the information on the target has been initialized. 173 // 174 // FIXME: This should be eliminated. What we want to do is make this part of 175 // the "default target for arguments" selection process, once we get out of 176 // the argument translation business. 177 mutable bool TargetInitialized; 178 179 /// Whether we are targeting iPhoneOS target. 180 mutable bool TargetIsIPhoneOS; 181 182 /// Whether we are targeting the iPhoneOS simulator target. 183 mutable bool TargetIsIPhoneOSSimulator; 184 185 /// The OS version we are targeting. 186 mutable VersionTuple TargetVersion; 187 188 protected: 189 // FIXME: Remove this once there is a proper way to detect an ARC runtime 190 // for the simulator. 191 mutable VersionTuple TargetSimulatorVersionFromDefines; 192 193 private: 194 /// The default macosx-version-min of this tool chain; empty until 195 /// initialized. 196 std::string MacosxVersionMin; 197 198 /// The default ios-version-min of this tool chain; empty until 199 /// initialized. 200 std::string iOSVersionMin; 201 202 private: 203 void AddDeploymentTarget(DerivedArgList &Args) const; 204 205 public: 206 Darwin(const Driver &D, const llvm::Triple& Triple); 207 ~Darwin(); 208 209 std::string ComputeEffectiveClangTriple(const ArgList &Args, 210 types::ID InputType) const; 211 212 /// @name Darwin Specific Toolchain API 213 /// { 214 215 // FIXME: Eliminate these ...Target functions and derive separate tool chains 216 // for these targets and put version in constructor. setTarget(bool IsIPhoneOS,unsigned Major,unsigned Minor,unsigned Micro,bool IsIOSSim)217 void setTarget(bool IsIPhoneOS, unsigned Major, unsigned Minor, 218 unsigned Micro, bool IsIOSSim) const { 219 assert((!IsIOSSim || IsIPhoneOS) && "Unexpected deployment target!"); 220 221 // FIXME: For now, allow reinitialization as long as values don't 222 // change. This will go away when we move away from argument translation. 223 if (TargetInitialized && TargetIsIPhoneOS == IsIPhoneOS && 224 TargetIsIPhoneOSSimulator == IsIOSSim && 225 TargetVersion == VersionTuple(Major, Minor, Micro)) 226 return; 227 228 assert(!TargetInitialized && "Target already initialized!"); 229 TargetInitialized = true; 230 TargetIsIPhoneOS = IsIPhoneOS; 231 TargetIsIPhoneOSSimulator = IsIOSSim; 232 TargetVersion = VersionTuple(Major, Minor, Micro); 233 } 234 isTargetIPhoneOS()235 bool isTargetIPhoneOS() const { 236 assert(TargetInitialized && "Target not initialized!"); 237 return TargetIsIPhoneOS; 238 } 239 isTargetIOSSimulator()240 bool isTargetIOSSimulator() const { 241 assert(TargetInitialized && "Target not initialized!"); 242 return TargetIsIPhoneOSSimulator; 243 } 244 isTargetMacOS()245 bool isTargetMacOS() const { 246 return !isTargetIOSSimulator() && 247 !isTargetIPhoneOS() && 248 TargetSimulatorVersionFromDefines == VersionTuple(); 249 } 250 isTargetInitialized()251 bool isTargetInitialized() const { return TargetInitialized; } 252 getTargetVersion()253 VersionTuple getTargetVersion() const { 254 assert(TargetInitialized && "Target not initialized!"); 255 return TargetVersion; 256 } 257 258 /// getDarwinArchName - Get the "Darwin" arch name for a particular compiler 259 /// invocation. For example, Darwin treats different ARM variations as 260 /// distinct architectures. 261 StringRef getDarwinArchName(const ArgList &Args) const; 262 263 bool isIPhoneOSVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const { 264 assert(isTargetIPhoneOS() && "Unexpected call for OS X target!"); 265 return TargetVersion < VersionTuple(V0, V1, V2); 266 } 267 268 bool isMacosxVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const { 269 assert(!isTargetIPhoneOS() && "Unexpected call for iPhoneOS target!"); 270 return TargetVersion < VersionTuple(V0, V1, V2); 271 } 272 273 /// AddLinkARCArgs - Add the linker arguments to link the ARC runtime library. 274 virtual void AddLinkARCArgs(const ArgList &Args, 275 ArgStringList &CmdArgs) const = 0; 276 277 /// AddLinkRuntimeLibArgs - Add the linker arguments to link the compiler 278 /// runtime library. 279 virtual void AddLinkRuntimeLibArgs(const ArgList &Args, 280 ArgStringList &CmdArgs) const = 0; 281 282 /// } 283 /// @name ToolChain Implementation 284 /// { 285 286 virtual types::ID LookupTypeForExtension(const char *Ext) const; 287 288 virtual bool HasNativeLLVMSupport() const; 289 290 virtual ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const; 291 virtual bool hasBlocksRuntime() const; 292 293 virtual DerivedArgList *TranslateArgs(const DerivedArgList &Args, 294 const char *BoundArch) const; 295 296 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 297 const ActionList &Inputs) const; 298 IsBlocksDefault()299 virtual bool IsBlocksDefault() const { 300 // Always allow blocks on Darwin; users interested in versioning are 301 // expected to use /usr/include/Blocks.h. 302 return true; 303 } IsIntegratedAssemblerDefault()304 virtual bool IsIntegratedAssemblerDefault() const { 305 #ifdef DISABLE_DEFAULT_INTEGRATED_ASSEMBLER 306 return false; 307 #else 308 // Default integrated assembler to on for Darwin. 309 return true; 310 #endif 311 } IsStrictAliasingDefault()312 virtual bool IsStrictAliasingDefault() const { 313 #ifdef DISABLE_DEFAULT_STRICT_ALIASING 314 return false; 315 #else 316 return ToolChain::IsStrictAliasingDefault(); 317 #endif 318 } 319 IsMathErrnoDefault()320 virtual bool IsMathErrnoDefault() const { 321 return false; 322 } 323 IsObjCDefaultSynthPropertiesDefault()324 virtual bool IsObjCDefaultSynthPropertiesDefault() const { 325 return true; 326 } 327 IsObjCNonFragileABIDefault()328 virtual bool IsObjCNonFragileABIDefault() const { 329 // Non-fragile ABI is default for everything but i386. 330 return getTriple().getArch() != llvm::Triple::x86; 331 } 332 UseObjCMixedDispatch()333 virtual bool UseObjCMixedDispatch() const { 334 // This is only used with the non-fragile ABI and non-legacy dispatch. 335 336 // Mixed dispatch is used everywhere except OS X before 10.6. 337 return !(!isTargetIPhoneOS() && isMacosxVersionLT(10, 6)); 338 } 339 virtual bool IsUnwindTablesDefault() const; GetDefaultStackProtectorLevel(bool KernelOrKext)340 virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const { 341 // Stack protectors default to on for user code on 10.5, 342 // and for everything in 10.6 and beyond 343 return isTargetIPhoneOS() || 344 (!isMacosxVersionLT(10, 6) || 345 (!isMacosxVersionLT(10, 5) && !KernelOrKext)); 346 } GetDefaultRuntimeLibType()347 virtual RuntimeLibType GetDefaultRuntimeLibType() const { 348 return ToolChain::RLT_CompilerRT; 349 } 350 virtual const char *GetDefaultRelocationModel() const; 351 virtual const char *GetForcedPicModel() const; 352 353 virtual bool SupportsProfiling() const; 354 355 virtual bool SupportsObjCGC() const; 356 357 virtual void CheckObjCARC() const; 358 359 virtual bool UseDwarfDebugFlags() const; 360 361 virtual bool UseSjLjExceptions() const; 362 363 /// } 364 }; 365 366 /// DarwinClang - The Darwin toolchain used by Clang. 367 class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { 368 private: 369 void AddGCCLibexecPath(unsigned darwinVersion); 370 371 public: 372 DarwinClang(const Driver &D, const llvm::Triple& Triple); 373 374 /// @name Darwin ToolChain Implementation 375 /// { 376 377 virtual void AddLinkRuntimeLibArgs(const ArgList &Args, 378 ArgStringList &CmdArgs) const; 379 void AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs, 380 const char *DarwinStaticLib) const; 381 382 virtual void AddCXXStdlibLibArgs(const ArgList &Args, 383 ArgStringList &CmdArgs) const; 384 385 virtual void AddCCKextLibArgs(const ArgList &Args, 386 ArgStringList &CmdArgs) const; 387 388 virtual void AddLinkARCArgs(const ArgList &Args, 389 ArgStringList &CmdArgs) const; 390 /// } 391 }; 392 393 /// Darwin_Generic_GCC - Generic Darwin tool chain using gcc. 394 class LLVM_LIBRARY_VISIBILITY Darwin_Generic_GCC : public Generic_GCC { 395 public: Darwin_Generic_GCC(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)396 Darwin_Generic_GCC(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 397 : Generic_GCC(D, Triple, Args) {} 398 399 std::string ComputeEffectiveClangTriple(const ArgList &Args, 400 types::ID InputType) const; 401 GetDefaultRelocationModel()402 virtual const char *GetDefaultRelocationModel() const { return "pic"; } 403 }; 404 405 class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC { 406 virtual void anchor(); 407 public: Generic_ELF(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)408 Generic_ELF(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 409 : Generic_GCC(D, Triple, Args) {} 410 IsIntegratedAssemblerDefault()411 virtual bool IsIntegratedAssemblerDefault() const { 412 // Default integrated assembler to on for x86. 413 return (getTriple().getArch() == llvm::Triple::x86 || 414 getTriple().getArch() == llvm::Triple::x86_64); 415 } 416 }; 417 418 class LLVM_LIBRARY_VISIBILITY AuroraUX : public Generic_GCC { 419 public: 420 AuroraUX(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 421 422 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 423 const ActionList &Inputs) const; 424 }; 425 426 class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_GCC { 427 public: 428 Solaris(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 429 430 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 431 const ActionList &Inputs) const; 432 IsIntegratedAssemblerDefault()433 virtual bool IsIntegratedAssemblerDefault() const { return true; } 434 }; 435 436 437 class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic_ELF { 438 public: 439 OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 440 IsMathErrnoDefault()441 virtual bool IsMathErrnoDefault() const { return false; } IsObjCNonFragileABIDefault()442 virtual bool IsObjCNonFragileABIDefault() const { return true; } 443 444 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 445 const ActionList &Inputs) const; 446 }; 447 448 class LLVM_LIBRARY_VISIBILITY Bitrig : public Generic_ELF { 449 public: 450 Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 451 IsMathErrnoDefault()452 virtual bool IsMathErrnoDefault() const { return false; } IsObjCNonFragileABIDefault()453 virtual bool IsObjCNonFragileABIDefault() const { return true; } IsObjCLegacyDispatchDefault()454 virtual bool IsObjCLegacyDispatchDefault() const { return false; } 455 456 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 457 const ActionList &Inputs) const; 458 459 virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 460 ArgStringList &CC1Args) const; 461 virtual void AddCXXStdlibLibArgs(const ArgList &Args, 462 ArgStringList &CmdArgs) const; GetDefaultStackProtectorLevel(bool KernelOrKext)463 virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const { 464 return 1; 465 } 466 }; 467 468 class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF { 469 public: 470 FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 471 IsMathErrnoDefault()472 virtual bool IsMathErrnoDefault() const { return false; } IsObjCNonFragileABIDefault()473 virtual bool IsObjCNonFragileABIDefault() const { return true; } 474 475 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 476 const ActionList &Inputs) const; 477 }; 478 479 class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF { 480 public: 481 NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 482 IsMathErrnoDefault()483 virtual bool IsMathErrnoDefault() const { return false; } IsObjCNonFragileABIDefault()484 virtual bool IsObjCNonFragileABIDefault() const { return true; } 485 486 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 487 const ActionList &Inputs) const; 488 }; 489 490 class LLVM_LIBRARY_VISIBILITY Minix : public Generic_ELF { 491 public: 492 Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 493 494 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 495 const ActionList &Inputs) const; 496 }; 497 498 class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_ELF { 499 public: 500 DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 501 IsMathErrnoDefault()502 virtual bool IsMathErrnoDefault() const { return false; } 503 504 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 505 const ActionList &Inputs) const; 506 }; 507 508 class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF { 509 public: 510 Linux(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 511 512 virtual bool HasNativeLLVMSupport() const; 513 514 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 515 const ActionList &Inputs) const; 516 517 virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs, 518 ArgStringList &CC1Args) const; 519 virtual void addClangTargetOptions(ArgStringList &CC1Args) const; 520 virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 521 ArgStringList &CC1Args) const; 522 523 std::string Linker; 524 std::vector<std::string> ExtraOpts; 525 526 private: 527 static bool addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir, 528 const ArgList &DriverArgs, 529 ArgStringList &CC1Args); 530 }; 531 532 533 /// TCEToolChain - A tool chain using the llvm bitcode tools to perform 534 /// all subcommands. See http://tce.cs.tut.fi for our peculiar target. 535 class LLVM_LIBRARY_VISIBILITY TCEToolChain : public ToolChain { 536 public: 537 TCEToolChain(const Driver &D, const llvm::Triple& Triple); 538 ~TCEToolChain(); 539 540 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 541 const ActionList &Inputs) const; 542 bool IsMathErrnoDefault() const; 543 bool IsUnwindTablesDefault() const; 544 const char* GetDefaultRelocationModel() const; 545 const char* GetForcedPicModel() const; 546 547 private: 548 mutable llvm::DenseMap<unsigned, Tool*> Tools; 549 550 }; 551 552 class LLVM_LIBRARY_VISIBILITY Windows : public ToolChain { 553 mutable llvm::DenseMap<unsigned, Tool*> Tools; 554 555 public: 556 Windows(const Driver &D, const llvm::Triple& Triple); 557 558 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 559 const ActionList &Inputs) const; 560 IsObjCDefaultSynthPropertiesDefault()561 virtual bool IsObjCDefaultSynthPropertiesDefault() const { 562 return true; 563 } 564 565 virtual bool IsIntegratedAssemblerDefault() const; 566 virtual bool IsUnwindTablesDefault() const; 567 virtual const char *GetDefaultRelocationModel() const; 568 virtual const char *GetForcedPicModel() const; 569 570 virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs, 571 ArgStringList &CC1Args) const; 572 virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 573 ArgStringList &CC1Args) const; 574 575 }; 576 577 } // end namespace toolchains 578 } // end namespace driver 579 } // end namespace clang 580 581 #endif 582