diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 42 | ||||
-rw-r--r-- | clang/lib/AST/DeclPrinter.cpp | 19 | ||||
-rw-r--r-- | clang/lib/Parse/ParseCXXInlineMethods.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 6 |
7 files changed, 53 insertions, 31 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 diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 3bb9c3eb9c2..613e0e33f7b 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -172,7 +172,7 @@ void Parser::ParseLexedMethodDefs(ParsingClass &Class) { if (Tok.is(tok::colon)) ParseConstructorInitializer(LM.D); else - Actions.ActOnDefaultCDtorInitializers(LM.D); + Actions.ActOnDefaultCtorInitializers(LM.D); // FIXME: What if ParseConstructorInitializer doesn't leave us with a '{'?? ParseFunctionStatementBody(LM.D); diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index e7b0f337320..32604442406 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -666,7 +666,7 @@ Parser::DeclPtrTy Parser::ParseFunctionDefinition(Declarator &D, if (Tok.is(tok::colon)) ParseConstructorInitializer(Res); else - Actions.ActOnDefaultCDtorInitializers(Res); + Actions.ActOnDefaultCtorInitializers(Res); return ParseFunctionStatementBody(Res); } diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 47938dcd417..f13ebd3eb31 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1463,7 +1463,7 @@ public: SourceLocation MemberLoc, IdentifierInfo &Member, DeclPtrTy ImplDecl); - virtual void ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl); + virtual void ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl); bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, FunctionDecl *FDecl, const FunctionProtoType *Proto, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 989e08ee9da..4674327e6cf 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3282,12 +3282,15 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg, // Verify that that gotos and switch cases don't jump into scopes illegally. if (CurFunctionNeedsScopeChecking) DiagnoseInvalidJumps(Body); - - // C++ constructors that have function-try-blocks can't have return statements - // in the handlers of that block. (C++ [except.handle]p14) Verify this. + + // C++ constructors that have function-try-blocks can't have return + // statements in the handlers of that block. (C++ [except.handle]p14) + // Verify this. if (isa<CXXConstructorDecl>(dcl) && isa<CXXTryStmt>(Body)) DiagnoseReturnInConstructorExceptionHandler(cast<CXXTryStmt>(Body)); - + + if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(dcl)) + Destructor->computeBaseOrMembersToDestroy(Context); return D; } diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index cb62debfe95..1dcac3fc9ec 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -918,7 +918,7 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, } } -void Sema::ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl) { +void Sema::ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) { if (!CDtorDecl) return; @@ -926,10 +926,6 @@ void Sema::ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl) { = 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 { |