BlockCounter.cpp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. //==- BlockCounter.h - ADT for counting block visits -------------*- C++ -*-//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines BlockCounter, an abstract data type used to count
  11. // the number of times a given block has been visited along a path
  12. // analyzed by CoreEngine.
  13. //
  14. //===----------------------------------------------------------------------===//
  15. #include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
  16. #include "llvm/ADT/ImmutableMap.h"
  17. using namespace clang;
  18. using namespace ento;
  19. namespace {
  20. class CountKey {
  21. const StackFrameContext *CallSite;
  22. unsigned BlockID;
  23. public:
  24. CountKey(const StackFrameContext *CS, unsigned ID)
  25. : CallSite(CS), BlockID(ID) {}
  26. bool operator==(const CountKey &RHS) const {
  27. return (CallSite == RHS.CallSite) && (BlockID == RHS.BlockID);
  28. }
  29. bool operator<(const CountKey &RHS) const {
  30. return std::tie(CallSite, BlockID) < std::tie(RHS.CallSite, RHS.BlockID);
  31. }
  32. void Profile(llvm::FoldingSetNodeID &ID) const {
  33. ID.AddPointer(CallSite);
  34. ID.AddInteger(BlockID);
  35. }
  36. };
  37. }
  38. typedef llvm::ImmutableMap<CountKey, unsigned> CountMap;
  39. static inline CountMap GetMap(void *D) {
  40. return CountMap(static_cast<CountMap::TreeTy*>(D));
  41. }
  42. static inline CountMap::Factory& GetFactory(void *F) {
  43. return *static_cast<CountMap::Factory*>(F);
  44. }
  45. unsigned BlockCounter::getNumVisited(const StackFrameContext *CallSite,
  46. unsigned BlockID) const {
  47. CountMap M = GetMap(Data);
  48. CountMap::data_type* T = M.lookup(CountKey(CallSite, BlockID));
  49. return T ? *T : 0;
  50. }
  51. BlockCounter::Factory::Factory(llvm::BumpPtrAllocator& Alloc) {
  52. F = new CountMap::Factory(Alloc);
  53. }
  54. BlockCounter::Factory::~Factory() {
  55. delete static_cast<CountMap::Factory*>(F);
  56. }
  57. BlockCounter
  58. BlockCounter::Factory::IncrementCount(BlockCounter BC,
  59. const StackFrameContext *CallSite,
  60. unsigned BlockID) {
  61. return BlockCounter(GetFactory(F).add(GetMap(BC.Data),
  62. CountKey(CallSite, BlockID),
  63. BC.getNumVisited(CallSite, BlockID)+1).getRoot());
  64. }
  65. BlockCounter
  66. BlockCounter::Factory::GetEmptyCounter() {
  67. return BlockCounter(GetFactory(F).getEmptyMap().getRoot());
  68. }