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 (CallSite == RHS.CallSite) ? (BlockID < RHS.BlockID) 00038 : (CallSite < RHS.CallSite); 00039 } 00040 00041 void Profile(llvm::FoldingSetNodeID &ID) const { 00042 ID.AddPointer(CallSite); 00043 ID.AddInteger(BlockID); 00044 } 00045 }; 00046 00047 } 00048 00049 typedef llvm::ImmutableMap<CountKey, unsigned> CountMap; 00050 00051 static inline CountMap GetMap(void *D) { 00052 return CountMap(static_cast<CountMap::TreeTy*>(D)); 00053 } 00054 00055 static inline CountMap::Factory& GetFactory(void *F) { 00056 return *static_cast<CountMap::Factory*>(F); 00057 } 00058 00059 unsigned BlockCounter::getNumVisited(const StackFrameContext *CallSite, 00060 unsigned BlockID) const { 00061 CountMap M = GetMap(Data); 00062 CountMap::data_type* T = M.lookup(CountKey(CallSite, BlockID)); 00063 return T ? *T : 0; 00064 } 00065 00066 BlockCounter::Factory::Factory(llvm::BumpPtrAllocator& Alloc) { 00067 F = new CountMap::Factory(Alloc); 00068 } 00069 00070 BlockCounter::Factory::~Factory() { 00071 delete static_cast<CountMap::Factory*>(F); 00072 } 00073 00074 BlockCounter 00075 BlockCounter::Factory::IncrementCount(BlockCounter BC, 00076 const StackFrameContext *CallSite, 00077 unsigned BlockID) { 00078 return BlockCounter(GetFactory(F).add(GetMap(BC.Data), 00079 CountKey(CallSite, BlockID), 00080 BC.getNumVisited(CallSite, BlockID)+1).getRoot()); 00081 } 00082 00083 BlockCounter 00084 BlockCounter::Factory::GetEmptyCounter() { 00085 return BlockCounter(GetFactory(F).getEmptyMap().getRoot()); 00086 }