From: Fariborz Jahanian Date: Sun, 16 Aug 2009 19:36:17 +0000 (+0000) Subject: Patch toward synthesizing non-trivial destructors. WIP X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b193a414f13d7cfa2524a8149eff8d4871f8cbf6;p=clang Patch toward synthesizing non-trivial destructors. WIP git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79199 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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(FD)) + DeferredDestructorToEmit(D); else if (const CXXMethodDecl *MD = dyn_cast(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(DtorDecl.getDecl()); + const CXXRecordDecl *ClassDecl = cast(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(Base->getType()->getAs()->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()) { + if ((*Field)->isAnonymousStructOrUnion()) + continue; + CXXRecordDecl *FieldClassDecl + = cast(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). diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 8f69df51a5..cb3f0ba687 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -399,6 +399,7 @@ private: const VarDecl *D); void DeferredCopyConstructorToEmit(GlobalDecl D); void DeferredCopyAssignmentToEmit(GlobalDecl D); + void DeferredDestructorToEmit(GlobalDecl D); /// SetCommonAttributes - Set attributes which are common to any /// form of a global definition (alias, Objective-C method,