Skip to content

Commit d448fcd

Browse files
author
Balazs Benics
committed
[analyzer][NFC] Introduce CallDescriptionSets
Sometimes we only want to decide if some function is called, and we don't care which of the set. This `CallDescriptionSet` will have the same behavior, except instead of `lookup()` returning a pointer to the mapped value, the `contains()` returns `bool`. Internally, it uses the `CallDescriptionMap<bool>` for implementing the behavior. It is preferred, to reuse the generic `CallDescriptionMap::lookup()` logic, instead of duplicating it. The generic version might be improved by implementing a hash lookup or something along those lines. Reviewed By: martong, Szelethus Differential Revision: https://reviews.llvm.org/D113589
1 parent 76effb0 commit d448fcd

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ class CallDescription {
8888
/// An immutable map from CallDescriptions to arbitrary data. Provides a unified
8989
/// way for checkers to react on function calls.
9090
template <typename T> class CallDescriptionMap {
91+
friend class CallDescriptionSet;
92+
9193
// Some call descriptions aren't easily hashable (eg., the ones with qualified
9294
// names in which some sections are omitted), so let's put them
9395
// in a simple vector and use linear lookup.
@@ -118,6 +120,21 @@ template <typename T> class CallDescriptionMap {
118120
}
119121
};
120122

123+
/// An immutable set of CallDescriptions.
124+
/// Checkers can efficiently decide if a given CallEvent matches any
125+
/// CallDescription in the set.
126+
class CallDescriptionSet {
127+
CallDescriptionMap<bool /*unused*/> Impl = {};
128+
129+
public:
130+
CallDescriptionSet(std::initializer_list<CallDescription> &&List);
131+
132+
CallDescriptionSet(const CallDescriptionSet &) = delete;
133+
CallDescriptionSet &operator=(const CallDescription &) = delete;
134+
135+
LLVM_NODISCARD bool contains(const CallEvent &Call) const;
136+
};
137+
121138
} // namespace ento
122139
} // namespace clang
123140

clang/lib/StaticAnalyzer/Core/CallDescription.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,14 @@ ento::CallDescription::CallDescription(
4646
Optional<unsigned> RequiredArgs /*= None*/,
4747
Optional<size_t> RequiredParams /*= None*/)
4848
: CallDescription(0, QualifiedName, RequiredArgs, RequiredParams) {}
49+
50+
ento::CallDescriptionSet::CallDescriptionSet(
51+
std::initializer_list<CallDescription> &&List) {
52+
Impl.LinearMap.reserve(List.size());
53+
for (const CallDescription &CD : List)
54+
Impl.LinearMap.push_back({CD, /*unused*/ true});
55+
}
56+
57+
bool ento::CallDescriptionSet::contains(const CallEvent &Call) const {
58+
return static_cast<bool>(Impl.lookup(Call));
59+
}

0 commit comments

Comments
 (0)