diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp | 731 |
1 files changed, 731 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..292678b --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Driver/HostInfo.cpp @@ -0,0 +1,731 @@ +//===--- 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 { + /// 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 ToolChain *CreateToolChain(const ArgList &Args, + const char *ArchName) const; +}; + +DarwinHostInfo::DarwinHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) { +} + +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. + if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64 || + Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) { + TC = new toolchains::DarwinClang(*this, TCTriple); + } 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 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 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 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 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 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 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 { + 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::FreeBSD(*this, TCTriple); + } + + return TC; +} + +// NetBSD Host Info + +/// NetBSDHostInfo - NetBSD host information implementation. +class NetBSDHostInfo : public HostInfo { + /// Cache of tool chains we have created. + mutable llvm::StringMap<ToolChain*> ToolChains; + +public: + NetBSDHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) {} + ~NetBSDHostInfo(); + + virtual bool useDriverDriver() const; + + virtual ToolChain *CreateToolChain(const ArgList &Args, + const char *ArchName) const; +}; + +NetBSDHostInfo::~NetBSDHostInfo() { + for (llvm::StringMap<ToolChain*>::iterator + it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it) + delete it->second; +} + +bool NetBSDHostInfo::useDriverDriver() const { + return false; +} + +ToolChain *NetBSDHostInfo::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"; + } + } + llvm::Triple TargetTriple(getTriple()); + TargetTriple.setArchName(ArchName); + + ToolChain *TC; + + // XXX Cache toolchain even if -m32 is used + if (Arch == ArchName) { + TC = ToolChains[ArchName]; + if (TC) + return TC; + } + + TC = new toolchains::NetBSD(*this, TargetTriple, getTriple()); + + return TC; +} + +// Minix Host Info + +/// MinixHostInfo - Minix host information implementation. +class MinixHostInfo : public HostInfo { + /// Cache of tool chains we have created. + mutable llvm::StringMap<ToolChain*> ToolChains; + +public: + MinixHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) {} + ~MinixHostInfo(); + + virtual bool useDriverDriver() const; + + virtual ToolChain *CreateToolChain(const ArgList &Args, + const char *ArchName) const; +}; + +MinixHostInfo::~MinixHostInfo() { + for (llvm::StringMap<ToolChain*>::iterator + it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it){ + delete it->second; + } +} + +bool MinixHostInfo::useDriverDriver() const { + return false; +} + +ToolChain *MinixHostInfo::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::Minix(*this, TCTriple); + } + + 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 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 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; +} + +// Windows Host Info + +/// WindowsHostInfo - Host information to use on Microsoft Windows. +class WindowsHostInfo : public HostInfo { + /// Cache of tool chains we have created. + mutable llvm::StringMap<ToolChain*> ToolChains; + +public: + WindowsHostInfo(const Driver &D, const llvm::Triple& Triple); + ~WindowsHostInfo(); + + 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; +}; + +WindowsHostInfo::WindowsHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) { +} + +WindowsHostInfo::~WindowsHostInfo() { + for (llvm::StringMap<ToolChain*>::iterator + it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it) + delete it->second; +} + +bool WindowsHostInfo::useDriverDriver() const { + return false; +} + +ToolChain *WindowsHostInfo::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"; + } + } + + ToolChain *&TC = ToolChains[ArchName]; + if (!TC) { + llvm::Triple TCTriple(getTriple()); + TCTriple.setArchName(ArchName); + + TC = new toolchains::Windows(*this, TCTriple); + } + + return TC; +} + +// FIXME: This is a placeholder. +class MinGWHostInfo : public UnknownHostInfo { +public: + MinGWHostInfo(const Driver &D, const llvm::Triple& Triple); +}; + +MinGWHostInfo::MinGWHostInfo(const Driver &D, const llvm::Triple& Triple) + : UnknownHostInfo(D, Triple) {} + +} // end anon namespace + +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::createNetBSDHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new NetBSDHostInfo(D, Triple); +} + +const HostInfo * +clang::driver::createMinixHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new MinixHostInfo(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::createWindowsHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new WindowsHostInfo(D, Triple); +} + +const HostInfo * +clang::driver::createMinGWHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new MinGWHostInfo(D, Triple); +} + +const HostInfo * +clang::driver::createUnknownHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new UnknownHostInfo(D, Triple); +} |