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