1accaf19bc1129c0273ec50dba52318e60bc29103Benjamin Kramer//===--- TransZeroOutPropsInDealloc.cpp - Transformations 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: 386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ZeroOutInDeallocRemover(MigrationPass &pass) : Pass(pass), SelfD(nullptr) { 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. 116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *PID : IMD->property_impls()) { 117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (PID->getPropertyImplementation() == 118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCPropertyImplDecl::Synthesize) { 119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCPropertyDecl *PD = PID->getPropertyDecl(); 120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCMethodDecl *setterM = PD->getSetterMethodDecl(); 121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!(setterM && setterM->isDefined())) { 122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCPropertyDecl::PropertyAttributeKind AttrKind = 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PD->getPropertyAttributes(); 124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (AttrKind & 125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (ObjCPropertyDecl::OBJC_PR_retain | 126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCPropertyDecl::OBJC_PR_copy | 127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCPropertyDecl::OBJC_PR_strong)) 128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SynthesizedProperties[PD] = PID; 1297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1337196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Now, remove all zeroing of ivars etc. 1347196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis base::TraverseObjCMethodDecl(D); 1357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1367196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // clear out for next method. 1377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SynthesizedProperties.clear(); 1386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SelfD = nullptr; 1397196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Removables.clear(); 1407196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 1417196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1427196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1437196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool TraverseFunctionDecl(FunctionDecl *D) { return true; } 1447196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool TraverseBlockDecl(BlockDecl *block) { return true; } 1457196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool TraverseBlockExpr(BlockExpr *block) { return true; } 1467196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1477196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisprivate: 1487196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool isRemovable(Expr *E) const { 1497196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return Removables.count(E); 1507196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1517196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1527196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool isZeroingPropIvar(Expr *E) { 1534b9c2d235fb9449e249d74f48ecfec601650de93John McCall E = E->IgnoreParens(); 1544b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) 1554b9c2d235fb9449e249d74f48ecfec601650de93John McCall return isZeroingPropIvar(BO); 1564b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (PseudoObjectExpr *PO = dyn_cast<PseudoObjectExpr>(E)) 1574b9c2d235fb9449e249d74f48ecfec601650de93John McCall return isZeroingPropIvar(PO); 1584b9c2d235fb9449e249d74f48ecfec601650de93John McCall return false; 1594b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 1607196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1614b9c2d235fb9449e249d74f48ecfec601650de93John McCall bool isZeroingPropIvar(BinaryOperator *BOE) { 1627196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (BOE->getOpcode() == BO_Comma) 1637196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return isZeroingPropIvar(BOE->getLHS()) && 1647196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis isZeroingPropIvar(BOE->getRHS()); 1657196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1667196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (BOE->getOpcode() != BO_Assign) 1674b9c2d235fb9449e249d74f48ecfec601650de93John McCall return false; 1687196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1697196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Expr *LHS = BOE->getLHS(); 1707196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (ObjCIvarRefExpr *IV = dyn_cast<ObjCIvarRefExpr>(LHS)) { 1717196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ObjCIvarDecl *IVDecl = IV->getDecl(); 1727196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!IVDecl->getType()->isObjCObjectPointerType()) 1737196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return false; 1747196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool IvarBacksPropertySynthesis = false; 1757196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (llvm::DenseMap<ObjCPropertyDecl*, ObjCPropertyImplDecl*>::iterator 1767196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis P = SynthesizedProperties.begin(), 1777196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis E = SynthesizedProperties.end(); P != E; ++P) { 1787196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ObjCPropertyImplDecl *PropImpDecl = P->second; 1797196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (PropImpDecl && PropImpDecl->getPropertyIvarDecl() == IVDecl) { 1807196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis IvarBacksPropertySynthesis = true; 1817196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis break; 1827196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1837196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1847196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (!IvarBacksPropertySynthesis) 1857196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return false; 1867196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1877196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis else 1887196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return false; 1897196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1904b9c2d235fb9449e249d74f48ecfec601650de93John McCall return isZero(BOE->getRHS()); 1914b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 1924b9c2d235fb9449e249d74f48ecfec601650de93John McCall 1934b9c2d235fb9449e249d74f48ecfec601650de93John McCall bool isZeroingPropIvar(PseudoObjectExpr *PO) { 1944b9c2d235fb9449e249d74f48ecfec601650de93John McCall BinaryOperator *BO = dyn_cast<BinaryOperator>(PO->getSyntacticForm()); 1954b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (!BO) return false; 1964b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (BO->getOpcode() != BO_Assign) return false; 1974b9c2d235fb9449e249d74f48ecfec601650de93John McCall 1984b9c2d235fb9449e249d74f48ecfec601650de93John McCall ObjCPropertyRefExpr *PropRefExp = 1994b9c2d235fb9449e249d74f48ecfec601650de93John McCall dyn_cast<ObjCPropertyRefExpr>(BO->getLHS()->IgnoreParens()); 2004b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (!PropRefExp) return false; 2014b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2024b9c2d235fb9449e249d74f48ecfec601650de93John McCall // TODO: Using implicit property decl. 2034b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (PropRefExp->isImplicitProperty()) 2044b9c2d235fb9449e249d74f48ecfec601650de93John McCall return false; 2054b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2064b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (ObjCPropertyDecl *PDecl = PropRefExp->getExplicitProperty()) { 2074b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (!SynthesizedProperties.count(PDecl)) 2084b9c2d235fb9449e249d74f48ecfec601650de93John McCall return false; 2094b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 2104b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2114b9c2d235fb9449e249d74f48ecfec601650de93John McCall return isZero(cast<OpaqueValueExpr>(BO->getRHS())->getSourceExpr()); 2124b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 2134b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2144b9c2d235fb9449e249d74f48ecfec601650de93John McCall bool isZero(Expr *E) { 2154b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (E->isNullPointerConstant(Pass.Ctx, Expr::NPC_ValueDependentIsNull)) 2167196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis return true; 2177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2184b9c2d235fb9449e249d74f48ecfec601650de93John McCall return isZeroingPropIvar(E); 2197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis}; 2217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // anonymous namespace 2237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 224e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidisvoid trans::removeZeroOutPropsInDeallocFinalize(MigrationPass &pass) { 2257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ZeroOutInDeallocRemover trans(pass); 2267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); 2277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} 228