//==- BlockCounter.h - ADT for counting block visits -------------*- C++ -*-//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  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 std::tie(CallSite, BlockID) < std::tie(RHS.CallSite, RHS.BlockID);
  }

  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());
}
