diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/StaticAnalyzer/Core/BlockCounter.cpp')
| -rw-r--r-- | contrib/llvm-project/clang/lib/StaticAnalyzer/Core/BlockCounter.cpp | 84 | 
1 files changed, 84 insertions, 0 deletions
| diff --git a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/BlockCounter.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/BlockCounter.cpp new file mode 100644 index 000000000000..e7ac6f1cfa00 --- /dev/null +++ b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/BlockCounter.cpp @@ -0,0 +1,84 @@ +//==- BlockCounter.h - ADT for counting block visits -------------*- C++ -*-// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +//  This file defines BlockCounter, an abstract data type used to count +//  the number of times a given block has been visited along a path +//  analyzed by CoreEngine. +// +//===----------------------------------------------------------------------===// + +#include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h" +#include "llvm/ADT/ImmutableMap.h" + +using namespace clang; +using namespace ento; + +namespace { + +class CountKey { +  const StackFrameContext *CallSite; +  unsigned BlockID; + +public: +  CountKey(const StackFrameContext *CS, unsigned ID) +    : CallSite(CS), BlockID(ID) {} + +  bool operator==(const CountKey &RHS) const { +    return (CallSite == RHS.CallSite) && (BlockID == RHS.BlockID); +  } + +  bool operator<(const CountKey &RHS) const { +    return std::tie(CallSite, BlockID) < std::tie(RHS.CallSite, RHS.BlockID); +  } + +  void Profile(llvm::FoldingSetNodeID &ID) const { +    ID.AddPointer(CallSite); +    ID.AddInteger(BlockID); +  } +}; + +} + +typedef llvm::ImmutableMap<CountKey, unsigned> CountMap; + +static inline CountMap GetMap(void *D) { +  return CountMap(static_cast<CountMap::TreeTy*>(D)); +} + +static inline CountMap::Factory& GetFactory(void *F) { +  return *static_cast<CountMap::Factory*>(F); +} + +unsigned BlockCounter::getNumVisited(const StackFrameContext *CallSite, +                                       unsigned BlockID) const { +  CountMap M = GetMap(Data); +  CountMap::data_type* T = M.lookup(CountKey(CallSite, BlockID)); +  return T ? *T : 0; +} + +BlockCounter::Factory::Factory(llvm::BumpPtrAllocator& Alloc) { +  F = new CountMap::Factory(Alloc); +} + +BlockCounter::Factory::~Factory() { +  delete static_cast<CountMap::Factory*>(F); +} + +BlockCounter +BlockCounter::Factory::IncrementCount(BlockCounter BC, +                                        const StackFrameContext *CallSite, +                                        unsigned BlockID) { +  return BlockCounter(GetFactory(F).add(GetMap(BC.Data), +                                          CountKey(CallSite, BlockID), +                             BC.getNumVisited(CallSite, BlockID)+1).getRoot()); +} + +BlockCounter +BlockCounter::Factory::GetEmptyCounter() { +  return BlockCounter(GetFactory(F).getEmptyMap().getRoot()); +} | 
