#include "llvm/Support/Casting.h"
#include "clang/Analysis/Support/BumpVector.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include <vector>
namespace clang {
friend class CoreEngine;
// Type definitions.
- typedef SmallVector<ExplodedNode*,2> RootsTy;
- typedef SmallVector<ExplodedNode*,10> EndNodesTy;
+ typedef std::vector<ExplodedNode *> NodeVector;
- /// Roots - The roots of the simulation graph. Usually there will be only
+ /// The roots of the simulation graph. Usually there will be only
/// one, but clients are free to establish multiple subgraphs within a single
/// SimulGraph. Moreover, these subgraphs can often merge when paths from
/// different roots reach the same state at the same program location.
- RootsTy Roots;
+ NodeVector Roots;
- /// EndNodes - The nodes in the simulation graph which have been
- /// specially marked as the endpoint of an abstract simulation path.
- EndNodesTy EndNodes;
+ /// The nodes in the simulation graph which have been
+ /// specially marked as the endpoint of an abstract simulation path.
+ NodeVector EndNodes;
/// Nodes - The nodes in the graph.
llvm::FoldingSet<ExplodedNode> Nodes;
unsigned NumNodes;
/// A list of recently allocated nodes that can potentially be recycled.
- void *recentlyAllocatedNodes;
+ NodeVector ChangedNodes;
/// A list of nodes that can be reused.
- void *freeNodes;
+ NodeVector FreeNodes;
/// A flag that indicates whether nodes should be recycled.
bool reclaimNodes;
// Iterators.
typedef ExplodedNode NodeTy;
typedef llvm::FoldingSet<ExplodedNode> AllNodesTy;
- typedef NodeTy** roots_iterator;
- typedef NodeTy* const * const_roots_iterator;
- typedef NodeTy** eop_iterator;
- typedef NodeTy* const * const_eop_iterator;
+ typedef NodeVector::iterator roots_iterator;
+ typedef NodeVector::const_iterator const_roots_iterator;
+ typedef NodeVector::iterator eop_iterator;
+ typedef NodeVector::const_iterator const_eop_iterator;
typedef AllNodesTy::iterator node_iterator;
typedef AllNodesTy::const_iterator const_node_iterator;
// Cleanup.
//===----------------------------------------------------------------------===//
-typedef std::vector<ExplodedNode*> NodeList;
-static inline NodeList*& getNodeList(void *&p) { return (NodeList*&) p; }
-
static const unsigned CounterTop = 1000;
ExplodedGraph::ExplodedGraph()
- : NumNodes(0), recentlyAllocatedNodes(0),
- freeNodes(0), reclaimNodes(false),
- reclaimCounter(CounterTop) {}
-
-ExplodedGraph::~ExplodedGraph() {
- if (reclaimNodes) {
- delete getNodeList(recentlyAllocatedNodes);
- delete getNodeList(freeNodes);
- }
-}
+ : NumNodes(0), reclaimNodes(false), reclaimCounter(CounterTop) {}
+
+ExplodedGraph::~ExplodedGraph() {}
//===----------------------------------------------------------------------===//
// Node reclamation.
ExplodedNode *succ = *(node->succ_begin());
pred->replaceSuccessor(succ);
succ->replacePredecessor(pred);
- if (!freeNodes)
- freeNodes = new NodeList();
- getNodeList(freeNodes)->push_back(node);
+ FreeNodes.push_back(node);
Nodes.RemoveNode(node);
--NumNodes;
node->~ExplodedNode();
}
void ExplodedGraph::reclaimRecentlyAllocatedNodes() {
- if (!recentlyAllocatedNodes)
+ if (ChangedNodes.empty())
return;
// Only periodically relcaim nodes so that we can build up a set of
if (--reclaimCounter != 0)
return;
reclaimCounter = CounterTop;
-
- NodeList &nl = *getNodeList(recentlyAllocatedNodes);
-
- for (NodeList::iterator i = nl.begin(), e = nl.end() ; i != e; ++i) {
- ExplodedNode *node = *i;
+
+ for (NodeVector::iterator it = ChangedNodes.begin(), et = ChangedNodes.end();
+ it != et; ++it) {
+ ExplodedNode *node = *it;
if (shouldCollect(node))
collectNode(node);
}
-
- nl.clear();
+ ChangedNodes.clear();
}
//===----------------------------------------------------------------------===//
NodeTy* V = Nodes.FindNodeOrInsertPos(profile, InsertPos);
if (!V) {
- if (freeNodes && !getNodeList(freeNodes)->empty()) {
- NodeList *nl = getNodeList(freeNodes);
- V = nl->back();
- nl->pop_back();
+ if (!FreeNodes.empty()) {
+ V = FreeNodes.back();
+ FreeNodes.pop_back();
}
else {
// Allocate a new node.
new (V) NodeTy(L, State, IsSink);
- if (reclaimNodes) {
- if (!recentlyAllocatedNodes)
- recentlyAllocatedNodes = new NodeList();
- getNodeList(recentlyAllocatedNodes)->push_back(V);
- }
+ if (reclaimNodes)
+ ChangedNodes.push_back(V);
// Insert the node into the node set and return it.
Nodes.InsertNode(V, InsertPos);
-
++NumNodes;
if (IsNew) *IsNew = true;