[cfe-commits] r87083 - in /cfe/trunk/lib/CodeGen: CGCXX.cpp CGCXXExpr.cpp CodeGenFunction.h

Anders Carlsson andersca at mac.com
Thu Nov 12 20:45:42 PST 2009


Author: andersca
Date: Thu Nov 12 22:45:41 2009
New Revision: 87083

URL: http://llvm.org/viewvc/llvm-project?rev=87083&view=rev
Log:
Add a special BuildVirtualCall that's going to be used for building calls to destructors. This is needed because when compiling:

struct A {
	virtual ~A();
};

void f(A* a) {
	delete a;
}

A's deleting destructor should be called.

Modified:
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CGCXXExpr.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=87083&r1=87082&r2=87083&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Thu Nov 12 22:45:41 2009
@@ -985,20 +985,35 @@
   return VBaseOffset;
 }
 
+static llvm::Value *BuildVirtualCall(CodeGenFunction &CGF, int64_t VtableIndex, 
+                                     llvm::Value *This, const llvm::Type *Ty) {
+  Ty = Ty->getPointerTo()->getPointerTo()->getPointerTo();
+  
+  llvm::Value *Vtable = CGF.Builder.CreateBitCast(This, Ty);
+  Vtable = CGF.Builder.CreateLoad(Vtable);
+  
+  llvm::Value *VFuncPtr = 
+    CGF.Builder.CreateConstInBoundsGEP1_64(Vtable, VtableIndex, "vfn");
+  return CGF.Builder.CreateLoad(VFuncPtr);
+}
+
 llvm::Value *
-CodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *&This,
+CodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This,
                                   const llvm::Type *Ty) {
-  int64_t Index = CGM.getVtableInfo().getMethodVtableIndex(MD);
+  MD = MD->getCanonicalDecl();
+  int64_t VtableIndex = CGM.getVtableInfo().getMethodVtableIndex(MD);
   
-  Ty = llvm::PointerType::get(Ty, 0);
-  Ty = llvm::PointerType::get(Ty, 0);
-  Ty = llvm::PointerType::get(Ty, 0);
-  llvm::Value *vtbl = Builder.CreateBitCast(This, Ty);
-  vtbl = Builder.CreateLoad(vtbl);
-  llvm::Value *vfn = Builder.CreateConstInBoundsGEP1_64(vtbl,
-                                                        Index, "vfn");
-  vfn = Builder.CreateLoad(vfn);
-  return vfn;
+  return ::BuildVirtualCall(*this, VtableIndex, This, Ty);
+}
+
+llvm::Value *
+CodeGenFunction::BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type, 
+                                  llvm::Value *&This, const llvm::Type *Ty) {
+  DD = cast<CXXDestructorDecl>(DD->getCanonicalDecl());
+  int64_t VtableIndex = 
+    CGM.getVtableInfo().getMethodVtableIndex(DD);
+
+  return ::BuildVirtualCall(*this, VtableIndex, This, Ty);
 }
 
 /// EmitClassAggrMemberwiseCopy - This routine generates code to copy a class

Modified: cfe/trunk/lib/CodeGen/CGCXXExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXExpr.cpp?rev=87083&r1=87082&r2=87083&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXXExpr.cpp Thu Nov 12 22:45:41 2009
@@ -265,7 +265,9 @@
 
   Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
   EmitBlock(DeleteNotNull);
-
+  
+  bool ShouldCallDelete = true;
+  
   // Call the destructor if necessary.
   if (const RecordType *RT = DeleteTy->getAs<RecordType>()) {
     if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
@@ -276,30 +278,35 @@
             CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(Dtor),
                                            /*isVariadic=*/false);
           
-          llvm::Value *Callee = BuildVirtualCall(Dtor, Ptr, Ty);
+          llvm::Value *Callee = BuildVirtualCall(Dtor, Dtor_Deleting, Ptr, Ty);
           EmitCXXMemberCall(Dtor, Callee, Ptr, 0, 0);
+
+          // The dtor took care of deleting the object.
+          ShouldCallDelete = false;
         } else 
           EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr);
       }
     }
   }
 
-  // Call delete.
-  FunctionDecl *DeleteFD = E->getOperatorDelete();
-  const FunctionProtoType *DeleteFTy =
-    DeleteFD->getType()->getAs<FunctionProtoType>();
-
-  CallArgList DeleteArgs;
-
-  QualType ArgTy = DeleteFTy->getArgType(0);
-  llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
-  DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy));
-
-  // Emit the call to delete.
-  EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(),
-                                          DeleteArgs),
-           CGM.GetAddrOfFunction(DeleteFD),
-           DeleteArgs, DeleteFD);
-
+  if (ShouldCallDelete) {
+    // Call delete.
+    FunctionDecl *DeleteFD = E->getOperatorDelete();
+    const FunctionProtoType *DeleteFTy =
+      DeleteFD->getType()->getAs<FunctionProtoType>();
+
+    CallArgList DeleteArgs;
+
+    QualType ArgTy = DeleteFTy->getArgType(0);
+    llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
+    DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy));
+
+    // Emit the call to delete.
+    EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(),
+                                            DeleteArgs),
+             CGM.GetAddrOfFunction(DeleteFD),
+             DeleteArgs, DeleteFD);
+  }
+  
   EmitBlock(DeleteEnd);
 }

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=87083&r1=87082&r2=87083&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Nov 12 22:45:41 2009
@@ -883,8 +883,11 @@
                   const Decl *TargetDecl = 0);
   RValue EmitCallExpr(const CallExpr *E);
 
-  llvm::Value *BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *&This,
+  llvm::Value *BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This,
                                 const llvm::Type *Ty);
+  llvm::Value *BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type, 
+                                llvm::Value *&This, const llvm::Type *Ty);
+
   RValue EmitCXXMemberCall(const CXXMethodDecl *MD,
                            llvm::Value *Callee,
                            llvm::Value *This,





More information about the cfe-commits mailing list