17196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===--- TransZeroOutPropsInDealloc.cpp - Tranformations to ARC mode ------===// 27196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 37196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// The LLVM Compiler Infrastructure 47196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 57196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 67196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// License. See LICENSE.TXT for details. 77196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 87196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 97196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 107196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// removeZeroOutPropsInDealloc: 117196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 127196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// Removes zero'ing out "strong" @synthesized properties in a -dealloc method. 137196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 147196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 157196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 167196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "Transforms.h" 177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "Internals.h" 18471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer#include "clang/AST/ASTContext.h" 197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace clang; 217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace arcmt; 227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace trans; 237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisnamespace { 257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisclass ZeroOutInDeallocRemover : 277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis public RecursiveASTVisitor<ZeroOutInDeallocRemover> { 287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis typedef RecursiveASTVisitor<ZeroOutInDeallocRemover> base; 297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 307196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis MigrationPass &Pass; 317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis llvm::DenseMap<ObjCPropertyDecl*, ObjCPropertyImplDecl*> SynthesizedProperties; 337196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ImplicitParamDecl *SelfD; 347196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ExprSet Removables; 35e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis Selector FinalizeSel; 367196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidispublic: 38e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis ZeroOutInDeallocRemover(MigrationPass &pass) : Pass(pass), SelfD(0) { 39e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis FinalizeSel = 40e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("finalize")); 41e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis } 427196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 437196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitObjCMessageExpr(ObjCMessageExpr *ME) { 447196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ASTContext &Ctx = Pass.Ctx; 457196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis TransformActions &TA = Pass.TA; 467196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 477196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (ME->getReceiverKind() != ObjCMessageExpr::Instance) 487196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 497196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Expr *receiver = ME->getInstanceReceiver(); 507196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!receiver) 517196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 527196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 537196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis DeclRefExpr *refE = dyn_cast<DeclRefExpr>(receiver->IgnoreParenCasts()); 547196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!refE || refE->getDecl() != SelfD) 557196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 567196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 577196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool BackedBySynthesizeSetter = false; 587196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (llvm::DenseMap<ObjCPropertyDecl*, ObjCPropertyImplDecl*>::iterator 597196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis P = SynthesizedProperties.begin(), 607196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis E = SynthesizedProperties.end(); P != E; ++P) { 617196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ObjCPropertyDecl *PropDecl = P->first; 627196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (PropDecl->getSetterName() == ME->getSelector()) { 637196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis BackedBySynthesizeSetter = true; 647196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis break; 657196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 667196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 677196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!BackedBySynthesizeSetter) 687196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 697196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 707196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Remove the setter message if RHS is null 717196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Transaction Trans(TA); 727196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Expr *RHS = ME->getArg(0); 737196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool RHSIsNull = 747196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis RHS->isNullPointerConstant(Ctx, 757196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Expr::NPC_ValueDependentIsNull); 767196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (RHSIsNull && isRemovable(ME)) 777196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis TA.removeStmt(ME); 787196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 797196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 807196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 817196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 824b9c2d235fb9449e249d74f48ecfec601650de93John McCall bool VisitPseudoObjectExpr(PseudoObjectExpr *POE) { 834b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (isZeroingPropIvar(POE) && isRemovable(POE)) { 844b9c2d235fb9449e249d74f48ecfec601650de93John McCall Transaction Trans(Pass.TA); 854b9c2d235fb9449e249d74f48ecfec601650de93John McCall Pass.TA.removeStmt(POE); 864b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 874b9c2d235fb9449e249d74f48ecfec601650de93John McCall 884b9c2d235fb9449e249d74f48ecfec601650de93John McCall return true; 894b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 904b9c2d235fb9449e249d74f48ecfec601650de93John McCall 917196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool VisitBinaryOperator(BinaryOperator *BOE) { 927196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (isZeroingPropIvar(BOE) && isRemovable(BOE)) { 937196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Transaction Trans(Pass.TA); 947196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Pass.TA.removeStmt(BOE); 957196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 967196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 977196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 987196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 997196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1007196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool TraverseObjCMethodDecl(ObjCMethodDecl *D) { 101e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis if (D->getMethodFamily() != OMF_dealloc && 102e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis !(D->isInstanceMethod() && D->getSelector() == FinalizeSel)) 1037196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 1047196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!D->hasBody()) 1057196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 1067196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1077196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(D->getDeclContext()); 1087196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!IMD) 1097196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 1107196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1117196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SelfD = D->getSelfDecl(); 1127196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis collectRemovables(D->getBody(), Removables); 1137196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1147196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // For a 'dealloc' method use, find all property implementations in 1157196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // this class implementation. 1167196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (ObjCImplDecl::propimpl_iterator 1177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis I = IMD->propimpl_begin(), EI = IMD->propimpl_end(); I != EI; ++I) { 118581deb3da481053c4993c7600f97acf7768caac5David Blaikie ObjCPropertyImplDecl *PID = *I; 1197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (PID->getPropertyImplementation() == 1207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ObjCPropertyImplDecl::Synthesize) { 1217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ObjCPropertyDecl *PD = PID->getPropertyDecl(); 1227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ObjCMethodDecl *setterM = PD->getSetterMethodDecl(); 1237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!(setterM && setterM->isDefined())) { 1247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ObjCPropertyDecl::PropertyAttributeKind AttrKind = 1257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis PD->getPropertyAttributes(); 1267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (AttrKind & 1277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis (ObjCPropertyDecl::OBJC_PR_retain | 1287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ObjCPropertyDecl::OBJC_PR_copy | 1297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ObjCPropertyDecl::OBJC_PR_strong)) 1307196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SynthesizedProperties[PD] = PID; 1317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1337196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1347196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Now, remove all zeroing of ivars etc. 1367196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis base::TraverseObjCMethodDecl(D); 1377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1387196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // clear out for next method. 1397196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SynthesizedProperties.clear(); 1407196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SelfD = 0; 1417196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Removables.clear(); 1427196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 1437196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1447196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1457196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool TraverseFunctionDecl(FunctionDecl *D) { return true; } 1467196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool TraverseBlockDecl(BlockDecl *block) { return true; } 1477196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool TraverseBlockExpr(BlockExpr *block) { return true; } 1487196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1497196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisprivate: 1507196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool isRemovable(Expr *E) const { 1517196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return Removables.count(E); 1527196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1537196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1547196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool isZeroingPropIvar(Expr *E) { 1554b9c2d235fb9449e249d74f48ecfec601650de93John McCall E = E->IgnoreParens(); 1564b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) 1574b9c2d235fb9449e249d74f48ecfec601650de93John McCall return isZeroingPropIvar(BO); 1584b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (PseudoObjectExpr *PO = dyn_cast<PseudoObjectExpr>(E)) 1594b9c2d235fb9449e249d74f48ecfec601650de93John McCall return isZeroingPropIvar(PO); 1604b9c2d235fb9449e249d74f48ecfec601650de93John McCall return false; 1614b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 1627196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1634b9c2d235fb9449e249d74f48ecfec601650de93John McCall bool isZeroingPropIvar(BinaryOperator *BOE) { 1647196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (BOE->getOpcode() == BO_Comma) 1657196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return isZeroingPropIvar(BOE->getLHS()) && 1667196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis isZeroingPropIvar(BOE->getRHS()); 1677196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1687196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (BOE->getOpcode() != BO_Assign) 1694b9c2d235fb9449e249d74f48ecfec601650de93John McCall return false; 1707196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1717196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Expr *LHS = BOE->getLHS(); 1727196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (ObjCIvarRefExpr *IV = dyn_cast<ObjCIvarRefExpr>(LHS)) { 1737196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ObjCIvarDecl *IVDecl = IV->getDecl(); 1747196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!IVDecl->getType()->isObjCObjectPointerType()) 1757196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return false; 1767196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool IvarBacksPropertySynthesis = false; 1777196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (llvm::DenseMap<ObjCPropertyDecl*, ObjCPropertyImplDecl*>::iterator 1787196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis P = SynthesizedProperties.begin(), 1797196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis E = SynthesizedProperties.end(); P != E; ++P) { 1807196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ObjCPropertyImplDecl *PropImpDecl = P->second; 1817196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (PropImpDecl && PropImpDecl->getPropertyIvarDecl() == IVDecl) { 1827196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis IvarBacksPropertySynthesis = true; 1837196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis break; 1847196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1857196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1867196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!IvarBacksPropertySynthesis) 1877196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return false; 1887196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1897196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis else 1907196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return false; 1917196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1924b9c2d235fb9449e249d74f48ecfec601650de93John McCall return isZero(BOE->getRHS()); 1934b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 1944b9c2d235fb9449e249d74f48ecfec601650de93John McCall 1954b9c2d235fb9449e249d74f48ecfec601650de93John McCall bool isZeroingPropIvar(PseudoObjectExpr *PO) { 1964b9c2d235fb9449e249d74f48ecfec601650de93John McCall BinaryOperator *BO = dyn_cast<BinaryOperator>(PO->getSyntacticForm()); 1974b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (!BO) return false; 1984b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (BO->getOpcode() != BO_Assign) return false; 1994b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2004b9c2d235fb9449e249d74f48ecfec601650de93John McCall ObjCPropertyRefExpr *PropRefExp = 2014b9c2d235fb9449e249d74f48ecfec601650de93John McCall dyn_cast<ObjCPropertyRefExpr>(BO->getLHS()->IgnoreParens()); 2024b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (!PropRefExp) return false; 2034b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2044b9c2d235fb9449e249d74f48ecfec601650de93John McCall // TODO: Using implicit property decl. 2054b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (PropRefExp->isImplicitProperty()) 2064b9c2d235fb9449e249d74f48ecfec601650de93John McCall return false; 2074b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2084b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (ObjCPropertyDecl *PDecl = PropRefExp->getExplicitProperty()) { 2094b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (!SynthesizedProperties.count(PDecl)) 2104b9c2d235fb9449e249d74f48ecfec601650de93John McCall return false; 2114b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 2124b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2134b9c2d235fb9449e249d74f48ecfec601650de93John McCall return isZero(cast<OpaqueValueExpr>(BO->getRHS())->getSourceExpr()); 2144b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 2154b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2164b9c2d235fb9449e249d74f48ecfec601650de93John McCall bool isZero(Expr *E) { 2174b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (E->isNullPointerConstant(Pass.Ctx, Expr::NPC_ValueDependentIsNull)) 2187196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 2197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2204b9c2d235fb9449e249d74f48ecfec601650de93John McCall return isZeroingPropIvar(E); 2217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis}; 2237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // anonymous namespace 2257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 226e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidisvoid trans::removeZeroOutPropsInDeallocFinalize(MigrationPass &pass) { 2277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ZeroOutInDeallocRemover trans(pass); 2287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); 2297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} 230