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