//===--- TransEmptyStatements.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.
//
//===----------------------------------------------------------------------===//
//
// removeEmptyStatementsAndDealloc:
//
// Removes empty statements that are leftovers from previous transformations.
// e.g for
//
//  [x retain];
//
// removeRetainReleaseDealloc will leave an empty ";" that removeEmptyStatements
// will remove.
//
//===----------------------------------------------------------------------===//

#include "Transforms.h"
#include "Internals.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/SourceManager.h"

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

static bool isEmptyARCMTMacroStatement(NullStmt *S,
                                       std::vector<SourceLocation> &MacroLocs,
                                       ASTContext &Ctx) {
  if (!S->hasLeadingEmptyMacro())
    return false;

  SourceLocation SemiLoc = S->getSemiLoc();
  if (SemiLoc.isInvalid() || SemiLoc.isMacroID())
    return false;

  if (MacroLocs.empty())
    return false;

  SourceManager &SM = Ctx.getSourceManager();
  std::vector<SourceLocation>::iterator
    I = std::upper_bound(MacroLocs.begin(), MacroLocs.end(), SemiLoc,
                         SourceManager::LocBeforeThanCompare(SM));
  --I;
  SourceLocation
      AfterMacroLoc = I->getLocWithOffset(getARCMTMacroName().size());
  assert(AfterMacroLoc.isFileID());

  if (AfterMacroLoc == SemiLoc)
    return true;

  int RelOffs = 0;
  if (!SM.isInSameSLocAddrSpace(AfterMacroLoc, SemiLoc, &RelOffs))
    return false;
  if (RelOffs < 0)
    return false;

  // We make the reasonable assumption that a semicolon after 100 characters
  // means that it is not the next token after our macro. If this assumption
  // fails it is not critical, we will just fail to clear out, e.g., an empty
  // 'if'.
  if (RelOffs - getARCMTMacroName().size() > 100)
    return false;

  SourceLocation AfterMacroSemiLoc = findSemiAfterLocation(AfterMacroLoc, Ctx);
  return AfterMacroSemiLoc == SemiLoc;
}

namespace {

/// \brief Returns true if the statement became empty due to previous
/// transformations.
class EmptyChecker : public StmtVisitor<EmptyChecker, bool> {
  ASTContext &Ctx;
  std::vector<SourceLocation> &MacroLocs;

public:
  EmptyChecker(ASTContext &ctx, std::vector<SourceLocation> &macroLocs)
    : Ctx(ctx), MacroLocs(macroLocs) { }

  bool VisitNullStmt(NullStmt *S) {
    return isEmptyARCMTMacroStatement(S, MacroLocs, Ctx);
  }
  bool VisitCompoundStmt(CompoundStmt *S) {
    if (S->body_empty())
      return false; // was already empty, not because of transformations.
    for (CompoundStmt::body_iterator
           I = S->body_begin(), E = S->body_end(); I != E; ++I)
      if (!Visit(*I))
        return false;
    return true;
  }
  bool VisitIfStmt(IfStmt *S) {
    if (S->getConditionVariable())
      return false;
    Expr *condE = S->getCond();
    if (!condE)
      return false;
    if (hasSideEffects(condE, Ctx))
      return false;
    if (!S->getThen() || !Visit(S->getThen()))
      return false;
    if (S->getElse() && !Visit(S->getElse()))
      return false;
    return true;
  }
  bool VisitWhileStmt(WhileStmt *S) {
    if (S->getConditionVariable())
      return false;
    Expr *condE = S->getCond();
    if (!condE)
      return false;
    if (hasSideEffects(condE, Ctx))
      return false;
    if (!S->getBody())
      return false;
    return Visit(S->getBody());
  }
  bool VisitDoStmt(DoStmt *S) {
    Expr *condE = S->getCond();
    if (!condE)
      return false;
    if (hasSideEffects(condE, Ctx))
      return false;
    if (!S->getBody())
      return false;
    return Visit(S->getBody());
  }
  bool VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
    Expr *Exp = S->getCollection();
    if (!Exp)
      return false;
    if (hasSideEffects(Exp, Ctx))
      return false;
    if (!S->getBody())
      return false;
    return Visit(S->getBody());
  }
  bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
    if (!S->getSubStmt())
      return false;
    return Visit(S->getSubStmt());
  }
};

class EmptyStatementsRemover :
                            public RecursiveASTVisitor<EmptyStatementsRemover> {
  MigrationPass &Pass;

public:
  EmptyStatementsRemover(MigrationPass &pass) : Pass(pass) { }

  bool TraverseStmtExpr(StmtExpr *E) {
    CompoundStmt *S = E->getSubStmt();
    for (CompoundStmt::body_iterator
           I = S->body_begin(), E = S->body_end(); I != E; ++I) {
      if (I != E - 1)
        check(*I);
      TraverseStmt(*I);
    }
    return true;
  }

  bool VisitCompoundStmt(CompoundStmt *S) {
    for (CompoundStmt::body_iterator
           I = S->body_begin(), E = S->body_end(); I != E; ++I)
      check(*I);
    return true;
  }

  ASTContext &getContext() { return Pass.Ctx; }

private:
  void check(Stmt *S) {
    if (!S) return;
    if (EmptyChecker(Pass.Ctx, Pass.ARCMTMacroLocs).Visit(S)) {
      Transaction Trans(Pass.TA);
      Pass.TA.removeStmt(S);
    }
  }
};

} // anonymous namespace

static bool isBodyEmpty(CompoundStmt *body, ASTContext &Ctx,
                        std::vector<SourceLocation> &MacroLocs) {
  for (CompoundStmt::body_iterator
         I = body->body_begin(), E = body->body_end(); I != E; ++I)
    if (!EmptyChecker(Ctx, MacroLocs).Visit(*I))
      return false;

  return true;
}

static void removeDeallocMethod(MigrationPass &pass) {
  ASTContext &Ctx = pass.Ctx;
  TransformActions &TA = pass.TA;
  DeclContext *DC = Ctx.getTranslationUnitDecl();

  typedef DeclContext::specific_decl_iterator<ObjCImplementationDecl>
    impl_iterator;
  for (impl_iterator I = impl_iterator(DC->decls_begin()),
                     E = impl_iterator(DC->decls_end()); I != E; ++I) {
    for (ObjCImplementationDecl::instmeth_iterator
           MI = (*I)->instmeth_begin(),
           ME = (*I)->instmeth_end(); MI != ME; ++MI) {
      ObjCMethodDecl *MD = *MI;
      if (MD->getMethodFamily() == OMF_dealloc) {
        if (MD->hasBody() &&
            isBodyEmpty(MD->getCompoundBody(), Ctx, pass.ARCMTMacroLocs)) {
          Transaction Trans(TA);
          TA.remove(MD->getSourceRange());
        }
        break;
      }
    }
  }
}

void trans::removeEmptyStatementsAndDealloc(MigrationPass &pass) {
  EmptyStatementsRemover(pass).TraverseDecl(pass.Ctx.getTranslationUnitDecl());

  removeDeallocMethod(pass);

  for (unsigned i = 0, e = pass.ARCMTMacroLocs.size(); i != e; ++i) {
    Transaction Trans(pass.TA);
    pass.TA.remove(pass.ARCMTMacroLocs[i]);
  }
}
