//== Checker.h - Abstract interface for checkers -----------------*- C++ -*--=//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines Checker and CheckerVisitor, classes used for creating
//  domain-specific checks.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_ANALYSIS_CHECKER
#define LLVM_CLANG_ANALYSIS_CHECKER
#include "clang/Analysis/Support/SaveAndRestore.h"
#include "clang/Checker/PathSensitive/GRCoreEngine.h"
#include "clang/Checker/PathSensitive/GRState.h"
#include "clang/Checker/PathSensitive/GRExprEngine.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"

//===----------------------------------------------------------------------===//
// Checker interface.
//===----------------------------------------------------------------------===//

namespace clang {
  class GRExprEngine;

class CheckerContext {
  ExplodedNodeSet &Dst;
  GRStmtNodeBuilder &B;
  GRExprEngine &Eng;
  ExplodedNode *Pred;
  SaveAndRestore<bool> OldSink;
  SaveAndRestore<const void*> OldTag;
  SaveAndRestore<ProgramPoint::Kind> OldPointKind;
  SaveOr OldHasGen;
  const GRState *ST;
  const Stmt *statement;
  const unsigned size;
  bool DoneEvaluating; // FIXME: This is not a permanent API change.
public:
  CheckerContext(ExplodedNodeSet &dst, GRStmtNodeBuilder &builder,
                 GRExprEngine &eng, ExplodedNode *pred,
                 const void *tag, ProgramPoint::Kind K,
                 const Stmt *stmt = 0, const GRState *st = 0)
    : Dst(dst), B(builder), Eng(eng), Pred(pred),
      OldSink(B.BuildSinks),
      OldTag(B.Tag, tag),
      OldPointKind(B.PointKind, K),
      OldHasGen(B.HasGeneratedNode),
      ST(st), statement(stmt), size(Dst.size()) {}

  ~CheckerContext();

  GRExprEngine &getEngine() {
    return Eng;
  }

  AnalysisManager &getAnalysisManager() {
    return Eng.getAnalysisManager();
  }

  ConstraintManager &getConstraintManager() {
    return Eng.getConstraintManager();
  }

  StoreManager &getStoreManager() {
    return Eng.getStoreManager();
  }

  ExplodedNodeSet &getNodeSet() { return Dst; }
  GRStmtNodeBuilder &getNodeBuilder() { return B; }
  ExplodedNode *&getPredecessor() { return Pred; }
  const GRState *getState() { return ST ? ST : B.GetState(Pred); }

  ASTContext &getASTContext() {
    return Eng.getContext();
  }
  
  BugReporter &getBugReporter() {
    return Eng.getBugReporter();
  }
  
  SourceManager &getSourceManager() {
    return getBugReporter().getSourceManager();
  }

  ValueManager &getValueManager() {
    return Eng.getValueManager();
  }

  SValuator &getSValuator() {
    return Eng.getSValuator();
  }

  ExplodedNode *GenerateNode(bool autoTransition = true) {
    assert(statement && "Only transitions with statements currently supported");
    ExplodedNode *N = GenerateNodeImpl(statement, getState(), false);
    if (N && autoTransition)
      Dst.Add(N);
    return N;
  }
  
  ExplodedNode *GenerateNode(const Stmt *stmt, const GRState *state,
                             bool autoTransition = true) {
    assert(state);
    ExplodedNode *N = GenerateNodeImpl(stmt, state, false);
    if (N && autoTransition)
      addTransition(N);
    return N;
  }

  ExplodedNode *GenerateNode(const GRState *state, ExplodedNode *pred,
                             bool autoTransition = true) {
   assert(statement && "Only transitions with statements currently supported");
    ExplodedNode *N = GenerateNodeImpl(statement, state, pred, false);
    if (N && autoTransition)
      addTransition(N);
    return N;
  }

  ExplodedNode *GenerateNode(const GRState *state, bool autoTransition = true) {
    assert(statement && "Only transitions with statements currently supported");
    ExplodedNode *N = GenerateNodeImpl(statement, state, false);
    if (N && autoTransition)
      addTransition(N);
    return N;
  }

  ExplodedNode *GenerateSink(const Stmt *stmt, const GRState *state = 0) {
    return GenerateNodeImpl(stmt, state ? state : getState(), true);
  }
  
  ExplodedNode *GenerateSink(const GRState *state = 0) {
    assert(statement && "Only transitions with statements currently supported");
    return GenerateNodeImpl(statement, state ? state : getState(), true);
  }

  void addTransition(ExplodedNode *node) {
    Dst.Add(node);
  }
  
  void addTransition(const GRState *state) {
    assert(state);
    // If the 'state' is not new, we need to check if the cached state 'ST'
    // is new.
    if (state != getState() || (ST && ST != B.GetState(Pred)))
      GenerateNode(state, true);
    else
      Dst.Add(Pred);
  }

