(llvm up) Use llvm::Triple for storing target triples.
 - This commit has some messy stuff in it to extend string lifetimes, but that
   will go away once we switch to using the enum'd Triple interfaces.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72243 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 3be083e..76dc46c 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -917,8 +917,11 @@
 
   if (const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
     const char *ArchName = BAA->getArchName();
-    if (!ArchName)
-      ArchName = C.getDefaultToolChain().getArchName().c_str();
+    std::string Arch;
+    if (!ArchName) {
+      Arch = C.getDefaultToolChain().getArchName();
+      ArchName = Arch.c_str();
+    }
     BuildJobsForAction(C,
                        *BAA->begin(), 
                        Host->getToolChain(C.getArgs(), ArchName),
@@ -1133,48 +1136,34 @@
   return P.toString();
 }
 
-const HostInfo *Driver::GetHostInfo(const char *Triple) const {
+const HostInfo *Driver::GetHostInfo(const char *TripleStr) const {
   llvm::PrettyStackTraceString CrashInfo("Constructing host");
-  // Dice into arch, platform, and OS. This matches 
-  //  arch,platform,os = '(.*?)-(.*?)-(.*?)'
-  // and missing fields are left empty.
-  std::string Arch, Platform, OS;
-
-  if (const char *ArchEnd = strchr(Triple, '-')) {
-    Arch = std::string(Triple, ArchEnd);
-
-    if (const char *PlatformEnd = strchr(ArchEnd+1, '-')) {
-      Platform = std::string(ArchEnd+1, PlatformEnd);
-      OS = PlatformEnd+1;
-    } else
-      Platform = ArchEnd+1;
-  } else
-    Arch = Triple;
+  llvm::Triple Triple(TripleStr);
 
   // Normalize Arch a bit. 
   //
-  // FIXME: This is very incomplete.
-  if (Arch == "i686") 
-    Arch = "i386";
-  else if (Arch == "amd64")
-    Arch = "x86_64";
-  else if (Arch == "ppc" || Arch == "Power Macintosh")
-    Arch = "powerpc";
-  else if (Arch == "ppc64")
-    Arch = "powerpc64";
-  
-  if (memcmp(&OS[0], "darwin", 6) == 0)
-    return createDarwinHostInfo(*this, Arch.c_str(), Platform.c_str(), 
-                                OS.c_str());
-  if (memcmp(&OS[0], "freebsd", 7) == 0)
-    return createFreeBSDHostInfo(*this, Arch.c_str(), Platform.c_str(), 
-                                 OS.c_str());
-  if (memcmp(&OS[0], "dragonfly", 9) == 0)
-    return createDragonFlyHostInfo(*this, Arch.c_str(), Platform.c_str(),
-                                 OS.c_str());    
+  // FIXME: We shouldn't need to do this once everything goes through the triple
+  // interface.
+  if (Triple.getArchName() == "i686") 
+    Triple.setArchName("i386");
+  else if (Triple.getArchName() == "amd64")
+    Triple.setArchName("x86_64");
+  else if (Triple.getArchName() == "ppc" || 
+           Triple.getArchName() == "Power Macintosh")
+    Triple.setArchName("powerpc");
+  else if (Triple.getArchName() == "ppc64")
+    Triple.setArchName("powerpc64");
 
-  return createUnknownHostInfo(*this, Arch.c_str(), Platform.c_str(), 
-                               OS.c_str());
+  switch (Triple.getOS()) {
+  case llvm::Triple::Darwin:
+    return createDarwinHostInfo(*this, Triple);
+  case llvm::Triple::DragonFly:
+    return createDragonFlyHostInfo(*this, Triple);
+  case llvm::Triple::FreeBSD:
+    return createFreeBSDHostInfo(*this, Triple);
+  default:
+    return createUnknownHostInfo(*this, Triple);
+  }
 }
 
 bool Driver::ShouldUseClangCompiler(const Compilation &C, const JobAction &JA,
diff --git a/lib/Driver/HostInfo.cpp b/lib/Driver/HostInfo.cpp
index 1bee69f..fc6b87f 100644
--- a/lib/Driver/HostInfo.cpp
+++ b/lib/Driver/HostInfo.cpp
@@ -25,9 +25,8 @@
  
 using namespace clang::driver;
 
-HostInfo::HostInfo(const Driver &D, const char *_Arch, const char *_Platform,
-                   const char *_OS) 
-  : TheDriver(D), Arch(_Arch), Platform(_Platform), OS(_OS) 
+HostInfo::HostInfo(const Driver &D, const llvm::Triple &_Triple)
+  : TheDriver(D), Triple(_Triple)
 {
   
 }
@@ -51,8 +50,7 @@
   mutable llvm::StringMap<ToolChain *> ToolChains;
 
 public:
-  DarwinHostInfo(const Driver &D, const char *Arch, 
-                 const char *Platform, const char *OS);
+  DarwinHostInfo(const Driver &D, const llvm::Triple &Triple);
   ~DarwinHostInfo();
 
   virtual bool useDriverDriver() const;
@@ -72,9 +70,8 @@
                                   const char *ArchName) const;
 };
 
-DarwinHostInfo::DarwinHostInfo(const Driver &D, const char *_Arch, 
-                               const char *_Platform, const char *_OS) 
-  : HostInfo(D, _Arch, _Platform, _OS) {
+DarwinHostInfo::DarwinHostInfo(const Driver &D, const llvm::Triple& Triple)
+  : HostInfo(D, Triple) {
   
   assert((getArchName() == "i386" || getArchName() == "x86_64" || 
           getArchName() == "powerpc" || getArchName() == "powerpc64") &&
@@ -108,8 +105,10 @@
 
 ToolChain *DarwinHostInfo::getToolChain(const ArgList &Args, 
                                         const char *ArchName) const {
+  std::string Arch;
   if (!ArchName) {
-    ArchName = getArchName().c_str();
+    Arch = getArchName();
+    ArchName = Arch.c_str();
 
     // If no arch name is specified, infer it from the host and
     // -m32/-m64.
@@ -124,6 +123,9 @@
     } 
   } else {
     // Normalize arch name; we shouldn't be doing this here.
+    //
+    // FIXME: This should be unnecessary once everything moves over to using the
+    // ID based Triple interface.
     if (strcmp(ArchName, "ppc") == 0)
       ArchName = "powerpc";
     else if (strcmp(ArchName, "ppc64") == 0)
@@ -132,16 +134,15 @@
 
   ToolChain *&TC = ToolChains[ArchName];
   if (!TC) {
+    llvm::Triple TCTriple(getTriple());
+    TCTriple.setArchName(ArchName);
+                          
     if (strcmp(ArchName, "i386") == 0 || strcmp(ArchName, "x86_64") == 0)
-      TC = new toolchains::Darwin_X86(*this, ArchName, 
-                                      getPlatformName().c_str(), 
-                                      getOSName().c_str(),
+      TC = new toolchains::Darwin_X86(*this, TCTriple,
                                       DarwinVersion,
                                       GCCVersion);
     else
-      TC = new toolchains::Darwin_GCC(*this, ArchName, 
-                                      getPlatformName().c_str(), 
-                                      getOSName().c_str());
+      TC = new toolchains::Darwin_GCC(*this, TCTriple);
   }
 
   return TC;
@@ -156,8 +157,7 @@
   mutable llvm::StringMap<ToolChain*> ToolChains;
 
 public:
-  UnknownHostInfo(const Driver &D, const char *Arch, 
-                  const char *Platform, const char *OS);
+  UnknownHostInfo(const Driver &D, const llvm::Triple& Triple);
   ~UnknownHostInfo();
 
   virtual bool useDriverDriver() const;
@@ -170,9 +170,8 @@
                                   const char *ArchName) const;
 };
 
-UnknownHostInfo::UnknownHostInfo(const Driver &D, const char *Arch, 
-                                 const char *Platform, const char *OS) 
-  : HostInfo(D, Arch, Platform, OS) {
+UnknownHostInfo::UnknownHostInfo(const Driver &D, const llvm::Triple& Triple) 
+  : HostInfo(D, Triple) {
 }
 
 UnknownHostInfo::~UnknownHostInfo() {
@@ -191,7 +190,8 @@
          "Unexpected arch name on platform without driver driver support.");
   
   // Automatically handle some instances of -m32/-m64 we know about.
-  ArchName = getArchName().c_str();
+  std::string Arch = getArchName();
+  ArchName = Arch.c_str();
   if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
     if (getArchName() == "i386" || getArchName() == "x86_64") {
       ArchName = 
@@ -203,10 +203,12 @@
   } 
   
   ToolChain *&TC = ToolChains[ArchName];
-  if (!TC)
-    TC = new toolchains::Generic_GCC(*this, ArchName, 
-                                     getPlatformName().c_str(), 
-                                     getOSName().c_str());
+  if (!TC) {
+    llvm::Triple TCTriple(getTriple());
+    TCTriple.setArchName(ArchName);
+
+    TC = new toolchains::Generic_GCC(*this, TCTriple);
+  }
 
   return TC;
 }
@@ -219,8 +221,8 @@
   mutable llvm::StringMap<ToolChain*> ToolChains;
 
 public:
-  FreeBSDHostInfo(const Driver &D, const char *Arch, 
-                  const char *Platform, const char *OS);
+  FreeBSDHostInfo(const Driver &D, const llvm::Triple& Triple) 
+    : HostInfo(D, Triple) {}
   ~FreeBSDHostInfo();
 
   virtual bool useDriverDriver() const;
@@ -233,11 +235,6 @@
                                   const char *ArchName) const;
 };
 
-FreeBSDHostInfo::FreeBSDHostInfo(const Driver &D, const char *Arch, 
-                                 const char *Platform, const char *OS) 
-  : HostInfo(D, Arch, Platform, OS) {
-}
-
 FreeBSDHostInfo::~FreeBSDHostInfo() {
   for (llvm::StringMap<ToolChain*>::iterator
          it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
@@ -258,17 +255,20 @@
   // 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.
-  ArchName = getArchName().c_str();
+  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)
-    TC = new toolchains::FreeBSD(*this, ArchName, 
-                                 getPlatformName().c_str(), 
-                                 getOSName().c_str(), Lib32);
+  if (!TC) {
+    llvm::Triple TCTriple(getTriple());
+    TCTriple.setArchName(ArchName);
+
+    TC = new toolchains::FreeBSD(*this, TCTriple, Lib32);
+  }
 
   return TC;
 }
@@ -281,8 +281,8 @@
   mutable llvm::StringMap<ToolChain*> ToolChains;
 
 public:
-  DragonFlyHostInfo(const Driver &D, const char *Arch, 
-                  const char *Platform, const char *OS);
+  DragonFlyHostInfo(const Driver &D, const llvm::Triple& Triple)
+    : HostInfo(D, Triple) {}
   ~DragonFlyHostInfo();
 
   virtual bool useDriverDriver() const;
@@ -295,11 +295,6 @@
                                   const char *ArchName) const;
 };
 
