[cfe-commits] r135028 - in /cfe/trunk/lib/CodeGen: CGDeclCXX.cpp CodeGenFunction.h

John McCall rjmccall at apple.com
Tue Jul 12 20:01:35 PDT 2011


Author: rjmccall
Date: Tue Jul 12 22:01:35 2011
New Revision: 135028

URL: http://llvm.org/viewvc/llvm-project?rev=135028&view=rev
Log:
Generalize the routine for destroying an object with static
storage duration, then explicitly exempt ownership-qualified
types from it.


Modified:
    cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=135028&r1=135027&r2=135028&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Tue Jul 12 22:01:35 2011
@@ -53,41 +53,50 @@
 /// Emit code to cause the destruction of the given variable with
 /// static storage duration.
 static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,
-                            llvm::Constant *DeclPtr) {
+                            llvm::Constant *addr) {
   CodeGenModule &CGM = CGF.CGM;
-  ASTContext &Context = CGF.getContext();
-  
-  QualType T = D.getType();
-  
-  // Drill down past array types.
-  const ConstantArrayType *Array = Context.getAsConstantArrayType(T);
-  if (Array)
-    T = Context.getBaseElementType(Array);
+
+  // FIXME:  __attribute__((cleanup)) ?
   
-  /// If that's not a record, we're done.
-  /// FIXME:  __attribute__((cleanup)) ?
-  const RecordType *RT = T->getAs<RecordType>();
-  if (!RT)
+  QualType type = D.getType();
+  QualType::DestructionKind dtorKind = type.isDestructedType();
+
+  switch (dtorKind) {
+  case QualType::DK_none:
     return;
-  
-  CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-  if (RD->hasTrivialDestructor())
+
+  case QualType::DK_cxx_destructor:
+    break;
+
+  case QualType::DK_objc_strong_lifetime:
+  case QualType::DK_objc_weak_lifetime:
+    // We don't care about releasing objects during process teardown.
     return;
-  
-  CXXDestructorDecl *Dtor = RD->getDestructor();
-  
-  llvm::Constant *DtorFn;
-  if (Array) {
-    DtorFn = 
-      CodeGenFunction(CGM).GenerateCXXAggrDestructorHelper(Dtor, Array, 
-                                                           DeclPtr);
-    const llvm::Type *Int8PtrTy =
-      llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
-    DeclPtr = llvm::Constant::getNullValue(Int8PtrTy);
-  } else
-    DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete);
-  
-  CGF.EmitCXXGlobalDtorRegistration(DtorFn, DeclPtr);
+  }
+
+  llvm::Constant *function;
+  llvm::Constant *argument;
+
+  // Special-case non-array C++ destructors, where there's a function
+  // with the right signature that we can just call.
+  const CXXRecordDecl *record = 0;
+  if (dtorKind == QualType::DK_cxx_destructor &&
+      (record = type->getAsCXXRecordDecl())) {
+    assert(!record->hasTrivialDestructor());
+    CXXDestructorDecl *dtor = record->getDestructor();
+
+    function = CGM.GetAddrOfCXXDestructor(dtor, Dtor_Complete);
+    argument = addr;
+
+  // Otherwise, the standard logic requires a helper function.
+  } else {
+    function = CodeGenFunction(CGM).generateDestroyHelper(addr, type,
+                                                  CGF.getDestroyer(dtorKind),
+                                                  CGF.needsEHCleanup(dtorKind));
+    argument = llvm::Constant::getNullValue(CGF.Int8PtrTy);
+  }
+
+  CGF.EmitCXXGlobalDtorRegistration(function, argument);
 }
 
 void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
@@ -328,13 +337,13 @@
   FinishFunction();
 }
 
-/// GenerateCXXAggrDestructorHelper - Generates a helper function which when
-/// invoked, calls the default destructor on array elements in reverse order of
-/// construction.
+/// generateDestroyHelper - Generates a helper function which, when
+/// invoked, destroys the given object.
 llvm::Function * 
-CodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
-                                                 const ArrayType *Array,
-                                                 llvm::Value *This) {
+CodeGenFunction::generateDestroyHelper(llvm::Constant *addr,
+                                       QualType type,
+                                       Destroyer &destroyer,
+                                       bool useEHCleanupForArray) {
   FunctionArgList args;
   ImplicitParamDecl dst(0, SourceLocation(), 0, getContext().VoidPtrTy);
   args.push_back(&dst);
@@ -343,19 +352,16 @@
     CGM.getTypes().getFunctionInfo(getContext().VoidTy, args, 
                                    FunctionType::ExtInfo());
   const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false);
-  llvm::Function *Fn = 
+  llvm::Function *fn = 
     CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor");
 
-  StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FI, args,
+  StartFunction(GlobalDecl(), getContext().VoidTy, fn, FI, args,
                 SourceLocation());
 
-  QualType BaseElementTy = getContext().getBaseElementType(Array);
-  const llvm::Type *BasePtr = ConvertType(BaseElementTy)->getPointerTo();
-  llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr);
-  
-  EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr);
+  emitDestroy(addr, type, destroyer, useEHCleanupForArray);
   
   FinishFunction();
   
-  return Fn;
+  return fn;
 }
+

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=135028&r1=135027&r2=135028&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Jul 12 22:01:35 2011
@@ -1204,6 +1204,10 @@
                    Destroyer &destroyer, bool useEHCleanupForArray);
   void emitDestroy(llvm::Value *addr, QualType type, Destroyer &destroyer,
                    bool useEHCleanupForArray);
+  llvm::Function *generateDestroyHelper(llvm::Constant *addr,
+                                        QualType type,
+                                        Destroyer &destroyer,
+                                        bool useEHCleanupForArray);
   void emitArrayDestroy(llvm::Value *begin, llvm::Value *end,
                         QualType type, Destroyer &destroyer,
                         bool useEHCleanup);
@@ -1708,10 +1712,6 @@
                                  llvm::Value *NumElements,
                                  llvm::Value *This);
 
-  llvm::Function *GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
-                                                  const ArrayType *Array,
-                                                  llvm::Value *This);
-
   void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type,
                              bool ForVirtualBase, llvm::Value *This);
 





More information about the cfe-commits mailing list