aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-07-13 03:01:35 +0000
committerJohn McCall <rjmccall@apple.com>2011-07-13 03:01:35 +0000
commita91f6661c4685fecee6dc09bdaef73254c1aaa06 (patch)
tree20ebcef78924c64b7659823e0ecbd92ac592ef04
parente7003b72e691c4d83ba5516c58bccc2f2a4b3fe0 (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.cpp96
-rw-r--r--lib/CodeGen/CodeGenFunction.h8
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);