blob: 06d29550a10dab6541e9d735387b918f1bec37fd [file] [log] [blame]
Ted Kremenek72197902008-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 Kremenek5a535ba2008-02-14 17:30:51 +000015#include "clang/Analysis/PathSensitive/RValues.h"
Ted Kremenek72197902008-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 Kremenek80d52d02008-02-07 05:48:01 +000027 SymbolID& X = DataToSymbol[getKey(D)];
Ted Kremenek72197902008-01-31 19:34:24 +000028
29 if (!X.isInitialized()) {
30 X = SymbolToData.size();
Ted Kremenek80d52d02008-02-07 05:48:01 +000031 SymbolToData.push_back(SymbolDataParmVar(D));
Ted Kremenek72197902008-01-31 19:34:24 +000032 }
33
34 return X;
35}
36
Ted Kremenek80d52d02008-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 Kremenekab359c12008-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 Kremenek80d52d02008-02-07 05:48:01 +000054 return cast<SymbolDataParmVar>(this)->getDecl()->getType();
55
Ted Kremenekab359c12008-02-06 17:32:17 +000056 }
57}
58
Ted Kremenek72197902008-01-31 19:34:24 +000059SymbolManager::SymbolManager() {}
60SymbolManager::~SymbolManager() {}
61
62//===----------------------------------------------------------------------===//
Ted Kremenekcdb310d2008-02-05 21:32:43 +000063// Values and ValueManager.
Ted Kremenek72197902008-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 Kremenekcdb310d2008-02-05 21:32:43 +000074const APSInt& ValueManager::getValue(const APSInt& X) {
Ted Kremenek72197902008-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 Kremenekcdb310d2008-02-05 21:32:43 +000091const APSInt& ValueManager::getValue(uint64_t X, unsigned BitWidth,
92 bool isUnsigned) {
Ted Kremenek72197902008-01-31 19:34:24 +000093 APSInt V(BitWidth, isUnsigned);
94 V = X;
95 return getValue(V);
96}
97
Ted Kremenekcdb310d2008-02-05 21:32:43 +000098const APSInt& ValueManager::getValue(uint64_t X, QualType T,
99 SourceLocation Loc) {
100
Ted Kremenek72197902008-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 Kremenekcdb310d2008-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 Kremenek6e24a802008-02-01 06:36:40 +0000126
Ted Kremenek6e24a802008-02-01 06:36:40 +0000127
Ted Kremenek6e24a802008-02-01 06:36:40 +0000128
Ted Kremenek15cb0782008-02-06 22:50:25 +0000129//===----------------------------------------------------------------------===//
130// Transfer function dispatch for Non-LValues.
131//===----------------------------------------------------------------------===//
Ted Kremenek6e24a802008-02-01 06:36:40 +0000132
Ted Kremenek15cb0782008-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 Kremenekadec14b2008-02-08 02:57:34 +0000139 if (isa<UnknownVal>(this) || isa<UnknownVal>(RHS))
140 return cast<NonLValue>(UnknownVal());
Ted Kremenek15cb0782008-02-06 22:50:25 +0000141
Ted Kremenekadec14b2008-02-08 02:57:34 +0000142 if (isa<UninitializedVal>(this) || isa<UninitializedVal>(RHS))
143 return cast<NonLValue>(UninitializedVal());
Ted Kremenek15cb0782008-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 Kremenekadec14b2008-02-08 02:57:34 +0000156 else if(isa<UnknownVal>(RHS))
157 return cast<NonLValue>(UnknownVal());
Ted Kremenek15cb0782008-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 Kremenek6e24a802008-02-01 06:36:40 +0000176}
177
Ted Kremenek15cb0782008-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 Kremenek15cb0782008-02-06 22:50:25 +0000201 case BinaryOperator::Shl:
Ted Kremenek3e1e4f52008-02-08 07:14:58 +0000202 return ValMgr.getValue( V1.operator<<( (unsigned) V2.getZExtValue() ));
Ted Kremenek15cb0782008-02-06 22:50:25 +0000203
204 case BinaryOperator::Shr:
Ted Kremenek3e1e4f52008-02-08 07:14:58 +0000205 return ValMgr.getValue( V1.operator>>( (unsigned) V2.getZExtValue() ));
Ted Kremenek15cb0782008-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
246NonLValue NonLValue::EvalComplement(ValueManager& ValMgr) const {
247 switch (getSubKind()) {
248 case nonlval::ConcreteIntKind:
249 return cast<nonlval::ConcreteInt>(this)->EvalComplement(ValMgr);
250 default:
Ted Kremenekadec14b2008-02-08 02:57:34 +0000251 return cast<NonLValue>(UnknownVal());
Ted Kremenek15cb0782008-02-06 22:50:25 +0000252 }
253}
254
255nonlval::ConcreteInt
256nonlval::ConcreteInt::EvalComplement(ValueManager& ValMgr) const {
257 return ValMgr.getValue(~getValue());
258}
259
Ted Kremenek15cb0782008-02-06 22:50:25 +0000260 // Unary Minus.
Ted Kremenek72197902008-01-31 19:34:24 +0000261
Ted Kremenek15cb0782008-02-06 22:50:25 +0000262NonLValue NonLValue::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
Ted Kremenek72197902008-01-31 19:34:24 +0000263 switch (getSubKind()) {
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000264 case nonlval::ConcreteIntKind:
Ted Kremenek15cb0782008-02-06 22:50:25 +0000265 return cast<nonlval::ConcreteInt>(this)->EvalMinus(ValMgr, U);
Ted Kremenek72197902008-01-31 19:34:24 +0000266 default:
Ted Kremenekadec14b2008-02-08 02:57:34 +0000267 return cast<NonLValue>(UnknownVal());
Ted Kremenek72197902008-01-31 19:34:24 +0000268 }
269}
270
Ted Kremenek15cb0782008-02-06 22:50:25 +0000271nonlval::ConcreteInt
272nonlval::ConcreteInt::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
273 assert (U->getType() == U->getSubExpr()->getType());
274 assert (U->getType()->isIntegerType());
275 return ValMgr.getValue(-getValue());
Ted Kremenek2cb46642008-02-04 16:58:30 +0000276}
277
Ted Kremenek72197902008-01-31 19:34:24 +0000278//===----------------------------------------------------------------------===//
279// Transfer function dispatch for LValues.
280//===----------------------------------------------------------------------===//
281
Ted Kremenek15cb0782008-02-06 22:50:25 +0000282 // Binary Operators (except assignments and comma).
283
284RValue LValue::EvalBinaryOp(ValueManager& ValMgr,
285 BinaryOperator::Opcode Op,
286 const LValue& RHS) const {
287
288 switch (Op) {
289 default:
290 assert (false && "Not yet implemented.");
291
292 case BinaryOperator::EQ:
293 return EQ(ValMgr, RHS);
294
295 case BinaryOperator::NE:
296 return NE(ValMgr, RHS);
297 }
298}
299
300
301lval::ConcreteInt
302lval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
303 BinaryOperator::Opcode Op,
304 const lval::ConcreteInt& RHS) const {
305
306 assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
307 (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));
308
309 return EvaluateAPSInt(ValMgr, Op, getValue(), RHS.getValue());
310}
Ted Kremenek72197902008-01-31 19:34:24 +0000311
312NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremenek72197902008-01-31 19:34:24 +0000313 switch (getSubKind()) {
314 default:
315 assert(false && "EQ not implemented for this LValue.");
Ted Kremenekadec14b2008-02-08 02:57:34 +0000316 return cast<NonLValue>(UnknownVal());
Ted Kremenek15cb0782008-02-06 22:50:25 +0000317
Ted Kremenek81eacb22008-02-05 23:08:41 +0000318 case lval::ConcreteIntKind:
319 if (isa<lval::ConcreteInt>(RHS)) {
320 bool b = cast<lval::ConcreteInt>(this)->getValue() ==
Ted Kremenek15cb0782008-02-06 22:50:25 +0000321 cast<lval::ConcreteInt>(RHS).getValue();
322
Ted Kremenek81eacb22008-02-05 23:08:41 +0000323 return NonLValue::GetIntTruthValue(ValMgr, b);
324 }
325 else if (isa<lval::SymbolVal>(RHS)) {
Ted Kremenek15cb0782008-02-06 22:50:25 +0000326
Ted Kremenek81eacb22008-02-05 23:08:41 +0000327 const SymIntConstraint& C =
Ted Kremenek15cb0782008-02-06 22:50:25 +0000328 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
329 BinaryOperator::EQ,
330 cast<lval::ConcreteInt>(this)->getValue());
Ted Kremenek81eacb22008-02-05 23:08:41 +0000331
332 return nonlval::SymIntConstraintVal(C);
333 }
334
335 break;
336
Ted Kremenek15cb0782008-02-06 22:50:25 +0000337 case lval::SymbolValKind: {
338 if (isa<lval::ConcreteInt>(RHS)) {
339
340 const SymIntConstraint& C =
Ted Kremenek81eacb22008-02-05 23:08:41 +0000341 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
342 BinaryOperator::EQ,
343 cast<lval::ConcreteInt>(RHS).getValue());
Ted Kremenek15cb0782008-02-06 22:50:25 +0000344
345 return nonlval::SymIntConstraintVal(C);
346 }
Ted Kremenek81eacb22008-02-05 23:08:41 +0000347
Ted Kremenek15cb0782008-02-06 22:50:25 +0000348 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement unification.");
349
350 break;
Ted Kremenek81eacb22008-02-05 23:08:41 +0000351 }
Ted Kremenek81eacb22008-02-05 23:08:41 +0000352
Ted Kremenek15cb0782008-02-06 22:50:25 +0000353 case lval::DeclValKind:
Ted Kremenek81eacb22008-02-05 23:08:41 +0000354 if (isa<lval::DeclVal>(RHS)) {
355 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
356 return NonLValue::GetIntTruthValue(ValMgr, b);
357 }
358
359 break;
Ted Kremenek72197902008-01-31 19:34:24 +0000360 }
Ted Kremenek81eacb22008-02-05 23:08:41 +0000361
362 return NonLValue::GetIntTruthValue(ValMgr, false);
Ted Kremenek72197902008-01-31 19:34:24 +0000363}
364
365NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremenek72197902008-01-31 19:34:24 +0000366 switch (getSubKind()) {
367 default:
Ted Kremenek81eacb22008-02-05 23:08:41 +0000368 assert(false && "NE not implemented for this LValue.");
Ted Kremenekadec14b2008-02-08 02:57:34 +0000369 return cast<NonLValue>(UnknownVal());
Ted Kremenek72197902008-01-31 19:34:24 +0000370
Ted Kremenek81eacb22008-02-05 23:08:41 +0000371 case lval::ConcreteIntKind:
372 if (isa<lval::ConcreteInt>(RHS)) {
373 bool b = cast<lval::ConcreteInt>(this)->getValue() !=
Ted Kremenek15cb0782008-02-06 22:50:25 +0000374 cast<lval::ConcreteInt>(RHS).getValue();
Ted Kremenek81eacb22008-02-05 23:08:41 +0000375
376 return NonLValue::GetIntTruthValue(ValMgr, b);
377 }
378 else if (isa<lval::SymbolVal>(RHS)) {
379
380 const SymIntConstraint& C =
381 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
382 BinaryOperator::NE,
383 cast<lval::ConcreteInt>(this)->getValue());
384
385 return nonlval::SymIntConstraintVal(C);
386 }
Ted Kremenek6e24a802008-02-01 06:36:40 +0000387
Ted Kremenek81eacb22008-02-05 23:08:41 +0000388 break;
Ted Kremenek6e24a802008-02-01 06:36:40 +0000389
Ted Kremenek81eacb22008-02-05 23:08:41 +0000390 case lval::SymbolValKind: {
391 if (isa<lval::ConcreteInt>(RHS)) {
392
393 const SymIntConstraint& C =
394 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
395 BinaryOperator::NE,
396 cast<lval::ConcreteInt>(RHS).getValue());
397
398 return nonlval::SymIntConstraintVal(C);
399 }
400
401 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement sym !=.");
402
403 break;
404 }
405
406 case lval::DeclValKind:
407 if (isa<lval::DeclVal>(RHS)) {
408 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
409 return NonLValue::GetIntTruthValue(ValMgr, b);
410 }
411
412 break;
Ted Kremenek72197902008-01-31 19:34:24 +0000413 }
Ted Kremenek81eacb22008-02-05 23:08:41 +0000414
415 return NonLValue::GetIntTruthValue(ValMgr, true);
Ted Kremenek72197902008-01-31 19:34:24 +0000416}
417
Ted Kremenek15cb0782008-02-06 22:50:25 +0000418
Ted Kremenek72197902008-01-31 19:34:24 +0000419
420//===----------------------------------------------------------------------===//
421// Utility methods for constructing Non-LValues.
422//===----------------------------------------------------------------------===//
423
424NonLValue NonLValue::GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
425 SourceLocation Loc) {
426
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000427 return nonlval::ConcreteInt(ValMgr.getValue(X, T, Loc));
Ted Kremenek72197902008-01-31 19:34:24 +0000428}
429
430NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000431 return nonlval::ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
432 I->getType()->isUnsignedIntegerType())));
Ted Kremenek72197902008-01-31 19:34:24 +0000433}
434
Ted Kremenek15cb0782008-02-06 22:50:25 +0000435NonLValue NonLValue::GetIntTruthValue(ValueManager& ValMgr, bool b) {
436 return nonlval::ConcreteInt(ValMgr.getTruthValue(b));
437}
438
Ted Kremenek72197902008-01-31 19:34:24 +0000439RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
440 QualType T = D->getType();
441
442 if (T->isPointerType() || T->isReferenceType())
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000443 return lval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremenek72197902008-01-31 19:34:24 +0000444 else
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000445 return nonlval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremenek72197902008-01-31 19:34:24 +0000446}
447
Ted Kremenekad884682008-02-12 21:37:56 +0000448//===----------------------------------------------------------------------===//
449// Utility methods for constructing LValues.
450//===----------------------------------------------------------------------===//
451
452LValue LValue::GetValue(AddrLabelExpr* E) {
453 return lval::GotoLabel(E->getLabel());
Ted Kremeneke1f38b62008-02-07 01:08:27 +0000454}
Ted Kremenek15cb0782008-02-06 22:50:25 +0000455
Ted Kremenek72197902008-01-31 19:34:24 +0000456//===----------------------------------------------------------------------===//
457// Pretty-Printing.
458//===----------------------------------------------------------------------===//
459
Ted Kremenekad884682008-02-12 21:37:56 +0000460void RValue::print() const {
461 print(*llvm::cerr.stream());
462}
463
Ted Kremenek72197902008-01-31 19:34:24 +0000464void RValue::print(std::ostream& Out) const {
465 switch (getBaseKind()) {
Ted Kremenek0428e022008-02-08 03:02:48 +0000466 case UnknownKind:
Ted Kremenek72197902008-01-31 19:34:24 +0000467 Out << "Invalid";
468 break;
469
470 case NonLValueKind:
471 cast<NonLValue>(this)->print(Out);
472 break;
473
474 case LValueKind:
475 cast<LValue>(this)->print(Out);
476 break;
477
478 case UninitializedKind:
479 Out << "Uninitialized";
480 break;
481
482 default:
483 assert (false && "Invalid RValue.");
484 }
485}
486
Ted Kremenek81eacb22008-02-05 23:08:41 +0000487static void printOpcode(std::ostream& Out, BinaryOperator::Opcode Op) {
Ted Kremenek02b5b402008-02-07 15:20:13 +0000488 switch (Op) {
489 case BinaryOperator::Add: Out << "+" ; break;
490 case BinaryOperator::Sub: Out << "-" ; break;
Ted Kremenek81eacb22008-02-05 23:08:41 +0000491 case BinaryOperator::EQ: Out << "=="; break;
492 case BinaryOperator::NE: Out << "!="; break;
493 default: assert(false && "Not yet implemented.");
494 }
495}
496
Ted Kremenek72197902008-01-31 19:34:24 +0000497void NonLValue::print(std::ostream& Out) const {
498 switch (getSubKind()) {
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000499 case nonlval::ConcreteIntKind:
500 Out << cast<nonlval::ConcreteInt>(this)->getValue().toString();
Ted Kremenek15cb0782008-02-06 22:50:25 +0000501
502 if (cast<nonlval::ConcreteInt>(this)->getValue().isUnsigned())
503 Out << 'U';
504
Ted Kremenek72197902008-01-31 19:34:24 +0000505 break;
506
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000507 case nonlval::SymbolValKind:
Ted Kremenek81eacb22008-02-05 23:08:41 +0000508 Out << '$' << cast<nonlval::SymbolVal>(this)->getSymbol();
Ted Kremenek72197902008-01-31 19:34:24 +0000509 break;
Ted Kremenek81eacb22008-02-05 23:08:41 +0000510
511 case nonlval::SymIntConstraintValKind: {
512 const nonlval::SymIntConstraintVal& C =
513 *cast<nonlval::SymIntConstraintVal>(this);
514
515 Out << '$' << C.getConstraint().getSymbol() << ' ';
516 printOpcode(Out, C.getConstraint().getOpcode());
517 Out << ' ' << C.getConstraint().getInt().toString();
Ted Kremenek15cb0782008-02-06 22:50:25 +0000518
519 if (C.getConstraint().getInt().isUnsigned())
520 Out << 'U';
521
Ted Kremenek81eacb22008-02-05 23:08:41 +0000522 break;
523 }
Ted Kremenek72197902008-01-31 19:34:24 +0000524
525 default:
526 assert (false && "Pretty-printed not implemented for this NonLValue.");
527 break;
528 }
529}
530
Ted Kremenek80d52d02008-02-07 05:48:01 +0000531
Ted Kremenek72197902008-01-31 19:34:24 +0000532void LValue::print(std::ostream& Out) const {
Ted Kremenek6e24a802008-02-01 06:36:40 +0000533 switch (getSubKind()) {
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000534 case lval::ConcreteIntKind:
535 Out << cast<lval::ConcreteInt>(this)->getValue().toString()
Ted Kremenek6e24a802008-02-01 06:36:40 +0000536 << " (LValue)";
537 break;
538
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000539 case lval::SymbolValKind:
Ted Kremenek81eacb22008-02-05 23:08:41 +0000540 Out << '$' << cast<lval::SymbolVal>(this)->getSymbol();
Ted Kremenek72197902008-01-31 19:34:24 +0000541 break;
Ted Kremenekad884682008-02-12 21:37:56 +0000542
543 case lval::GotoLabelKind:
544 Out << "&&"
545 << cast<lval::GotoLabel>(this)->getLabel()->getID()->getName();
546 break;
Ted Kremenek0033fbb2008-02-06 04:31:33 +0000547
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000548 case lval::DeclValKind:
Ted Kremenek72197902008-01-31 19:34:24 +0000549 Out << '&'
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000550 << cast<lval::DeclVal>(this)->getDecl()->getIdentifier()->getName();
Ted Kremenek72197902008-01-31 19:34:24 +0000551 break;
552
553 default:
554 assert (false && "Pretty-printed not implemented for this LValue.");
555 break;
556 }
557}
Ted Kremenek80d52d02008-02-07 05:48:01 +0000558