More work on thunks - don't assert if there's a variable with the same name as the thunk already.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99303 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp
index 6fee2a5..9204e4e 100644
--- a/lib/CodeGen/CGVtable.cpp
+++ b/lib/CodeGen/CGVtable.cpp
@@ -3669,8 +3669,40 @@
 void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk)
 {
   llvm::Constant *ThunkFn = CGM.GetAddrOfThunk(GD, Thunk);
+  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
   
-  (void)ThunkFn;
+  // Strip off a bitcast if we got one back.
+  if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(ThunkFn)) {
+    assert(CE->getOpcode() == llvm::Instruction::BitCast);
+    ThunkFn = CE->getOperand(0);
+  }
+  
+  const llvm::Type *ThunkFnTy =
+    cast<llvm::GlobalValue>(ThunkFn)->getType()->getElementType();
+
+  // There's already a declaration with the same name, check if it has the same
+  // type or if we need to replace it.
+  if (ThunkFnTy != CGM.getTypes().GetFunctionTypeForVtable(MD)) {
+    llvm::GlobalValue *OldThunkFn = cast<llvm::GlobalValue>(ThunkFn);
+    
+    // If the types mismatch then we have to rewrite the definition.
+    assert(OldThunkFn->isDeclaration() &&
+           "Shouldn't replace non-declaration");
+
+    // Remove the name from the old thunk function and get a new thunk.
+    OldThunkFn->setName(llvm::StringRef());
+    ThunkFn = CGM.GetAddrOfThunk(GD, Thunk);
+    
+    // If needed, replace the old thunk with a bitcast.
+    if (!OldThunkFn->use_empty()) {
+      llvm::Constant *NewPtrForOldDecl =
+        llvm::ConstantExpr::getBitCast(ThunkFn, OldThunkFn->getType());
+      OldThunkFn->replaceAllUsesWith(NewPtrForOldDecl);
+    }
+    
+    // Remove the old thunk.
+    OldThunkFn->eraseFromParent();
+  }
 }
 
 void CodeGenVTables::EmitThunks(GlobalDecl GD)
diff --git a/lib/CodeGen/CGVtable.h b/lib/CodeGen/CGVtable.h
index 450fa93..cc4cb87 100644
--- a/lib/CodeGen/CGVtable.h
+++ b/lib/CodeGen/CGVtable.h
@@ -341,7 +341,7 @@
   // have, as well as the vtable itself if the global decl is the key function.
   void EmitVTableRelatedData(GlobalDecl GD);
 
-  /// GenerateClassData - Generate all the class data requires to be generated
+  /// GenerateClassData - Generate all the class data required to be generated
   /// upon definition of a KeyFunction.  This includes the vtable, the
   /// rtti data structure and the VTT.
   ///