clang API Documentation
00001 //==- BlockCounter.h - ADT for counting block visits -------------*- C++ -*-// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines BlockCounter, an abstract data type used to count 00011 // the number of times a given block has been visited along a path 00012 // analyzed by CoreEngine. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h" 00017 #include "llvm/ADT/ImmutableMap.h" 00018 00019 using namespace clang; 00020 using namespace ento; 00021 00022 namespace { 00023 00024 class CountKey { 00025 const StackFrameContext *CallSite; 00026 unsigned BlockID; 00027 00028 public: 00029 CountKey(const StackFrameContext *CS, unsigned ID) 00030 : CallSite(CS), BlockID(ID) {} 00031 00032 bool operator==(const CountKey &RHS) const { 00033 return (CallSite == RHS.CallSite) && (BlockID == RHS.BlockID); 00034 } 00035 00036 bool operator<(const CountKey &RHS) const { 00037 return std::tie(CallSite, BlockID) < std::tie(RHS.CallSite, RHS.BlockID); 00038 } 00039 00040 void Profile(llvm::FoldingSetNodeID &ID) const { 00041 ID.AddPointer(CallSite); 00042 ID.AddInteger(BlockID); 00043 } 00044 }; 00045 00046 } 00047 00048 typedef llvm::ImmutableMap<CountKey, unsigned> CountMap; 00049 00050 static inline CountMap GetMap(void *D) { 00051 return CountMap(static_cast<CountMap::TreeTy*>(D)); 00052 } 00053 00054 static inline CountMap::Factory& GetFactory(void *F) { 00055 return *static_cast<CountMap::Factory*>(F); 00056 } 00057 00058 unsigned BlockCounter::getNumVisited(const StackFrameContext *CallSite, 00059 unsigned BlockID) const { 00060 CountMap M = GetMap(Data); 00061 CountMap::data_type* T = M.lookup(CountKey(CallSite, BlockID)); 00062 return T ? *T : 0; 00063 } 00064 00065 BlockCounter::Factory::Factory(llvm::BumpPtrAllocator& Alloc) { 00066 F = new CountMap::Factory(Alloc); 00067 } 00068 00069 BlockCounter::Factory::~Factory() { 00070 delete static_cast<CountMap::Factory*>(F); 00071 } 00072 00073 BlockCounter 00074 BlockCounter::Factory::IncrementCount(BlockCounter BC, 00075 const StackFrameContext *CallSite, 00076 unsigned BlockID) { 00077 return BlockCounter(GetFactory(F).add(GetMap(BC.Data), 00078 CountKey(CallSite, BlockID), 00079 BC.getNumVisited(CallSite, BlockID)+1).getRoot()); 00080 } 00081 00082 BlockCounter 00083 BlockCounter::Factory::GetEmptyCounter() { 00084 return BlockCounter(GetFactory(F).getEmptyMap().getRoot()); 00085 }