-DragonFlyHostInfo::DragonFlyHostInfo(const Driver &D, const char *Arch, 
-                                 const char *Platform, const char *OS) 
-  : HostInfo(D, Arch, Platform, OS) {
-}
-
 DragonFlyHostInfo::~DragonFlyHostInfo() {
   for (llvm::StringMap<ToolChain*>::iterator
          it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
@@ -311,50 +306,44 @@
 }
 
 ToolChain *DragonFlyHostInfo::getToolChain(const ArgList &Args, 
-                                         const char *ArchName) const {
-
+                                           const char *ArchName) const {
   assert(!ArchName && 
          "Unexpected arch name on platform without driver driver support.");
 
+  ToolChain *&TC = ToolChains[getArchName()];
 
-  ArchName = getArchName().c_str();
-  
-  ToolChain *&TC = ToolChains[ArchName];
+  if (!TC) {
+    llvm::Triple TCTriple(getTriple());
+    TCTriple.setArchName(getArchName());
 
+    TC = new toolchains::DragonFly(*this, TCTriple);
+  }
 
-  if (!TC)
-    TC = new toolchains::DragonFly(*this, ArchName, 
-                                 getPlatformName().c_str(), 
-                                 getOSName().c_str());
   return TC;
 }
 
 }
 
-const HostInfo *clang::driver::createDarwinHostInfo(const Driver &D,
-                                                    const char *Arch, 
-                                                    const char *Platform, 
-                                                    const char *OS) {
-  return new DarwinHostInfo(D, Arch, Platform, OS);
+const HostInfo *
+clang::driver::createDarwinHostInfo(const Driver &D,
+                                    const llvm::Triple& Triple){
+  return new DarwinHostInfo(D, Triple);
 }
 
-const HostInfo *clang::driver::createFreeBSDHostInfo(const Driver &D,
-                                                     const char *Arch, 
-                                                     const char *Platform, 
-                                                     const char *OS) {
-  return new FreeBSDHostInfo(D, Arch, Platform, OS);
+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 char *Arch, 
-                                                     const char *Platform, 
-                                                     const char *OS) {
-  return new DragonFlyHostInfo(D, Arch, Platform, OS);
+const HostInfo *
+clang::driver::createDragonFlyHostInfo(const Driver &D,
+                                       const llvm::Triple& Triple) {
+  return new DragonFlyHostInfo(D, Triple);
 }
 
-const HostInfo *clang::driver::createUnknownHostInfo(const Driver &D,
-                                                     const char *Arch, 
-                                                     const char *Platform, 
-                                                     const char *OS) {
-  return new UnknownHostInfo(D, Arch, Platform, OS);
+const HostInfo *
+clang::driver::createUnknownHostInfo(const Driver &D,
+                                     const llvm::Triple& Triple) {
+  return new UnknownHostInfo(D, Triple);
 }
diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp
index a7f6550..20ed31b 100644
--- a/lib/Driver/ToolChain.cpp
+++ b/lib/Driver/ToolChain.cpp
@@ -15,9 +15,8 @@
 
 using namespace clang::driver;
 
-ToolChain::ToolChain(const HostInfo &_Host, const char *_Arch, 
-                     const char *_Platform, const char *_OS) 
-  : Host(_Host), Arch(_Arch), Platform(_Platform), OS(_OS) {
+ToolChain::ToolChain(const HostInfo &_Host, const llvm::Triple &_Triple)
+  : Host(_Host), Triple(_Triple) {
 }
 
 ToolChain::~ToolChain() {
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 7310535..718f628 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -27,11 +27,10 @@
 
 /// Darwin_X86 - Darwin tool chain for i386 and x86_64.
 
-Darwin_X86::Darwin_X86(const HostInfo &Host, const char *Arch, 
-                       const char *Platform, const char *OS, 
+Darwin_X86::Darwin_X86(const HostInfo &Host, const llvm::Triple& Triple,
                        const unsigned (&_DarwinVersion)[3],
                        const unsigned (&_GCCVersion)[3])
-  : ToolChain(Host, Arch, Platform, OS) {
+  : ToolChain(Host, Triple) {
   DarwinVersion[0] = _DarwinVersion[0];
   DarwinVersion[1] = _DarwinVersion[1];
   DarwinVersion[2] = _DarwinVersion[2];
@@ -309,9 +308,8 @@
 /// all subcommands; this relies on gcc translating the majority of
 /// command line options.
 
-Generic_GCC::Generic_GCC(const HostInfo &Host, const char *Arch, 
-                         const char *Platform, const char *OS)
-  : ToolChain(Host, Arch, Platform, OS) 
+Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
+  : ToolChain(Host, Triple) 
 {
   std::string Path(getHost().getDriver().Dir);
   Path += "/../libexec";
@@ -388,9 +386,8 @@
 
 /// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
 
-FreeBSD::FreeBSD(const HostInfo &Host, const char *Arch, 
-                 const char *Platform, const char *OS, bool Lib32)
-  : Generic_GCC(Host, Arch, Platform, OS) {
+FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32)
+  : Generic_GCC(Host, Triple) {
   if (Lib32) {
     getFilePaths().push_back(getHost().getDriver().Dir + "/../lib32");
     getFilePaths().push_back("/usr/lib32");
@@ -424,9 +421,8 @@
 
 /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
 
-DragonFly::DragonFly(const HostInfo &Host, const char *Arch, 
-                 const char *Platform, const char *OS)
-  : Generic_GCC(Host, Arch, Platform, OS) {
+DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple)
+  : Generic_GCC(Host, Triple) {
 
   // Path mangling to find libexec
   std::string Path(getHost().getDriver().Dir);
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index baab99b..5a5c13b 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -30,8 +30,7 @@
   mutable llvm::DenseMap<unsigned, Tool*> Tools;
 
 public:
-  Generic_GCC(const HostInfo &Host, const char *Arch, const char *Platform, 
-              const char *OS);
+  Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple);
   ~Generic_GCC();
 
   virtual DerivedArgList *TranslateArgs(InputArgList &Args) const;
@@ -64,8 +63,8 @@
   const char *getMacosxVersionMin() const;
 
 public:
-  Darwin_X86(const HostInfo &Host, const char *Arch, const char *Platform, 
-             const char *OS, const unsigned (&DarwinVersion)[3],
+  Darwin_X86(const HostInfo &Host, const llvm::Triple& Triple, 
+             const unsigned (&DarwinVersion)[3],
              const unsigned (&GCCVersion)[3]);
   ~Darwin_X86();
 
@@ -102,24 +101,22 @@
   /// Darwin_GCC - Generic Darwin tool chain using gcc.
 class VISIBILITY_HIDDEN Darwin_GCC : public Generic_GCC {
 public:
-  Darwin_GCC(const HostInfo &Host, const char *Arch, const char *Platform, 
-             const char *OS) : Generic_GCC(Host, Arch, Platform, OS) {}
+  Darwin_GCC(const HostInfo &Host, const llvm::Triple& Triple) 
+    : Generic_GCC(Host, Triple) {}
 
   virtual const char *GetDefaultRelocationModel() const { return "pic"; }
 };
 
 class VISIBILITY_HIDDEN FreeBSD : public Generic_GCC {
 public:
-  FreeBSD(const HostInfo &Host, const char *Arch, const char *Platform, 
-          const char *OS, bool Lib32);
+  FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32);
 
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
 };
 
 class VISIBILITY_HIDDEN DragonFly : public Generic_GCC {
 public:
-  DragonFly(const HostInfo &Host, const char *Arch, const char *Platform, 
-          const char *OS);
+  DragonFly(const HostInfo &Host, const llvm::Triple& Triple);
 
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
 };