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 | 560de45ccbf21c5e4dbeef3fc49f932e499cc181 (patch) | |
tree | f9d477eeec5d7b350031c47efa84bea707e325d5 | |
parent | fde2efe96e00c5d03e7caaf0c1e67d7b011d9d0c (diff) |
Added ASTs to destructor decl AST for default destruction of object's
base/members.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75849 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/DeclCXX.h | 39 | ||||
-rw-r--r-- | include/clang/Parse/Action.h | 2 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 44 | ||||
-rw-r--r-- | lib/AST/DeclPrinter.cpp | 30 | ||||
-rw-r--r-- | lib/Parse/ParseCXXInlineMethods.cpp | 2 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 11 |
8 files changed, 123 insertions, 9 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index ff0dd676aa..af4976df76 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -895,7 +895,16 @@ class CXXDestructorDecl : public CXXMethodDecl { /// explicitly defaulted (i.e., defined with " = default") will have /// @c !Implicit && ImplicitlyDefined. bool ImplicitlyDefined : 1; - + + /// Support for base and member destruction. + /// BaseOrMemberDestructions - The arguments used to destruct the base + /// or member. + // FIXME. May want to use a new class as CXXBaseOrMemberInitializer has + // more info. than is needed. At the least, CXXBaseOrMemberInitializer need + // be renamed to something neutral. + CXXBaseOrMemberInitializer **BaseOrMemberDestructions; + unsigned NumBaseOrMemberDestructions; + CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L, DeclarationName N, QualType T, bool isInline, bool isImplicitlyDeclared) @@ -928,6 +937,34 @@ public: ImplicitlyDefined = ID; } + /// destr_iterator - Iterates through the member/base destruction list. + typedef CXXBaseOrMemberInitializer **destr_iterator; + + /// destr_const_iterator - Iterates through the member/base destruction list. + typedef CXXBaseOrMemberInitializer * const * destr_const_iterator; + + /// destr_begin() - Retrieve an iterator to the first destructed member/base. + destr_iterator destr_begin() { return BaseOrMemberDestructions; } + /// destr_begin() - Retrieve an iterator to the first destructed member/base. + destr_const_iterator destr_begin() const { return BaseOrMemberDestructions; } + + /// destr_end() - Retrieve an iterator past the last destructed member/base. + destr_iterator destr_end() { + return BaseOrMemberDestructions + NumBaseOrMemberDestructions; + } + /// destr_end() - Retrieve an iterator past the last destructed member/base. + destr_const_iterator destr_end() const { + return BaseOrMemberDestructions + NumBaseOrMemberDestructions; + } + + /// getNumArgs - Determine the number of arguments used to + /// destruct the member or base. + unsigned getNumBaseOrMemberDestructions() const { + return NumBaseOrMemberDestructions; + } + + void setBaseOrMemberDestructions(ASTContext &C); + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == CXXDestructor; diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index b88ea17a67..1f6780e1fe 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -1233,7 +1233,7 @@ public: MemInitTy **MemInits, unsigned NumMemInits){ } - virtual void ActOnDefaultInitializers(DeclPtrTy ConstructorDecl) {} + virtual void ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl) {} /// ActOnFinishCXXMemberSpecification - Invoked after all member declarators /// are parsed but *before* parsing of inline method definitions. diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 674e98a265..57ac611b2c 100644 --- a/lib/AST/DeclCXX.cpp +++ b/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/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index c7ad8d0a71..84ae72977e 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/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 { diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp index 8dcf24f86a..3bb9c3eb9c 100644 --- a/lib/Parse/ParseCXXInlineMethods.cpp +++ b/lib/Parse/ParseCXXInlineMethods.cpp @@ -172,7 +172,7 @@ void Parser::ParseLexedMethodDefs(ParsingClass &Class) { if (Tok.is(tok::colon)) ParseConstructorInitializer(LM.D); else - Actions.ActOnDefaultInitializers(LM.D); + Actions.ActOnDefaultCDtorInitializers(LM.D); // FIXME: What if ParseConstructorInitializer doesn't leave us with a '{'?? ParseFunctionStatementBody(LM.D); diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index bac3a86dc4..e7b0f33732 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -666,7 +666,7 @@ Parser::DeclPtrTy Parser::ParseFunctionDefinition(Declarator &D, if (Tok.is(tok::colon)) ParseConstructorInitializer(Res); else - Actions.ActOnDefaultInitializers(Res); + Actions.ActOnDefaultCDtorInitializers(Res); return ParseFunctionStatementBody(Res); } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index e01bf23ce6..f17b77baaa 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1468,7 +1468,7 @@ public: SourceLocation MemberLoc, IdentifierInfo &Member, DeclPtrTy ImplDecl); - virtual void ActOnDefaultInitializers(DeclPtrTy ConstructorDecl); + virtual void ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl); bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, FunctionDecl *FDecl, const FunctionProtoType *Proto, diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 7d039dc2d6..c62858ac73 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -902,15 +902,18 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, } } -void Sema::ActOnDefaultInitializers(DeclPtrTy ConstructorDecl) { - if (!ConstructorDecl) +void Sema::ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl) { + if (!CDtorDecl) return; if (CXXConstructorDecl *Constructor - = dyn_cast<CXXConstructorDecl>(ConstructorDecl.getAs<Decl>())) + = dyn_cast<CXXConstructorDecl>(CDtorDecl.getAs<Decl>())) Constructor->setBaseOrMemberInitializers(Context, (CXXBaseOrMemberInitializer **)0, 0); - + else + if (CXXDestructorDecl *Destructor + = dyn_cast<CXXDestructorDecl>(CDtorDecl.getAs<Decl>())) + Destructor->setBaseOrMemberDestructions(Context); } namespace { |