From aee31ac31696b9c956987e655dc06adb34f992df Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 21 Jul 2009 22:36:06 +0000 Subject: Patch to accomodate Doug's comment on default destruction of base/members for each destructor AST. llvm-svn: 76663 --- clang/lib/AST/DeclCXX.cpp | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) (limited to 'clang/lib/AST/DeclCXX.cpp') diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 78c351035ae..2f8a1ebd7e3 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -480,13 +480,25 @@ CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, } void -CXXDestructorDecl::setBaseOrMemberDestructions(ASTContext &C) { +CXXDestructorDecl::Destroy(ASTContext& C) { + C.Deallocate(BaseOrMemberDestructions); + CXXMethodDecl::Destroy(C); +} + +void +CXXDestructorDecl::computeBaseOrMembersToDestroy(ASTContext &C) { CXXRecordDecl *ClassDecl = cast(getDeclContext()); - llvm::SmallVector AllToDestruct; + llvm::SmallVector AllToDestruct; + for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); VBase != E; ++VBase) { - CXXBaseOrMemberInitializer *Member = - new CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,SourceLocation()); + // Skip over virtual bases which have trivial destructors. + CXXRecordDecl *BaseClassDecl + = cast(VBase->getType()->getAsRecordType()->getDecl()); + if (BaseClassDecl->hasTrivialDestructor()) + continue; + uintptr_t Member = + reinterpret_cast(VBase->getType().getTypePtr()) | 0x1; AllToDestruct.push_back(Member); } for (CXXRecordDecl::base_class_iterator Base = @@ -494,10 +506,17 @@ CXXDestructorDecl::setBaseOrMemberDestructions(ASTContext &C) { E = ClassDecl->bases_end(); Base != E; ++Base) { if (Base->isVirtual()) continue; - CXXBaseOrMemberInitializer *Member = - new CXXBaseOrMemberInitializer(Base->getType(), 0, 0, SourceLocation()); + // Skip over virtual bases which have trivial destructors. + CXXRecordDecl *BaseClassDecl + = cast(Base->getType()->getAsRecordType()->getDecl()); + if (BaseClassDecl->hasTrivialDestructor()) + continue; + + uintptr_t Member = + reinterpret_cast(Base->getType().getTypePtr()) | 0x2; AllToDestruct.push_back(Member); } + // non-static data members. for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), E = ClassDecl->field_end(); Field != E; ++Field) { @@ -506,8 +525,12 @@ CXXDestructorDecl::setBaseOrMemberDestructions(ASTContext &C) { FieldType = AT->getElementType(); if (FieldType->getAsRecordType()) { - CXXBaseOrMemberInitializer *Member = - new CXXBaseOrMemberInitializer((*Field), 0, 0, SourceLocation()); + // Skip over virtual bases which have trivial destructors. + CXXRecordDecl *BaseClassDecl + = cast(FieldType->getAsRecordType()->getDecl()); + if (BaseClassDecl->hasTrivialDestructor()) + continue; + uintptr_t Member = reinterpret_cast(*Field); AllToDestruct.push_back(Member); } } @@ -515,8 +538,7 @@ CXXDestructorDecl::setBaseOrMemberDestructions(ASTContext &C) { unsigned NumDestructions = AllToDestruct.size(); if (NumDestructions > 0) { NumBaseOrMemberDestructions = NumDestructions; - BaseOrMemberDestructions = - new (C) CXXBaseOrMemberInitializer*[NumDestructions]; + BaseOrMemberDestructions = new (C) uintptr_t [NumDestructions]; // Insert in reverse order. for (int Idx = NumDestructions-1, i=0 ; Idx >= 0; --Idx) BaseOrMemberDestructions[i++] = AllToDestruct[Idx]; -- cgit v1.2.3