diff options
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 42 | ||||
-rw-r--r-- | clang/lib/AST/DeclPrinter.cpp | 19 |
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 |