summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/DeclCXX.cpp42
-rw-r--r--clang/lib/AST/DeclPrinter.cpp19
2 files changed, 42 insertions, 19 deletions
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<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 @@ 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<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 @@ 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<CXXRecordDecl>(FieldType->getAsRecordType()->getDecl());
+ if (BaseClassDecl->hasTrivialDestructor())
+ continue;
+ uintptr_t Member = reinterpret_cast<uintptr_t>(*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];
diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp
index 84ae72977e6..fcc623ec787 100644
--- a/clang/lib/AST/DeclPrinter.cpp
+++ b/clang/lib/AST/DeclPrinter.cpp
@@ -376,25 +376,25 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
}
else if (CXXDestructorDecl *DDecl = dyn_cast<CXXDestructorDecl>(D)) {
if (DDecl->getNumBaseOrMemberDestructions() > 0) {
- // FIXME. This is strictly for visualization of destructor's AST for
- // how base/members are destructed. It has no other validity.
+ // List order of base/member destruction for visualization purposes.
assert (D->isThisDeclarationADefinition() && "Destructor with dtor-list");
- Proto += " : ";
- for (CXXDestructorDecl::destr_const_iterator B = DDecl->destr_begin(),
- E = DDecl->destr_end();
+ Proto += "/* : ";
+ for (CXXDestructorDecl::destr_const_iterator *B = DDecl->destr_begin(),
+ *E = DDecl->destr_end();
B != E; ++B) {
- CXXBaseOrMemberInitializer * BMInitializer = (*B);
+ uintptr_t BaseOrMember = (*B);
if (B != DDecl->destr_begin())
Proto += ", ";
- if (BMInitializer->isMemberInitializer()) {
- FieldDecl *FD = BMInitializer->getMember();
+ if (DDecl->isMemberToDestroy(BaseOrMember)) {
+ FieldDecl *FD = DDecl->getMemberToDestroy(BaseOrMember);
Proto += "~";
Proto += FD->getNameAsString();
}
else // FIXME. skip dependent types for now.
if (const RecordType *RT =
- BMInitializer->getBaseClass()->getAsRecordType()) {
+ DDecl->getAnyBaseClassToDestroy(BaseOrMember)
+ ->getAsRecordType()) {
const CXXRecordDecl *BaseDecl =
cast<CXXRecordDecl>(RT->getDecl());
Proto += "~";
@@ -402,6 +402,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
}
Proto += "()";
}
+ Proto += " */";
}
}
else
OpenPOWER on IntegriCloud