1 //==- BlockCounter.h - ADT for counting block visits -------------*- C++ -*-//
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
7 //===----------------------------------------------------------------------===//
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.
13 //===----------------------------------------------------------------------===//
15 #include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
16 #include "llvm/ADT/ImmutableMap.h"
18 using namespace clang
;
24 const StackFrameContext
*CallSite
;
28 CountKey(const StackFrameContext
*CS
, unsigned ID
)
29 : CallSite(CS
), BlockID(ID
) {}
31 bool operator==(const CountKey
&RHS
) const {
32 return (CallSite
== RHS
.CallSite
) && (BlockID
== RHS
.BlockID
);
35 bool operator<(const CountKey
&RHS
) const {
36 return std::tie(CallSite
, BlockID
) < std::tie(RHS
.CallSite
, RHS
.BlockID
);
39 void Profile(llvm::FoldingSetNodeID
&ID
) const {
40 ID
.AddPointer(CallSite
);
41 ID
.AddInteger(BlockID
);
47 typedef llvm::ImmutableMap
<CountKey
, unsigned> CountMap
;
49 static inline CountMap
GetMap(void *D
) {
50 return CountMap(static_cast<CountMap::TreeTy
*>(D
));
53 static inline CountMap::Factory
& GetFactory(void *F
) {
54 return *static_cast<CountMap::Factory
*>(F
);
57 unsigned BlockCounter::getNumVisited(const StackFrameContext
*CallSite
,
58 unsigned BlockID
) const {
59 CountMap M
= GetMap(Data
);
60 CountMap::data_type
* T
= M
.lookup(CountKey(CallSite
, BlockID
));
64 BlockCounter::Factory::Factory(llvm::BumpPtrAllocator
& Alloc
) {
65 F
= new CountMap::Factory(Alloc
);
68 BlockCounter::Factory::~Factory() {
69 delete static_cast<CountMap::Factory
*>(F
);
73 BlockCounter::Factory::IncrementCount(BlockCounter BC
,
74 const StackFrameContext
*CallSite
,
76 return BlockCounter(GetFactory(F
).add(GetMap(BC
.Data
),
77 CountKey(CallSite
, BlockID
),
78 BC
.getNumVisited(CallSite
, BlockID
)+1).getRoot());
82 BlockCounter::Factory::GetEmptyCounter() {
83 return BlockCounter(GetFactory(F
).getEmptyMap().getRoot());