//==- BlockCounter.h - ADT for counting block visits -------------*- 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 BlockCounter, an abstract data type used to count
//  the number of times a given block has been visited along a path
//  analyzed by CoreEngine.
//
//===----------------------------------------------------------------------===//

#include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
#include "llvm/ADT/ImmutableMap.h"

using namespace clang;
using namespace ento;

namespace {

class CountKey {
  const StackFrameContext *CallSite;
  unsigned BlockID;

public:
  CountKey(const StackFrameContext *CS, unsigned ID) 
    : CallSite(CS), BlockID(ID) {}

  bool operator==(const CountKey &RHS) const {
    return (CallSite == RHS.CallSite) && (BlockID == RHS.BlockID);
  }

  bool operator<(const CountKey &RHS) const {
    return (CallSite == RHS.CallSite) ? (BlockID < RHS.BlockID) 
                                      : (CallSite < RHS.CallSite);
  }

  void Profile(llvm::FoldingSetNodeID &ID) const {
    ID.AddPointer(CallSite);
    ID.AddInteger(BlockID);
  }
};

}

typedef llvm::ImmutableMap<CountKey, unsigned> CountMap;

static inline CountMap GetMap(void *D) {
  return CountMap(static_cast<CountMap::TreeTy*>(D));
}

static inline CountMap::Factory& GetFactory(void *F) {
  return *static_cast<CountMap::Factory*>(F);
}

unsigned BlockCounter::getNumVisited(const StackFrameContext *CallSite, 
                                       unsigned BlockID) const {
  CountMap M = GetMap(Data);
  CountMap::data_type* T = M.lookup(CountKey(CallSite, BlockID));
  return T ? *T : 0;
}

BlockCounter::Factory::Factory(llvm::BumpPtrAllocator& Alloc) {
  F = new CountMap::Factory(Alloc);
}

BlockCounter::Factory::~Factory() {
  delete static_cast<CountMap::Factory*>(F);
}

BlockCounter
BlockCounter::Factory::IncrementCount(BlockCounter BC, 
                                        const StackFrameContext *CallSite,
                                        unsigned BlockID) {
  return BlockCounter(GetFactory(F).add(GetMap(BC.Data), 
                                          CountKey(CallSite, BlockID),
                             BC.getNumVisited(CallSite, BlockID)+1).getRoot());
}

BlockCounter
BlockCounter::Factory::GetEmptyCounter() {
  return BlockCounter(GetFactory(F).getEmptyMap().getRoot());
}
