blob: 6dfc470530a4e341dc773cb6b6e49e44c9ac72be [file] [log] [blame]
Zhongxing Xud19e21b2008-08-29 15:09:12 +00001//== BasicConstraintManager.cpp - Manage basic constraints.------*- 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//
Mike Stump1eb44332009-09-09 15:08:12 +000010// This file defines BasicConstraintManager, a class that tracks simple
Zhongxing Xud19e21b2008-08-29 15:09:12 +000011// equality and inequality constraints on symbolic values of GRState.
12//
13//===----------------------------------------------------------------------===//
14
Ted Kremenek45021952009-02-14 17:08:39 +000015#include "SimpleConstraintManager.h"
Zhongxing Xu30ad1672008-08-27 14:03:33 +000016#include "clang/Analysis/PathSensitive/GRState.h"
Zhongxing Xu39cfed32008-08-29 14:52:36 +000017#include "clang/Analysis/PathSensitive/GRStateTrait.h"
Ted Kremenek2fb78a72008-12-17 21:50:35 +000018#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
Zhongxing Xu39cfed32008-08-29 14:52:36 +000019#include "llvm/Support/raw_ostream.h"
Zhongxing Xu30ad1672008-08-27 14:03:33 +000020
21using namespace clang;
22
Ted Kremenek8ee74d52009-01-26 06:04:53 +000023
Kovarththanan Rajaratnamba5fb5a2009-11-28 06:07:30 +000024namespace { class ConstNotEq {}; }
25namespace { class ConstEq {}; }
Zhongxing Xu30ad1672008-08-27 14:03:33 +000026
Ted Kremenek2dabd432008-12-05 02:27:51 +000027typedef llvm::ImmutableMap<SymbolRef,GRState::IntSetTy> ConstNotEqTy;
28typedef llvm::ImmutableMap<SymbolRef,const llvm::APSInt*> ConstEqTy;
Mike Stump1eb44332009-09-09 15:08:12 +000029
Ted Kremenek8ee74d52009-01-26 06:04:53 +000030static int ConstEqIndex = 0;
31static int ConstNotEqIndex = 0;
Zhongxing Xu39cfed32008-08-29 14:52:36 +000032
Ted Kremenek8ee74d52009-01-26 06:04:53 +000033namespace clang {
34template<>
35struct GRStateTrait<ConstNotEq> : public GRStatePartialTrait<ConstNotEqTy> {
Mike Stump1eb44332009-09-09 15:08:12 +000036 static inline void* GDMIndex() { return &ConstNotEqIndex; }
Ted Kremenek8ee74d52009-01-26 06:04:53 +000037};
38
39template<>
40struct GRStateTrait<ConstEq> : public GRStatePartialTrait<ConstEqTy> {
Mike Stump1eb44332009-09-09 15:08:12 +000041 static inline void* GDMIndex() { return &ConstEqIndex; }
Ted Kremenek8ee74d52009-01-26 06:04:53 +000042};
Mike Stump1eb44332009-09-09 15:08:12 +000043}
44
Ted Kremenek8ee74d52009-01-26 06:04:53 +000045namespace {
Zhongxing Xu30ad1672008-08-27 14:03:33 +000046// BasicConstraintManager only tracks equality and inequality constraints of
47// constants and integer variables.
Kovarththanan Rajaratnamba5fb5a2009-11-28 06:07:30 +000048class BasicConstraintManager
Ted Kremenek45021952009-02-14 17:08:39 +000049 : public SimpleConstraintManager {
Zhongxing Xuf0bc50e2008-11-27 06:08:40 +000050 GRState::IntSetTy::Factory ISetFactory;
Zhongxing Xu30ad1672008-08-27 14:03:33 +000051public:
Ted Kremenek32a58082010-01-05 00:15:18 +000052 BasicConstraintManager(GRStateManager &statemgr, GRSubEngine &subengine)
53 : SimpleConstraintManager(subengine),
54 ISetFactory(statemgr.getAllocator()) {}
Zhongxing Xu30ad1672008-08-27 14:03:33 +000055
Ted Kremeneka591bc02009-06-18 22:57:13 +000056 const GRState* AssumeSymNE(const GRState* state, SymbolRef sym,
57 const llvm::APSInt& V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +000058
Ted Kremeneka591bc02009-06-18 22:57:13 +000059 const GRState* AssumeSymEQ(const GRState* state, SymbolRef sym,
60 const llvm::APSInt& V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +000061
Ted Kremeneka591bc02009-06-18 22:57:13 +000062 const GRState* AssumeSymLT(const GRState* state, SymbolRef sym,
63 const llvm::APSInt& V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +000064
Ted Kremeneka591bc02009-06-18 22:57:13 +000065 const GRState* AssumeSymGT(const GRState* state, SymbolRef sym,
66 const llvm::APSInt& V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +000067
Ted Kremeneka591bc02009-06-18 22:57:13 +000068 const GRState* AssumeSymGE(const GRState* state, SymbolRef sym,
69 const llvm::APSInt& V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +000070
Ted Kremeneka591bc02009-06-18 22:57:13 +000071 const GRState* AssumeSymLE(const GRState* state, SymbolRef sym,
72 const llvm::APSInt& V);
Zhongxing Xu39cfed32008-08-29 14:52:36 +000073
Ted Kremeneka591bc02009-06-18 22:57:13 +000074 const GRState* AddEQ(const GRState* state, SymbolRef sym, const llvm::APSInt& V);
Zhongxing Xu39cfed32008-08-29 14:52:36 +000075
Ted Kremeneka591bc02009-06-18 22:57:13 +000076 const GRState* AddNE(const GRState* state, SymbolRef sym, const llvm::APSInt& V);
Zhongxing Xu39cfed32008-08-29 14:52:36 +000077
Ted Kremeneka591bc02009-06-18 22:57:13 +000078 const llvm::APSInt* getSymVal(const GRState* state, SymbolRef sym) const;
79 bool isNotEqual(const GRState* state, SymbolRef sym, const llvm::APSInt& V)
Ted Kremenek45021952009-02-14 17:08:39 +000080 const;
Ted Kremeneka591bc02009-06-18 22:57:13 +000081 bool isEqual(const GRState* state, SymbolRef sym, const llvm::APSInt& V)
Ted Kremenek45021952009-02-14 17:08:39 +000082 const;
Zhongxing Xu39cfed32008-08-29 14:52:36 +000083
Ted Kremeneka591bc02009-06-18 22:57:13 +000084 const GRState* RemoveDeadBindings(const GRState* state, SymbolReaper& SymReaper);
Ted Kremenek241677a2009-01-21 22:26:05 +000085
Mike Stump1eb44332009-09-09 15:08:12 +000086 void print(const GRState* state, llvm::raw_ostream& Out,
Zhongxing Xu39cfed32008-08-29 14:52:36 +000087 const char* nl, const char *sep);
88};
Zhongxing Xu30ad1672008-08-27 14:03:33 +000089
90} // end anonymous namespace
91
Ted Kremenek32a58082010-01-05 00:15:18 +000092ConstraintManager* clang::CreateBasicConstraintManager(GRStateManager& statemgr,
93 GRSubEngine &subengine) {
94 return new BasicConstraintManager(statemgr, subengine);
Zhongxing Xu30ad1672008-08-27 14:03:33 +000095}
96
Zhongxing Xu30ad1672008-08-27 14:03:33 +000097const GRState*
Ted Kremeneka591bc02009-06-18 22:57:13 +000098BasicConstraintManager::AssumeSymNE(const GRState *state, SymbolRef sym,
99 const llvm::APSInt& V) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000100 // First, determine if sym == X, where X != V.
Ted Kremeneka591bc02009-06-18 22:57:13 +0000101 if (const llvm::APSInt* X = getSymVal(state, sym)) {
102 bool isFeasible = (*X != V);
103 return isFeasible ? state : NULL;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000104 }
105
106 // Second, determine if sym != V.
Ted Kremeneka591bc02009-06-18 22:57:13 +0000107 if (isNotEqual(state, sym, V))
108 return state;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000109
110 // If we reach here, sym is not a constant and we don't know if it is != V.
111 // Make that assumption.
Ted Kremeneka591bc02009-06-18 22:57:13 +0000112 return AddNE(state, sym, V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000113}
114
Ted Kremeneka591bc02009-06-18 22:57:13 +0000115const GRState *BasicConstraintManager::AssumeSymEQ(const GRState *state,
116 SymbolRef sym,
117 const llvm::APSInt &V) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000118 // First, determine if sym == X, where X != V.
Ted Kremeneka591bc02009-06-18 22:57:13 +0000119 if (const llvm::APSInt* X = getSymVal(state, sym)) {
120 bool isFeasible = *X == V;
121 return isFeasible ? state : NULL;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000122 }
123
124 // Second, determine if sym != V.
Ted Kremeneka591bc02009-06-18 22:57:13 +0000125 if (isNotEqual(state, sym, V))
126 return NULL;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000127
128 // If we reach here, sym is not a constant and we don't know if it is == V.
129 // Make that assumption.
Ted Kremeneka591bc02009-06-18 22:57:13 +0000130 return AddEQ(state, sym, V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000131}
132
133// These logic will be handled in another ConstraintManager.
Ted Kremeneka591bc02009-06-18 22:57:13 +0000134const GRState *BasicConstraintManager::AssumeSymLT(const GRState *state,
135 SymbolRef sym,
Mike Stump1eb44332009-09-09 15:08:12 +0000136 const llvm::APSInt& V) {
Ted Kremenek73abd132008-12-03 18:56:12 +0000137 // Is 'V' the smallest possible value?
Chris Lattner071e04e2009-01-30 01:58:33 +0000138 if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isUnsigned())) {
Ted Kremenek73abd132008-12-03 18:56:12 +0000139 // sym cannot be any value less than 'V'. This path is infeasible.
Ted Kremeneka591bc02009-06-18 22:57:13 +0000140 return NULL;
Ted Kremenek73abd132008-12-03 18:56:12 +0000141 }
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000142
143 // FIXME: For now have assuming x < y be the same as assuming sym != V;
Ted Kremeneka591bc02009-06-18 22:57:13 +0000144 return AssumeSymNE(state, sym, V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000145}
146
Ted Kremeneka591bc02009-06-18 22:57:13 +0000147const GRState *BasicConstraintManager::AssumeSymGT(const GRState *state,
148 SymbolRef sym,
149 const llvm::APSInt& V) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000150
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000151 // Is 'V' the largest possible value?
Chris Lattner071e04e2009-01-30 01:58:33 +0000152 if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isUnsigned())) {
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000153 // sym cannot be any value greater than 'V'. This path is infeasible.
Ted Kremeneka591bc02009-06-18 22:57:13 +0000154 return NULL;
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000155 }
156
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000157 // FIXME: For now have assuming x > y be the same as assuming sym != V;
Ted Kremeneka591bc02009-06-18 22:57:13 +0000158 return AssumeSymNE(state, sym, V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000159}
160
Ted Kremeneka591bc02009-06-18 22:57:13 +0000161const GRState *BasicConstraintManager::AssumeSymGE(const GRState *state,
162 SymbolRef sym,
163 const llvm::APSInt &V) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000164
Ted Kremenek8c3e7fb2008-09-16 23:24:45 +0000165 // Reject a path if the value of sym is a constant X and !(X >= V).
Ted Kremeneka591bc02009-06-18 22:57:13 +0000166 if (const llvm::APSInt *X = getSymVal(state, sym)) {
167 bool isFeasible = *X >= V;
168 return isFeasible ? state : NULL;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000169 }
Mike Stump1eb44332009-09-09 15:08:12 +0000170
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000171 // Sym is not a constant, but it is worth looking to see if V is the
172 // maximum integer value.
Chris Lattner071e04e2009-01-30 01:58:33 +0000173 if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isUnsigned())) {
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000174 // If we know that sym != V, then this condition is infeasible since
Mike Stump1eb44332009-09-09 15:08:12 +0000175 // there is no other value greater than V.
Ted Kremeneka591bc02009-06-18 22:57:13 +0000176 bool isFeasible = !isNotEqual(state, sym, V);
Mike Stump1eb44332009-09-09 15:08:12 +0000177
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000178 // If the path is still feasible then as a consequence we know that
179 // 'sym == V' because we cannot have 'sym > V' (no larger values).
180 // Add this constraint.
Ted Kremeneka591bc02009-06-18 22:57:13 +0000181 return isFeasible ? AddEQ(state, sym, V) : NULL;
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000182 }
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000183
Ted Kremeneka591bc02009-06-18 22:57:13 +0000184 return state;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000185}
186
187const GRState*
Ted Kremeneka591bc02009-06-18 22:57:13 +0000188BasicConstraintManager::AssumeSymLE(const GRState* state, SymbolRef sym,
189 const llvm::APSInt& V) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000190
Ted Kremenek73abd132008-12-03 18:56:12 +0000191 // Reject a path if the value of sym is a constant X and !(X <= V).
Ted Kremeneka591bc02009-06-18 22:57:13 +0000192 if (const llvm::APSInt* X = getSymVal(state, sym)) {
193 bool isFeasible = *X <= V;
194 return isFeasible ? state : NULL;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000195 }
Mike Stump1eb44332009-09-09 15:08:12 +0000196
Ted Kremenek73abd132008-12-03 18:56:12 +0000197 // Sym is not a constant, but it is worth looking to see if V is the
198 // minimum integer value.
Chris Lattner071e04e2009-01-30 01:58:33 +0000199 if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isUnsigned())) {
Ted Kremenek73abd132008-12-03 18:56:12 +0000200 // If we know that sym != V, then this condition is infeasible since
Mike Stump1eb44332009-09-09 15:08:12 +0000201 // there is no other value less than V.
Ted Kremeneka591bc02009-06-18 22:57:13 +0000202 bool isFeasible = !isNotEqual(state, sym, V);
Mike Stump1eb44332009-09-09 15:08:12 +0000203
Ted Kremenek73abd132008-12-03 18:56:12 +0000204 // If the path is still feasible then as a consequence we know that
205 // 'sym == V' because we cannot have 'sym < V' (no smaller values).
206 // Add this constraint.
Ted Kremeneka591bc02009-06-18 22:57:13 +0000207 return isFeasible ? AddEQ(state, sym, V) : NULL;
Ted Kremenek73abd132008-12-03 18:56:12 +0000208 }
Mike Stump1eb44332009-09-09 15:08:12 +0000209
Ted Kremeneka591bc02009-06-18 22:57:13 +0000210 return state;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000211}
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000212
Ted Kremenekc8781382009-06-17 22:28:13 +0000213const GRState* BasicConstraintManager::AddEQ(const GRState* state, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000214 const llvm::APSInt& V) {
215 // Create a new state with the old binding replaced.
Ted Kremenekc8781382009-06-17 22:28:13 +0000216 return state->set<ConstEq>(sym, &V);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000217}
218
Ted Kremenekc8781382009-06-17 22:28:13 +0000219const GRState* BasicConstraintManager::AddNE(const GRState* state, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000220 const llvm::APSInt& V) {
Zhongxing Xuf0bc50e2008-11-27 06:08:40 +0000221
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000222 // First, retrieve the NE-set associated with the given symbol.
Ted Kremenekc8781382009-06-17 22:28:13 +0000223 ConstNotEqTy::data_type* T = state->get<ConstNotEq>(sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000224 GRState::IntSetTy S = T ? *T : ISetFactory.GetEmptySet();
Mike Stump1eb44332009-09-09 15:08:12 +0000225
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000226 // Now add V to the NE set.
227 S = ISetFactory.Add(S, &V);
Mike Stump1eb44332009-09-09 15:08:12 +0000228
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000229 // Create a new state with the old binding replaced.
Ted Kremenekc8781382009-06-17 22:28:13 +0000230 return state->set<ConstNotEq>(sym, S);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000231}
232
Ted Kremeneka591bc02009-06-18 22:57:13 +0000233const llvm::APSInt* BasicConstraintManager::getSymVal(const GRState* state,
Ted Kremenek45021952009-02-14 17:08:39 +0000234 SymbolRef sym) const {
Ted Kremeneka591bc02009-06-18 22:57:13 +0000235 const ConstEqTy::data_type* T = state->get<ConstEq>(sym);
Ted Kremenek45021952009-02-14 17:08:39 +0000236 return T ? *T : NULL;
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000237}
238
Mike Stump1eb44332009-09-09 15:08:12 +0000239bool BasicConstraintManager::isNotEqual(const GRState* state, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000240 const llvm::APSInt& V) const {
241
242 // Retrieve the NE-set associated with the given symbol.
Ted Kremeneka591bc02009-06-18 22:57:13 +0000243 const ConstNotEqTy::data_type* T = state->get<ConstNotEq>(sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000244
245 // See if V is present in the NE-set.
246 return T ? T->contains(&V) : false;
247}
248
Ted Kremeneka591bc02009-06-18 22:57:13 +0000249bool BasicConstraintManager::isEqual(const GRState* state, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000250 const llvm::APSInt& V) const {
251 // Retrieve the EQ-set associated with the given symbol.
Ted Kremeneka591bc02009-06-18 22:57:13 +0000252 const ConstEqTy::data_type* T = state->get<ConstEq>(sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000253 // See if V is present in the EQ-set.
254 return T ? **T == V : false;
255}
256
Zhongxing Xu8fd9b352008-11-27 02:39:34 +0000257/// Scan all symbols referenced by the constraints. If the symbol is not alive
258/// as marked in LSymbols, mark it as dead in DSymbols.
Ted Kremenek241677a2009-01-21 22:26:05 +0000259const GRState*
Ted Kremenekc8781382009-06-17 22:28:13 +0000260BasicConstraintManager::RemoveDeadBindings(const GRState* state,
Ted Kremenek241677a2009-01-21 22:26:05 +0000261 SymbolReaper& SymReaper) {
262
Ted Kremenekc8781382009-06-17 22:28:13 +0000263 ConstEqTy CE = state->get<ConstEq>();
264 ConstEqTy::Factory& CEFactory = state->get_context<ConstEq>();
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000265
266 for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) {
Ted Kremenek241677a2009-01-21 22:26:05 +0000267 SymbolRef sym = I.getKey();
268 if (SymReaper.maybeDead(sym)) CE = CEFactory.Remove(CE, sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000269 }
Ted Kremenekc8781382009-06-17 22:28:13 +0000270 state = state->set<ConstEq>(CE);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000271
Ted Kremenekc8781382009-06-17 22:28:13 +0000272 ConstNotEqTy CNE = state->get<ConstNotEq>();
273 ConstNotEqTy::Factory& CNEFactory = state->get_context<ConstNotEq>();
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000274
275 for (ConstNotEqTy::iterator I = CNE.begin(), E = CNE.end(); I != E; ++I) {
Mike Stump1eb44332009-09-09 15:08:12 +0000276 SymbolRef sym = I.getKey();
Ted Kremenek241677a2009-01-21 22:26:05 +0000277 if (SymReaper.maybeDead(sym)) CNE = CNEFactory.Remove(CNE, sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000278 }
Mike Stump1eb44332009-09-09 15:08:12 +0000279
Ted Kremenekc8781382009-06-17 22:28:13 +0000280 return state->set<ConstNotEq>(CNE);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000281}
282
Mike Stump1eb44332009-09-09 15:08:12 +0000283void BasicConstraintManager::print(const GRState* state, llvm::raw_ostream& Out,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000284 const char* nl, const char *sep) {
285 // Print equality constraints.
286
Ted Kremeneka591bc02009-06-18 22:57:13 +0000287 ConstEqTy CE = state->get<ConstEq>();
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000288
289 if (!CE.isEmpty()) {
290 Out << nl << sep << "'==' constraints:";
Ted Kremenek53ba0b62009-06-24 23:06:47 +0000291 for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I)
292 Out << nl << " $" << I.getKey() << " : " << *I.getData();
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000293 }
294
295 // Print != constraints.
Mike Stump1eb44332009-09-09 15:08:12 +0000296
Ted Kremeneka591bc02009-06-18 22:57:13 +0000297 ConstNotEqTy CNE = state->get<ConstNotEq>();
Mike Stump1eb44332009-09-09 15:08:12 +0000298
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000299 if (!CNE.isEmpty()) {
300 Out << nl << sep << "'!=' constraints:";
Mike Stump1eb44332009-09-09 15:08:12 +0000301
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000302 for (ConstNotEqTy::iterator I = CNE.begin(), EI = CNE.end(); I!=EI; ++I) {
303 Out << nl << " $" << I.getKey() << " : ";
304 bool isFirst = true;
Mike Stump1eb44332009-09-09 15:08:12 +0000305
306 GRState::IntSetTy::iterator J = I.getData().begin(),
307 EJ = I.getData().end();
308
309 for ( ; J != EJ; ++J) {
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000310 if (isFirst) isFirst = false;
311 else Out << ", ";
Mike Stump1eb44332009-09-09 15:08:12 +0000312
Zhongxing Xu7d94e262008-11-10 05:00:06 +0000313 Out << (*J)->getSExtValue(); // Hack: should print to raw_ostream.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000314 }
315 }
316 }
Daniel Dunbar0e194dd2008-08-30 02:06:22 +0000317}