//===--- TransZeroOutPropsInDealloc.cpp - Tranformations to ARC mode ------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// removeZeroOutPropsInDealloc:
//
// Removes zero'ing out "strong" @synthesized properties in a -dealloc method.
//
//===----------------------------------------------------------------------===//

#include "Transforms.h"
#include "Internals.h"

using namespace clang;
using namespace arcmt;
using namespace trans;

namespace {

class ZeroOutInDeallocRemover :
                           public RecursiveASTVisitor<ZeroOutInDeallocRemover> {
  typedef RecursiveASTVisitor<ZeroOutInDeallocRemover> base;

  MigrationPass &Pass;

  llvm::DenseMap<ObjCPropertyDecl*, ObjCPropertyImplDecl*> SynthesizedProperties;
  ImplicitParamDecl *SelfD;
  ExprSet Removables;
  Selector FinalizeSel;

public:
  ZeroOutInDeallocRemover(MigrationPass &pass) : Pass(pass), SelfD(0) {
    FinalizeSel =
        Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("finalize"));
  }

  bool VisitObjCMessageExpr(ObjCMessageExpr *ME) {
    ASTContext &Ctx = Pass.Ctx;
    TransformActions &TA = Pass.TA;

    if (ME->getReceiverKind() != ObjCMessageExpr::Instance)
      return true;
    Expr *receiver = ME->getInstanceReceiver();
    if (!receiver)
      return true;

    DeclRefExpr *refE = dyn_cast<DeclRefExpr>(receiver->IgnoreParenCasts());
    if (!refE || refE->getDecl() != SelfD)
      return true;

    bool BackedBySynthesizeSetter = false;
    for (llvm::DenseMap<ObjCPropertyDecl*, ObjCPropertyImplDecl*>::iterator
         P = SynthesizedProperties.begin(), 
         E = SynthesizedProperties.end(); P != E; ++P) {
      ObjCPropertyDecl *PropDecl = P->first;
      if (PropDecl->getSetterName() == ME->getSelector()) {
        BackedBySynthesizeSetter = true;
        break;
      }
    }
    if (!BackedBySynthesizeSetter)
      return true;
    
    // Remove the setter message if RHS is null
    Transaction Trans(TA);
    Expr *RHS = ME->getArg(0);
    bool RHSIsNull = 
      RHS->isNullPointerConstant(Ctx,
                                 Expr::NPC_ValueDependentIsNull);
    if (RHSIsNull && isRemovable(ME))
      TA.removeStmt(ME);

    return true;
  }

  bool VisitPseudoObjectExpr(PseudoObjectExpr *POE) {
    if (isZeroingPropIvar(POE) && isRemovable(POE)) {
      Transaction Trans(Pass.TA);
      Pass.TA.removeStmt(POE);
    }

    return true;
  }

  bool VisitBinaryOperator(BinaryOperator *BOE) {
    if (isZeroingPropIvar(BOE) && isRemovable(BOE)) {
      Transaction Trans(Pass.TA);
      Pass.TA.removeStmt(BOE);
    }

    return true;
  }

  bool TraverseObjCMethodDecl(ObjCMethodDecl *D) {
    if (D->getMethodFamily() != OMF_dealloc &&
        !(D->isInstanceMethod() && D->getSelector() == FinalizeSel))
      return true;
    if (!D->hasBody())
      return true;

    ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(D->getDeclContext());
    if (!IMD)
      return true;

    SelfD = D->getSelfDecl();
    collectRemovables(D->getBody(), Removables);

    // For a 'dealloc' method use, find all property implementations in
    // this class implementation.
    for (ObjCImplDecl::propimpl_iterator
           I = IMD->propimpl_begin(), EI = IMD->propimpl_end(); I != EI; ++I) {
        ObjCPropertyImplDecl *PID = &*I;
        if (PID->getPropertyImplementation() ==
            ObjCPropertyImplDecl::Synthesize) {
          ObjCPropertyDecl *PD = PID->getPropertyDecl();
          ObjCMethodDecl *setterM = PD->getSetterMethodDecl();
          if (!(setterM && setterM->isDefined())) {
            ObjCPropertyDecl::PropertyAttributeKind AttrKind = 
              PD->getPropertyAttributes();
              if (AttrKind & 
                  (ObjCPropertyDecl::OBJC_PR_retain | 
                   ObjCPropertyDecl::OBJC_PR_copy   |
                   ObjCPropertyDecl::OBJC_PR_strong))
                SynthesizedProperties[PD] = PID;
          }
        }
    }

    // Now, remove all zeroing of ivars etc.
    base::TraverseObjCMethodDecl(D);

    // clear out for next method.
    SynthesizedProperties.clear();
    SelfD = 0;
    Removables.clear();
    return true;
  }

