blob: 17425aff5a15f914724c4a28d64d07605482a988 [file] [log] [blame]
Ted Kremeneka90ccfe2008-01-31 19:34:24 +00001//= RValues.cpp - Abstract RValues for Path-Sens. Value Tracking -*- 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 files defines RValue, LValue, and NonLValue, classes that represent
11// abstract r-values for use with path-sensitive value tracking.
12//
13//===----------------------------------------------------------------------===//
14
Ted Kremenekcc409b72008-02-14 17:30:51 +000015#include "clang/Analysis/PathSensitive/RValues.h"
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000016
17using namespace clang;
18using llvm::dyn_cast;
19using llvm::cast;
20using llvm::APSInt;
21
22//===----------------------------------------------------------------------===//
23// SymbolManager.
24//===----------------------------------------------------------------------===//
25
26SymbolID SymbolManager::getSymbol(ParmVarDecl* D) {
Ted Kremenekd131c4f2008-02-07 05:48:01 +000027 SymbolID& X = DataToSymbol[getKey(D)];
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000028
29 if (!X.isInitialized()) {
30 X = SymbolToData.size();
Ted Kremenekd131c4f2008-02-07 05:48:01 +000031 SymbolToData.push_back(SymbolDataParmVar(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000032 }
33
34 return X;
35}
36
Ted Kremenekd131c4f2008-02-07 05:48:01 +000037SymbolID SymbolManager::getContentsOfSymbol(SymbolID sym) {
38 SymbolID& X = DataToSymbol[getKey(sym)];
39
40 if (!X.isInitialized()) {
41 X = SymbolToData.size();
42 SymbolToData.push_back(SymbolDataContentsOf(sym));
43 }
44
45 return X;
46}
47
Ted Kremenekfeb01f62008-02-06 17:32:17 +000048QualType SymbolData::getType() const {
49 switch (getKind()) {
50 default:
51 assert (false && "getType() not implemented for this symbol.");
52
53 case ParmKind:
Ted Kremenekd131c4f2008-02-07 05:48:01 +000054 return cast<SymbolDataParmVar>(this)->getDecl()->getType();
55
Ted Kremenekfeb01f62008-02-06 17:32:17 +000056 }
57}
58
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000059SymbolManager::SymbolManager() {}
60SymbolManager::~SymbolManager() {}
61
62//===----------------------------------------------------------------------===//
Ted Kremenek1fbdb022008-02-05 21:32:43 +000063// Values and ValueManager.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000064//===----------------------------------------------------------------------===//
65
66ValueManager::~ValueManager() {
67 // Note that the dstor for the contents of APSIntSet will never be called,
68 // so we iterate over the set and invoke the dstor for each APSInt. This
69 // frees an aux. memory allocated to represent very large constants.
70 for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
71 I->getValue().~APSInt();
72}
73
Ted Kremenek1fbdb022008-02-05 21:32:43 +000074const APSInt& ValueManager::getValue(const APSInt& X) {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000075 llvm::FoldingSetNodeID ID;
76 void* InsertPos;
77 typedef llvm::FoldingSetNodeWrapper<APSInt> FoldNodeTy;
78
79 X.Profile(ID);
80 FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
81
82 if (!P) {
83 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
84 new (P) FoldNodeTy(X);
85 APSIntSet.InsertNode(P, InsertPos);
86 }
87
88 return *P;
89}
90
Ted Kremenek1fbdb022008-02-05 21:32:43 +000091const APSInt& ValueManager::getValue(uint64_t X, unsigned BitWidth,
92 bool isUnsigned) {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000093 APSInt V(BitWidth, isUnsigned);
94 V = X;
95 return getValue(V);
96}
97
Ted Kremenek1fbdb022008-02-05 21:32:43 +000098const APSInt& ValueManager::getValue(uint64_t X, QualType T,
99 SourceLocation Loc) {
100
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000101 unsigned bits = Ctx.getTypeSize(T, Loc);
102 APSInt V(bits, T->isUnsignedIntegerType());
103 V = X;
104 return getValue(V);
105}
106
Ted Kremenek1fbdb022008-02-05 21:32:43 +0000107const SymIntConstraint&
108ValueManager::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
109 const llvm::APSInt& V) {
110
111 llvm::FoldingSetNodeID ID;
112 SymIntConstraint::Profile(ID, sym, Op, V);
113 void* InsertPos;
114
115 SymIntConstraint* C = SymIntCSet.FindNodeOrInsertPos(ID, InsertPos);
116
117 if (!C) {
118 C = (SymIntConstraint*) BPAlloc.Allocate<SymIntConstraint>();
119 new (C) SymIntConstraint(sym, Op, V);
120 SymIntCSet.InsertNode(C, InsertPos);
121 }
122
123 return *C;
124}
125
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000126
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000127
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000128
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000129//===----------------------------------------------------------------------===//
130// Transfer function dispatch for Non-LValues.
131//===----------------------------------------------------------------------===//
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000132
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000133 // Binary Operators (except assignments and comma).
134
135NonLValue NonLValue::EvalBinaryOp(ValueManager& ValMgr,
136 BinaryOperator::Opcode Op,
137 const NonLValue& RHS) const {
138
Ted Kremenek22031182008-02-08 02:57:34 +0000139 if (isa<UnknownVal>(this) || isa<UnknownVal>(RHS))
140 return cast<NonLValue>(UnknownVal());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000141
Ted Kremenek22031182008-02-08 02:57:34 +0000142 if (isa<UninitializedVal>(this) || isa<UninitializedVal>(RHS))
143 return cast<NonLValue>(UninitializedVal());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000144
145 switch (getSubKind()) {
146 default:
147 assert (false && "Binary Operators not implemented for this NonLValue");
148
149 case nonlval::ConcreteIntKind:
150
151 if (isa<nonlval::ConcreteInt>(RHS)) {
152 nonlval::ConcreteInt& self = cast<nonlval::ConcreteInt>(*this);
153 return self.EvalBinaryOp(ValMgr, Op,
154 cast<nonlval::ConcreteInt>(RHS));
155 }
Ted Kremenek22031182008-02-08 02:57:34 +0000156 else if(isa<UnknownVal>(RHS))
157 return cast<NonLValue>(UnknownVal());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000158 else
159 return RHS.EvalBinaryOp(ValMgr, Op, *this);
160
161 case nonlval::SymbolValKind: {
162 const nonlval::SymbolVal& self = cast<nonlval::SymbolVal>(*this);
163
164 switch (RHS.getSubKind()) {
165 default: assert ("Not Implemented." && false);
166 case nonlval::ConcreteIntKind: {
167 const SymIntConstraint& C =
168 ValMgr.getConstraint(self.getSymbol(), Op,
169 cast<nonlval::ConcreteInt>(RHS).getValue());
170
171 return nonlval::SymIntConstraintVal(C);
172 }
173 }
174 }
175 }
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000176}
177
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000178static const
179llvm::APSInt& EvaluateAPSInt(ValueManager& ValMgr, BinaryOperator::Opcode Op,
180 const llvm::APSInt& V1, const llvm::APSInt& V2) {
181
182 switch (Op) {
183 default:
184 assert (false && "Invalid Opcode.");
185
186 case BinaryOperator::Mul:
187 return ValMgr.getValue( V1 * V2 );
188
189 case BinaryOperator::Div:
190 return ValMgr.getValue( V1 / V2 );
191
192 case BinaryOperator::Rem:
193 return ValMgr.getValue( V1 % V2 );
194
195 case BinaryOperator::Add:
196 return ValMgr.getValue( V1 + V2 );
197
198 case BinaryOperator::Sub:
199 return ValMgr.getValue( V1 - V2 );
200
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000201 case BinaryOperator::Shl:
Ted Kremenek59c2d262008-02-08 07:14:58 +0000202 return ValMgr.getValue( V1.operator<<( (unsigned) V2.getZExtValue() ));
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000203
204 case BinaryOperator::Shr:
Ted Kremenek59c2d262008-02-08 07:14:58 +0000205 return ValMgr.getValue( V1.operator>>( (unsigned) V2.getZExtValue() ));
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000206
207 case BinaryOperator::LT:
208 return ValMgr.getTruthValue( V1 < V2 );
209
210 case BinaryOperator::GT:
211 return ValMgr.getTruthValue( V1 > V2 );
212
213 case BinaryOperator::LE:
214 return ValMgr.getTruthValue( V1 <= V2 );
215
216 case BinaryOperator::GE:
217 return ValMgr.getTruthValue( V1 >= V2 );
218
219 case BinaryOperator::EQ:
220 return ValMgr.getTruthValue( V1 == V2 );
221
222 case BinaryOperator::NE:
223 return ValMgr.getTruthValue( V1 != V2 );
224
225 // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
226
227 case BinaryOperator::And:
228 return ValMgr.getValue( V1 & V2 );
229
230 case BinaryOperator::Or:
231 return ValMgr.getValue( V1 | V2 );
232 }
233}
234
235nonlval::ConcreteInt
236nonlval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
237 BinaryOperator::Opcode Op,
238 const nonlval::ConcreteInt& RHS) const {
239
240 return EvaluateAPSInt(ValMgr, Op, getValue(), RHS.getValue());
241}
242
243
244 // Bitwise-Complement.
245
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000246
247nonlval::ConcreteInt
248nonlval::ConcreteInt::EvalComplement(ValueManager& ValMgr) const {
249 return ValMgr.getValue(~getValue());
250}
251
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000252 // Unary Minus.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000253
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000254nonlval::ConcreteInt
255nonlval::ConcreteInt::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
256 assert (U->getType() == U->getSubExpr()->getType());
257 assert (U->getType()->isIntegerType());
258 return ValMgr.getValue(-getValue());
Ted Kremenekc5d3b4c2008-02-04 16:58:30 +0000259}
260
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000261//===----------------------------------------------------------------------===//
262// Transfer function dispatch for LValues.
263//===----------------------------------------------------------------------===//
264
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000265 // Binary Operators (except assignments and comma).
266
267RValue LValue::EvalBinaryOp(ValueManager& ValMgr,
268 BinaryOperator::Opcode Op,
269 const LValue& RHS) const {
270
271 switch (Op) {
272 default:
273 assert (false && "Not yet implemented.");
274
275 case BinaryOperator::EQ:
276 return EQ(ValMgr, RHS);
277
278 case BinaryOperator::NE:
279 return NE(ValMgr, RHS);
280 }
281}
282
283
284lval::ConcreteInt
285lval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
286 BinaryOperator::Opcode Op,
287 const lval::ConcreteInt& RHS) const {
288
289 assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
290 (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));
291
292 return EvaluateAPSInt(ValMgr, Op, getValue(), RHS.getValue());
293}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000294
295NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000296 switch (getSubKind()) {
297 default:
298 assert(false && "EQ not implemented for this LValue.");
Ted Kremenek22031182008-02-08 02:57:34 +0000299 return cast<NonLValue>(UnknownVal());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000300
Ted Kremenek0806acf2008-02-05 23:08:41 +0000301 case lval::ConcreteIntKind:
302 if (isa<lval::ConcreteInt>(RHS)) {
303 bool b = cast<lval::ConcreteInt>(this)->getValue() ==
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000304 cast<lval::ConcreteInt>(RHS).getValue();
305
Ted Kremenek0806acf2008-02-05 23:08:41 +0000306 return NonLValue::GetIntTruthValue(ValMgr, b);
307 }
308 else if (isa<lval::SymbolVal>(RHS)) {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000309
Ted Kremenek0806acf2008-02-05 23:08:41 +0000310 const SymIntConstraint& C =
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000311 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
312 BinaryOperator::EQ,
313 cast<lval::ConcreteInt>(this)->getValue());
Ted Kremenek0806acf2008-02-05 23:08:41 +0000314
315 return nonlval::SymIntConstraintVal(C);
316 }
317
318 break;
319
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000320 case lval::SymbolValKind: {
321 if (isa<lval::ConcreteInt>(RHS)) {
322
323 const SymIntConstraint& C =
Ted Kremenek0806acf2008-02-05 23:08:41 +0000324 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
325 BinaryOperator::EQ,
326 cast<lval::ConcreteInt>(RHS).getValue());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000327
328 return nonlval::SymIntConstraintVal(C);
329 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000330
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000331 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement unification.");
332
333 break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000334 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000335
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000336 case lval::DeclValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000337 if (isa<lval::DeclVal>(RHS)) {
338 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
339 return NonLValue::GetIntTruthValue(ValMgr, b);
340 }
341
342 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000343 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000344
345 return NonLValue::GetIntTruthValue(ValMgr, false);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000346}
347
348NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000349 switch (getSubKind()) {
350 default:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000351 assert(false && "NE not implemented for this LValue.");
Ted Kremenek22031182008-02-08 02:57:34 +0000352 return cast<NonLValue>(UnknownVal());
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000353
Ted Kremenek0806acf2008-02-05 23:08:41 +0000354 case lval::ConcreteIntKind:
355 if (isa<lval::ConcreteInt>(RHS)) {
356 bool b = cast<lval::ConcreteInt>(this)->getValue() !=
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000357 cast<lval::ConcreteInt>(RHS).getValue();
Ted Kremenek0806acf2008-02-05 23:08:41 +0000358
359 return NonLValue::GetIntTruthValue(ValMgr, b);
360 }
361 else if (isa<lval::SymbolVal>(RHS)) {
362
363 const SymIntConstraint& C =
364 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
365 BinaryOperator::NE,
366 cast<lval::ConcreteInt>(this)->getValue());
367
368 return nonlval::SymIntConstraintVal(C);
369 }
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000370
Ted Kremenek0806acf2008-02-05 23:08:41 +0000371 break;
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000372
Ted Kremenek0806acf2008-02-05 23:08:41 +0000373 case lval::SymbolValKind: {
374 if (isa<lval::ConcreteInt>(RHS)) {
375
376 const SymIntConstraint& C =
377 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
378 BinaryOperator::NE,
379 cast<lval::ConcreteInt>(RHS).getValue());
380
381 return nonlval::SymIntConstraintVal(C);
382 }
383
384 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement sym !=.");
385
386 break;
387 }
388
389 case lval::DeclValKind:
390 if (isa<lval::DeclVal>(RHS)) {
391 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
392 return NonLValue::GetIntTruthValue(ValMgr, b);
393 }
394
395 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000396 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000397
398 return NonLValue::GetIntTruthValue(ValMgr, true);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000399}
400
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000401
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000402
403//===----------------------------------------------------------------------===//
404// Utility methods for constructing Non-LValues.
405//===----------------------------------------------------------------------===//
406
407NonLValue NonLValue::GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
408 SourceLocation Loc) {
409
Ted Kremenek329f8542008-02-05 21:52:21 +0000410 return nonlval::ConcreteInt(ValMgr.getValue(X, T, Loc));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000411}
412
413NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000414 return nonlval::ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
415 I->getType()->isUnsignedIntegerType())));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000416}
417
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000418NonLValue NonLValue::GetIntTruthValue(ValueManager& ValMgr, bool b) {
419 return nonlval::ConcreteInt(ValMgr.getTruthValue(b));
420}
421
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000422RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
423 QualType T = D->getType();
424
425 if (T->isPointerType() || T->isReferenceType())
Ted Kremenek329f8542008-02-05 21:52:21 +0000426 return lval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000427 else
Ted Kremenek329f8542008-02-05 21:52:21 +0000428 return nonlval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000429}
430
Ted Kremenek2a502572008-02-12 21:37:56 +0000431//===----------------------------------------------------------------------===//
432// Utility methods for constructing LValues.
433//===----------------------------------------------------------------------===//
434
435LValue LValue::GetValue(AddrLabelExpr* E) {
436 return lval::GotoLabel(E->getLabel());
Ted Kremenek5b6dc2d2008-02-07 01:08:27 +0000437}
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000438
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000439//===----------------------------------------------------------------------===//
440// Pretty-Printing.
441//===----------------------------------------------------------------------===//
442
Ted Kremenek2a502572008-02-12 21:37:56 +0000443void RValue::print() const {
444 print(*llvm::cerr.stream());
445}
446
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000447void RValue::print(std::ostream& Out) const {
448 switch (getBaseKind()) {
Ted Kremenek53c641a2008-02-08 03:02:48 +0000449 case UnknownKind:
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000450 Out << "Invalid";
451 break;
452
453 case NonLValueKind:
454 cast<NonLValue>(this)->print(Out);
455 break;
456
457 case LValueKind:
458 cast<LValue>(this)->print(Out);
459 break;
460
461 case UninitializedKind:
462 Out << "Uninitialized";
463 break;
464
465 default:
466 assert (false && "Invalid RValue.");
467 }
468}
469
Ted Kremenek0806acf2008-02-05 23:08:41 +0000470static void printOpcode(std::ostream& Out, BinaryOperator::Opcode Op) {
Ted Kremenek7e593362008-02-07 15:20:13 +0000471 switch (Op) {
472 case BinaryOperator::Add: Out << "+" ; break;
473 case BinaryOperator::Sub: Out << "-" ; break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000474 case BinaryOperator::EQ: Out << "=="; break;
475 case BinaryOperator::NE: Out << "!="; break;
476 default: assert(false && "Not yet implemented.");
477 }
478}
479
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000480void NonLValue::print(std::ostream& Out) const {
481 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000482 case nonlval::ConcreteIntKind:
483 Out << cast<nonlval::ConcreteInt>(this)->getValue().toString();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000484
485 if (cast<nonlval::ConcreteInt>(this)->getValue().isUnsigned())
486 Out << 'U';
487
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000488 break;
489
Ted Kremenek329f8542008-02-05 21:52:21 +0000490 case nonlval::SymbolValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000491 Out << '$' << cast<nonlval::SymbolVal>(this)->getSymbol();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000492 break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000493
494 case nonlval::SymIntConstraintValKind: {
495 const nonlval::SymIntConstraintVal& C =
496 *cast<nonlval::SymIntConstraintVal>(this);
497
498 Out << '$' << C.getConstraint().getSymbol() << ' ';
499 printOpcode(Out, C.getConstraint().getOpcode());
500 Out << ' ' << C.getConstraint().getInt().toString();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000501
502 if (C.getConstraint().getInt().isUnsigned())
503 Out << 'U';
504
Ted Kremenek0806acf2008-02-05 23:08:41 +0000505 break;
506 }
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000507
508 default:
509 assert (false && "Pretty-printed not implemented for this NonLValue.");
510 break;
511 }
512}
513
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000514
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000515void LValue::print(std::ostream& Out) const {
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000516 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000517 case lval::ConcreteIntKind:
518 Out << cast<lval::ConcreteInt>(this)->getValue().toString()
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000519 << " (LValue)";
520 break;
521
Ted Kremenek329f8542008-02-05 21:52:21 +0000522 case lval::SymbolValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000523 Out << '$' << cast<lval::SymbolVal>(this)->getSymbol();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000524 break;
Ted Kremenek2a502572008-02-12 21:37:56 +0000525
526 case lval::GotoLabelKind:
527 Out << "&&"
528 << cast<lval::GotoLabel>(this)->getLabel()->getID()->getName();
529 break;
Ted Kremenek08b66252008-02-06 04:31:33 +0000530
Ted Kremenek329f8542008-02-05 21:52:21 +0000531 case lval::DeclValKind:
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000532 Out << '&'
Ted Kremenek329f8542008-02-05 21:52:21 +0000533 << cast<lval::DeclVal>(this)->getDecl()->getIdentifier()->getName();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000534 break;
535
536 default:
537 assert (false && "Pretty-printed not implemented for this LValue.");
538 break;
539 }
540}
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000541