From e81ac69c5da9fadfac33ee76e98d5fb558c4e389 Mon Sep 17 00:00:00 2001 From: John McCall Date: Tue, 22 Mar 2011 07:05:39 +0000 Subject: The emission of an Objective-C++'s class .cxx_destruct method should be conditioned on whether it has any destructible ivars, not on whether it has any non-trivial class-object initializers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128074 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenModule.cpp | 45 +++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 17 deletions(-) (limited to 'lib/CodeGen/CodeGenModule.cpp') diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index ea74abff54..a528d2ede7 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -1937,37 +1937,48 @@ void CodeGenModule::EmitObjCPropertyImplementations(const } } +static bool needsDestructMethod(ObjCImplementationDecl *impl) { + ObjCInterfaceDecl *iface + = const_cast(impl->getClassInterface()); + for (ObjCIvarDecl *ivar = iface->all_declared_ivar_begin(); + ivar; ivar = ivar->getNextIvar()) + if (ivar->getType().isDestructedType()) + return true; + + return false; +} + /// EmitObjCIvarInitializations - Emit information for ivar initialization /// for an implementation. void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) { + // We might need a .cxx_destruct even if we don't have any ivar initializers. + if (needsDestructMethod(D)) { + IdentifierInfo *II = &getContext().Idents.get(".cxx_destruct"); + Selector cxxSelector = getContext().Selectors.getSelector(0, &II); + ObjCMethodDecl *DTORMethod = + ObjCMethodDecl::Create(getContext(), D->getLocation(), D->getLocation(), + cxxSelector, getContext().VoidTy, 0, D, true, + false, true, false, ObjCMethodDecl::Required); + D->addInstanceMethod(DTORMethod); + CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, DTORMethod, false); + } + + // If the implementation doesn't have any ivar initializers, we don't need + // a .cxx_construct. if (D->getNumIvarInitializers() == 0) return; - DeclContext* DC = const_cast(dyn_cast(D)); - assert(DC && "EmitObjCIvarInitializations - null DeclContext"); - IdentifierInfo *II = &getContext().Idents.get(".cxx_destruct"); - Selector cxxSelector = getContext().Selectors.getSelector(0, &II); - ObjCMethodDecl *DTORMethod = ObjCMethodDecl::Create(getContext(), - D->getLocation(), - D->getLocation(), cxxSelector, - getContext().VoidTy, 0, - DC, true, false, true, false, - ObjCMethodDecl::Required); - D->addInstanceMethod(DTORMethod); - CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, DTORMethod, false); - II = &getContext().Idents.get(".cxx_construct"); - cxxSelector = getContext().Selectors.getSelector(0, &II); + IdentifierInfo *II = &getContext().Idents.get(".cxx_construct"); + Selector cxxSelector = getContext().Selectors.getSelector(0, &II); // The constructor returns 'self'. ObjCMethodDecl *CTORMethod = ObjCMethodDecl::Create(getContext(), D->getLocation(), D->getLocation(), cxxSelector, getContext().getObjCIdType(), 0, - DC, true, false, true, false, + D, true, false, true, false, ObjCMethodDecl::Required); D->addInstanceMethod(CTORMethod); CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, CTORMethod, true); - - } /// EmitNamespace - Emit all declarations in a namespace. -- cgit v1.2.3-70-g09d2