diff options
author | Anders Carlsson <andersca@mac.com> | 2009-11-17 04:44:12 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-11-17 04:44:12 +0000 |
commit | 9f853df0d3c25c646907a7b7ef22398370def00f (patch) | |
tree | 3a7ff5637f4a9d49e3b36cc8cd91ed793e343770 /lib/Sema/SemaDeclCXX.cpp | |
parent | 0ed303c918915cbe2c611cddbfabd00404664831 (diff) |
Unify the way destructor epilogues are generated for synthesized and regular destructors. Also fix PR5529.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89034 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 104 |
1 files changed, 45 insertions, 59 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 18e62291e5..9ba03a90fc 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1633,77 +1633,63 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, } void -Sema::computeBaseOrMembersToDestroy(CXXDestructorDecl *Destructor) { - CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Destructor->getDeclContext()); - llvm::SmallVector<uintptr_t, 32> AllToDestruct; +Sema::MarkBaseAndMemberDestructorsReferenced(CXXDestructorDecl *Destructor) { + // Ignore dependent destructors. + if (Destructor->isDependentContext()) + return; + + CXXRecordDecl *ClassDecl = Destructor->getParent(); - for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(), - E = ClassDecl->vbases_end(); VBase != E; ++VBase) { - if (VBase->getType()->isDependentType()) + // Non-static data members. + for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), + E = ClassDecl->field_end(); I != E; ++I) { + FieldDecl *Field = *I; + + QualType FieldType = Context.getBaseElementType(Field->getType()); + + const RecordType* RT = FieldType->getAs<RecordType>(); + if (!RT) continue; - // Skip over virtual bases which have trivial destructors. - CXXRecordDecl *BaseClassDecl - = cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl()); - if (BaseClassDecl->hasTrivialDestructor()) + + CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); + if (FieldClassDecl->hasTrivialDestructor()) continue; - if (const CXXDestructorDecl *Dtor = BaseClassDecl->getDestructor(Context)) - MarkDeclarationReferenced(Destructor->getLocation(), - const_cast<CXXDestructorDecl*>(Dtor)); - uintptr_t Member = - reinterpret_cast<uintptr_t>(VBase->getType().getTypePtr()) - | CXXDestructorDecl::VBASE; - AllToDestruct.push_back(Member); + const CXXDestructorDecl *Dtor = FieldClassDecl->getDestructor(Context); + MarkDeclarationReferenced(Destructor->getLocation(), + const_cast<CXXDestructorDecl*>(Dtor)); } - for (CXXRecordDecl::base_class_iterator Base = - ClassDecl->bases_begin(), + + // Bases. + for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), E = ClassDecl->bases_end(); Base != E; ++Base) { + // Ignore virtual bases. if (Base->isVirtual()) continue; - if (Base->getType()->isDependentType()) - continue; - // Skip over virtual bases which have trivial destructors. + + // Ignore trivial destructors. CXXRecordDecl *BaseClassDecl - = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); + = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); if (BaseClassDecl->hasTrivialDestructor()) continue; - if (const CXXDestructorDecl *Dtor = BaseClassDecl->getDestructor(Context)) - MarkDeclarationReferenced(Destructor->getLocation(), - const_cast<CXXDestructorDecl*>(Dtor)); - uintptr_t Member = - reinterpret_cast<uintptr_t>(Base->getType().getTypePtr()) - | CXXDestructorDecl::DRCTNONVBASE; - AllToDestruct.push_back(Member); - } - - // non-static data members. - for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), - E = ClassDecl->field_end(); Field != E; ++Field) { - QualType FieldType = Context.getBaseElementType((*Field)->getType()); - - if (const RecordType* RT = FieldType->getAs<RecordType>()) { - // Skip over virtual bases which have trivial destructors. - CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); - if (FieldClassDecl->hasTrivialDestructor()) - continue; - if (const CXXDestructorDecl *Dtor = - FieldClassDecl->getDestructor(Context)) - MarkDeclarationReferenced(Destructor->getLocation(), - const_cast<CXXDestructorDecl*>(Dtor)); - uintptr_t Member = reinterpret_cast<uintptr_t>(*Field); - AllToDestruct.push_back(Member); - } + + const CXXDestructorDecl *Dtor = BaseClassDecl->getDestructor(Context); + MarkDeclarationReferenced(Destructor->getLocation(), + const_cast<CXXDestructorDecl*>(Dtor)); } - - unsigned NumDestructions = AllToDestruct.size(); - if (NumDestructions > 0) { - Destructor->setNumBaseOrMemberDestructions(NumDestructions); - uintptr_t *BaseOrMemberDestructions = - new (Context) uintptr_t [NumDestructions]; - // Insert in reverse order. - for (int Idx = NumDestructions-1, i=0 ; Idx >= 0; --Idx) - BaseOrMemberDestructions[i++] = AllToDestruct[Idx]; - Destructor->setBaseOrMemberDestructions(BaseOrMemberDestructions); + + // Virtual bases. + for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(), + E = ClassDecl->vbases_end(); VBase != E; ++VBase) { + // Ignore trivial destructors. + CXXRecordDecl *BaseClassDecl + = cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl()); + if (BaseClassDecl->hasTrivialDestructor()) + continue; + + const CXXDestructorDecl *Dtor = BaseClassDecl->getDestructor(Context); + MarkDeclarationReferenced(Destructor->getLocation(), + const_cast<CXXDestructorDecl*>(Dtor)); } } |