aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-08-16 19:36:17 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-08-16 19:36:17 +0000
commitb193a414f13d7cfa2524a8149eff8d4871f8cbf6 (patch)
tree205f700a68e970dde9b3dde4a5a07cd42787accc /lib/CodeGen/CodeGenModule.cpp
parentfe3010d09cec5cd06e31a3d57fe188a04d9bfa17 (diff)
Patch toward synthesizing non-trivial destructors. WIP
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79199 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--lib/CodeGen/CodeGenModule.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 70aee8f2c3..a92e6d9251 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -657,6 +657,8 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName,
else if (!ClassDecl->hasUserDeclaredConstructor())
DeferredDeclsToEmit.push_back(D);
}
+ else if (isa<CXXDestructorDecl>(FD))
+ DeferredDestructorToEmit(D);
else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
if (MD->isCopyAssignment())
DeferredCopyAssignmentToEmit(D);
@@ -766,6 +768,42 @@ void CodeGenModule::DeferredCopyAssignmentToEmit(GlobalDecl CopyAssignDecl) {
DeferredDeclsToEmit.push_back(CopyAssignDecl);
}
+void CodeGenModule::DeferredDestructorToEmit(GlobalDecl DtorDecl) {
+ const CXXDestructorDecl *DD = cast<CXXDestructorDecl>(DtorDecl.getDecl());
+ const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext());
+ if (ClassDecl->hasTrivialDestructor() ||
+ ClassDecl->hasUserDeclaredDestructor())
+ return;
+
+ for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
+ Base != ClassDecl->bases_end(); ++Base) {
+ CXXRecordDecl *BaseClassDecl
+ = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+ if (const CXXDestructorDecl *BaseDtor =
+ BaseClassDecl->getDestructor(Context))
+ GetAddrOfCXXDestructor(BaseDtor, Dtor_Complete);
+ }
+
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ FieldEnd = ClassDecl->field_end();
+ Field != FieldEnd; ++Field) {
+ QualType FieldType = Context.getCanonicalType((*Field)->getType());
+ if (const ArrayType *Array = Context.getAsArrayType(FieldType))
+ FieldType = Array->getElementType();
+ if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+ if ((*Field)->isAnonymousStructOrUnion())
+ continue;
+ CXXRecordDecl *FieldClassDecl
+ = cast<CXXRecordDecl>(FieldClassType->getDecl());
+ if (const CXXDestructorDecl *FieldDtor =
+ FieldClassDecl->getDestructor(Context))
+ GetAddrOfCXXDestructor(FieldDtor, Dtor_Complete);
+ }
+ }
+ DeferredDeclsToEmit.push_back(DtorDecl);
+}
+
+
/// GetAddrOfFunction - Return the address of the given function. If Ty is
/// non-null, then this function will use the specified type if it has to
/// create it (this occurs when we see a definition of the function).