blob: 35e9d9de9a0ef5584cf4aa04869fd848778a7315 [file] [log] [blame]
Ted Kremenek9eb49a42008-01-13 04:56:13 +00001//=-- ExplodedGraph.cpp - Local, Path-Sens. "Exploded Graph" -*- C++ -*------=//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the template classes ExplodedNode and ExplodedGraph,
11// which represent a path-sensitive, intra-procedural "exploded graph."
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
16#include <vector>
17
18using namespace clang;
19
20
21static inline std::vector<ExplodedNodeImpl*>& getVector(void* P) {
22 return *reinterpret_cast<std::vector<ExplodedNodeImpl*>*>(P);
23}
24
25void ExplodedNodeImpl::NodeGroup::addNode(ExplodedNodeImpl* N) {
26 if (getKind() == Size1) {
27 if (ExplodedNodeImpl* NOld = getNode()) {
28 std::vector<ExplodedNodeImpl*>* V = new std::vector<ExplodedNodeImpl*>();
29 V->push_back(NOld);
30 V->push_back(N);
31 P = reinterpret_cast<uintptr_t>(V) & SizeOther;
32 }
33 else
34 P = reinterpret_cast<uintptr_t>(N);
35 }
36 else
37 getVector(getPtr()).push_back(N);
38}
39
40bool ExplodedNodeImpl::NodeGroup::empty() const {
41 if (getKind() == Size1)
42 return getNode() ? false : true;
43 else
44 return getVector(getPtr()).empty();
45}
46
47unsigned ExplodedNodeImpl::NodeGroup::size() const {
48 if (getKind() == Size1)
49 return getNode() ? 1 : 0;
50 else
51 return getVector(getPtr()).size();
52}
53
54ExplodedNodeImpl** ExplodedNodeImpl::NodeGroup::begin() const {
55 if (getKind() == Size1)
56 return (ExplodedNodeImpl**) &P;
57 else
58 return const_cast<ExplodedNodeImpl**>(&*(getVector(getPtr()).begin()));
59}
60
61ExplodedNodeImpl** ExplodedNodeImpl::NodeGroup::end() const {
62 if (getKind() == Size1)
63 return ((ExplodedNodeImpl**) &P)+1;
64 else
65 return const_cast<ExplodedNodeImpl**>(&*(getVector(getPtr()).rbegin())+1);
66}
67
68ExplodedNodeImpl::NodeGroup::~NodeGroup() {
69 if (getKind() == SizeOther) delete &getVector(getPtr());
70}
Ted Kremenekd880c182008-01-13 05:33:04 +000071
72
73ExplodedGraphImpl::~ExplodedGraphImpl() {
74 // Delete the FoldingSet's in Nodes. Note that the contents
75 // of the FoldingSets are nodes allocated from the BumpPtrAllocator,
76 // so all of those will get nuked when that object is destroyed.
77 for (EdgeNodeSetMap::iterator I=Nodes.begin(), E=Nodes.end(); I!=E; ++I) {
78 llvm::FoldingSet<ExplodedNodeImpl>* ENodes =
79 reinterpret_cast<llvm::FoldingSet<ExplodedNodeImpl>*>(I->second);
80
81 for (llvm::FoldingSet<ExplodedNodeImpl>::iterator
82 I=ENodes->begin(), E=ENodes->end(); I!=E; ++I)
Ted Kremeneka5a1ef42008-01-16 19:27:42 +000083 (*I).~ExplodedNodeImpl();
Ted Kremenekd880c182008-01-13 05:33:04 +000084
85 delete ENodes;
86 }
87}