r175271 - Abstract out emitting the vdtor calls and do it properly when using -cxx-abi microsoft; also fix vdtor calls for the ARM ABI

Timur Iskhodzhanov timurrrr at google.com
Fri Feb 15 06:45:23 PST 2013


Author: timurrrr
Date: Fri Feb 15 08:45:22 2013
New Revision: 175271

URL: http://llvm.org/viewvc/llvm-project?rev=175271&view=rev
Log:
Abstract out emitting the vdtor calls and do it properly when using -cxx-abi microsoft; also fix vdtor calls for the ARM ABI

Modified:
    cfe/trunk/lib/CodeGen/CGCXXABI.h
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
    cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
    cfe/trunk/test/CodeGenCXX/arm.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp

Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=175271&r1=175270&r2=175271&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)
+++ cfe/trunk/lib/CodeGen/CGCXXABI.h Fri Feb 15 08:45:22 2013
@@ -207,6 +207,14 @@ public:
   /// Emit the ABI-specific prolog for the function.
   virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF) = 0;
 
+  /// Emit the ABI-specific virtual destructor call.
+  virtual RValue EmitVirtualDestructorCall(CodeGenFunction &CGF,
+                                           const CXXDestructorDecl *Dtor,
+                                           CXXDtorType DtorType,
+                                           SourceLocation CallLoc,
+                                           ReturnValueSlot ReturnValue,
+                                           llvm::Value *This) = 0;
+
   virtual void EmitReturnFromThunk(CodeGenFunction &CGF,
                                    RValue RV, QualType ResultType);
 

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=175271&r1=175270&r2=175271&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Fri Feb 15 08:45:22 2013
@@ -284,7 +284,12 @@ RValue CodeGenFunction::EmitCXXMemberCal
   llvm::Value *Callee;
   if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(MD)) {
     if (UseVirtualCall) {
-      Callee = BuildVirtualCall(Dtor, Dtor_Complete, This, Ty);
+      assert(CE->arg_begin() == CE->arg_end() &&
+             "Virtual destructor shouldn't have explicit parameters");
+      return CGM.getCXXABI().EmitVirtualDestructorCall(*this, Dtor,
+                                                       Dtor_Complete,
+                                                       CE->getExprLoc(),
+                                                       ReturnValue, This);
     } else {
       if (getLangOpts().AppleKext &&
           MD->isVirtual() &&
@@ -1399,18 +1404,12 @@ static void EmitObjectDelete(CodeGenFunc
                                                     completePtr, OperatorDelete,
                                                     ElementType);
         }
-        
-        llvm::Type *Ty =
-          CGF.getTypes().GetFunctionType(
-                         CGF.getTypes().arrangeCXXDestructor(Dtor, Dtor_Complete));
-          
-        llvm::Value *Callee
-          = CGF.BuildVirtualCall(Dtor, 
-                                 UseGlobalDelete? Dtor_Complete : Dtor_Deleting,
-                                 Ptr, Ty);
+
         // FIXME: Provide a source location here.
-        CGF.EmitCXXMemberCall(Dtor, SourceLocation(), Callee, ReturnValueSlot(),
-                              Ptr, /*ImplicitParam=*/0, QualType(), 0, 0);
+        CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting;
+        CGF.CGM.getCXXABI().EmitVirtualDestructorCall(CGF, Dtor, DtorType,
+                                                      SourceLocation(),
+                                                      ReturnValueSlot(), Ptr);
 
         if (UseGlobalDelete) {
           CGF.PopCleanupBlock();

Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=175271&r1=175270&r2=175271&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Fri Feb 15 08:45:22 2013
@@ -112,6 +112,13 @@ public:
 
   void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
 
+  RValue EmitVirtualDestructorCall(CodeGenFunction &CGF,
+                                   const CXXDestructorDecl *Dtor,
+                                   CXXDtorType DtorType,
+                                   SourceLocation CallLoc,
+                                   ReturnValueSlot ReturnValue,
+                                   llvm::Value *This);
+
   StringRef GetPureVirtualCallName() { return "__cxa_pure_virtual"; }
   StringRef GetDeletedVirtualCallName() { return "__cxa_deleted_virtual"; }
 
@@ -819,6 +826,23 @@ void ARMCXXABI::EmitInstanceFunctionProl
     CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
 }
 
+RValue ItaniumCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF,
+                                                const CXXDestructorDecl *Dtor,
+                                                CXXDtorType DtorType,
+                                                SourceLocation CallLoc,
+                                                ReturnValueSlot ReturnValue,
+                                                llvm::Value *This) {
+  assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
+
+  const CGFunctionInfo *FInfo
+    = &CGM.getTypes().arrangeCXXDestructor(Dtor, DtorType);
+  llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
+  llvm::Value *Callee = CGF.BuildVirtualCall(Dtor, DtorType, This, Ty);
+
+  return CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValue, This,
+                               /*ImplicitParam=*/0, QualType(), 0, 0);
+}
+
 void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
                                     RValue RV, QualType ResultType) {
   if (!isa<CXXDestructorDecl>(CGF.CurGD.getDecl()))

Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=175271&r1=175270&r2=175271&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Fri Feb 15 08:45:22 2013
@@ -53,6 +53,13 @@ public:
 
   void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
 
+  RValue EmitVirtualDestructorCall(CodeGenFunction &CGF,
+                                   const CXXDestructorDecl *Dtor,
+                                   CXXDtorType DtorType,
+                                   SourceLocation CallLoc,
+                                   ReturnValueSlot ReturnValue,
+                                   llvm::Value *This);
+
   void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
                        llvm::GlobalVariable *DeclPtr,
                        bool PerformInit);
