Fix bug: test/Regression/CBackend/2002-05-16-NameCollide.ll by tracking
which global variables would have name collisions if they were not mangled,
and use this info to mangle them iff they would collide.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2639 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index 27199fe..dd5f0b1 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -26,6 +26,7 @@
 #include "Support/StringExtras.h"
 #include "Support/STLExtras.h"
 #include <algorithm>
+#include <set>
 using std::string;
 using std::map;
 using std::ostream;
@@ -209,6 +210,7 @@
     SlotCalculator &Table;
     const Module *TheModule;
     map<const Type *, string> TypeNames;
+    std::set<const Value*> MangledGlobals;
   public:
     inline CWriter(ostream &o, SlotCalculator &Tab, const Module *M)
       : Out(o), Table(Tab), TheModule(M) {
@@ -294,7 +296,6 @@
     case '.': tmp += "d_"; break;
     case ' ': tmp += "s_"; break;
     case '-': tmp += "D_"; break;
-    case '_': tmp += "__"; break;
     default:  tmp += *sI;
     }
 
@@ -303,7 +304,8 @@
 
 string CWriter::getValueName(const Value *V) {
   if (V->hasName()) {             // Print out the label if it exists...
-    if (isa<GlobalValue>(V))  // Do not mangle globals...
+    if (isa<GlobalValue>(V) &&    // Do not mangle globals...
+        !MangledGlobals.count(V)) // Unless the name would collide unless we do.
       return makeNameProper(V->getName());
 
     return "l" + utostr(V->getType()->getUniqueID()) + "_" +
@@ -352,6 +354,26 @@
 }
 
 void CWriter::printModule(Module *M) {
+  // Calculate which global values have names that will collide when we throw
+  // away type information.
+  {  // Scope to declare the FoundNames set when we are done with it...
+    std::set<string> FoundNames;
+    for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+      if ((*I)->hasName())                      // If the global has a name...
+        if (FoundNames.count((*I)->getName()))  // And the name is already used
+          MangledGlobals.insert(*I);            // Mangle the name
+        else
+          FoundNames.insert((*I)->getName());   // Otherwise, keep track of name
+
+    for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I)
+      if ((*I)->hasName())                      // If the global has a name...
+        if (FoundNames.count((*I)->getName()))  // And the name is already used
+          MangledGlobals.insert(*I);            // Mangle the name
+        else
+          FoundNames.insert((*I)->getName());   // Otherwise, keep track of name
+  }
+
+
   // printing stdlib inclusion
   // Out << "#include <stdlib.h>\n";
 
diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp
index 27199fe..dd5f0b1 100644
--- a/lib/Target/CBackend/Writer.cpp
+++ b/lib/Target/CBackend/Writer.cpp
@@ -26,6 +26,7 @@
 #include "Support/StringExtras.h"
 #include "Support/STLExtras.h"
 #include <algorithm>
+#include <set>
 using std::string;
 using std::map;
 using std::ostream;
@@ -209,6 +210,7 @@
     SlotCalculator &Table;
     const Module *TheModule;
     map<const Type *, string> TypeNames;
+    std::set<const Value*> MangledGlobals;
   public:
     inline CWriter(ostream &o, SlotCalculator &Tab, const Module *M)
       : Out(o), Table(Tab), TheModule(M) {
@@ -294,7 +296,6 @@
     case '.': tmp += "d_"; break;
     case ' ': tmp += "s_"; break;
     case '-': tmp += "D_"; break;
-    case '_': tmp += "__"; break;
     default:  tmp += *sI;
     }
 
@@ -303,7 +304,8 @@
 
 string CWriter::getValueName(const Value *V) {
   if (V->hasName()) {             // Print out the label if it exists...
-    if (isa<GlobalValue>(V))  // Do not mangle globals...
+    if (isa<GlobalValue>(V) &&    // Do not mangle globals...
+        !MangledGlobals.count(V)) // Unless the name would collide unless we do.
       return makeNameProper(V->getName());
 
     return "l" + utostr(V->getType()->getUniqueID()) + "_" +
@@ -352,6 +354,26 @@
 }
 
 void CWriter::printModule(Module *M) {
+  // Calculate which global values have names that will collide when we throw
+  // away type information.
+  {  // Scope to declare the FoundNames set when we are done with it...
+    std::set<string> FoundNames;
+    for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+      if ((*I)->hasName())                      // If the global has a name...
+        if (FoundNames.count((*I)->getName()))  // And the name is already used
+          MangledGlobals.insert(*I);            // Mangle the name
+        else
+          FoundNames.insert((*I)->getName());   // Otherwise, keep track of name
+
+    for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I)
+      if ((*I)->hasName())                      // If the global has a name...
+        if (FoundNames.count((*I)->getName()))  // And the name is already used
+          MangledGlobals.insert(*I);            // Mangle the name
+        else
+          FoundNames.insert((*I)->getName());   // Otherwise, keep track of name
+  }
+
+
   // printing stdlib inclusion
   // Out << "#include <stdlib.h>\n";