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. 87 bool isValid() const { return IsValid; } 88 89 /// \brief Get the GCC triple for the detected install. 90 const llvm::Triple &getTriple() const { return GCCTriple; } 91 92 /// \brief Get the detected GCC installation path. 93 StringRef getInstallPath() const { return GCCInstallPath; } 94 95 /// \brief Get the detected GCC installation path suffix for multiarch GCCs. 96 StringRef getMultiarchSuffix() const { return GCCMultiarchSuffix; } 97 98 /// \brief Get the detected GCC parent lib path. 99 StringRef getParentLibPath() const { return GCCParentLibPath; } 100 101 /// \brief Get the detected GCC version string. 102 StringRef getVersion() const { return Version.Text; } 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. 139 bool isTarget64Bit() const { return getTriple().isArch64Bit(); } 140 141 /// \brief Check whether the target triple's architecture is 32-bits. 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 // FIXME: Remove this once there is a proper way to detect an ARC runtime 180 // for the simulator. 181 public: 182 mutable enum { 183 ARCSimulator_None, 184 ARCSimulator_HasARCRuntime, 185 ARCSimulator_NoARCRuntime 186 } ARCRuntimeForSimulator; 187 188 mutable enum { 189 LibCXXSimulator_None, 190 LibCXXSimulator_NotAvailable, 191 LibCXXSimulator_Available 192 } LibCXXForSimulator; 193 194 private: 195 /// Whether we are targeting iPhoneOS target. 196 mutable bool TargetIsIPhoneOS; 197 198 /// Whether we are targeting the iPhoneOS simulator target. 199 mutable bool TargetIsIPhoneOSSimulator; 200 201 /// The OS version we are targeting. 202 mutable VersionTuple TargetVersion; 203 204 /// The default macosx-version-min of this tool chain; empty until 205 /// initialized. 206 std::string MacosxVersionMin; 207 208 bool hasARCRuntime() const; 209 bool hasSubscriptingRuntime() const; 210 211 private: 212 void AddDeploymentTarget(DerivedArgList &Args) const; 213 214 public: 215 Darwin(const Driver &D, const llvm::Triple& Triple); 216 ~Darwin(); 217 218 std::string ComputeEffectiveClangTriple(const ArgList &Args, 219 types::ID InputType) const; 220 221 /// @name Darwin Specific Toolchain API 222 /// { 223 224 // FIXME: Eliminate these ...Target functions and derive separate tool chains 225 // for these targets and put version in constructor. 226 void setTarget(bool IsIPhoneOS, unsigned Major, unsigned Minor, 227 unsigned Micro, bool IsIOSSim) const { 228 assert((!IsIOSSim || IsIPhoneOS) && "Unexpected deployment target!"); 229 230 // FIXME: For now, allow reinitialization as long as values don't 231 // change. This will go away when we move away from argument translation. 232 if (TargetInitialized && TargetIsIPhoneOS == IsIPhoneOS && 233 TargetIsIPhoneOSSimulator == IsIOSSim && 234 TargetVersion == VersionTuple(Major, Minor, Micro)) 235 return; 236 237 assert(!TargetInitialized && "Target already initialized!"); 238 TargetInitialized = true; 239 TargetIsIPhoneOS = IsIPhoneOS; 240 TargetIsIPhoneOSSimulator = IsIOSSim; 241 TargetVersion = VersionTuple(Major, Minor, Micro); 242 } 243 244 bool isTargetIPhoneOS() const { 245 assert(TargetInitialized && "Target not initialized!"); 246 return TargetIsIPhoneOS; 247 } 248 249 bool isTargetIOSSimulator() const { 250 assert(TargetInitialized && "Target not initialized!"); 251 return TargetIsIPhoneOSSimulator; 252 } 253 254 bool isTargetMacOS() const { 255 return !isTargetIOSSimulator() && 256 !isTargetIPhoneOS() && 257 ARCRuntimeForSimulator == ARCSimulator_None; 258 } 259 260 bool isTargetInitialized() const { return TargetInitialized; } 261 262 VersionTuple getTargetVersion() const { 263 assert(TargetInitialized && "Target not initialized!"); 264 return TargetVersion; 265 } 266 267 /// getDarwinArchName - Get the "Darwin" arch name for a particular compiler 268 /// invocation. For example, Darwin treats different ARM variations as 269 /// distinct architectures. 270 StringRef getDarwinArchName(const ArgList &Args) const; 271 272 bool isIPhoneOSVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const { 273 assert(isTargetIPhoneOS() && "Unexpected call for OS X target!"); 274 return TargetVersion < VersionTuple(V0, V1, V2); 275 } 276 277 bool isMacosxVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const { 278 assert(!isTargetIPhoneOS() && "Unexpected call for iPhoneOS target!"); 279 return TargetVersion < VersionTuple(V0, V1, V2); 280 } 281 282 /// AddLinkSearchPathArgs - Add the linker search paths to \arg CmdArgs. 283 /// 284 /// \param Args - The input argument list. 285 /// \param CmdArgs [out] - The command argument list to append the paths 286 /// (prefixed by -L) to. 287 virtual void AddLinkSearchPathArgs(const ArgList &Args, 288 ArgStringList &CmdArgs) const = 0; 289 290 /// AddLinkARCArgs - Add the linker arguments to link the ARC runtime library. 291 virtual void AddLinkARCArgs(const ArgList &Args, 292 ArgStringList &CmdArgs) const = 0; 293 294 /// AddLinkRuntimeLibArgs - Add the linker arguments to link the compiler 295 /// runtime library. 296 virtual void AddLinkRuntimeLibArgs(const ArgList &Args, 297 ArgStringList &CmdArgs) const = 0; 298 299 /// } 300 /// @name ToolChain Implementation 301 /// { 302 303 virtual types::ID LookupTypeForExtension(const char *Ext) const; 304 305 virtual bool HasNativeLLVMSupport() const; 306 307 virtual void configureObjCRuntime(ObjCRuntime &runtime) const; 308 virtual bool hasBlocksRuntime() const; 309 310 virtual DerivedArgList *TranslateArgs(const DerivedArgList &Args, 311 const char *BoundArch) const; 312 313 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 314 const ActionList &Inputs) const; 315 316 virtual bool IsBlocksDefault() const { 317 // Always allow blocks on Darwin; users interested in versioning are 318 // expected to use /usr/include/Blocks.h. 319 return true; 320 } 321 virtual bool IsIntegratedAssemblerDefault() const { 322 #ifdef DISABLE_DEFAULT_INTEGRATED_ASSEMBLER 323 return false; 324 #else 325 // Default integrated assembler to on for Darwin. 326 return true; 327 #endif 328 } 329 virtual bool IsStrictAliasingDefault() const { 330 #ifdef DISABLE_DEFAULT_STRICT_ALIASING 331 return false; 332 #else 333 return ToolChain::IsStrictAliasingDefault(); 334 #endif 335 } 336 337 virtual bool IsObjCDefaultSynthPropertiesDefault() const { 338 return true; 339 } 340 341 virtual bool IsObjCNonFragileABIDefault() const { 342 // Non-fragile ABI is default for everything but i386. 343 return getTriple().getArch() != llvm::Triple::x86; 344 } 345 virtual bool IsObjCLegacyDispatchDefault() const { 346 // This is only used with the non-fragile ABI. 347 348 // Legacy dispatch is used everywhere except on x86_64. 349 return getTriple().getArch() != llvm::Triple::x86_64; 350 } 351 virtual bool UseObjCMixedDispatch() const { 352 // This is only used with the non-fragile ABI and non-legacy dispatch. 353 354 // Mixed dispatch is used everywhere except OS X before 10.6. 355 return !(!isTargetIPhoneOS() && isMacosxVersionLT(10, 6)); 356 } 357 virtual bool IsUnwindTablesDefault() const; 358 virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const { 359 // Stack protectors default to on for user code on 10.5, 360 // and for everything in 10.6 and beyond 361 return isTargetIPhoneOS() || 362 (!isMacosxVersionLT(10, 6) || 363 (!isMacosxVersionLT(10, 5) && !KernelOrKext)); 364 } 365 virtual RuntimeLibType GetDefaultRuntimeLibType() const { 366 return ToolChain::RLT_CompilerRT; 367 } 368 virtual const char *GetDefaultRelocationModel() const; 369 virtual const char *GetForcedPicModel() const; 370 371 virtual bool SupportsProfiling() const; 372 373 virtual bool SupportsObjCGC() const; 374 375 virtual bool SupportsObjCARC() const; 376 377 virtual bool UseDwarfDebugFlags() const; 378 379 virtual bool UseSjLjExceptions() const; 380 381 /// } 382 }; 383 384 /// DarwinClang - The Darwin toolchain used by Clang. 385 class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { 386 private: 387 void AddGCCLibexecPath(unsigned darwinVersion); 388 389 public: 390 DarwinClang(const Driver &D, const llvm::Triple& Triple); 391 392 /// @name Darwin ToolChain Implementation 393 /// { 394 395 virtual void AddLinkSearchPathArgs(const ArgList &Args, 396 ArgStringList &CmdArgs) const; 397 398 virtual void AddLinkRuntimeLibArgs(const ArgList &Args, 399 ArgStringList &CmdArgs) const; 400 void AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs, 401 const char *DarwinStaticLib) const; 402 403 virtual void AddCXXStdlibLibArgs(const ArgList &Args, 404 ArgStringList &CmdArgs) const; 405 406 virtual void AddCCKextLibArgs(const ArgList &Args, 407 ArgStringList &CmdArgs) const; 408 409 virtual void AddLinkARCArgs(const ArgList &Args, 410 ArgStringList &CmdArgs) const; 411 /// } 412 }; 413 414 /// Darwin_Generic_GCC - Generic Darwin tool chain using gcc. 415 class LLVM_LIBRARY_VISIBILITY Darwin_Generic_GCC : public Generic_GCC { 416 public: 417 Darwin_Generic_GCC(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 418 : Generic_GCC(D, Triple, Args) {} 419 420 std::string ComputeEffectiveClangTriple(const ArgList &Args, 421 types::ID InputType) const; 422 423 virtual const char *GetDefaultRelocationModel() const { return "pic"; } 424 }; 425 426 class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC { 427 virtual void anchor(); 428 public: 429 Generic_ELF(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) 430 : Generic_GCC(D, Triple, Args) {} 431 432 virtual bool IsIntegratedAssemblerDefault() const { 433 // Default integrated assembler to on for x86. 434 return (getTriple().getArch() == llvm::Triple::x86 || 435 getTriple().getArch() == llvm::Triple::x86_64); 436 } 437 }; 438 439 class LLVM_LIBRARY_VISIBILITY AuroraUX : public Generic_GCC { 440 public: 441 AuroraUX(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 442 443 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 444 const ActionList &Inputs) const; 445 }; 446 447 class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_GCC { 448 public: 449 Solaris(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 450 451 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 452 const ActionList &Inputs) const; 453 454 virtual bool IsIntegratedAssemblerDefault() const { return true; } 455 }; 456 457 458 class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic_ELF { 459 public: 460 OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 461 462 virtual bool IsObjCNonFragileABIDefault() const { return true; } 463 virtual bool IsObjCLegacyDispatchDefault() const { 464 llvm::Triple::ArchType Arch = getTriple().getArch(); 465 if (Arch == llvm::Triple::arm || 466 Arch == llvm::Triple::x86 || 467 Arch == llvm::Triple::x86_64) 468 return false; 469 return true; 470 } 471 472 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 473 const ActionList &Inputs) const; 474 }; 475 476 class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF { 477 public: 478 FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 479 480 virtual bool IsObjCNonFragileABIDefault() const { return true; } 481 virtual bool IsObjCLegacyDispatchDefault() const { 482 llvm::Triple::ArchType Arch = getTriple().getArch(); 483 if (Arch == llvm::Triple::arm || 484 Arch == llvm::Triple::x86 || 485 Arch == llvm::Triple::x86_64) 486 return false; 487 return true; 488 } 489 490 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 491 const ActionList &Inputs) const; 492 }; 493 494 class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF { 495 public: 496 NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 497 498 virtual bool IsObjCNonFragileABIDefault() const { return true; } 499 virtual bool IsObjCLegacyDispatchDefault() const { 500 llvm::Triple::ArchType Arch = getTriple().getArch(); 501 if (Arch == llvm::Triple::arm || 502 Arch == llvm::Triple::x86 || 503 Arch == llvm::Triple::x86_64) 504 return false; 505 return true; 506 } 507 508 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 509 const ActionList &Inputs) const; 510 }; 511 512 class LLVM_LIBRARY_VISIBILITY Minix : public Generic_ELF { 513 public: 514 Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 515 516 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 517 const ActionList &Inputs) const; 518 }; 519 520 class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_ELF { 521 public: 522 DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 523 524 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 525 const ActionList &Inputs) const; 526 }; 527 528 class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF { 529 public: 530 Linux(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); 531 532 virtual bool HasNativeLLVMSupport() const; 533 534 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 535 const ActionList &Inputs) const; 536 537 virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs, 538 ArgStringList &CC1Args) const; 539 virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 540 ArgStringList &CC1Args) const; 541 542 std::string Linker; 543 std::vector<std::string> ExtraOpts; 544 545 private: 546 static bool addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir, 547 const ArgList &DriverArgs, 548 ArgStringList &CC1Args); 549 }; 550 551 552 /// TCEToolChain - A tool chain using the llvm bitcode tools to perform 553 /// all subcommands. See http://tce.cs.tut.fi for our peculiar target. 554 class LLVM_LIBRARY_VISIBILITY TCEToolChain : public ToolChain { 555 public: 556 TCEToolChain(const Driver &D, const llvm::Triple& Triple); 557 ~TCEToolChain(); 558 559 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 560 const ActionList &Inputs) const; 561 bool IsMathErrnoDefault() const; 562 bool IsUnwindTablesDefault() const; 563 const char* GetDefaultRelocationModel() const; 564 const char* GetForcedPicModel() const; 565 566 private: 567 mutable llvm::DenseMap<unsigned, Tool*> Tools; 568 569 }; 570 571 class LLVM_LIBRARY_VISIBILITY Windows : public ToolChain { 572 mutable llvm::DenseMap<unsigned, Tool*> Tools; 573 574 public: 575 Windows(const Driver &D, const llvm::Triple& Triple); 576 577 virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, 578 const ActionList &Inputs) const; 579 580 virtual bool IsIntegratedAssemblerDefault() const; 581 virtual bool IsUnwindTablesDefault() const; 582 virtual const char *GetDefaultRelocationModel() const; 583 virtual const char *GetForcedPicModel() const; 584 585 virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs, 586 ArgStringList &CC1Args) const; 587 virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 588 ArgStringList &CC1Args) const; 589 590 }; 591 592 } // end namespace toolchains 593 } // end namespace driver 594 } // end namespace clang 595 596 #endif 597