1// EntryPointStats.h - Tracking statistics per entry point ------*- 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#ifndef CLANG_INCLUDE_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENTRYPOINTSTATS_H
10#define CLANG_INCLUDE_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENTRYPOINTSTATS_H
11
12#include "llvm/ADT/Statistic.h"
13#include "llvm/ADT/StringRef.h"
14
15namespace llvm {
16class raw_ostream;
17} // namespace llvm
18
19namespace clang {
20class Decl;
21
22namespace ento {
23
24class EntryPointStat {
25public:
26 llvm::StringLiteral name() const { return Name; }
27
28 static void lockRegistry();
29
30 static void takeSnapshot(const Decl *EntryPoint);
31 static void dumpStatsAsCSV(llvm::raw_ostream &OS);
32 static void dumpStatsAsCSV(llvm::StringRef FileName);
33
34protected:
35 explicit EntryPointStat(llvm::StringLiteral Name) : Name{Name} {}
36 EntryPointStat(const EntryPointStat &) = delete;
37 EntryPointStat(EntryPointStat &&) = delete;
38 EntryPointStat &operator=(EntryPointStat &) = delete;
39 EntryPointStat &operator=(EntryPointStat &&) = delete;
40
41private:
42 llvm::StringLiteral Name;
43};
44
45class BoolEPStat : public EntryPointStat {
46 std::optional<bool> Value = {};
47
48public:
49 explicit BoolEPStat(llvm::StringLiteral Name);
50 unsigned value() const { return Value && *Value; }
51 void set(bool V) {
52 assert(!Value.has_value());
53 Value = V;
54 }
55 void reset() { Value = {}; }
56};
57
58// used by CounterEntryPointTranslationUnitStat
59class CounterEPStat : public EntryPointStat {
60 using EntryPointStat::EntryPointStat;
61 unsigned Value = {};
62
63public:
64 explicit CounterEPStat(llvm::StringLiteral Name);
65 unsigned value() const { return Value; }
66 void reset() { Value = {}; }
67 CounterEPStat &operator++() {
68 ++Value;
69 return *this;
70 }
71
72 CounterEPStat &operator++(int) {
73 // No difference as you can't extract the value
74 return ++(*this);
75 }
76
77 CounterEPStat &operator+=(unsigned Inc) {
78 Value += Inc;
79 return *this;
80 }
81};
82
83// used by UnsignedMaxEtryPointTranslationUnitStatistic
84class UnsignedMaxEPStat : public EntryPointStat {
85 using EntryPointStat::EntryPointStat;
86 unsigned Value = {};
87
88public:
89 explicit UnsignedMaxEPStat(llvm::StringLiteral Name);
90 unsigned value() const { return Value; }
91 void reset() { Value = {}; }
92 void updateMax(unsigned X) { Value = std::max(a: Value, b: X); }
93};
94
95class UnsignedEPStat : public EntryPointStat {
96 using EntryPointStat::EntryPointStat;
97 std::optional<unsigned> Value = {};
98
99public:
100 explicit UnsignedEPStat(llvm::StringLiteral Name);
101 unsigned value() const { return Value.value_or(u: 0); }
102 void reset() { Value.reset(); }
103 void set(unsigned V) {
104 assert(!Value.has_value());
105 Value = V;
106 }
107};
108
109class CounterEntryPointTranslationUnitStat {
110 CounterEPStat M;
111 llvm::TrackingStatistic S;
112
113public:
114 CounterEntryPointTranslationUnitStat(const char *DebugType,
115 llvm::StringLiteral Name,
116 llvm::StringLiteral Desc)
117 : M(Name), S(DebugType, Name.data(), Desc.data()) {}
118 CounterEntryPointTranslationUnitStat &operator++() {
119 ++M;
120 ++S;
121 return *this;
122 }
123
124 CounterEntryPointTranslationUnitStat &operator++(int) {
125 // No difference with prefix as the value is not observable.
126 return ++(*this);
127 }
128
129 CounterEntryPointTranslationUnitStat &operator+=(unsigned Inc) {
130 M += Inc;
131 S += Inc;
132 return *this;
133 }
134};
135
136class UnsignedMaxEntryPointTranslationUnitStatistic {
137 UnsignedMaxEPStat M;
138 llvm::TrackingStatistic S;
139
140public:
141 UnsignedMaxEntryPointTranslationUnitStatistic(const char *DebugType,
142 llvm::StringLiteral Name,
143 llvm::StringLiteral Desc)
144 : M(Name), S(DebugType, Name.data(), Desc.data()) {}
145 void updateMax(uint64_t Value) {
146 M.updateMax(X: static_cast<unsigned>(Value));
147 S.updateMax(V: Value);
148 }
149};
150
151#define STAT_COUNTER(VARNAME, DESC) \
152 static clang::ento::CounterEntryPointTranslationUnitStat VARNAME = { \
153 DEBUG_TYPE, #VARNAME, DESC}
154
155#define STAT_MAX(VARNAME, DESC) \
156 static clang::ento::UnsignedMaxEntryPointTranslationUnitStatistic VARNAME = \
157 {DEBUG_TYPE, #VARNAME, DESC}
158
159} // namespace ento
160} // namespace clang
161
162#endif // CLANG_INCLUDE_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENTRYPOINTSTATS_H
163

source code of clang/include/clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h