Revision: 125424
Author:   clattner
Date:     2007-03-27 17:04:40 -0700 (Tue, 27 Mar 2007)

Log Message:
-----------
Fix C++Frontend/2007-03-27-FunctionVarRename.cpp

Modified Paths:
--------------
    apple-local/branches/llvm/gcc/llvm-backend.cpp
    apple-local/branches/llvm/gcc/llvm-convert.cpp
    apple-local/branches/llvm/gcc/llvm-internal.h

Modified: apple-local/branches/llvm/gcc/llvm-backend.cpp
===================================================================
--- apple-local/branches/llvm/gcc/llvm-backend.cpp      2007-03-27 23:55:33 UTC 
(rev 125423)
+++ apple-local/branches/llvm/gcc/llvm-backend.cpp      2007-03-28 00:04:40 UTC 
(rev 125424)
@@ -789,11 +789,12 @@
 
     // If we have "extern void foo", make the global have type {} instead of
     // type void.
-    if (Ty == Type::VoidTy) Ty = StructType::get(std::vector<const Type*>(),
-                                                 false);
+    if (Ty == Type::VoidTy) 
+      Ty = StructType::get(std::vector<const Type*>(), false);
+    
     if (Name[0] == 0) {   // Global has no name.
       GV = new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage, 0,
-                              Name, TheModule);
+                              "", TheModule);
 
       // Check for external weak linkage
       if (DECL_EXTERNAL(decl) && DECL_WEAK(decl))
@@ -826,6 +827,28 @@
         // Handle visibility style
         if (TREE_PUBLIC(decl) && DECL_VISIBILITY(decl) == VISIBILITY_HIDDEN)
           GV->setVisibility(Function::HiddenVisibility);
+        
+        // If GV got renamed, then there is already an object with this name in
+        // the symbol table.  If this happens, the old one must be a forward
+        // decl, just replace it with a cast of the new one.
+        if (GV->getName() != Name) {
+          Function *F = TheModule->getFunction(Name);
+          assert(F && F->isDeclaration() && "A function turned into a 
global?");
+          
+          // Replace any uses of "F" with uses of GV.
+          Value *FInNewType = ConstantExpr::getBitCast(GV, F->getType());
+          F->replaceAllUsesWith(FInNewType);
+          
+          // Update the decl that points to F.
+          changeLLVMValue(F, FInNewType);
+          
+          // F is now dead, nuke it.
+          F->eraseFromParent();
+          
+          // Now we can give GV the proper name.
+          GV->setName(Name);
+        }
+        
       } else {
         GV = GVE;  // Global already created, reuse it.
       }

Modified: apple-local/branches/llvm/gcc/llvm-convert.cpp
===================================================================
--- apple-local/branches/llvm/gcc/llvm-convert.cpp      2007-03-27 23:55:33 UTC 
(rev 125423)
+++ apple-local/branches/llvm/gcc/llvm-convert.cpp      2007-03-28 00:04:40 UTC 
(rev 125424)
@@ -133,6 +133,29 @@
   return LLVMValues[Index - 1];
 }
 
+/// changeLLVMValue - If Old exists in the LLVMValues map, rewrite it to New.
+/// At this point we know that New is not in the map.
+void changeLLVMValue(Value *Old, Value *New) {
+  assert(!LLVMValuesMap.count(New) && "New cannot be in the map!");
+  
+  // Find Old in the table.
+  LLVMValuesMapTy::iterator I = LLVMValuesMap.find(Old);
+  if (I == LLVMValuesMap.end()) return;
+  
+  unsigned Idx = I->second-1;
+  assert(Idx < LLVMValues.size() && "Out of range index!");
+  assert(LLVMValues[Idx] == Old && "Inconsistent LLVMValues mapping!");
+  
+  LLVMValues[Idx] = New;
+  
+  // Remove the old value from the value map.
+  LLVMValuesMap.erase(I);
+  
+  // Insert the new value into the value map.  We know that it can't already
+  // exist in the mapping.
+  LLVMValuesMap[New] = Idx+1;
+}
+
 // Read LLVM Types string table
 void readLLVMValuesStringTable() {
 

Modified: apple-local/branches/llvm/gcc/llvm-internal.h
===================================================================
--- apple-local/branches/llvm/gcc/llvm-internal.h       2007-03-27 23:55:33 UTC 
(rev 125423)
+++ apple-local/branches/llvm/gcc/llvm-internal.h       2007-03-28 00:04:40 UTC 
(rev 125424)
@@ -87,11 +87,12 @@
 /// AttributeUsedGlobals - The list of globals that are marked attribute(used).
 extern std::vector<GlobalValue*> AttributeUsedGlobals;
 
-extern void readLLVMTypesStringTable();
-extern void writeLLVMTypesStringTable();
-extern void readLLVMValuesStringTable();
-extern void writeLLVMValuesStringTable();
-extern void clearTargetBuiltinCache();
+void changeLLVMValue(Value *Old, Value *New);
+void readLLVMTypesStringTable();
+void writeLLVMTypesStringTable();
+void readLLVMValuesStringTable();
+void writeLLVMValuesStringTable();
+void clearTargetBuiltinCache();
 
 struct StructTypeConversionInfo;
 


_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to