BlockCounter.cpp 2.5 KB

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