1218887Sdim//==- BlockCounter.h - ADT for counting block visits -------------*- C++ -*-// 2218887Sdim// 3218887Sdim// The LLVM Compiler Infrastructure 4218887Sdim// 5218887Sdim// This file is distributed under the University of Illinois Open Source 6218887Sdim// License. See LICENSE.TXT for details. 7218887Sdim// 8218887Sdim//===----------------------------------------------------------------------===// 9218887Sdim// 10218887Sdim// This file defines BlockCounter, an abstract data type used to count 11218887Sdim// the number of times a given block has been visited along a path 12218887Sdim// analyzed by CoreEngine. 13218887Sdim// 14218887Sdim//===----------------------------------------------------------------------===// 15218887Sdim 16218887Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h" 17218887Sdim#include "llvm/ADT/ImmutableMap.h" 18218887Sdim 19218887Sdimusing namespace clang; 20218887Sdimusing namespace ento; 21218887Sdim 22218887Sdimnamespace { 23218887Sdim 24218887Sdimclass CountKey { 25218887Sdim const StackFrameContext *CallSite; 26218887Sdim unsigned BlockID; 27218887Sdim 28218887Sdimpublic: 29218887Sdim CountKey(const StackFrameContext *CS, unsigned ID) 30218887Sdim : CallSite(CS), BlockID(ID) {} 31218887Sdim 32218887Sdim bool operator==(const CountKey &RHS) const { 33218887Sdim return (CallSite == RHS.CallSite) && (BlockID == RHS.BlockID); 34218887Sdim } 35218887Sdim 36218887Sdim bool operator<(const CountKey &RHS) const { 37218887Sdim return (CallSite == RHS.CallSite) ? (BlockID < RHS.BlockID) 38218887Sdim : (CallSite < RHS.CallSite); 39218887Sdim } 40218887Sdim 41218887Sdim void Profile(llvm::FoldingSetNodeID &ID) const { 42218887Sdim ID.AddPointer(CallSite); 43218887Sdim ID.AddInteger(BlockID); 44218887Sdim } 45218887Sdim}; 46218887Sdim 47218887Sdim} 48218887Sdim 49218887Sdimtypedef llvm::ImmutableMap<CountKey, unsigned> CountMap; 50218887Sdim 51226633Sdimstatic inline CountMap GetMap(void *D) { 52218887Sdim return CountMap(static_cast<CountMap::TreeTy*>(D)); 53218887Sdim} 54218887Sdim 55226633Sdimstatic inline CountMap::Factory& GetFactory(void *F) { 56218887Sdim return *static_cast<CountMap::Factory*>(F); 57218887Sdim} 58218887Sdim 59218887Sdimunsigned BlockCounter::getNumVisited(const StackFrameContext *CallSite, 60218887Sdim unsigned BlockID) const { 61218887Sdim CountMap M = GetMap(Data); 62218887Sdim CountMap::data_type* T = M.lookup(CountKey(CallSite, BlockID)); 63218887Sdim return T ? *T : 0; 64218887Sdim} 65218887Sdim 66218887SdimBlockCounter::Factory::Factory(llvm::BumpPtrAllocator& Alloc) { 67218887Sdim F = new CountMap::Factory(Alloc); 68218887Sdim} 69218887Sdim 70218887SdimBlockCounter::Factory::~Factory() { 71218887Sdim delete static_cast<CountMap::Factory*>(F); 72218887Sdim} 73218887Sdim 74218887SdimBlockCounter 75218887SdimBlockCounter::Factory::IncrementCount(BlockCounter BC, 76218887Sdim const StackFrameContext *CallSite, 77218887Sdim unsigned BlockID) { 78218887Sdim return BlockCounter(GetFactory(F).add(GetMap(BC.Data), 79218887Sdim CountKey(CallSite, BlockID), 80218887Sdim BC.getNumVisited(CallSite, BlockID)+1).getRoot()); 81218887Sdim} 82218887Sdim 83218887SdimBlockCounter 84218887SdimBlockCounter::Factory::GetEmptyCounter() { 85218887Sdim return BlockCounter(GetFactory(F).getEmptyMap().getRoot()); 86218887Sdim} 87