diff --git a/clang/include/clang/Driver/HostInfo.h b/clang/include/clang/Driver/HostInfo.h index 343809a4330e..fc86d878bb72 100644 --- a/clang/include/clang/Driver/HostInfo.h +++ b/clang/include/clang/Driver/HostInfo.h @@ -11,6 +11,7 @@ #define CLANG_DRIVER_HOSTINFO_H_ #include "clang/Driver/Types.h" +#include "llvm/ADT/Triple.h" #include namespace clang { @@ -28,19 +29,20 @@ namespace driver { /// driver may differ from the actual host. class HostInfo { const Driver &TheDriver; - std::string Arch, Platform, OS; + const llvm::Triple Triple; protected: - HostInfo(const Driver &D, const char *Arch, - const char *Platform, const char *OS); + HostInfo(const Driver &D, const llvm::Triple &_Triple); public: virtual ~HostInfo(); const Driver &getDriver() const { return TheDriver; } - const std::string &getArchName() const { return Arch; } - const std::string &getPlatformName() const { return Platform; } - const std::string &getOSName() const { return OS; } + + const llvm::Triple& getTriple() const { return Triple; } + std::string getArchName() const { return Triple.getArchName(); } + std::string getPlatformName() const { return Triple.getVendorName(); } + std::string getOSName() const { return Triple.getOSName(); } /// useDriverDriver - Whether the driver should act as a driver /// driver for this host and support -arch, -Xarch, etc. @@ -65,14 +67,14 @@ public: const char *ArchName=0) const = 0; }; -const HostInfo *createDarwinHostInfo(const Driver &D, const char *Arch, - const char *Platform, const char *OS); -const HostInfo *createFreeBSDHostInfo(const Driver &D, const char *Arch, - const char *Platform, const char *OS); -const HostInfo *createDragonFlyHostInfo(const Driver &D, const char *Arch, - const char *Platform, const char *OS); -const HostInfo *createUnknownHostInfo(const Driver &D, const char *Arch, - const char *Platform, const char *OS); +const HostInfo *createDarwinHostInfo(const Driver &D, + const llvm::Triple& Triple); +const HostInfo *createFreeBSDHostInfo(const Driver &D, + const llvm::Triple& Triple); +const HostInfo *createDragonFlyHostInfo(const Driver &D, + const llvm::Triple& Triple); +const HostInfo *createUnknownHostInfo(const Driver &D, + const llvm::Triple& Triple); } // end namespace driver } // end namespace clang diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index f7d32ffee03e..6196c130266d 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -11,6 +11,7 @@ #define CLANG_DRIVER_TOOLCHAIN_H_ #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Triple.h" #include "llvm/System/Path.h" #include @@ -30,7 +31,7 @@ public: private: const HostInfo &Host; - std::string Arch, Platform, OS; + const llvm::Triple Triple; /// The list of toolchain specific path prefixes to search for /// files. @@ -41,8 +42,7 @@ private: path_list ProgramPaths; protected: - ToolChain(const HostInfo &Host, const char *_Arch, const char *_Platform, - const char *_OS); + ToolChain(const HostInfo &Host, const llvm::Triple &_Triple); public: virtual ~ToolChain(); @@ -50,12 +50,12 @@ public: // Accessors const HostInfo &getHost() const { return Host; } - const std::string &getArchName() const { return Arch; } - const std::string &getPlatform() const { return Platform; } - const std::string &getOS() const { return OS; } + std::string getArchName() const { return Triple.getArchName(); } + std::string getPlatform() const { return Triple.getVendorName(); } + std::string getOS() const { return Triple.getOSName(); } - const std::string getTripleString() const { - return getArchName() + "-" + getPlatform() + "-" + getOS(); + std::string getTripleString() const { + return Triple.getTriple(); } path_list &getFilePaths() { return FilePaths; } diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 3be083eb7eb2..76dc46cfa875 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -917,8 +917,11 @@ void Driver::BuildJobsForAction(Compilation &C, if (const BindArchAction *BAA = dyn_cast(A)) { const char *ArchName = BAA->getArchName(); - if (!ArchName) - ArchName = C.getDefaultToolChain().getArchName().c_str(); + std::string Arch; + if (!ArchName) { + Arch = C.getDefaultToolChain().getArchName(); + ArchName = Arch.c_str(); + } BuildJobsForAction(C, *BAA->begin(), Host->getToolChain(C.getArgs(), ArchName), @@ -1133,48 +1136,34 @@ std::string Driver::GetTemporaryPath(const char *Suffix) const { return P.toString(); } -const HostInfo *Driver::GetHostInfo(const char *Triple) const { +const HostInfo *Driver::GetHostInfo(const char *TripleStr) const { llvm::PrettyStackTraceString CrashInfo("Constructing host"); - // Dice into arch, platform, and OS. This matches - // arch,platform,os = '(.*?)-(.*?)-(.*?)' - // and missing fields are left empty. - std::string Arch, Platform, OS; - - if (const char *ArchEnd = strchr(Triple, '-')) { - Arch = std::string(Triple, ArchEnd); - - if (const char *PlatformEnd = strchr(ArchEnd+1, '-')) { - Platform = std::string(ArchEnd+1, PlatformEnd); - OS = PlatformEnd+1; - } else - Platform = ArchEnd+1; - } else - Arch = Triple; + llvm::Triple Triple(TripleStr); // Normalize Arch a bit. // - // FIXME: This is very incomplete. - if (Arch == "i686") - Arch = "i386"; - else if (Arch == "amd64") - Arch = "x86_64"; - else if (Arch == "ppc" || Arch == "Power Macintosh") - Arch = "powerpc"; - else if (Arch == "ppc64") - Arch = "powerpc64"; - - if (memcmp(&OS[0], "darwin", 6) == 0) - return createDarwinHostInfo(*this, Arch.c_str(), Platform.c_str(), - OS.c_str()); - if (memcmp(&OS[0], "freebsd", 7) == 0) - return createFreeBSDHostInfo(*this, Arch.c_str(), Platform.c_str(), - OS.c_str()); - if (memcmp(&OS[0], "dragonfly", 9) == 0) - return createDragonFlyHostInfo(*this, Arch.c_str(), Platform.c_str(), - OS.c_str()); + // FIXME: We shouldn't need to do this once everything goes through the triple + // interface. + if (Triple.getArchName() == "i686") + Triple.setArchName("i386"); + else if (Triple.getArchName() == "amd64") + Triple.setArchName("x86_64"); + else if (Triple.getArchName() == "ppc" || + Triple.getArchName() == "Power Macintosh") + Triple.setArchName("powerpc"); + else if (Triple.getArchName() == "ppc64") + Triple.setArchName("powerpc64"); - return createUnknownHostInfo(*this, Arch.c_str(), Platform.c_str(), - OS.c_str()); + switch (Triple.getOS()) { + case llvm::Triple::Darwin: + return createDarwinHostInfo(*this, Triple); + case llvm::Triple::DragonFly: + return createDragonFlyHostInfo(*this, Triple); + case llvm::Triple::FreeBSD: + return createFreeBSDHostInfo(*this, Triple); + default: + return createUnknownHostInfo(*this, Triple); + } } bool Driver::ShouldUseClangCompiler(const Compilation &C, const JobAction &JA, diff --git a/clang/lib/Driver/HostInfo.cpp b/clang/lib/Driver/HostInfo.cpp index 1bee69fd5812..fc6b87f5c6f7 100644 --- a/clang/lib/Driver/HostInfo.cpp +++ b/clang/lib/Driver/HostInfo.cpp @@ -25,9 +25,8 @@ using namespace clang::driver; -HostInfo::HostInfo(const Driver &D, const char *_Arch, const char *_Platform, - const char *_OS) - : TheDriver(D), Arch(_Arch), Platform(_Platform), OS(_OS) +HostInfo::HostInfo(const Driver &D, const llvm::Triple &_Triple) + : TheDriver(D), Triple(_Triple) { } @@ -51,8 +50,7 @@ class DarwinHostInfo : public HostInfo { mutable llvm::StringMap ToolChains; public: - DarwinHostInfo(const Driver &D, const char *Arch, - const char *Platform, const char *OS); + DarwinHostInfo(const Driver &D, const llvm::Triple &Triple); ~DarwinHostInfo(); virtual bool useDriverDriver() const; @@ -72,9 +70,8 @@ public: const char *ArchName) const; }; -DarwinHostInfo::DarwinHostInfo(const Driver &D, const char *_Arch, - const char *_Platform, const char *_OS) - : HostInfo(D, _Arch, _Platform, _OS) { +DarwinHostInfo::DarwinHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) { assert((getArchName() == "i386" || getArchName() == "x86_64" || getArchName() == "powerpc" || getArchName() == "powerpc64") && @@ -108,8 +105,10 @@ bool DarwinHostInfo::useDriverDriver() const { ToolChain *DarwinHostInfo::getToolChain(const ArgList &Args, const char *ArchName) const { + std::string Arch; if (!ArchName) { - ArchName = getArchName().c_str(); + Arch = getArchName(); + ArchName = Arch.c_str(); // If no arch name is specified, infer it from the host and // -m32/-m64. @@ -124,6 +123,9 @@ ToolChain *DarwinHostInfo::getToolChain(const ArgList &Args, } } else { // Normalize arch name; we shouldn't be doing this here. + // + // FIXME: This should be unnecessary once everything moves over to using the + // ID based Triple interface. if (strcmp(ArchName, "ppc") == 0) ArchName = "powerpc"; else if (strcmp(ArchName, "ppc64") == 0) @@ -132,16 +134,15 @@ ToolChain *DarwinHostInfo::getToolChain(const ArgList &Args, ToolChain *&TC = ToolChains[ArchName]; if (!TC) { + llvm::Triple TCTriple(getTriple()); + TCTriple.setArchName(ArchName); + if (strcmp(ArchName, "i386") == 0 || strcmp(ArchName, "x86_64") == 0) - TC = new toolchains::Darwin_X86(*this, ArchName, - getPlatformName().c_str(), - getOSName().c_str(), + TC = new toolchains::Darwin_X86(*this, TCTriple, DarwinVersion, GCCVersion); else - TC = new toolchains::Darwin_GCC(*this, ArchName, - getPlatformName().c_str(), - getOSName().c_str()); + TC = new toolchains::Darwin_GCC(*this, TCTriple); } return TC; @@ -156,8 +157,7 @@ class UnknownHostInfo : public HostInfo { mutable llvm::StringMap ToolChains; public: - UnknownHostInfo(const Driver &D, const char *Arch, - const char *Platform, const char *OS); + UnknownHostInfo(const Driver &D, const llvm::Triple& Triple); ~UnknownHostInfo(); virtual bool useDriverDriver() const; @@ -170,9 +170,8 @@ public: const char *ArchName) const; }; -UnknownHostInfo::UnknownHostInfo(const Driver &D, const char *Arch, - const char *Platform, const char *OS) - : HostInfo(D, Arch, Platform, OS) { +UnknownHostInfo::UnknownHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) { } UnknownHostInfo::~UnknownHostInfo() { @@ -191,7 +190,8 @@ ToolChain *UnknownHostInfo::getToolChain(const ArgList &Args, "Unexpected arch name on platform without driver driver support."); // Automatically handle some instances of -m32/-m64 we know about. - ArchName = getArchName().c_str(); + std::string Arch = getArchName(); + ArchName = Arch.c_str(); if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) { if (getArchName() == "i386" || getArchName() == "x86_64") { ArchName = @@ -203,10 +203,12 @@ ToolChain *UnknownHostInfo::getToolChain(const ArgList &Args, } ToolChain *&TC = ToolChains[ArchName]; - if (!TC) - TC = new toolchains::Generic_GCC(*this, ArchName, - getPlatformName().c_str(), - getOSName().c_str()); + if (!TC) { + llvm::Triple TCTriple(getTriple()); + TCTriple.setArchName(ArchName); + + TC = new toolchains::Generic_GCC(*this, TCTriple); + } return TC; } @@ -219,8 +221,8 @@ class FreeBSDHostInfo : public HostInfo { mutable llvm::StringMap ToolChains; public: - FreeBSDHostInfo(const Driver &D, const char *Arch, - const char *Platform, const char *OS); + FreeBSDHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) {} ~FreeBSDHostInfo(); virtual bool useDriverDriver() const; @@ -233,11 +235,6 @@ public: const char *ArchName) const; }; -FreeBSDHostInfo::FreeBSDHostInfo(const Driver &D, const char *Arch, - const char *Platform, const char *OS) - : HostInfo(D, Arch, Platform, OS) { -} - FreeBSDHostInfo::~FreeBSDHostInfo() { for (llvm::StringMap::iterator it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it) @@ -258,17 +255,20 @@ ToolChain *FreeBSDHostInfo::getToolChain(const ArgList &Args, // On x86_64 we need to be able to compile 32-bits binaries as well. // Compiling 64-bit binaries on i386 is not supported. We don't have a // lib64. - ArchName = getArchName().c_str(); + std::string Arch = getArchName(); + ArchName = Arch.c_str(); if (Args.hasArg(options::OPT_m32) && getArchName() == "x86_64") { ArchName = "i386"; Lib32 = true; } ToolChain *&TC = ToolChains[ArchName]; - if (!TC) - TC = new toolchains::FreeBSD(*this, ArchName, - getPlatformName().c_str(), - getOSName().c_str(), Lib32); + if (!TC) { + llvm::Triple TCTriple(getTriple()); + TCTriple.setArchName(ArchName); + + TC = new toolchains::FreeBSD(*this, TCTriple, Lib32); + } return TC; } @@ -281,8 +281,8 @@ class DragonFlyHostInfo : public HostInfo { mutable llvm::StringMap ToolChains; public: - DragonFlyHostInfo(const Driver &D, const char *Arch, - const char *Platform, const char *OS); + DragonFlyHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) {} ~DragonFlyHostInfo(); virtual bool useDriverDriver() const; @@ -295,11 +295,6 @@ public: const char *ArchName) const; }; -DragonFlyHostInfo::DragonFlyHostInfo(const Driver &D, const char *Arch, - const char *Platform, const char *OS) - : HostInfo(D, Arch, Platform, OS) { -} - DragonFlyHostInfo::~DragonFlyHostInfo() { for (llvm::StringMap::iterator it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it) @@ -311,50 +306,44 @@ bool DragonFlyHostInfo::useDriverDriver() const { } ToolChain *DragonFlyHostInfo::getToolChain(const ArgList &Args, - const char *ArchName) const { - + const char *ArchName) const { assert(!ArchName && "Unexpected arch name on platform without driver driver support."); + ToolChain *&TC = ToolChains[getArchName()]; - ArchName = getArchName().c_str(); - - ToolChain *&TC = ToolChains[ArchName]; + if (!TC) { + llvm::Triple TCTriple(getTriple()); + TCTriple.setArchName(getArchName()); + TC = new toolchains::DragonFly(*this, TCTriple); + } - if (!TC) - TC = new toolchains::DragonFly(*this, ArchName, - getPlatformName().c_str(), - getOSName().c_str()); return TC; } } -const HostInfo *clang::driver::createDarwinHostInfo(const Driver &D, - const char *Arch, - const char *Platform, - const char *OS) { - return new DarwinHostInfo(D, Arch, Platform, OS); +const HostInfo * +clang::driver::createDarwinHostInfo(const Driver &D, + const llvm::Triple& Triple){ + return new DarwinHostInfo(D, Triple); } -const HostInfo *clang::driver::createFreeBSDHostInfo(const Driver &D, - const char *Arch, - const char *Platform, - const char *OS) { - return new FreeBSDHostInfo(D, Arch, Platform, OS); +const HostInfo * +clang::driver::createFreeBSDHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new FreeBSDHostInfo(D, Triple); } -const HostInfo *clang::driver::createDragonFlyHostInfo(const Driver &D, - const char *Arch, - const char *Platform, - const char *OS) { - return new DragonFlyHostInfo(D, Arch, Platform, OS); +const HostInfo * +clang::driver::createDragonFlyHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new DragonFlyHostInfo(D, Triple); } -const HostInfo *clang::driver::createUnknownHostInfo(const Driver &D, - const char *Arch, - const char *Platform, - const char *OS) { - return new UnknownHostInfo(D, Arch, Platform, OS); +const HostInfo * +clang::driver::createUnknownHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new UnknownHostInfo(D, Triple); } diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index a7f655020532..20ed31bd6e02 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -15,9 +15,8 @@ using namespace clang::driver; -ToolChain::ToolChain(const HostInfo &_Host, const char *_Arch, - const char *_Platform, const char *_OS) - : Host(_Host), Arch(_Arch), Platform(_Platform), OS(_OS) { +ToolChain::ToolChain(const HostInfo &_Host, const llvm::Triple &_Triple) + : Host(_Host), Triple(_Triple) { } ToolChain::~ToolChain() { diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index 73105355f821..718f6280b353 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -27,11 +27,10 @@ using namespace clang::driver::toolchains; /// Darwin_X86 - Darwin tool chain for i386 and x86_64. -Darwin_X86::Darwin_X86(const HostInfo &Host, const char *Arch, - const char *Platform, const char *OS, +Darwin_X86::Darwin_X86(const HostInfo &Host, const llvm::Triple& Triple, const unsigned (&_DarwinVersion)[3], const unsigned (&_GCCVersion)[3]) - : ToolChain(Host, Arch, Platform, OS) { + : ToolChain(Host, Triple) { DarwinVersion[0] = _DarwinVersion[0]; DarwinVersion[1] = _DarwinVersion[1]; DarwinVersion[2] = _DarwinVersion[2]; @@ -309,9 +308,8 @@ const char *Darwin_X86::GetForcedPicModel() const { /// all subcommands; this relies on gcc translating the majority of /// command line options. -Generic_GCC::Generic_GCC(const HostInfo &Host, const char *Arch, - const char *Platform, const char *OS) - : ToolChain(Host, Arch, Platform, OS) +Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple) + : ToolChain(Host, Triple) { std::string Path(getHost().getDriver().Dir); Path += "/../libexec"; @@ -388,9 +386,8 @@ DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const { /// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. -FreeBSD::FreeBSD(const HostInfo &Host, const char *Arch, - const char *Platform, const char *OS, bool Lib32) - : Generic_GCC(Host, Arch, Platform, OS) { +FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32) + : Generic_GCC(Host, Triple) { if (Lib32) { getFilePaths().push_back(getHost().getDriver().Dir + "/../lib32"); getFilePaths().push_back("/usr/lib32"); @@ -424,9 +421,8 @@ Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const { /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. -DragonFly::DragonFly(const HostInfo &Host, const char *Arch, - const char *Platform, const char *OS) - : Generic_GCC(Host, Arch, Platform, OS) { +DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple) + : Generic_GCC(Host, Triple) { // Path mangling to find libexec std::string Path(getHost().getDriver().Dir); diff --git a/clang/lib/Driver/ToolChains.h b/clang/lib/Driver/ToolChains.h index baab99bc5ca6..5a5c13bf2e12 100644 --- a/clang/lib/Driver/ToolChains.h +++ b/clang/lib/Driver/ToolChains.h @@ -30,8 +30,7 @@ protected: mutable llvm::DenseMap Tools; public: - Generic_GCC(const HostInfo &Host, const char *Arch, const char *Platform, - const char *OS); + Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple); ~Generic_GCC(); virtual DerivedArgList *TranslateArgs(InputArgList &Args) const; @@ -64,8 +63,8 @@ class VISIBILITY_HIDDEN Darwin_X86 : public ToolChain { const char *getMacosxVersionMin() const; public: - Darwin_X86(const HostInfo &Host, const char *Arch, const char *Platform, - const char *OS, const unsigned (&DarwinVersion)[3], + Darwin_X86(const HostInfo &Host, const llvm::Triple& Triple, + const unsigned (&DarwinVersion)[3], const unsigned (&GCCVersion)[3]); ~Darwin_X86(); @@ -102,24 +101,22 @@ public: /// Darwin_GCC - Generic Darwin tool chain using gcc. class VISIBILITY_HIDDEN Darwin_GCC : public Generic_GCC { public: - Darwin_GCC(const HostInfo &Host, const char *Arch, const char *Platform, - const char *OS) : Generic_GCC(Host, Arch, Platform, OS) {} + Darwin_GCC(const HostInfo &Host, const llvm::Triple& Triple) + : Generic_GCC(Host, Triple) {} virtual const char *GetDefaultRelocationModel() const { return "pic"; } }; class VISIBILITY_HIDDEN FreeBSD : public Generic_GCC { public: - FreeBSD(const HostInfo &Host, const char *Arch, const char *Platform, - const char *OS, bool Lib32); + FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32); virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const; }; class VISIBILITY_HIDDEN DragonFly : public Generic_GCC { public: - DragonFly(const HostInfo &Host, const char *Arch, const char *Platform, - const char *OS); + DragonFly(const HostInfo &Host, const llvm::Triple& Triple); virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const; };