Patch to accomodate Doug's comment on default
destruction of base/members for each destructor AST.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76663 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 78c3510..2f8a1eb 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -480,13 +480,25 @@
}
void
-CXXDestructorDecl::setBaseOrMemberDestructions(ASTContext &C) {
+CXXDestructorDecl::Destroy(ASTContext& C) {
+ C.Deallocate(BaseOrMemberDestructions);
+ CXXMethodDecl::Destroy(C);
+}
+
+void
+CXXDestructorDecl::computeBaseOrMembersToDestroy(ASTContext &C) {
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(getDeclContext());
- llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToDestruct;
+ llvm::SmallVector<uintptr_t, 32> 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<CXXRecordDecl>(VBase->getType()->getAsRecordType()->getDecl());
+ if (BaseClassDecl->hasTrivialDestructor())
+ continue;
+ uintptr_t Member =
+ reinterpret_cast<uintptr_t>(VBase->getType().getTypePtr()) | 0x1;
AllToDestruct.push_back(Member);
}
for (CXXRecordDecl::base_class_iterator Base =
@@ -494,10 +506,17 @@
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<CXXRecordDecl>(Base->getType()->getAsRecordType()->getDecl());
+ if (BaseClassDecl->hasTrivialDestructor())
+ continue;
+
+ uintptr_t Member =
+ reinterpret_cast<uintptr_t>(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 @@
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<CXXRecordDecl>(FieldType->getAsRecordType()->getDecl());
+ if (BaseClassDecl->hasTrivialDestructor())
+ continue;
+ uintptr_t Member = reinterpret_cast<uintptr_t>(*Field);
AllToDestruct.push_back(Member);
}
}
@@ -515,8 +538,7 @@
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];