diff options
Diffstat (limited to 'clang/lib/Driver/Driver.cpp')
-rw-r--r-- | clang/lib/Driver/Driver.cpp | 172 |
1 files changed, 119 insertions, 53 deletions
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index f44fe279b02..69dba47be26 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -18,7 +18,6 @@ #include "clang/Driver/ArgList.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/DriverDiagnostic.h" -#include "clang/Driver/HostInfo.h" #include "clang/Driver/Job.h" #include "clang/Driver/OptTable.h" #include "clang/Driver/Option.h" @@ -40,6 +39,7 @@ #include "llvm/Support/Program.h" #include "InputInfo.h" +#include "ToolChains.h" #include <map> @@ -91,7 +91,11 @@ Driver::Driver(StringRef ClangExecutable, Driver::~Driver() { delete Opts; - delete Host; + + for (llvm::StringMap<ToolChain *>::iterator I = ToolChains.begin(), + E = ToolChains.end(); + I != E; ++I) + delete I->second; } InputArgList *Driver::ParseArgStrings(ArrayRef<const char *> ArgList) { @@ -236,18 +240,6 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const { return DAL; } -/// \brief Compute target triple from args. -/// -/// This routine provides the logic to compute a target triple from various -/// args passed to the driver and the default triple string. -static llvm::Triple computeTargetTriple(StringRef DefaultTargetTriple, - const ArgList &Args) { - if (const Arg *A = Args.getLastArg(options::OPT_target)) - DefaultTargetTriple = A->getValue(Args); - - return llvm::Triple(llvm::Triple::normalize(DefaultTargetTriple)); -} - Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { llvm::PrettyStackTraceString CrashInfo("Compilation construction"); @@ -329,15 +321,11 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { if (Args->hasArg(options::OPT_nostdlib)) UseStdLib = false; - // Compute the target triple based on the args, and build a Host out of it. - // FIXME: Yes, this makes no sense. HostInfo has little to do with the host. - Host = GetHostInfo(computeTargetTriple(DefaultTargetTriple, *Args)); - // Perform the default argument translations. DerivedArgList *TranslatedArgs = TranslateInputArgs(*Args); // Owned by the host. - const ToolChain &TC = *Host->CreateToolChain(*Args); + const ToolChain &TC = getToolChain(*Args); // The compilation takes ownership of Args. Compilation *C = new Compilation(*this, TC, Args, TranslatedArgs); @@ -1328,9 +1316,8 @@ void Driver::BuildJobsForAction(Compilation &C, if (const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) { const ToolChain *TC = &C.getDefaultToolChain(); - std::string Arch; if (BAA->getArchName()) - TC = Host->CreateToolChain(C.getArgs(), BAA->getArchName()); + TC = &getToolChain(C.getArgs(), BAA->getArchName()); BuildJobsForAction(C, *BAA->begin(), TC, BAA->getArchName(), AtTopLevel, LinkingOutput, Result); @@ -1584,39 +1571,118 @@ std::string Driver::GetTemporaryPath(StringRef Prefix, const char *Suffix) return P.str(); } -const HostInfo *Driver::GetHostInfo(const llvm::Triple &Triple) const { - llvm::PrettyStackTraceString CrashInfo("Constructing host"); - - // TCE is an osless target - if (Triple.getArchName() == "tce") - return createTCEHostInfo(*this, Triple); - - switch (Triple.getOS()) { - case llvm::Triple::AuroraUX: - return createAuroraUXHostInfo(*this, Triple); - case llvm::Triple::Darwin: - case llvm::Triple::MacOSX: - case llvm::Triple::IOS: - return createDarwinHostInfo(*this, Triple); - case llvm::Triple::DragonFly: - return createDragonFlyHostInfo(*this, Triple); - case llvm::Triple::OpenBSD: - return createOpenBSDHostInfo(*this, Triple); - case llvm::Triple::NetBSD: - return createNetBSDHostInfo(*this, Triple); - case llvm::Triple::FreeBSD: - return createFreeBSDHostInfo(*this, Triple); - case llvm::Triple::Minix: - return createMinixHostInfo(*this, Triple); - case llvm::Triple::Linux: - return createLinuxHostInfo(*this, Triple); - case llvm::Triple::Win32: - return createWindowsHostInfo(*this, Triple); - case llvm::Triple::MinGW32: - return createMinGWHostInfo(*this, Triple); - default: - return createUnknownHostInfo(*this, Triple); +/// \brief Compute target triple from args. +/// +/// This routine provides the logic to compute a target triple from various +/// args passed to the driver and the default triple string. +static llvm::Triple computeTargetTriple(StringRef DefaultTargetTriple, + const ArgList &Args, + StringRef DarwinArchName) { + if (const Arg *A = Args.getLastArg(options::OPT_target)) + DefaultTargetTriple = A->getValue(Args); + + llvm::Triple Target(llvm::Triple::normalize(DefaultTargetTriple)); + + // Handle Darwin-specific options available here. + if (Target.isOSDarwin()) { + // If an explict Darwin arch name is given, that trumps all. + if (!DarwinArchName.empty()) { + Target.setArch( + llvm::Triple::getArchTypeForDarwinArchName(DarwinArchName)); + return Target; + } + + // Handle the Darwin '-arch' flag. + if (Arg *A = Args.getLastArg(options::OPT_arch)) { + llvm::Triple::ArchType DarwinArch + = llvm::Triple::getArchTypeForDarwinArchName(A->getValue(Args)); + if (DarwinArch != llvm::Triple::UnknownArch) + Target.setArch(DarwinArch); + } + } + + // Skip further flag support on OSes which don't support '-m32' or '-m64'. + if (Target.getArchName() == "tce" || + Target.getOS() == llvm::Triple::AuroraUX || + Target.getOS() == llvm::Triple::Minix) + return Target; + + // Handle pseudo-target flags '-m32' and '-m64'. + // 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 (Target.getArch() == llvm::Triple::x86_64) + Target.setArch(llvm::Triple::x86); + if (Target.getArch() == llvm::Triple::ppc64) + Target.setArch(llvm::Triple::ppc); + } else { + if (Target.getArch() == llvm::Triple::x86) + Target.setArch(llvm::Triple::x86_64); + if (Target.getArch() == llvm::Triple::ppc) + Target.setArch(llvm::Triple::ppc64); + } + } + + return Target; +} + +const ToolChain &Driver::getToolChain(const ArgList &Args, + StringRef DarwinArchName) const { + llvm::Triple Target = computeTargetTriple(DefaultTargetTriple, Args, + DarwinArchName); + + ToolChain *&TC = ToolChains[Target.str()]; + if (!TC) { + switch (Target.getOS()) { + case llvm::Triple::AuroraUX: + TC = new toolchains::AuroraUX(*this, Target); + break; + case llvm::Triple::Darwin: + case llvm::Triple::MacOSX: + case llvm::Triple::IOS: + if (Target.getArch() == llvm::Triple::x86 || + Target.getArch() == llvm::Triple::x86_64 || + Target.getArch() == llvm::Triple::arm || + Target.getArch() == llvm::Triple::thumb) + TC = new toolchains::DarwinClang(*this, Target); + else + TC = new toolchains::Darwin_Generic_GCC(*this, Target); + break; + case llvm::Triple::DragonFly: + TC = new toolchains::DragonFly(*this, Target); + break; + case llvm::Triple::OpenBSD: + TC = new toolchains::OpenBSD(*this, Target); + break; + case llvm::Triple::NetBSD: + TC = new toolchains::NetBSD(*this, Target, Target); + break; + case llvm::Triple::FreeBSD: + TC = new toolchains::FreeBSD(*this, Target); + break; + case llvm::Triple::Minix: + TC = new toolchains::Minix(*this, Target); + break; + case llvm::Triple::Linux: + TC = new toolchains::Linux(*this, Target); + break; + case llvm::Triple::Win32: + TC = new toolchains::Windows(*this, Target); + break; + case llvm::Triple::MinGW32: + // FIXME: We need a MinGW toolchain. Fallthrough for now. + default: + // TCE is an OSless target + if (Target.getArchName() == "tce") { + TC = new toolchains::TCEToolChain(*this, Target); + break; + } + + TC = new toolchains::Generic_GCC(*this, Target); + break; + } } + return *TC; } bool Driver::ShouldUseClangCompiler(const Compilation &C, const JobAction &JA, |