@@ -174,6 +181,30 @@ void MicrosoftCXXABI::EmitInstanceFuncti
   }
 }
 
+RValue MicrosoftCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF,
+                                                  const CXXDestructorDecl *Dtor,
+                                                  CXXDtorType DtorType,
+                                                  SourceLocation CallLoc,
+                                                  ReturnValueSlot ReturnValue,
+                                                  llvm::Value *This) {
+  assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
+
+  // We have only one destructor in the vftable but can get both behaviors
+  // by passing an implicit bool parameter.
+  const CGFunctionInfo *FInfo
+      = &CGM.getTypes().arrangeCXXDestructor(Dtor, Dtor_Deleting);
+  llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
+  llvm::Value *Callee = CGF.BuildVirtualCall(Dtor, Dtor_Deleting, This, Ty);
+
+  ASTContext &Context = CGF.getContext();
+  llvm::Value *ImplicitParam
+    = llvm::ConstantInt::get(llvm::IntegerType::getInt1Ty(CGF.getLLVMContext()),
+                             DtorType == Dtor_Deleting);
+
+  return CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValue, This,
+                               ImplicitParam, Context.BoolTy, 0, 0);
+}
+
 bool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
                                    QualType elementType) {
   // Microsoft seems to completely ignore the possibility of a

Modified: cfe/trunk/test/CodeGenCXX/arm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/arm.cpp?rev=175271&r1=175270&r2=175271&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/arm.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/arm.cpp Fri Feb 15 08:45:22 2013
@@ -274,11 +274,11 @@ namespace test6 {
     // CHECK-NEXT: [[V:%.*]] = load [[A]]** [[AVAR]], align 4
     // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq [[A]]* [[V]], null
     // CHECK-NEXT: br i1 [[ISNULL]]
-    // CHECK:      [[T0:%.*]] = bitcast [[A]]* [[V]] to [[A]]* ([[A]]*)***
-    // CHECK-NEXT: [[T1:%.*]] = load [[A]]* ([[A]]*)*** [[T0]]
-    // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]]* ([[A]]*)** [[T1]], i64 1
-    // CHECK-NEXT: [[T3:%.*]] = load [[A]]* ([[A]]*)** [[T2]]
-    // CHECK-NEXT: call [[A]]* [[T3]]([[A]]* [[V]])
+    // CHECK:      [[T0:%.*]] = bitcast [[A]]* [[V]] to void ([[A]]*)***
+    // CHECK-NEXT: [[T1:%.*]] = load void ([[A]]*)*** [[T0]]
+    // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds void ([[A]]*)** [[T1]], i64 1
+    // CHECK-NEXT: [[T3:%.*]] = load void ([[A]]*)** [[T2]]
+    // CHECK-NEXT: call void [[T3]]([[A]]* [[V]])
     // CHECK-NEXT: br label
     // CHECK:      ret void
     delete a;

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp?rev=175271&r1=175270&r2=175271&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp Fri Feb 15 08:45:22 2013
@@ -32,7 +32,9 @@ struct B {
 // DTORS: define {{.*}} x86_thiscallcc void @"\01??1B@@UAE at XZ"(%struct.B* %this)
 
 // Then, the scalar deleting destructor (used in the vtable):
-// DTORS:      define {{.*}} x86_thiscallcc void @"\01??_GB@@UAEPAXI at Z"(%struct.B* %this, i1 zeroext %should_call_delete)
+// FIXME: add a test that verifies that the out-of-line scalar deleting
+// destructor is linkonce_odr too.
+// DTORS:      define linkonce_odr x86_thiscallcc void @"\01??_GB@@UAEPAXI at Z"(%struct.B* %this, i1 zeroext %should_call_delete)
 // DTORS:        %[[FROMBOOL:[0-9a-z]+]] = zext i1 %should_call_delete to i8
 // DTORS-NEXT:   store i8 %[[FROMBOOL]], i8* %[[SHOULD_DELETE_VAR:[0-9a-z._]+]], align 1
 // DTORS:        %[[SHOULD_DELETE_VALUE:[0-9a-z._]+]] = load i8* %[[SHOULD_DELETE_VAR]]
@@ -61,17 +63,29 @@ void check_vftable_offset() {
 // CHECK: store i8** getelementptr inbounds ([2 x i8*]* @"\01??_7B@@6B@", i64 0, i64 0), i8*** [[THIS_PTR]]
 }
 
-// FIXME: Enable the following block and add expectations when calls
-// to virtual complete dtor are supported.
-#if 0
 void call_complete_dtor(B *obj_ptr) {
+// CHECK: define void @"\01?call_complete_dtor@@YAXPAUB@@@Z"(%struct.B* %obj_ptr)
   obj_ptr->~B();
+// CHECK: %[[OBJ_PTR_VALUE:.*]] = load %struct.B** %{{.*}}, align 4
+// CHECK-NEXT: %[[PVTABLE:.*]] = bitcast %struct.B* %[[OBJ_PTR_VALUE]] to void (%struct.B*, i1)***
+// CHECK-NEXT: %[[VTABLE:.*]] = load void (%struct.B*, i1)*** %[[PVTABLE]]
+// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds void (%struct.B*, i1)** %[[VTABLE]], i64 0
+// CHECK-NEXT: %[[VDTOR:.*]] = load void (%struct.B*, i1)** %[[PVDTOR]]
+// CHECK-NEXT: call x86_thiscallcc void %[[VDTOR]](%struct.B* %[[OBJ_PTR_VALUE]], i1 zeroext false)
+// CHECK-NEXT: ret void
 }
-#endif
 
 void call_deleting_dtor(B *obj_ptr) {
-// FIXME: Add CHECKs when calls to virtual deleting dtor are generated properly.
+// CHECK: define void @"\01?call_deleting_dtor@@YAXPAUB@@@Z"(%struct.B* %obj_ptr)
   delete obj_ptr;
+// CHECK:      %[[OBJ_PTR_VALUE:.*]] = load %struct.B** %{{.*}}, align 4
+// CHECK:      {{.*}}:{{%{0,1}[0-9]*}}
+// CHECK-NEXT:   %[[PVTABLE:.*]] = bitcast %struct.B* %[[OBJ_PTR_VALUE]] to void (%struct.B*, i1)***
+// CHECK-NEXT:   %[[VTABLE:.*]] = load void (%struct.B*, i1)*** %[[PVTABLE]]
+// CHECK-NEXT:   %[[PVDTOR:.*]] = getelementptr inbounds void (%struct.B*, i1)** %[[VTABLE]], i64 0
+// CHECK-NEXT:   %[[VDTOR:.*]] = load void (%struct.B*, i1)** %[[PVDTOR]]
+// CHECK-NEXT:   call x86_thiscallcc void %[[VDTOR]](%struct.B* %[[OBJ_PTR_VALUE]], i1 zeroext true)
+// CHECK:      ret void
 }
 
 struct C {





More information about the cfe-commits mailing list