diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp | 590 |
1 files changed, 590 insertions, 0 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp b/contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp new file mode 100644 index 0000000..d9e2e37 --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp @@ -0,0 +1,590 @@ +//===--- 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::DenseMap<unsigned, 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 *CreateToolChain(const ArgList &Args, + const char *ArchName) const; +}; + +DarwinHostInfo::DarwinHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) { + + assert(Triple.getArch() != llvm::Triple::UnknownArch && "Invalid 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::DenseMap<unsigned, ToolChain*>::iterator + it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it) + delete it->second; +} + +bool DarwinHostInfo::useDriverDriver() const { + return true; +} + +ToolChain *DarwinHostInfo::CreateToolChain(const ArgList &Args, + const char *ArchName) const { + llvm::Triple::ArchType Arch; + + if (!ArchName) { + // If we aren't looking for a specific arch, infer the default architecture + // based on -arch and -m32/-m64 command line options. + if (Arg *A = Args.getLastArg(options::OPT_arch)) { + // The gcc driver behavior with multiple -arch flags wasn't consistent for + // things which rely on a default architecture. We just use the last -arch + // to find the default tool chain (assuming it is valid). + Arch = llvm::Triple::getArchTypeForDarwinArchName(A->getValue(Args)); + + // If it was invalid just use the host, we will reject this command line + // later. + if (Arch == llvm::Triple::UnknownArch) + Arch = getTriple().getArch(); + } else { + // Otherwise default to the arch of the host. + Arch = getTriple().getArch(); + } + + // Honor -m32 and -m64 when finding the default tool chain. + // + // FIXME: Should this information be in llvm::Triple? + if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) { + if (A->getOption().matches(options::OPT_m32)) { + if (Arch == llvm::Triple::x86_64) + Arch = llvm::Triple::x86; + if (Arch == llvm::Triple::ppc64) + Arch = llvm::Triple::ppc; + } else { + if (Arch == llvm::Triple::x86) + Arch = llvm::Triple::x86_64; + if (Arch == llvm::Triple::ppc) + Arch = llvm::Triple::ppc64; + } + } + } else + Arch = llvm::Triple::getArchTypeForDarwinArchName(ArchName); + + assert(Arch != llvm::Triple::UnknownArch && "Unexpected arch!"); + ToolChain *&TC = ToolChains[Arch]; + if (!TC) { + llvm::Triple TCTriple(getTriple()); + TCTriple.setArch(Arch); + + // If we recognized the arch, match it to the toolchains we support. + const char *UseNewToolChain = ::getenv("CCC_ENABLE_NEW_DARWIN_TOOLCHAIN"); + if (UseNewToolChain || + Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) { + TC = new toolchains::DarwinClang(*this, TCTriple, DarwinVersion); + } else if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) { + // We still use the legacy DarwinGCC toolchain on X86. + TC = new toolchains::DarwinGCC(*this, TCTriple, DarwinVersion, + GCCVersion); + } else + TC = new toolchains::Darwin_Generic_GCC(*this, TCTriple); + } + + return TC; +} + +// TCE Host Info + +/// TCEHostInfo - TCE host information implementation (see http://tce.cs.tut.fi) +class TCEHostInfo : public HostInfo { + +public: + TCEHostInfo(const Driver &D, const llvm::Triple &Triple); + ~TCEHostInfo() {} + + virtual bool useDriverDriver() const; + + virtual types::ID lookupTypeForExtension(const char *Ext) const { + types::ID Ty = types::lookupTypeForExtension(Ext); + + if (Ty == types::TY_PP_Asm) + return types::TY_Asm; + + return Ty; + } + + virtual ToolChain *CreateToolChain(const ArgList &Args, + const char *ArchName) const; +}; + +TCEHostInfo::TCEHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) { +} + +bool TCEHostInfo::useDriverDriver() const { + return false; +} + +ToolChain *TCEHostInfo::CreateToolChain(const ArgList &Args, + const char *ArchName) const { + llvm::Triple TCTriple(getTriple()); +// TCTriple.setArchName(ArchName); + return new toolchains::TCEToolChain(*this, TCTriple); +} + + +// 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 *CreateToolChain(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::CreateToolChain(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 (Triple.getArch() == llvm::Triple::x86 || + Triple.getArch() == llvm::Triple::x86_64) { + ArchName = + (A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64"; + } else if (Triple.getArch() == llvm::Triple::ppc || + Triple.getArch() == llvm::Triple::ppc64) { + ArchName = + (A->getOption().matches(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; +} + +// OpenBSD Host Info + +/// OpenBSDHostInfo - OpenBSD host information implementation. +class OpenBSDHostInfo : public HostInfo { + /// Cache of tool chains we have created. + mutable llvm::StringMap<ToolChain*> ToolChains; + +public: + OpenBSDHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) {} + ~OpenBSDHostInfo(); + + virtual bool useDriverDriver() const; + + virtual types::ID lookupTypeForExtension(const char *Ext) const { + return types::lookupTypeForExtension(Ext); + } + + virtual ToolChain *CreateToolChain(const ArgList &Args, + const char *ArchName) const; +}; + +OpenBSDHostInfo::~OpenBSDHostInfo() { + for (llvm::StringMap<ToolChain*>::iterator + it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it) + delete it->second; +} + +bool OpenBSDHostInfo::useDriverDriver() const { + return false; +} + +ToolChain *OpenBSDHostInfo::CreateToolChain(const ArgList &Args, + const char *ArchName) const { + assert(!ArchName && + "Unexpected arch name on platform without driver driver support."); + + std::string Arch = getArchName(); + ArchName = Arch.c_str(); + + ToolChain *&TC = ToolChains[ArchName]; + if (!TC) { + llvm::Triple TCTriple(getTriple()); + TCTriple.setArchName(ArchName); + + TC = new toolchains::OpenBSD(*this, TCTriple); + } + + return TC; +} + +// AuroraUX Host Info + +/// AuroraUXHostInfo - AuroraUX host information implementation. +class AuroraUXHostInfo : public HostInfo { + /// Cache of tool chains we have created. + mutable llvm::StringMap<ToolChain*> ToolChains; + +public: + AuroraUXHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) {} + ~AuroraUXHostInfo(); + + virtual bool useDriverDriver() const; + + virtual types::ID lookupTypeForExtension(const char *Ext) const { + return types::lookupTypeForExtension(Ext); + } + + virtual ToolChain *CreateToolChain(const ArgList &Args, + const char *ArchName) const; +}; + +AuroraUXHostInfo::~AuroraUXHostInfo() { + for (llvm::StringMap<ToolChain*>::iterator + it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it) + delete it->second; +} + +bool AuroraUXHostInfo::useDriverDriver() const { + return false; +} + +ToolChain *AuroraUXHostInfo::CreateToolChain(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::AuroraUX(*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 *CreateToolChain(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::CreateToolChain(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 *CreateToolChain(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::CreateToolChain(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 *CreateToolChain(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::CreateToolChain(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 (Triple.getArch() == llvm::Triple::x86 || + Triple.getArch() == llvm::Triple::x86_64) { + ArchName = + (A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64"; + } else if (Triple.getArch() == llvm::Triple::ppc || + Triple.getArch() == llvm::Triple::ppc64) { + ArchName = + (A->getOption().matches(options::OPT_m32)) ? "powerpc" : "powerpc64"; + } + } + + ToolChain *&TC = ToolChains[ArchName]; + + if (!TC) { + llvm::Triple TCTriple(getTriple()); + TCTriple.setArchName(ArchName); + + TC = new toolchains::Linux(*this, TCTriple); + } + + return TC; +} + +} + +const HostInfo * +clang::driver::createAuroraUXHostInfo(const Driver &D, + const llvm::Triple& Triple){ + return new AuroraUXHostInfo(D, Triple); +} + +const HostInfo * +clang::driver::createDarwinHostInfo(const Driver &D, + const llvm::Triple& Triple){ + return new DarwinHostInfo(D, Triple); +} + +const HostInfo * +clang::driver::createOpenBSDHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new OpenBSDHostInfo(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::createTCEHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new TCEHostInfo(D, Triple); +} + +const HostInfo * +clang::driver::createUnknownHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new UnknownHostInfo(D, Triple); +} |