diff options
| author | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 | 
|---|---|---|
| committer | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 | 
| commit | 222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch) | |
| tree | 7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/lib/StaticAnalyzer/Core/BlockCounter.cpp | |
| parent | 3d206f03985b50beacae843d880bccdc91a9f424 (diff) | |
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/BlockCounter.cpp')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/BlockCounter.cpp | 86 | 
1 files changed, 86 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/BlockCounter.cpp b/clang/lib/StaticAnalyzer/Core/BlockCounter.cpp new file mode 100644 index 0000000..74d761e --- /dev/null +++ b/clang/lib/StaticAnalyzer/Core/BlockCounter.cpp @@ -0,0 +1,86 @@ +//==- 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()); +}  | 
