diff options
author | John McCall <rjmccall@apple.com> | 2011-07-13 03:01:35 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-07-13 03:01:35 +0000 |
commit | a91f6661c4685fecee6dc09bdaef73254c1aaa06 (patch) | |
tree | 20ebcef78924c64b7659823e0ecbd92ac592ef04 | |
parent | e7003b72e691c4d83ba5516c58bccc2f2a4b3fe0 (diff) |
Generalize the routine for destroying an object with static
storage duration, then explicitly exempt ownership-qualified
types from it.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@135028 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGDeclCXX.cpp | 96 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 8 |
2 files changed, 55 insertions, 49 deletions
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp index 9c400e75a6..1102da5a61 100644 --- a/lib/CodeGen/CGDeclCXX.cpp +++ b/lib/CodeGen/CGDeclCXX.cpp @@ -53,41 +53,50 @@ static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, /// 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 @@ void CodeGenFunction::GenerateCXXGlobalDtorFunc(llvm::Function *Fn, 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 @@ CodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D, 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; } + diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 6236f3e1e8..d1c6d8bde9 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -1204,6 +1204,10 @@ public: 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 @@ public: 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); |