  // Generate a node with a new program point different from the one that will
  // be created by the GRStmtNodeBuilder.
  void addTransition(const GRState *state, ProgramPoint Loc) {
    ExplodedNode *N = B.generateNode(Loc, state, Pred);
    if (N)
      addTransition(N);
  }

  void EmitReport(BugReport *R) {
    Eng.getBugReporter().EmitReport(R);
  }

private:
  ExplodedNode *GenerateNodeImpl(const Stmt* stmt, const GRState *state,
                             bool markAsSink) {
    ExplodedNode *node = B.generateNode(stmt, state, Pred);
    if (markAsSink && node)
      node->markAsSink();
    return node;
  }

  ExplodedNode *GenerateNodeImpl(const Stmt* stmt, const GRState *state,
                                 ExplodedNode *pred, bool markAsSink) {
   ExplodedNode *node = B.generateNode(stmt, state, pred);
    if (markAsSink && node)
      node->markAsSink();
    return node;
  }
};

class Checker {
private:
  friend class GRExprEngine;

  // FIXME: Remove the 'tag' option.
  void GR_Visit(ExplodedNodeSet &Dst,
                GRStmtNodeBuilder &Builder,
                GRExprEngine &Eng,
                const Stmt *S,
                ExplodedNode *Pred, void *tag, bool isPrevisit) {
    CheckerContext C(Dst, Builder, Eng, Pred, tag,
                     isPrevisit ? ProgramPoint::PreStmtKind :
                     ProgramPoint::PostStmtKind, S);
    if (isPrevisit)
      _PreVisit(C, S);
    else
      _PostVisit(C, S);
  }

  bool GR_EvalNilReceiver(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
                          GRExprEngine &Eng, const ObjCMessageExpr *ME,
                          ExplodedNode *Pred, const GRState *state, void *tag) {
    CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
                     ME, state);
    return EvalNilReceiver(C, ME);
  }

  bool GR_EvalCallExpr(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
                       GRExprEngine &Eng, const CallExpr *CE,
                       ExplodedNode *Pred, void *tag) {
    CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
                     CE);
    return EvalCallExpr(C, CE);
  }

  // FIXME: Remove the 'tag' option.
  void GR_VisitBind(ExplodedNodeSet &Dst,
                    GRStmtNodeBuilder &Builder, GRExprEngine &Eng,
                    const Stmt *AssignE,
                    const Stmt *StoreE, ExplodedNode *Pred, void *tag, 
                    SVal location, SVal val,
                    bool isPrevisit) {
    CheckerContext C(Dst, Builder, Eng, Pred, tag,
                     isPrevisit ? ProgramPoint::PreStmtKind :
                     ProgramPoint::PostStmtKind, StoreE);
    assert(isPrevisit && "Only previsit supported for now.");
    PreVisitBind(C, AssignE, StoreE, location, val);
  }
  
  // FIXME: Remove the 'tag' option.
  void GR_VisitLocation(ExplodedNodeSet &Dst,
                        GRStmtNodeBuilder &Builder,
                        GRExprEngine &Eng,
                        const Stmt *S,
                        ExplodedNode *Pred, const GRState *state,
                        SVal location,
                        void *tag, bool isLoad) {
    CheckerContext C(Dst, Builder, Eng, Pred, tag,
                     isLoad ? ProgramPoint::PreLoadKind :
                     ProgramPoint::PreStoreKind, S, state);
    VisitLocation(C, S, location);
  }

  void GR_EvalDeadSymbols(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
                          GRExprEngine &Eng, const Stmt *S, ExplodedNode *Pred,
                          SymbolReaper &SymReaper, void *tag) {
    CheckerContext C(Dst, Builder, Eng, Pred, tag, 
                     ProgramPoint::PostPurgeDeadSymbolsKind, S);
    EvalDeadSymbols(C, S, SymReaper);
  }

public:
  virtual ~Checker();
  virtual void _PreVisit(CheckerContext &C, const Stmt *S) {}
  virtual void _PostVisit(CheckerContext &C, const Stmt *S) {}
  virtual void VisitLocation(CheckerContext &C, const Stmt *S, SVal location) {}
  virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
                            const Stmt *StoreE, SVal location, SVal val) {}
  virtual void EvalDeadSymbols(CheckerContext &C, const Stmt *S,
                               SymbolReaper &SymReaper) {}
  virtual void EvalEndPath(GREndPathNodeBuilder &B, void *tag,
                           GRExprEngine &Eng) {}

  virtual void VisitBranchCondition(GRBranchNodeBuilder &Builder,
                                    GRExprEngine &Eng,
                                    Stmt *Condition, void *tag) {}

  virtual bool EvalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME) {
    return false;
  }

  virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
    return false;
  }

  virtual const GRState *EvalAssume(const GRState *state, SVal Cond, 
                                    bool Assumption) {
    return state;
  }
};
} // end clang namespace

#endif

