diff options
| author | Fariborz Jahanian <fjahanian@apple.com> | 2009-07-15 22:34:08 +0000 |
|---|---|---|
| committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-07-15 22:34:08 +0000 |
| commit | 16094c2467e79ebcfe739da3582283b9d599de54 (patch) | |
| tree | 67f63c2d978e4d4ce53fd291ce7032cac866e771 /clang/lib/AST | |
| parent | c901392ba4a13e2e1894ea9888938d4d80d80725 (diff) | |
| download | bcm5719-llvm-16094c2467e79ebcfe739da3582283b9d599de54.tar.gz bcm5719-llvm-16094c2467e79ebcfe739da3582283b9d599de54.zip | |
Added ASTs to destructor decl AST for default destruction of object's
base/members.
llvm-svn: 75849
Diffstat (limited to 'clang/lib/AST')
| -rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 44 | ||||
| -rw-r--r-- | clang/lib/AST/DeclPrinter.cpp | 30 |
2 files changed, 74 insertions, 0 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 674e98a2657..57ac611b2ca 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -478,6 +478,50 @@ CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, } void +CXXDestructorDecl::setBaseOrMemberDestructions(ASTContext &C) { + CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(getDeclContext()); + llvm::SmallVector<CXXBaseOrMemberInitializer*, 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()); + AllToDestruct.push_back(Member); + } + for (CXXRecordDecl::base_class_iterator Base = + ClassDecl->bases_begin(), + E = ClassDecl->bases_end(); Base != E; ++Base) { + if (Base->isVirtual()) + continue; + CXXBaseOrMemberInitializer *Member = + new CXXBaseOrMemberInitializer(Base->getType(), 0, 0, SourceLocation()); + 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 = C.getCanonicalType((*Field)->getType()); + while (const ArrayType *AT = C.getAsArrayType(FieldType)) + FieldType = AT->getElementType(); + + if (FieldType->getAsRecordType()) { + CXXBaseOrMemberInitializer *Member = + new CXXBaseOrMemberInitializer((*Field), 0, 0, SourceLocation()); + AllToDestruct.push_back(Member); + } + } + + unsigned NumDestructions = AllToDestruct.size(); + if (NumDestructions > 0) { + NumBaseOrMemberDestructions = NumDestructions; + BaseOrMemberDestructions = + new (C) CXXBaseOrMemberInitializer*[NumDestructions]; + // Insert in reverse order. + for (int Idx = NumDestructions-1, i=0 ; Idx >= 0; --Idx) + BaseOrMemberDestructions[i++] = AllToDestruct[Idx]; + } +} + +void CXXConstructorDecl::setBaseOrMemberInitializers( ASTContext &C, CXXBaseOrMemberInitializer **Initializers, diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index c7ad8d0a711..84ae72977e6 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -374,6 +374,36 @@ 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. + assert (D->isThisDeclarationADefinition() && "Destructor with dtor-list"); + Proto += " : "; + for (CXXDestructorDecl::destr_const_iterator B = DDecl->destr_begin(), + E = DDecl->destr_end(); + B != E; ++B) { + CXXBaseOrMemberInitializer * BMInitializer = (*B); + if (B != DDecl->destr_begin()) + Proto += ", "; + + if (BMInitializer->isMemberInitializer()) { + FieldDecl *FD = BMInitializer->getMember(); + Proto += "~"; + Proto += FD->getNameAsString(); + } + else // FIXME. skip dependent types for now. + if (const RecordType *RT = + BMInitializer->getBaseClass()->getAsRecordType()) { + const CXXRecordDecl *BaseDecl = + cast<CXXRecordDecl>(RT->getDecl()); + Proto += "~"; + Proto += BaseDecl->getNameAsString(); + } + Proto += "()"; + } + } + } else AFT->getResultType().getAsStringInternal(Proto, Policy); } else { |

