Driver: Hide HostInfo implementations.
 - Also, normalize arch names a tad and stub out getToolChain
   implementations.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67091 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Driver/HostInfo.cpp b/lib/Driver/HostInfo.cpp
index 3ae0c38..5069bda 100644
--- a/lib/Driver/HostInfo.cpp
+++ b/lib/Driver/HostInfo.cpp
@@ -8,6 +8,16 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Driver/HostInfo.h"
+
+#include "clang/Driver/Arg.h"
+#include "clang/Driver/ArgList.h"
+#include "clang/Driver/Option.h"
+#include "clang/Driver/Options.h"
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Compiler.h"
+
+#include <cassert>
  
 using namespace clang::driver;
 
@@ -21,11 +31,37 @@
 HostInfo::~HostInfo() {
 }
 
+namespace VISIBILITY_HIDDEN {
+
 // Darwin Host Info
 
-DarwinHostInfo::DarwinHostInfo(const char *Arch, const char *Platform,
-                               const char *OS) 
-  : HostInfo(Arch, Platform, OS) {
+/// 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 char *Arch, const char *Platform, const char *OS);
+
+  virtual bool useDriverDriver() const;
+
+  virtual ToolChain *getToolChain(const ArgList &Args, 
+                                  const char *ArchName) const;
+};
+
+DarwinHostInfo::DarwinHostInfo(const char *_Arch, const char *_Platform,
+                               const char *_OS) 
+  : HostInfo(_Arch, _Platform, _OS) {
+  
+  assert((getArchName() == "i386" || getArchName() == "x86_64" || 
+          getArchName() == "ppc" || getArchName() == "ppc64") &&
+         "Unknown Darwin arch.");
 
   // FIXME: How to deal with errors?
   
@@ -41,13 +77,57 @@
 
 ToolChain *DarwinHostInfo::getToolChain(const ArgList &Args, 
                                         const char *ArchName) const {
-  return 0;
+  if (!ArchName) {
+    ArchName = getArchName().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() == "ppc" || getArchName() == "ppc64") {
+        ArchName = 
+          (A->getOption().getId() == options::OPT_m32) ? "ppc" : "ppc64";
+      }
+    } 
+  }
+
+  ToolChain *&TC = ToolChains[ArchName];
+  if (!TC) {
+    TC = 0;
+#if 0
+    if (ArchName == "i386")
+      TC = new Darwin_X86_ToolChain(ArchName);
+    else if (ArchName == "x86_64")
+      TC = new Darwin_X86_ToolChain(ArchName);
+    else
+      TC = new Darwin_GCC_ToolChain(ArchName);
+#endif
+  }
+
+  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 char *Arch, const char *Platform, const char *OS);
+
+  virtual bool useDriverDriver() const;
+
+  virtual ToolChain *getToolChain(const ArgList &Args, 
+                                  const char *ArchName) const;
+};
+
 UnknownHostInfo::UnknownHostInfo(const char *Arch, const char *Platform,
-                               const char *OS) 
+                                 const char *OS) 
   : HostInfo(Arch, Platform, OS) {
 }
 
@@ -57,5 +137,38 @@
 
 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.
+  ArchName = getArchName().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() == "ppc" || getArchName() == "ppc64") {
+      ArchName = 
+        (A->getOption().getId() == options::OPT_m32) ? "ppc" : "ppc64";
+    }
+  } 
+  
+  ToolChain *&TC = ToolChains[ArchName];
+  if (!TC)
+    TC = 0; //new Generic_GCC_ToolChain(ArchName);
+
   return 0;
 }
+
+}
+
+const HostInfo *clang::driver::createDarwinHostInfo(const char *Arch, 
+                                                    const char *Platform, 
+                                                    const char *OS) {
+  return new DarwinHostInfo(Arch, Platform, OS);
+}
+
+const HostInfo *clang::driver::createUnknownHostInfo(const char *Arch, 
+                                                     const char *Platform, 
+                                                     const char *OS) {
+  return new UnknownHostInfo(Arch, Platform, OS);
+}