diff options
author | ed <ed@FreeBSD.org> | 2009-06-02 17:58:47 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2009-06-02 17:58:47 +0000 |
commit | f27e5a09a0d815b8a4814152954ff87dadfdefc0 (patch) | |
tree | ce7d964cbb5e39695b71481698f10cb099c23d4a /lib/Driver/HostInfo.cpp | |
download | FreeBSD-src-f27e5a09a0d815b8a4814152954ff87dadfdefc0.zip FreeBSD-src-f27e5a09a0d815b8a4814152954ff87dadfdefc0.tar.gz |
Import Clang, at r72732.
Diffstat (limited to 'lib/Driver/HostInfo.cpp')
-rw-r--r-- | lib/Driver/HostInfo.cpp | 408 |
1 files changed, 408 insertions, 0 deletions
diff --git a/lib/Driver/HostInfo.cpp b/lib/Driver/HostInfo.cpp new file mode 100644 index 0000000..603b3ab --- /dev/null +++ b/lib/Driver/HostInfo.cpp @@ -0,0 +1,408 @@ +//===--- HostInfo.cpp - Host specific information -----------------------*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Driver/HostInfo.h" + +#include "clang/Driver/Arg.h" +#include "clang/Driver/ArgList.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/DriverDiagnostic.h" +#include "clang/Driver/Option.h" +#include "clang/Driver/Options.h" + +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/Compiler.h" + +#include "ToolChains.h" + +#include <cassert> + +using namespace clang::driver; + +HostInfo::HostInfo(const Driver &D, const llvm::Triple &_Triple) + : TheDriver(D), Triple(_Triple) +{ + +} + +HostInfo::~HostInfo() { +} + +namespace { + +// Darwin Host Info + +/// DarwinHostInfo - Darwin host information implementation. +class DarwinHostInfo : public HostInfo { + /// Darwin version of host. + unsigned DarwinVersion[3]; + + /// GCC version to use on this host. + unsigned GCCVersion[3]; + + /// Cache of tool chains we have created. + mutable llvm::StringMap<ToolChain *> ToolChains; + +public: + DarwinHostInfo(const Driver &D, const llvm::Triple &Triple); + ~DarwinHostInfo(); + + virtual bool useDriverDriver() const; + + virtual types::ID lookupTypeForExtension(const char *Ext) const { + types::ID Ty = types::lookupTypeForExtension(Ext); + + // Darwin always preprocesses assembly files (unless -x is used + // explicitly). + if (Ty == types::TY_PP_Asm) + return types::TY_Asm; + + return Ty; + } + + virtual ToolChain *getToolChain(const ArgList &Args, + const char *ArchName) const; +}; + +DarwinHostInfo::DarwinHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) { + + assert((getArchName() == "i386" || getArchName() == "x86_64" || + getArchName() == "powerpc" || getArchName() == "powerpc64" || + getArchName() == "arm") && + "Unknown Darwin arch."); + + assert(memcmp(&getOSName()[0], "darwin", 6) == 0 && + "Unknown Darwin platform."); + bool HadExtra; + if (!Driver::GetReleaseVersion(&getOSName()[6], + DarwinVersion[0], DarwinVersion[1], + DarwinVersion[2], HadExtra)) { + D.Diag(clang::diag::err_drv_invalid_darwin_version) + << getOSName(); + } + + // We can only call 4.2.1 for now. + GCCVersion[0] = 4; + GCCVersion[1] = 2; + GCCVersion[2] = 1; +} + +DarwinHostInfo::~DarwinHostInfo() { + for (llvm::StringMap<ToolChain*>::iterator + it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it) + delete it->second; +} + +bool DarwinHostInfo::useDriverDriver() const { + return true; +} + +ToolChain *DarwinHostInfo::getToolChain(const ArgList &Args, + const char *ArchName) const { + std::string Arch; + if (!ArchName) { + Arch = getArchName(); + ArchName = Arch.c_str(); + + // If no arch name is specified, infer it from the host and + // -m32/-m64. + if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) { + if (getArchName() == "i386" || getArchName() == "x86_64") { + ArchName = + (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64"; + } else if (getArchName() == "powerpc" || getArchName() == "powerpc64") { + ArchName = (A->getOption().getId() == options::OPT_m32) ? "powerpc" : + "powerpc64"; + } + } + } 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) + ArchName = "powerpc64"; + } + + 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, TCTriple, + DarwinVersion, + GCCVersion); + else + TC = new toolchains::Darwin_GCC(*this, TCTriple); + } + + return TC; +} + +// Unknown Host Info + +/// UnknownHostInfo - Generic host information to use for unknown +/// hosts. +class UnknownHostInfo : public HostInfo { + /// Cache of tool chains we have created. + mutable llvm::StringMap<ToolChain*> ToolChains; + +public: + UnknownHostInfo(const Driver &D, const llvm::Triple& Triple); + ~UnknownHostInfo(); + + virtual bool useDriverDriver() const; + + virtual types::ID lookupTypeForExtension(const char *Ext) const { + return types::lookupTypeForExtension(Ext); + } + + virtual ToolChain *getToolChain(const ArgList &Args, + const char *ArchName) const; +}; + +UnknownHostInfo::UnknownHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) { +} + +UnknownHostInfo::~UnknownHostInfo() { + for (llvm::StringMap<ToolChain*>::iterator + it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it) + delete it->second; +} + +bool UnknownHostInfo::useDriverDriver() const { + return false; +} + +ToolChain *UnknownHostInfo::getToolChain(const ArgList &Args, + const char *ArchName) const { + assert(!ArchName && + "Unexpected arch name on platform without driver driver support."); + + // Automatically handle some instances of -m32/-m64 we know about. + 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 = + (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64"; + } else if (getArchName() == "powerpc" || getArchName() == "powerpc64") { + ArchName = + (A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64"; + } + } + + ToolChain *&TC = ToolChains[ArchName]; + if (!TC) { + llvm::Triple TCTriple(getTriple()); + TCTriple.setArchName(ArchName); + + TC = new toolchains::Generic_GCC(*this, TCTriple); + } + + return TC; +} + +// FreeBSD Host Info + +/// FreeBSDHostInfo - FreeBSD host information implementation. +class FreeBSDHostInfo : public HostInfo { + /// Cache of tool chains we have created. + mutable llvm::StringMap<ToolChain*> ToolChains; + +public: + FreeBSDHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) {} + ~FreeBSDHostInfo(); + + virtual bool useDriverDriver() const; + + virtual types::ID lookupTypeForExtension(const char *Ext) const { + return types::lookupTypeForExtension(Ext); + } + + virtual ToolChain *getToolChain(const ArgList &Args, + const char *ArchName) const; +}; + +FreeBSDHostInfo::~FreeBSDHostInfo() { + for (llvm::StringMap<ToolChain*>::iterator + it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it) + delete it->second; +} + +bool FreeBSDHostInfo::useDriverDriver() const { + return false; +} + +ToolChain *FreeBSDHostInfo::getToolChain(const ArgList &Args, + const char *ArchName) const { + bool Lib32 = false; + + assert(!ArchName && + "Unexpected arch name on platform without driver driver support."); + + // 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. + 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) { + llvm::Triple TCTriple(getTriple()); + TCTriple.setArchName(ArchName); + + TC = new toolchains::FreeBSD(*this, TCTriple, Lib32); + } + + return TC; +} + +// DragonFly Host Info + +/// DragonFlyHostInfo - DragonFly host information implementation. +class DragonFlyHostInfo : public HostInfo { + /// Cache of tool chains we have created. + mutable llvm::StringMap<ToolChain*> ToolChains; + +public: + DragonFlyHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) {} + ~DragonFlyHostInfo(); + + virtual bool useDriverDriver() const; + + virtual types::ID lookupTypeForExtension(const char *Ext) const { + return types::lookupTypeForExtension(Ext); + } + + virtual ToolChain *getToolChain(const ArgList &Args, + const char *ArchName) const; +}; + +DragonFlyHostInfo::~DragonFlyHostInfo() { + for (llvm::StringMap<ToolChain*>::iterator + it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it) + delete it->second; +} + +bool DragonFlyHostInfo::useDriverDriver() const { + return false; +} + +ToolChain *DragonFlyHostInfo::getToolChain(const ArgList &Args, + const char *ArchName) const { + assert(!ArchName && + "Unexpected arch name on platform without driver driver support."); + + ToolChain *&TC = ToolChains[getArchName()]; + + if (!TC) { + llvm::Triple TCTriple(getTriple()); + TCTriple.setArchName(getArchName()); + + TC = new toolchains::DragonFly(*this, TCTriple); + } + + return TC; +} + +// Linux Host Info + +/// LinuxHostInfo - Linux host information implementation. +class LinuxHostInfo : public HostInfo { + /// Cache of tool chains we have created. + mutable llvm::StringMap<ToolChain*> ToolChains; + +public: + LinuxHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) {} + ~LinuxHostInfo(); + + virtual bool useDriverDriver() const; + + virtual types::ID lookupTypeForExtension(const char *Ext) const { + return types::lookupTypeForExtension(Ext); + } + + virtual ToolChain *getToolChain(const ArgList &Args, + const char *ArchName) const; +}; + +LinuxHostInfo::~LinuxHostInfo() { + for (llvm::StringMap<ToolChain*>::iterator + it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it) + delete it->second; +} + +bool LinuxHostInfo::useDriverDriver() const { + return false; +} + +ToolChain *LinuxHostInfo::getToolChain(const ArgList &Args, + const char *ArchName) const { + + assert(!ArchName && + "Unexpected arch name on platform without driver driver support."); + + ArchName = getArchName().c_str(); + + ToolChain *&TC = ToolChains[ArchName]; + + if (!TC) { + llvm::Triple TCTriple(getTriple()); + TCTriple.setArchName(getArchName()); + + TC = new toolchains::Linux(*this, TCTriple); + } + + return TC; +} + +} + +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 llvm::Triple& Triple) { + return new FreeBSDHostInfo(D, Triple); +} + +const HostInfo * +clang::driver::createDragonFlyHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new DragonFlyHostInfo(D, Triple); +} + +const HostInfo * +clang::driver::createLinuxHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new LinuxHostInfo(D, Triple); +} + +const HostInfo * +clang::driver::createUnknownHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new UnknownHostInfo(D, Triple); +} |