Author: Balazs Benics Date: 2021-11-19T18:32:13+01:00 New Revision: d448fcd9b2238377dd8832ce9e35a37b59ef5aeb
URL: https://github.com/llvm/llvm-project/commit/d448fcd9b2238377dd8832ce9e35a37b59ef5aeb DIFF: https://github.com/llvm/llvm-project/commit/d448fcd9b2238377dd8832ce9e35a37b59ef5aeb.diff LOG: [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 Added: Modified: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h clang/lib/StaticAnalyzer/Core/CallDescription.cpp Removed: ################################################################################ diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h index bbf58d753b1f6..b34e1c82eb7d6 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h @@ -88,6 +88,8 @@ class CallDescription { /// An immutable map from CallDescriptions to arbitrary data. Provides a unified /// way for checkers to react on function calls. template <typename T> class CallDescriptionMap { + friend class CallDescriptionSet; + // Some call descriptions aren't easily hashable (eg., the ones with qualified // names in which some sections are omitted), so let's put them // in a simple vector and use linear lookup. @@ -118,6 +120,21 @@ template <typename T> class CallDescriptionMap { } }; +/// An immutable set of CallDescriptions. +/// Checkers can efficiently decide if a given CallEvent matches any +/// CallDescription in the set. +class CallDescriptionSet { + CallDescriptionMap<bool /*unused*/> Impl = {}; + +public: + CallDescriptionSet(std::initializer_list<CallDescription> &&List); + + CallDescriptionSet(const CallDescriptionSet &) = delete; + CallDescriptionSet &operator=(const CallDescription &) = delete; + + LLVM_NODISCARD bool contains(const CallEvent &Call) const; +}; + } // namespace ento } // namespace clang diff --git a/clang/lib/StaticAnalyzer/Core/CallDescription.cpp b/clang/lib/StaticAnalyzer/Core/CallDescription.cpp index 0589a2c2cb980..097cbf68f0660 100644 --- a/clang/lib/StaticAnalyzer/Core/CallDescription.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallDescription.cpp @@ -46,3 +46,14 @@ ento::CallDescription::CallDescription( Optional<unsigned> RequiredArgs /*= None*/, Optional<size_t> RequiredParams /*= None*/) : CallDescription(0, QualifiedName, RequiredArgs, RequiredParams) {} + +ento::CallDescriptionSet::CallDescriptionSet( + std::initializer_list<CallDescription> &&List) { + Impl.LinearMap.reserve(List.size()); + for (const CallDescription &CD : List) + Impl.LinearMap.push_back({CD, /*unused*/ true}); +} + +bool ento::CallDescriptionSet::contains(const CallEvent &Call) const { + return static_cast<bool>(Impl.lookup(Call)); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits