summaryrefslogtreecommitdiffstats
path: root/clang/lib/Driver/Driver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Driver/Driver.cpp')
-rw-r--r--clang/lib/Driver/Driver.cpp172
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,
OpenPOWER on IntegriCloud