[cfe-commits] r80967 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/AST/DeclCXX.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExprCXX.cpp test/CodeGenCXX/constructor-template.cpp
Fariborz Jahanian
fjahanian at apple.com
Thu Sep 3 16:18:17 PDT 2009
Author: fjahanian
Date: Thu Sep 3 18:18:17 2009
New Revision: 80967
URL: http://llvm.org/viewvc/llvm-project?rev=80967&view=rev
Log:
Patch to instantiate destructors used to destruct
base and data members when they are needed.
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/CodeGenCXX/constructor-template.cpp
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=80967&r1=80966&r2=80967&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Thu Sep 3 18:18:17 2009
@@ -1095,12 +1095,13 @@
/// };
/// @endcode
class CXXDestructorDecl : public CXXMethodDecl {
+public:
enum KindOfObjectToDestroy {
VBASE = 0x1,
DRCTNONVBASE = 0x2,
ANYBASE = 0x3
};
-
+private:
/// ImplicitlyDefined - Whether this destructor was implicitly
/// defined by the compiler. When false, the destructor was defined
/// by the user. In C++03, this flag will have the same value as
@@ -1181,12 +1182,24 @@
return NumBaseOrMemberDestructions;
}
- /// getBaseOrMember - get the generic 'member' representing either the field
- /// or a base class.
+ /// setNumBaseOrMemberDestructions - Set number of base and non-static members
+ /// to destroy.
+ void setNumBaseOrMemberDestructions(unsigned numBaseOrMemberDestructions) {
+ NumBaseOrMemberDestructions = numBaseOrMemberDestructions;
+ }
+
+ /// getBaseOrMemberToDestroy - get the generic 'member' representing either
+ /// the field or a base class.
uintptr_t* getBaseOrMemberToDestroy() const {
return BaseOrMemberDestructions;
}
+ /// setBaseOrMemberToDestroy - set the generic 'member' representing either
+ /// the field or a base class.
+ void setBaseOrMemberDestructions(uintptr_t* baseOrMemberDestructions) {
+ BaseOrMemberDestructions = baseOrMemberDestructions;
+ }
+
/// isVbaseToDestroy - returns true, if object is virtual base.
bool isVbaseToDestroy(uintptr_t Vbase) const {
return (Vbase & VBASE) != 0;
@@ -1229,12 +1242,6 @@
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/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=80967&r1=80966&r2=80967&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Thu Sep 3 18:18:17 2009
@@ -523,67 +523,6 @@
}
void
-CXXDestructorDecl::computeBaseOrMembersToDestroy(ASTContext &C) {
- CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(getDeclContext());
- llvm::SmallVector<uintptr_t, 32> AllToDestruct;
-
- for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(),
- E = ClassDecl->vbases_end(); VBase != E; ++VBase) {
- if (VBase->getType()->isDependentType())
- continue;
- // Skip over virtual bases which have trivial destructors.
- CXXRecordDecl *BaseClassDecl
- = cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
- if (BaseClassDecl->hasTrivialDestructor())
- continue;
- uintptr_t Member =
- reinterpret_cast<uintptr_t>(VBase->getType().getTypePtr()) | VBASE;
- AllToDestruct.push_back(Member);
- }
- for (CXXRecordDecl::base_class_iterator Base =
- ClassDecl->bases_begin(),
- E = ClassDecl->bases_end(); Base != E; ++Base) {
- if (Base->isVirtual())
- continue;
- if (Base->getType()->isDependentType())
- continue;
- // Skip over virtual bases which have trivial destructors.
- CXXRecordDecl *BaseClassDecl
- = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
- if (BaseClassDecl->hasTrivialDestructor())
- continue;
-
- uintptr_t Member =
- reinterpret_cast<uintptr_t>(Base->getType().getTypePtr()) | DRCTNONVBASE;
- 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.getBaseElementType((*Field)->getType());
-
- if (const RecordType* RT = FieldType->getAs<RecordType>()) {
- // Skip over virtual bases which have trivial destructors.
- CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
- if (BaseClassDecl->hasTrivialDestructor())
- continue;
- uintptr_t Member = reinterpret_cast<uintptr_t>(*Field);
- AllToDestruct.push_back(Member);
- }
- }
-
- unsigned NumDestructions = AllToDestruct.size();
- if (NumDestructions > 0) {
- NumBaseOrMemberDestructions = 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];
- }
-}
-
-void
CXXConstructorDecl::Destroy(ASTContext& C) {
C.Deallocate(BaseOrMemberInitializers);
CXXMethodDecl::Destroy(C);
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=80967&r1=80966&r2=80967&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Sep 3 18:18:17 2009
@@ -2191,6 +2191,12 @@
llvm::SmallVectorImpl<CXXBaseSpecifier *>& Bases,
llvm::SmallVectorImpl<FieldDecl *>&Members);
+ /// 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(CXXDestructorDecl *Destructor);
+
void AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl);
virtual void ActOnMemInitializers(DeclPtrTy ConstructorDecl,
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=80967&r1=80966&r2=80967&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Sep 3 18:18:17 2009
@@ -3758,7 +3758,7 @@
DiagnoseReturnInConstructorExceptionHandler(cast<CXXTryStmt>(Body));
if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(dcl))
- Destructor->computeBaseOrMembersToDestroy(Context);
+ computeBaseOrMembersToDestroy(Destructor);
return D;
}
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=80967&r1=80966&r2=80967&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Sep 3 18:18:17 2009
@@ -1284,6 +1284,81 @@
}
}
+void
+Sema::computeBaseOrMembersToDestroy(CXXDestructorDecl *Destructor) {
+ CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Destructor->getDeclContext());
+ llvm::SmallVector<uintptr_t, 32> AllToDestruct;
+
+ for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(),
+ E = ClassDecl->vbases_end(); VBase != E; ++VBase) {
+ if (VBase->getType()->isDependentType())
+ continue;
+ // Skip over virtual bases which have trivial destructors.
+ CXXRecordDecl *BaseClassDecl
+ = cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
+ if (BaseClassDecl->hasTrivialDestructor())
+ continue;
+ if (const CXXDestructorDecl *Dtor = BaseClassDecl->getDestructor(Context))
+ MarkDeclarationReferenced(Destructor->getLocation(),
+ const_cast<CXXDestructorDecl*>(Dtor));
+
+ uintptr_t Member =
+ reinterpret_cast<uintptr_t>(VBase->getType().getTypePtr())
+ | CXXDestructorDecl::VBASE;
+ AllToDestruct.push_back(Member);
+ }
+ for (CXXRecordDecl::base_class_iterator Base =
+ ClassDecl->bases_begin(),
+ E = ClassDecl->bases_end(); Base != E; ++Base) {
+ if (Base->isVirtual())
+ continue;
+ if (Base->getType()->isDependentType())
+ continue;
+ // Skip over virtual bases which have trivial destructors.
+ CXXRecordDecl *BaseClassDecl
+ = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+ if (BaseClassDecl->hasTrivialDestructor())
+ continue;
+ if (const CXXDestructorDecl *Dtor = BaseClassDecl->getDestructor(Context))
+ MarkDeclarationReferenced(Destructor->getLocation(),
+ const_cast<CXXDestructorDecl*>(Dtor));
+ uintptr_t Member =
+ reinterpret_cast<uintptr_t>(Base->getType().getTypePtr())
+ | CXXDestructorDecl::DRCTNONVBASE;
+ 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 = Context.getBaseElementType((*Field)->getType());
+
+ if (const RecordType* RT = FieldType->getAs<RecordType>()) {
+ // Skip over virtual bases which have trivial destructors.
+ CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+ if (FieldClassDecl->hasTrivialDestructor())
+ continue;
+ if (const CXXDestructorDecl *Dtor =
+ FieldClassDecl->getDestructor(Context))
+ MarkDeclarationReferenced(Destructor->getLocation(),
+ const_cast<CXXDestructorDecl*>(Dtor));
+ uintptr_t Member = reinterpret_cast<uintptr_t>(*Field);
+ AllToDestruct.push_back(Member);
+ }
+ }
+
+ unsigned NumDestructions = AllToDestruct.size();
+ if (NumDestructions > 0) {
+ Destructor->setNumBaseOrMemberDestructions(NumDestructions);
+ uintptr_t *BaseOrMemberDestructions =
+ new (Context) uintptr_t [NumDestructions];
+ // Insert in reverse order.
+ for (int Idx = NumDestructions-1, i=0 ; Idx >= 0; --Idx)
+ BaseOrMemberDestructions[i++] = AllToDestruct[Idx];
+ Destructor->setBaseOrMemberDestructions(BaseOrMemberDestructions);
+ }
+}
+
void Sema::ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) {
if (!CDtorDecl)
return;
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=80967&r1=80966&r2=80967&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Sep 3 18:18:17 2009
@@ -757,6 +757,10 @@
&DeleteArg, 1, Record, /*AllowMissing=*/true,
OperatorDelete))
return ExprError();
+ if (!Record->hasTrivialDestructor())
+ if (const CXXDestructorDecl *Dtor = Record->getDestructor(Context))
+ MarkDeclarationReferenced(StartLoc,
+ const_cast<CXXDestructorDecl*>(Dtor));
}
if (!OperatorDelete) {
Modified: cfe/trunk/test/CodeGenCXX/constructor-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/constructor-template.cpp?rev=80967&r1=80966&r2=80967&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/constructor-template.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/constructor-template.cpp Thu Sep 3 18:18:17 2009
@@ -22,12 +22,14 @@
template <typename T> class List {
public:
List(){ } // List<BinomialNode<int>*>::List() remains undefined.
+ ~List() {}
};
template <typename T> class Node {
int i;
public:
Node(){ } // Node<BinomialNode<int>*>::Node() remains undefined.
+ ~Node() {}
};
@@ -40,10 +42,15 @@
int main() {
B<int> *n = new B<int>(4);
BinomialNode<int> *node = new BinomialNode<int>(1);
+ delete node;
}
+// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEED1Ev:
+// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEED2Ev:
// CHECK-LP64: __ZN4NodeIP12BinomialNodeIiEEC1Ev:
// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEEC1Ev:
+// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEED1Ev:
+// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEED2Ev:
// CHECK-LP32: __ZN4NodeIP12BinomialNodeIiEEC1Ev:
// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEEC1Ev:
More information about the cfe-commits
mailing list