  bool TraverseFunctionDecl(FunctionDecl *D) { return true; }
  bool TraverseBlockDecl(BlockDecl *block) { return true; }
  bool TraverseBlockExpr(BlockExpr *block) { return true; }

private:
  bool isRemovable(Expr *E) const {
    return Removables.count(E);
  }

  bool isZeroingPropIvar(Expr *E) {
    E = E->IgnoreParens();
    if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E))
      return isZeroingPropIvar(BO);
    if (PseudoObjectExpr *PO = dyn_cast<PseudoObjectExpr>(E))
      return isZeroingPropIvar(PO);
    return false;
  }

  bool isZeroingPropIvar(BinaryOperator *BOE) {
    if (BOE->getOpcode() == BO_Comma)
      return isZeroingPropIvar(BOE->getLHS()) &&
             isZeroingPropIvar(BOE->getRHS());

    if (BOE->getOpcode() != BO_Assign)
      return false;

    Expr *LHS = BOE->getLHS();
    if (ObjCIvarRefExpr *IV = dyn_cast<ObjCIvarRefExpr>(LHS)) {
      ObjCIvarDecl *IVDecl = IV->getDecl();
      if (!IVDecl->getType()->isObjCObjectPointerType())
        return false;
      bool IvarBacksPropertySynthesis = false;
      for (llvm::DenseMap<ObjCPropertyDecl*, ObjCPropertyImplDecl*>::iterator
           P = SynthesizedProperties.begin(), 
           E = SynthesizedProperties.end(); P != E; ++P) {
        ObjCPropertyImplDecl *PropImpDecl = P->second;
        if (PropImpDecl && PropImpDecl->getPropertyIvarDecl() == IVDecl) {
          IvarBacksPropertySynthesis = true;
          break;
        }
      }
      if (!IvarBacksPropertySynthesis)
        return false;
    }
    else
        return false;

    return isZero(BOE->getRHS());
  }

  bool isZeroingPropIvar(PseudoObjectExpr *PO) {
    BinaryOperator *BO = dyn_cast<BinaryOperator>(PO->getSyntacticForm());
    if (!BO) return false;
    if (BO->getOpcode() != BO_Assign) return false;

    ObjCPropertyRefExpr *PropRefExp =
      dyn_cast<ObjCPropertyRefExpr>(BO->getLHS()->IgnoreParens());
    if (!PropRefExp) return false;

    // TODO: Using implicit property decl.
    if (PropRefExp->isImplicitProperty())
      return false;

    if (ObjCPropertyDecl *PDecl = PropRefExp->getExplicitProperty()) {
      if (!SynthesizedProperties.count(PDecl))
        return false;
    }

    return isZero(cast<OpaqueValueExpr>(BO->getRHS())->getSourceExpr());
  }

  bool isZero(Expr *E) {
    if (E->isNullPointerConstant(Pass.Ctx, Expr::NPC_ValueDependentIsNull))
      return true;

    return isZeroingPropIvar(E);
  }
};

} // anonymous namespace

void trans::removeZeroOutPropsInDeallocFinalize(MigrationPass &pass) {
  ZeroOutInDeallocRemover trans(pass);
  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
}
