[cfe-commits] r76663 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/Parse/Action.h lib/AST/DeclCXX.cpp lib/AST/DeclPrinter.cpp lib/Parse/ParseCXXInlineMethods.cpp lib/Parse/Parser.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp
Fariborz Jahanian
fjahanian at apple.com
Tue Jul 21 15:36:06 PDT 2009
Author: fjahanian
Date: Tue Jul 21 17:36:06 2009
New Revision: 76663
URL: http://llvm.org/viewvc/llvm-project?rev=76663&view=rev
Log:
Patch to accomodate Doug's comment on default
destruction of base/members for each destructor AST.
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/lib/AST/DeclPrinter.cpp
cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=76663&r1=76662&r2=76663&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Tue Jul 21 17:36:06 2009
@@ -901,10 +901,7 @@
/// 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;
+ uintptr_t *BaseOrMemberDestructions;
unsigned NumBaseOrMemberDestructions;
CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L,
@@ -915,7 +912,8 @@
BaseOrMemberDestructions(0), NumBaseOrMemberDestructions(0) {
setImplicit(isImplicitlyDeclared);
}
-
+ virtual void Destroy(ASTContext& C);
+
public:
static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
@@ -941,32 +939,88 @@
}
/// 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;
+ typedef uintptr_t const destr_const_iterator;
/// destr_begin() - Retrieve an iterator to the first destructed member/base.
- destr_iterator destr_begin() { return BaseOrMemberDestructions; }
+ uintptr_t* destr_begin() {
+ return BaseOrMemberDestructions;
+ }
/// destr_begin() - Retrieve an iterator to the first destructed member/base.
- destr_const_iterator destr_begin() const { return BaseOrMemberDestructions; }
+ uintptr_t* destr_begin() const {
+ return BaseOrMemberDestructions;
+ }
/// destr_end() - Retrieve an iterator past the last destructed member/base.
- destr_iterator destr_end() {
+ uintptr_t* destr_end() {
return BaseOrMemberDestructions + NumBaseOrMemberDestructions;
}
/// destr_end() - Retrieve an iterator past the last destructed member/base.
- destr_const_iterator destr_end() const {
+ uintptr_t* destr_end() const {
return BaseOrMemberDestructions + NumBaseOrMemberDestructions;
}
- /// getNumArgs - Determine the number of arguments used to
- /// destruct the member or base.
+ /// getNumBaseOrMemberDestructions - Number of base and non-static members
+ /// to destroy.
unsigned getNumBaseOrMemberDestructions() const {
return NumBaseOrMemberDestructions;
}
- void setBaseOrMemberDestructions(ASTContext &C);
+ /// getBaseOrMember - get the generic 'member' representing either the field
+ /// or a base class.
+ uintptr_t* getBaseOrMemberToDestroy() const {
+ return BaseOrMemberDestructions;
+ }
+
+ /// isVbaseToDestroy - returns true, if object is virtual base.
+ bool isVbaseToDestroy(uintptr_t Vbase) const {
+ return (Vbase & 0x1) != 0;
+ }
+ /// isDirectNonVBaseToDestroy - returns true, if object is direct non-virtual
+ /// base.
+ bool isDirectNonVBaseToDestroy(uintptr_t DrctNonVbase) const {
+ return (DrctNonVbase & 0x2) != 0;
+ }
+ /// isAnyBaseToDestroy - returns true, if object is any base (virtual or
+ /// direct non-virtual)
+ bool isAnyBaseToDestroy(uintptr_t AnyBase) const {
+ return (AnyBase & 0x3) != 0;
+ }
+ /// isMemberToDestroy - returns true if object is a non-static data member.
+ bool isMemberToDestroy(uintptr_t Member) const {
+ return (Member & 0x3) == 0;
+ }
+ /// getAnyBaseClassToDestroy - Get the type for the given base class object.
+ Type *getAnyBaseClassToDestroy(uintptr_t Base) const {
+ if (isAnyBaseToDestroy(Base))
+ return reinterpret_cast<Type*>(Base & ~0x03);
+ return 0;
+ }
+ /// getMemberToDestroy - Get the member for the given object.
+ FieldDecl *getMemberToDestroy(uintptr_t Member) {
+ if (isMemberToDestroy(Member))
+ return reinterpret_cast<FieldDecl *>(Member);
+ return 0;
+ }
+ /// getVbaseClassToDestroy - Get the virtual base.
+ Type *getVbaseClassToDestroy(uintptr_t Vbase) const {
+ if (isVbaseToDestroy(Vbase))
+ return reinterpret_cast<Type*>(Vbase & ~0x01);
+ return 0;
+ }
+ /// getDirectNonVBaseClassToDestroy - Get the virtual base.
+ Type *getDirectNonVBaseClassToDestroy(uintptr_t Base) const {
+ if (isDirectNonVBaseToDestroy(Base))
+ return reinterpret_cast<Type*>(Base & ~0x02);
+ return 0;
+ }
+
+ /// computeBaseOrMembersToDestroy - Compute information in current
+ /// destructor decl's AST of bases and non-static data members which will be
+ /// implicitly destroyed. We are storing the destruction in the order that
+ /// they should occur (which is the reverse of construction order).
+ void computeBaseOrMembersToDestroy(ASTContext &C);
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=76663&r1=76662&r2=76663&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Jul 21 17:36:06 2009
@@ -1233,7 +1233,7 @@
MemInitTy **MemInits, unsigned NumMemInits){
}
- virtual void ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl) {}
+ virtual void ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) {}
/// ActOnFinishCXXMemberSpecification - Invoked after all member declarators
/// are parsed but *before* parsing of inline method definitions.
Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=76663&r1=76662&r2=76663&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Tue Jul 21 17:36:06 2009
@@ -480,13 +480,25 @@
}
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 @@
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 @@
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 @@
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];
Modified: cfe/trunk/lib/AST/DeclPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=76663&r1=76662&r2=76663&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Tue Jul 21 17:36:06 2009
@@ -376,25 +376,25 @@
}
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 @@
}
Proto += "()";
}
+ Proto += " */";
}
}
else
Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=76663&r1=76662&r2=76663&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Tue Jul 21 17:36:06 2009
@@ -172,7 +172,7 @@
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);
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=76663&r1=76662&r2=76663&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Tue Jul 21 17:36:06 2009
@@ -666,7 +666,7 @@
if (Tok.is(tok::colon))
ParseConstructorInitializer(Res);
else
- Actions.ActOnDefaultCDtorInitializers(Res);
+ Actions.ActOnDefaultCtorInitializers(Res);
return ParseFunctionStatementBody(Res);
}
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=76663&r1=76662&r2=76663&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Jul 21 17:36:06 2009
@@ -1463,7 +1463,7 @@
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,
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=76663&r1=76662&r2=76663&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Jul 21 17:36:06 2009
@@ -3282,12 +3282,15 @@
// 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;
}
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=76663&r1=76662&r2=76663&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Jul 21 17:36:06 2009
@@ -918,7 +918,7 @@
}
}
-void Sema::ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl) {
+void Sema::ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) {
if (!CDtorDecl)
return;
@@ -926,10 +926,6 @@
= 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 {
More information about the cfe-commits
mailing list