summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/DeclCXX.cpp42
-rw-r--r--clang/lib/AST/DeclPrinter.cpp19
-rw-r--r--clang/lib/Parse/ParseCXXInlineMethods.cpp2
-rw-r--r--clang/lib/Parse/Parser.cpp2
-rw-r--r--clang/lib/Sema/Sema.h2
-rw-r--r--clang/lib/Sema/SemaDecl.cpp11
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp6
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 {
OpenPOWER on IntegriCloud