]> granicus.if.org Git - clang/commitdiff
More work on thunks - don't assert if there's a variable with the same name as the...
authorAnders Carlsson <andersca@mac.com>
Tue, 23 Mar 2010 18:18:41 +0000 (18:18 +0000)
committerAnders Carlsson <andersca@mac.com>
Tue, 23 Mar 2010 18:18:41 +0000 (18:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99303 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGVtable.cpp
lib/CodeGen/CGVtable.h

index 6fee2a566c48488b9f4dd552edcbee474f363933..9204e4e565ccbb8e1e854c41e4f1ab97b6a70914 100644 (file)
@@ -3669,8 +3669,40 @@ llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD,
 void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk)
 {
   llvm::Constant *ThunkFn = CGM.GetAddrOfThunk(GD, Thunk);
+  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
+  
+  // 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);
+  }
   
-  (void)ThunkFn;
+  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)
index 450fa9382f2e61bc6adac17f13c98c3097865fef..cc4cb87f7f49711c80b0e37c6f2d037fe155fd8a 100644 (file)
@@ -341,7 +341,7 @@ public:
   // 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.
   ///