ArchSpec: fix unintentional promotion of unspecified unknowns to specified unknowns

* ArchSpec::MergeFrom() would erroneously promote an unspecified
  unknown to a specified unknown when both the ArchSpec and the merged
  in ArchSpec were both unspecified unknowns. This no longer happens,
  which fixes issues with global module cache lookup in some
  situations.

* Added ArchSpec::DumpTriple(Stream&) that now properly prints
  unspecified unknowns as '*' and specified unknows as 'unknown'.
  This makes it trivial to tell the difference between the two.
  Converted printing code over ot using DumpTriple() rather than
  building from scratch.

* Fixed up a couple places that were not guaranteeing that an
  unspecified unknown was recorded as such.

llvm-svn: 250253
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 9a84c34..b530517 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -79,7 +79,8 @@
     uint32_t properties = 0;
     if (target_arch.IsValid())
     {
-        strm.Printf ("%sarch=%s", properties++ > 0 ? ", " : " ( ", target_arch.GetTriple().str().c_str());
+        strm.Printf ("%sarch=", properties++ > 0 ? ", " : " ( ");
+        target_arch.DumpTriple (strm);
         properties++;
     }
     PlatformSP platform_sp (target->GetPlatform());
@@ -1459,15 +1460,18 @@
 {
     if (module)
     {
-        const char *arch_cstr;
+        StreamString arch_strm;
+
         if (full_triple)
-            arch_cstr = module->GetArchitecture().GetTriple().str().c_str();
+            module->GetArchitecture().DumpTriple(arch_strm);
         else
-            arch_cstr = module->GetArchitecture().GetArchitectureName();
+            arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
+        std::string arch_str = arch_strm.GetString();
+
         if (width)
-            strm.Printf("%-*s", width, arch_cstr);
+            strm.Printf("%-*s", width, arch_str.c_str());
         else
-            strm.PutCString(arch_cstr);
+            strm.PutCString(arch_str.c_str());
     }
 }
 
diff --git a/lldb/source/Core/ArchSpec.cpp b/lldb/source/Core/ArchSpec.cpp
index e38501c..2733542 100644
--- a/lldb/source/Core/ArchSpec.cpp
+++ b/lldb/source/Core/ArchSpec.cpp
@@ -844,9 +844,9 @@
 void
 ArchSpec::MergeFrom(const ArchSpec &other)
 {
-    if (GetTriple().getVendor() == llvm::Triple::UnknownVendor && !TripleVendorWasSpecified())
+    if (TripleVendorIsUnspecifiedUnknown() && !other.TripleVendorIsUnspecifiedUnknown())
         GetTriple().setVendor(other.GetTriple().getVendor());
-    if (GetTriple().getOS() == llvm::Triple::UnknownOS && !TripleOSWasSpecified())
+    if (TripleOSIsUnspecifiedUnknown() && !other.TripleOSIsUnspecifiedUnknown())
         GetTriple().setOS(other.GetTriple().getOS());
     if (GetTriple().getArch() == llvm::Triple::UnknownArch)
         GetTriple().setArch(other.GetTriple().getArch());
@@ -1444,3 +1444,18 @@
         return StopInfoOverrideCallbackTypeARM;
     return NULL;
 }
