diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Driver/ToolChains.h')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/ToolChains.h | 337 |
1 files changed, 208 insertions, 129 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h index 0e4d67c..eaa6be1 100644 --- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h +++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h @@ -13,6 +13,7 @@ #include "clang/Driver/Action.h" #include "clang/Driver/ToolChain.h" +#include "clang/Basic/VersionTuple.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Compiler.h" @@ -27,10 +28,100 @@ namespace toolchains { /// command line options. class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain { protected: + /// \brief Struct to store and manipulate GCC versions. + /// + /// We rely on assumptions about the form and structure of GCC version + /// numbers: they consist of at most three '.'-separated components, and each + /// component is a non-negative integer except for the last component. For + /// the last component we are very flexible in order to tolerate release + /// candidates or 'x' wildcards. + /// + /// Note that the ordering established among GCCVersions is based on the + /// preferred version string to use. For example we prefer versions without + /// a hard-coded patch number to those with a hard coded patch number. + /// + /// Currently this doesn't provide any logic for textual suffixes to patches + /// in the way that (for example) Debian's version format does. If that ever + /// becomes necessary, it can be added. + struct GCCVersion { + /// \brief The unparsed text of the version. + std::string Text; + + /// \brief The parsed major, minor, and patch numbers. + int Major, Minor, Patch; + + /// \brief Any textual suffix on the patch number. + std::string PatchSuffix; + + static GCCVersion Parse(StringRef VersionText); + bool operator<(const GCCVersion &RHS) const; + bool operator>(const GCCVersion &RHS) const { return RHS < *this; } + bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); } + bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); } + }; + + + /// \brief This is a class to find a viable GCC installation for Clang to + /// use. + /// + /// This class tries to find a GCC installation on the system, and report + /// information about it. It starts from the host information provided to the + /// Driver, and has logic for fuzzing that where appropriate. + class GCCInstallationDetector { + + bool IsValid; + llvm::Triple GCCTriple; + + // FIXME: These might be better as path objects. + std::string GCCInstallPath; + std::string GCCMultiarchSuffix; + std::string GCCParentLibPath; + + GCCVersion Version; + + public: + GCCInstallationDetector(const Driver &D, const llvm::Triple &TargetTriple, + const ArgList &Args); + + /// \brief Check whether we detected a valid GCC install. + bool isValid() const { return IsValid; } + + /// \brief Get the GCC triple for the detected install. + const llvm::Triple &getTriple() const { return GCCTriple; } + + /// \brief Get the detected GCC installation path. + StringRef getInstallPath() const { return GCCInstallPath; } + + /// \brief Get the detected GCC installation path suffix for multiarch GCCs. + StringRef getMultiarchSuffix() const { return GCCMultiarchSuffix; } + + /// \brief Get the detected GCC parent lib path. + StringRef getParentLibPath() const { return GCCParentLibPath; } + + /// \brief Get the detected GCC version string. + StringRef getVersion() const { return Version.Text; } + + private: + static void CollectLibDirsAndTriples( + const llvm::Triple &TargetTriple, + const llvm::Triple &MultiarchTriple, + SmallVectorImpl<StringRef> &LibDirs, + SmallVectorImpl<StringRef> &TripleAliases, + SmallVectorImpl<StringRef> &MultiarchLibDirs, + SmallVectorImpl<StringRef> &MultiarchTripleAliases); + + void ScanLibDirForGCCTriple(llvm::Triple::ArchType TargetArch, + const std::string &LibDir, + StringRef CandidateTriple, + bool NeedsMultiarchSuffix = false); + }; + + GCCInstallationDetector GCCInstallation; + mutable llvm::DenseMap<unsigned, Tool*> Tools; public: - Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple); + Generic_GCC(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); ~Generic_GCC(); virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, @@ -39,9 +130,37 @@ public: virtual bool IsUnwindTablesDefault() const; virtual const char *GetDefaultRelocationModel() const; virtual const char *GetForcedPicModel() const; + +protected: + /// \name ToolChain Implementation Helper Functions + /// @{ + + /// \brief Check whether the target triple's architecture is 64-bits. + bool isTarget64Bit() const { return getTriple().isArch64Bit(); } + + /// \brief Check whether the target triple's architecture is 32-bits. + bool isTarget32Bit() const { return getTriple().isArch32Bit(); } + + /// @} +}; + +class LLVM_LIBRARY_VISIBILITY Hexagon_TC : public ToolChain { +protected: + mutable llvm::DenseMap<unsigned, Tool*> Tools; + +public: + Hexagon_TC(const Driver &D, const llvm::Triple& Triple); + ~Hexagon_TC(); + + virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, + const ActionList &Inputs) const; + + virtual bool IsUnwindTablesDefault() const; + virtual const char *GetDefaultRelocationModel() const; + virtual const char *GetForcedPicModel() const; }; -/// Darwin - The base Darwin tool chain. + /// Darwin - The base Darwin tool chain. class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain { public: /// The host version. @@ -80,19 +199,20 @@ private: mutable bool TargetIsIPhoneOSSimulator; /// The OS version we are targeting. - mutable unsigned TargetVersion[3]; + mutable VersionTuple TargetVersion; /// The default macosx-version-min of this tool chain; empty until /// initialized. std::string MacosxVersionMin; bool hasARCRuntime() const; + bool hasSubscriptingRuntime() const; private: void AddDeploymentTarget(DerivedArgList &Args) const; public: - Darwin(const HostInfo &Host, const llvm::Triple& Triple); + Darwin(const Driver &D, const llvm::Triple& Triple); ~Darwin(); std::string ComputeEffectiveClangTriple(const ArgList &Args, @@ -111,17 +231,14 @@ public: // change. This will go away when we move away from argument translation. if (TargetInitialized && TargetIsIPhoneOS == IsIPhoneOS && TargetIsIPhoneOSSimulator == IsIOSSim && - TargetVersion[0] == Major && TargetVersion[1] == Minor && - TargetVersion[2] == Micro) + TargetVersion == VersionTuple(Major, Minor, Micro)) return; assert(!TargetInitialized && "Target already initialized!"); TargetInitialized = true; TargetIsIPhoneOS = IsIPhoneOS; TargetIsIPhoneOSSimulator = IsIOSSim; - TargetVersion[0] = Major; - TargetVersion[1] = Minor; - TargetVersion[2] = Micro; + TargetVersion = VersionTuple(Major, Minor, Micro); } bool isTargetIPhoneOS() const { @@ -134,13 +251,17 @@ public: return TargetIsIPhoneOSSimulator; } + bool isTargetMacOS() const { + return !isTargetIOSSimulator() && + !isTargetIPhoneOS() && + ARCRuntimeForSimulator == ARCSimulator_None; + } + bool isTargetInitialized() const { return TargetInitialized; } - void getTargetVersion(unsigned (&Res)[3]) const { + VersionTuple getTargetVersion() const { assert(TargetInitialized && "Target not initialized!"); - Res[0] = TargetVersion[0]; - Res[1] = TargetVersion[1]; - Res[2] = TargetVersion[2]; + return TargetVersion; } /// getDarwinArchName - Get the "Darwin" arch name for a particular compiler @@ -148,24 +269,14 @@ public: /// distinct architectures. StringRef getDarwinArchName(const ArgList &Args) const; - static bool isVersionLT(unsigned (&A)[3], unsigned (&B)[3]) { - for (unsigned i=0; i < 3; ++i) { - if (A[i] > B[i]) return false; - if (A[i] < B[i]) return true; - } - return false; - } - bool isIPhoneOSVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const { assert(isTargetIPhoneOS() && "Unexpected call for OS X target!"); - unsigned B[3] = { V0, V1, V2 }; - return isVersionLT(TargetVersion, B); + return TargetVersion < VersionTuple(V0, V1, V2); } bool isMacosxVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const { assert(!isTargetIPhoneOS() && "Unexpected call for iPhoneOS target!"); - unsigned B[3] = { V0, V1, V2 }; - return isVersionLT(TargetVersion, B); + return TargetVersion < VersionTuple(V0, V1, V2); } /// AddLinkSearchPathArgs - Add the linker search paths to \arg CmdArgs. @@ -211,9 +322,8 @@ public: #ifdef DISABLE_DEFAULT_INTEGRATED_ASSEMBLER return false; #else - // Default integrated assembler to on for x86. - return (getTriple().getArch() == llvm::Triple::x86 || - getTriple().getArch() == llvm::Triple::x86_64); + // Default integrated assembler to on for Darwin. + return true; #endif } virtual bool IsStrictAliasingDefault() const { @@ -225,7 +335,7 @@ public: } virtual bool IsObjCDefaultSynthPropertiesDefault() const { - return false; + return true; } virtual bool IsObjCNonFragileABIDefault() const { @@ -248,10 +358,13 @@ public: virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const { // Stack protectors default to on for user code on 10.5, // and for everything in 10.6 and beyond - return !isTargetIPhoneOS() && + return isTargetIPhoneOS() || (!isMacosxVersionLT(10, 6) || (!isMacosxVersionLT(10, 5) && !KernelOrKext)); } + virtual RuntimeLibType GetDefaultRuntimeLibType() const { + return ToolChain::RLT_CompilerRT; + } virtual const char *GetDefaultRelocationModel() const; virtual const char *GetForcedPicModel() const; @@ -259,6 +372,8 @@ public: virtual bool SupportsObjCGC() const; + virtual bool SupportsObjCARC() const; + virtual bool UseDwarfDebugFlags() const; virtual bool UseSjLjExceptions() const; @@ -272,7 +387,7 @@ private: void AddGCCLibexecPath(unsigned darwinVersion); public: - DarwinClang(const HostInfo &Host, const llvm::Triple& Triple); + DarwinClang(const Driver &D, const llvm::Triple& Triple); /// @name Darwin ToolChain Implementation /// { @@ -299,8 +414,8 @@ public: /// Darwin_Generic_GCC - Generic Darwin tool chain using gcc. class LLVM_LIBRARY_VISIBILITY Darwin_Generic_GCC : public Generic_GCC { public: - Darwin_Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple) - : Generic_GCC(Host, Triple) {} + Darwin_Generic_GCC(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) + : Generic_GCC(D, Triple, Args) {} std::string ComputeEffectiveClangTriple(const ArgList &Args, types::ID InputType) const; @@ -309,9 +424,10 @@ public: }; class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC { - public: - Generic_ELF(const HostInfo &Host, const llvm::Triple& Triple) - : Generic_GCC(Host, Triple) {} + virtual void anchor(); +public: + Generic_ELF(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) + : Generic_GCC(D, Triple, Args) {} virtual bool IsIntegratedAssemblerDefault() const { // Default integrated assembler to on for x86. @@ -322,15 +438,36 @@ class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC { class LLVM_LIBRARY_VISIBILITY AuroraUX : public Generic_GCC { public: - AuroraUX(const HostInfo &Host, const llvm::Triple& Triple); + AuroraUX(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); + + virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, + const ActionList &Inputs) const; +}; + +class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_GCC { +public: + Solaris(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, const ActionList &Inputs) const; + + virtual bool IsIntegratedAssemblerDefault() const { return true; } }; + class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic_ELF { public: - OpenBSD(const HostInfo &Host, const llvm::Triple& Triple); + OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); + + virtual bool IsObjCNonFragileABIDefault() const { return true; } + virtual bool IsObjCLegacyDispatchDefault() const { + llvm::Triple::ArchType Arch = getTriple().getArch(); + if (Arch == llvm::Triple::arm || + Arch == llvm::Triple::x86 || + Arch == llvm::Triple::x86_64) + return false; + return true; + } virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, const ActionList &Inputs) const; @@ -338,26 +475,43 @@ public: class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF { public: - FreeBSD(const HostInfo &Host, const llvm::Triple& Triple); + FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); + + virtual bool IsObjCNonFragileABIDefault() const { return true; } + virtual bool IsObjCLegacyDispatchDefault() const { + llvm::Triple::ArchType Arch = getTriple().getArch(); + if (Arch == llvm::Triple::arm || + Arch == llvm::Triple::x86 || + Arch == llvm::Triple::x86_64) + return false; + return true; + } virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, const ActionList &Inputs) const; }; class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF { - const llvm::Triple ToolTriple; - public: - NetBSD(const HostInfo &Host, const llvm::Triple& Triple, - const llvm::Triple& ToolTriple); + NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); + + virtual bool IsObjCNonFragileABIDefault() const { return true; } + virtual bool IsObjCLegacyDispatchDefault() const { + llvm::Triple::ArchType Arch = getTriple().getArch(); + if (Arch == llvm::Triple::arm || + Arch == llvm::Triple::x86 || + Arch == llvm::Triple::x86_64) + return false; + return true; + } virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, const ActionList &Inputs) const; }; -class LLVM_LIBRARY_VISIBILITY Minix : public Generic_GCC { +class LLVM_LIBRARY_VISIBILITY Minix : public Generic_ELF { public: - Minix(const HostInfo &Host, const llvm::Triple& Triple); + Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, const ActionList &Inputs) const; @@ -365,95 +519,15 @@ public: class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_ELF { public: - DragonFly(const HostInfo &Host, const llvm::Triple& Triple); + DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, const ActionList &Inputs) const; }; class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF { - /// \brief Struct to store and manipulate GCC versions. - /// - /// We rely on assumptions about the form and structure of GCC version - /// numbers: they consist of at most three '.'-separated components, and each - /// component is a non-negative integer except for the last component. For - /// the last component we are very flexible in order to tolerate release - /// candidates or 'x' wildcards. - /// - /// Note that the ordering established among GCCVersions is based on the - /// preferred version string to use. For example we prefer versions without - /// a hard-coded patch number to those with a hard coded patch number. - /// - /// Currently this doesn't provide any logic for textual suffixes to patches - /// in the way that (for example) Debian's version format does. If that ever - /// becomes necessary, it can be added. - struct GCCVersion { - /// \brief The unparsed text of the version. - std::string Text; - - /// \brief The parsed major, minor, and patch numbers. - int Major, Minor, Patch; - - /// \brief Any textual suffix on the patch number. - std::string PatchSuffix; - - static GCCVersion Parse(StringRef VersionText); - bool operator<(const GCCVersion &RHS) const; - bool operator>(const GCCVersion &RHS) const { return RHS < *this; } - bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); } - bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); } - }; - - - /// \brief This is a class to find a viable GCC installation for Clang to - /// use. - /// - /// This class tries to find a GCC installation on the system, and report - /// information about it. It starts from the host information provided to the - /// Driver, and has logic for fuzzing that where appropriate. - class GCCInstallationDetector { - - bool IsValid; - std::string GccTriple; - - // FIXME: These might be better as path objects. - std::string GccInstallPath; - std::string GccParentLibPath; - - GCCVersion Version; - - public: - GCCInstallationDetector(const Driver &D); - - /// \brief Check whether we detected a valid GCC install. - bool isValid() const { return IsValid; } - - /// \brief Get the GCC triple for the detected install. - StringRef getTriple() const { return GccTriple; } - - /// \brief Get the detected GCC installation path. - StringRef getInstallPath() const { return GccInstallPath; } - - /// \brief Get the detected GCC parent lib path. - StringRef getParentLibPath() const { return GccParentLibPath; } - - /// \brief Get the detected GCC version string. - StringRef getVersion() const { return Version.Text; } - - private: - static void CollectLibDirsAndTriples(llvm::Triple::ArchType HostArch, - SmallVectorImpl<StringRef> &LibDirs, - SmallVectorImpl<StringRef> &Triples); - - void ScanLibDirForGCCTriple(llvm::Triple::ArchType HostArch, - const std::string &LibDir, - StringRef CandidateTriple); - }; - - GCCInstallationDetector GCCInstallation; - public: - Linux(const HostInfo &Host, const llvm::Triple& Triple); + Linux(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); virtual bool HasNativeLLVMSupport() const; @@ -467,6 +541,11 @@ public: std::string Linker; std::vector<std::string> ExtraOpts; + +private: + static bool addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir, + const ArgList &DriverArgs, + ArgStringList &CC1Args); }; @@ -474,7 +553,7 @@ public: /// all subcommands. See http://tce.cs.tut.fi for our peculiar target. class LLVM_LIBRARY_VISIBILITY TCEToolChain : public ToolChain { public: - TCEToolChain(const HostInfo &Host, const llvm::Triple& Triple); + TCEToolChain(const Driver &D, const llvm::Triple& Triple); ~TCEToolChain(); virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, @@ -493,7 +572,7 @@ class LLVM_LIBRARY_VISIBILITY Windows : public ToolChain { mutable llvm::DenseMap<unsigned, Tool*> Tools; public: - Windows(const HostInfo &Host, const llvm::Triple& Triple); + Windows(const Driver &D, const llvm::Triple& Triple); virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, const ActionList &Inputs) const; |