blob: 274565bf6c886d34b382542a7d6fcfe00dee0b35 [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) {
Ted Kremenek596f0a12008-03-05 19:08:55 +000026
27 assert ((reinterpret_cast<uintptr_t>(N) & Mask) == 0x0);
28
Ted Kremenek9eb49a42008-01-13 04:56:13 +000029 if (getKind() == Size1) {
30 if (ExplodedNodeImpl* NOld = getNode()) {
31 std::vector<ExplodedNodeImpl*>* V = new std::vector<ExplodedNodeImpl*>();
Ted Kremenek596f0a12008-03-05 19:08:55 +000032 assert ((reinterpret_cast<uintptr_t>(V) & Mask) == 0x0);
Ted Kremenek9eb49a42008-01-13 04:56:13 +000033 V->push_back(NOld);
34 V->push_back(N);
Ted Kremenek45c63bd2008-01-29 23:31:09 +000035 P = reinterpret_cast<uintptr_t>(V) | SizeOther;
Ted Kremenek596f0a12008-03-05 19:08:55 +000036 assert (getPtr() == (void*) V);
37 assert (getKind() == SizeOther);
Ted Kremenek9eb49a42008-01-13 04:56:13 +000038 }
Ted Kremenek596f0a12008-03-05 19:08:55 +000039 else {
Ted Kremenek9eb49a42008-01-13 04:56:13 +000040 P = reinterpret_cast<uintptr_t>(N);
Ted Kremenek596f0a12008-03-05 19:08:55 +000041 assert (getKind() == Size1);
42 }
Ted Kremenek9eb49a42008-01-13 04:56:13 +000043 }
Ted Kremenek596f0a12008-03-05 19:08:55 +000044 else {
45 assert (getKind() == SizeOther);
Ted Kremenek9eb49a42008-01-13 04:56:13 +000046 getVector(getPtr()).push_back(N);
Ted Kremenek596f0a12008-03-05 19:08:55 +000047 }
Ted Kremenek9eb49a42008-01-13 04:56:13 +000048}
49
50bool ExplodedNodeImpl::NodeGroup::empty() const {
51 if (getKind() == Size1)
52 return getNode() ? false : true;
53 else
54 return getVector(getPtr()).empty();
55}
56
57unsigned ExplodedNodeImpl::NodeGroup::size() const {
58 if (getKind() == Size1)
59 return getNode() ? 1 : 0;
60 else
61 return getVector(getPtr()).size();
62}
63
64ExplodedNodeImpl** ExplodedNodeImpl::NodeGroup::begin() const {
65 if (getKind() == Size1)
66 return (ExplodedNodeImpl**) &P;
67 else
68 return const_cast<ExplodedNodeImpl**>(&*(getVector(getPtr()).begin()));
69}
70
71ExplodedNodeImpl** ExplodedNodeImpl::NodeGroup::end() const {
72 if (getKind() == Size1)
Ted Kremenek160760e2008-01-16 22:13:19 +000073 return (ExplodedNodeImpl**) (P ? &P+1 : &P);
Ted Kremenek9eb49a42008-01-13 04:56:13 +000074 else
Ted Kremenek596f0a12008-03-05 19:08:55 +000075 return const_cast<ExplodedNodeImpl**>(&*(getVector(getPtr()).end()));
Ted Kremenek9eb49a42008-01-13 04:56:13 +000076}
77
78ExplodedNodeImpl::NodeGroup::~NodeGroup() {
79 if (getKind() == SizeOther) delete &getVector(getPtr());
80}