+
+void
+ArchSpec::DumpTriple(Stream &s) const
+{
+    const llvm::Triple &triple = GetTriple();
+    llvm::StringRef arch_str = triple.getArchName();
+    llvm::StringRef vendor_str = triple.getVendorName();
+    llvm::StringRef os_str = triple.getOSName();
+
+    s.Printf("%s-%s-%s",
+             arch_str.empty() ? "*" : arch_str.str().c_str(),
+             vendor_str.empty() ? "*" : vendor_str.str().c_str(),
+             os_str.empty() ? "*" : os_str.str().c_str()
+             );
+}
diff --git a/lldb/source/Host/linux/HostInfoLinux.cpp b/lldb/source/Host/linux/HostInfoLinux.cpp
index 3a3023b..4732a2a 100644
--- a/lldb/source/Host/linux/HostInfoLinux.cpp
+++ b/lldb/source/Host/linux/HostInfoLinux.cpp
@@ -271,12 +271,12 @@
     {
         arch_32.SetDistributionId(distribution_id);
         if (arch_32.GetTriple().getVendor() == llvm::Triple::UnknownVendor)
-            arch_32.GetTriple().setVendorName("");
+            arch_32.GetTriple().setVendorName(llvm::StringRef());
     }
     if (arch_64.IsValid())
     {
         arch_64.SetDistributionId(distribution_id);
         if (arch_64.GetTriple().getVendor() == llvm::Triple::UnknownVendor)
-            arch_64.GetTriple().setVendorName("");
+            arch_64.GetTriple().setVendorName(llvm::StringRef());
     }
 }
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index f9f0358..0884a1c8 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -1605,6 +1605,12 @@
                 }
             }
 
+            // Make any unknown triple components to be unspecified unknowns.
+            if (arch_spec.GetTriple().getVendor() == llvm::Triple::UnknownVendor)
+                arch_spec.GetTriple().setVendorName (llvm::StringRef());
+            if (arch_spec.GetTriple().getOS() == llvm::Triple::UnknownOS)
+                arch_spec.GetTriple().setOSName (llvm::StringRef());
+
             return section_headers.size();
         }
     }
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index e43cdc6..33446a9 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -475,7 +475,11 @@
     if (arch.IsValid())
     {
         if (!arch.GetTriple().str().empty())
-        strm.Printf("    Triple: %s\n", arch.GetTriple().str().c_str());        
+        {
+            strm.Printf("    Triple: ");
+            arch.DumpTriple(strm);
+            strm.EOL();
+        }
     }
 
     if (GetOSVersion(major, minor, update))
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 8863fd0..cf30906 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -316,8 +316,12 @@
         }
     }
 
-    if (m_arch.IsValid())                       
-        s.Printf ("   arch = %s\n", m_arch.GetTriple().str().c_str());
+    if (m_arch.IsValid())
+    {
+        s.Printf ("   arch = ");
+        m_arch.DumpTriple(s);
+        s.EOL();
+    }
 
     if (m_uid != UINT32_MAX)
     {
@@ -370,7 +374,10 @@
         const char *cstr;
         s.Printf ("%-6" PRIu64 " %-6" PRIu64 " ", m_pid, m_parent_pid);
 
-    
+        StreamString arch_strm;
+        if (m_arch.IsValid())
+            m_arch.DumpTriple(arch_strm);
+
         if (verbose)
         {
             cstr = platform->GetUserName (m_uid);
@@ -396,13 +403,14 @@
                 s.Printf ("%-10s ", cstr);
             else
                 s.Printf ("%-10u ", m_egid);
-            s.Printf ("%-24s ", m_arch.IsValid() ? m_arch.GetTriple().str().c_str() : "");
+
+            s.Printf ("%-24s ", arch_strm.GetString().c_str());
         }
         else
         {
             s.Printf ("%-10s %-24s ",
                       platform->GetUserName (m_euid),
-                      m_arch.IsValid() ? m_arch.GetTriple().str().c_str() : "");
+                      arch_strm.GetString().c_str());
         }
 
         if (verbose || show_args)
diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp
index 552e951..af596f7 100644
--- a/lldb/source/Target/TargetList.cpp
+++ b/lldb/source/Target/TargetList.cpp
@@ -179,9 +179,14 @@
                         }
                         else
                         {
+                            StreamString platform_arch_strm;
+                            StreamString module_arch_strm;
+
+                            platform_arch.DumpTriple(platform_arch_strm);
+                            matching_module_spec.GetArchitecture().DumpTriple(module_arch_strm);
                             error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'",
-                                                           platform_arch.GetTriple().str().c_str(),
-                                                           matching_module_spec.GetArchitecture().GetTriple().str().c_str(),
+                                                           platform_arch_strm.GetString().c_str(),
+                                                           module_arch_strm.GetString().c_str(),
                                                            module_spec.GetFileSpec().GetPath().c_str());
                             return error;
                         }