//==- WorkList.h - Worklist class used by CoreEngine ---------------*- 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 WorkList, a pure virtual class that represents an opaque // worklist used by CoreEngine to explore the reachability state space. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_WORKLIST_H #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_WORKLIST_H #include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" #include namespace clang { class CFGBlock; namespace ento { class WorkListUnit { ExplodedNode *node; BlockCounter counter; const CFGBlock *block; unsigned blockIdx; // This is the index of the next statement. public: WorkListUnit(ExplodedNode *N, BlockCounter C, const CFGBlock *B, unsigned idx) : node(N), counter(C), block(B), blockIdx(idx) {} explicit WorkListUnit(ExplodedNode *N, BlockCounter C) : node(N), counter(C), block(nullptr), blockIdx(0) {} /// Returns the node associated with the worklist unit. ExplodedNode *getNode() const { return node; } /// Returns the block counter map associated with the worklist unit. BlockCounter getBlockCounter() const { return counter; } /// Returns the CFGblock associated with the worklist unit. const CFGBlock *getBlock() const { return block; } /// Return the index within the CFGBlock for the worklist unit. unsigned getIndex() const { return blockIdx; } }; class WorkList { BlockCounter CurrentCounter; public: virtual ~WorkList(); virtual bool hasWork() const = 0; virtual void enqueue(const WorkListUnit& U) = 0; void enqueue(ExplodedNode *N, const CFGBlock *B, unsigned idx) { enqueue(WorkListUnit(N, CurrentCounter, B, idx)); } void enqueue(ExplodedNode *N) { assert(N->getLocation().getKind() != ProgramPoint::PostStmtKind); enqueue(WorkListUnit(N, CurrentCounter)); } virtual WorkListUnit dequeue() = 0; void setBlockCounter(BlockCounter C) { CurrentCounter = C; } BlockCounter getBlockCounter() const { return CurrentCounter; } static std::unique_ptr makeDFS(); static std::unique_ptr makeBFS(); static std::unique_ptr makeBFSBlockDFSContents(); static std::unique_ptr makeUnexploredFirst(); static std::unique_ptr makeUnexploredFirstPriorityQueue(); static std::unique_ptr makeUnexploredFirstPriorityLocationQueue(); }; } // end ento namespace } // end clang namespace #endif