blob: bfdfe3bf45be65466c8350e38412900a0d41605b [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
15#include "RValues.h"
16
17using namespace clang;
18using llvm::dyn_cast;
19using llvm::cast;
20using llvm::APSInt;
21
22//===----------------------------------------------------------------------===//
23// SymbolManager.
24//===----------------------------------------------------------------------===//
25
26SymbolID SymbolManager::getSymbol(ParmVarDecl* D) {
27 SymbolID& X = DataToSymbol[D];
28
29 if (!X.isInitialized()) {
30 X = SymbolToData.size();
31 SymbolToData.push_back(D);
32 }
33
34 return X;
35}
36
Ted Kremenekfeb01f62008-02-06 17:32:17 +000037QualType SymbolData::getType() const {
38 switch (getKind()) {
39 default:
40 assert (false && "getType() not implemented for this symbol.");
41
42 case ParmKind:
43 return static_cast<ParmVarDecl*>(getPtr())->getType();
44 }
45}
46
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000047SymbolManager::SymbolManager() {}
48SymbolManager::~SymbolManager() {}
49
50//===----------------------------------------------------------------------===//
Ted Kremenek1fbdb022008-02-05 21:32:43 +000051// Values and ValueManager.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000052//===----------------------------------------------------------------------===//
53
54ValueManager::~ValueManager() {
55 // Note that the dstor for the contents of APSIntSet will never be called,
56 // so we iterate over the set and invoke the dstor for each APSInt. This
57 // frees an aux. memory allocated to represent very large constants.
58 for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
59 I->getValue().~APSInt();
60}
61
Ted Kremenek1fbdb022008-02-05 21:32:43 +000062const APSInt& ValueManager::getValue(const APSInt& X) {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000063 llvm::FoldingSetNodeID ID;
64 void* InsertPos;
65 typedef llvm::FoldingSetNodeWrapper<APSInt> FoldNodeTy;
66
67 X.Profile(ID);
68 FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
69
70 if (!P) {
71 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
72 new (P) FoldNodeTy(X);
73 APSIntSet.InsertNode(P, InsertPos);
74 }
75
76 return *P;
77}
78
Ted Kremenek1fbdb022008-02-05 21:32:43 +000079const APSInt& ValueManager::getValue(uint64_t X, unsigned BitWidth,
80 bool isUnsigned) {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000081 APSInt V(BitWidth, isUnsigned);
82 V = X;
83 return getValue(V);
84}
85
Ted Kremenek1fbdb022008-02-05 21:32:43 +000086const APSInt& ValueManager::getValue(uint64_t X, QualType T,
87 SourceLocation Loc) {
88
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000089 unsigned bits = Ctx.getTypeSize(T, Loc);
90 APSInt V(bits, T->isUnsignedIntegerType());
91 V = X;
92 return getValue(V);
93}
94
Ted Kremenek1fbdb022008-02-05 21:32:43 +000095const SymIntConstraint&
96ValueManager::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
97 const llvm::APSInt& V) {
98
99 llvm::FoldingSetNodeID ID;
100 SymIntConstraint::Profile(ID, sym, Op, V);
101 void* InsertPos;
102
103 SymIntConstraint* C = SymIntCSet.FindNodeOrInsertPos(ID, InsertPos);
104
105 if (!C) {
106 C = (SymIntConstraint*) BPAlloc.Allocate<SymIntConstraint>();
107 new (C) SymIntConstraint(sym, Op, V);
108 SymIntCSet.InsertNode(C, InsertPos);
109 }
110
111 return *C;
112}
113
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000114//===----------------------------------------------------------------------===//
115// Transfer function for Casts.
116//===----------------------------------------------------------------------===//
117
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000118RValue RValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000119 switch (getBaseKind()) {
120 default: assert(false && "Invalid RValue."); break;
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000121 case LValueKind: return cast<LValue>(this)->EvalCast(ValMgr, CastExpr);
122 case NonLValueKind: return cast<NonLValue>(this)->EvalCast(ValMgr, CastExpr);
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000123 case UninitializedKind: case InvalidKind: break;
124 }
125
126 return *this;
127}
128
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000129
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000130//===----------------------------------------------------------------------===//
131// Transfer function dispatch for Non-LValues.
132//===----------------------------------------------------------------------===//
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000133
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000134 // Binary Operators (except assignments and comma).
135
136NonLValue NonLValue::EvalBinaryOp(ValueManager& ValMgr,
137 BinaryOperator::Opcode Op,
138 const NonLValue& RHS) const {
139
140 if (isa<InvalidValue>(this) || isa<InvalidValue>(RHS))
141 return cast<NonLValue>(InvalidValue());
142
143 if (isa<UninitializedValue>(this) || isa<UninitializedValue>(RHS))
144 return cast<NonLValue>(UninitializedValue());
145
146 switch (getSubKind()) {
147 default:
148 assert (false && "Binary Operators not implemented for this NonLValue");
149
150 case nonlval::ConcreteIntKind:
151
152 if (isa<nonlval::ConcreteInt>(RHS)) {
153 nonlval::ConcreteInt& self = cast<nonlval::ConcreteInt>(*this);
154 return self.EvalBinaryOp(ValMgr, Op,
155 cast<nonlval::ConcreteInt>(RHS));
156 }
157 else if(isa<InvalidValue>(RHS))
158 return cast<NonLValue>(InvalidValue());
159 else
160 return RHS.EvalBinaryOp(ValMgr, Op, *this);
161
162 case nonlval::SymbolValKind: {
163 const nonlval::SymbolVal& self = cast<nonlval::SymbolVal>(*this);
164
165 switch (RHS.getSubKind()) {
166 default: assert ("Not Implemented." && false);
167 case nonlval::ConcreteIntKind: {
168 const SymIntConstraint& C =
169 ValMgr.getConstraint(self.getSymbol(), Op,
170 cast<nonlval::ConcreteInt>(RHS).getValue());
171
172 return nonlval::SymIntConstraintVal(C);
173 }
174 }
175 }
176 }
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000177}
178
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000179static const
180llvm::APSInt& EvaluateAPSInt(ValueManager& ValMgr, BinaryOperator::Opcode Op,
181 const llvm::APSInt& V1, const llvm::APSInt& V2) {
182
183 switch (Op) {
184 default:
185 assert (false && "Invalid Opcode.");
186
187 case BinaryOperator::Mul:
188 return ValMgr.getValue( V1 * V2 );
189
190 case BinaryOperator::Div:
191 return ValMgr.getValue( V1 / V2 );
192
193 case BinaryOperator::Rem:
194 return ValMgr.getValue( V1 % V2 );
195
196 case BinaryOperator::Add:
197 return ValMgr.getValue( V1 + V2 );
198
199 case BinaryOperator::Sub:
200 return ValMgr.getValue( V1 - V2 );
201
202#if 0
203 case BinaryOperator::Shl:
204 return ValMgr.getValue( V1 << V2 );
205
206 case BinaryOperator::Shr:
207 return ValMgr.getValue( V1 >> V2 );
208#endif
209
210 case BinaryOperator::LT:
211 return ValMgr.getTruthValue( V1 < V2 );
212
213 case BinaryOperator::GT:
214 return ValMgr.getTruthValue( V1 > V2 );
215
216 case BinaryOperator::LE:
217 return ValMgr.getTruthValue( V1 <= V2 );
218
219 case BinaryOperator::GE:
220 return ValMgr.getTruthValue( V1 >= V2 );
221
222 case BinaryOperator::EQ:
223 return ValMgr.getTruthValue( V1 == V2 );
224
225 case BinaryOperator::NE:
226 return ValMgr.getTruthValue( V1 != V2 );
227
228 // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
229
230 case BinaryOperator::And:
231 return ValMgr.getValue( V1 & V2 );
232
233 case BinaryOperator::Or:
234 return ValMgr.getValue( V1 | V2 );
235 }
236}
237
238nonlval::ConcreteInt
239nonlval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
240 BinaryOperator::Opcode Op,
241 const nonlval::ConcreteInt& RHS) const {
242
243 return EvaluateAPSInt(ValMgr, Op, getValue(), RHS.getValue());
244}
245
246
247 // Bitwise-Complement.
248
249NonLValue NonLValue::EvalComplement(ValueManager& ValMgr) const {
250 switch (getSubKind()) {
251 case nonlval::ConcreteIntKind:
252 return cast<nonlval::ConcreteInt>(this)->EvalComplement(ValMgr);
253 default:
254 return cast<NonLValue>(InvalidValue());
255 }
256}
257
258nonlval::ConcreteInt
259nonlval::ConcreteInt::EvalComplement(ValueManager& ValMgr) const {
260 return ValMgr.getValue(~getValue());
261}
262
263 // Casts.
264
265RValue NonLValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
Ted Kremenek329f8542008-02-05 21:52:21 +0000266 if (!isa<nonlval::ConcreteInt>(this))
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000267 return InvalidValue();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000268
Ted Kremenek329f8542008-02-05 21:52:21 +0000269 APSInt V = cast<nonlval::ConcreteInt>(this)->getValue();
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000270 QualType T = CastExpr->getType();
Ted Kremenek08b66252008-02-06 04:31:33 +0000271 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000272 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
273
274 if (CastExpr->getType()->isPointerType())
Ted Kremenek329f8542008-02-05 21:52:21 +0000275 return lval::ConcreteInt(ValMgr.getValue(V));
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000276 else
Ted Kremenek329f8542008-02-05 21:52:21 +0000277 return nonlval::ConcreteInt(ValMgr.getValue(V));
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000278}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000279
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000280 // Unary Minus.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000281
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000282NonLValue NonLValue::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000283 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000284 case nonlval::ConcreteIntKind:
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000285 return cast<nonlval::ConcreteInt>(this)->EvalMinus(ValMgr, U);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000286 default:
287 return cast<NonLValue>(InvalidValue());
288 }
289}
290
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000291nonlval::ConcreteInt
292nonlval::ConcreteInt::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
293 assert (U->getType() == U->getSubExpr()->getType());
294 assert (U->getType()->isIntegerType());
295 return ValMgr.getValue(-getValue());
Ted Kremenekc5d3b4c2008-02-04 16:58:30 +0000296}
297
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000298//===----------------------------------------------------------------------===//
299// Transfer function dispatch for LValues.
300//===----------------------------------------------------------------------===//
301
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000302 // Binary Operators (except assignments and comma).
303
304RValue LValue::EvalBinaryOp(ValueManager& ValMgr,
305 BinaryOperator::Opcode Op,
306 const LValue& RHS) const {
307
308 switch (Op) {
309 default:
310 assert (false && "Not yet implemented.");
311
312 case BinaryOperator::EQ:
313 return EQ(ValMgr, RHS);
314
315 case BinaryOperator::NE:
316 return NE(ValMgr, RHS);
317 }
318}
319
320
321lval::ConcreteInt
322lval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
323 BinaryOperator::Opcode Op,
324 const lval::ConcreteInt& RHS) const {
325
326 assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
327 (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));
328
329 return EvaluateAPSInt(ValMgr, Op, getValue(), RHS.getValue());
330}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000331
332NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000333 switch (getSubKind()) {
334 default:
335 assert(false && "EQ not implemented for this LValue.");
336 return cast<NonLValue>(InvalidValue());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000337
Ted Kremenek0806acf2008-02-05 23:08:41 +0000338 case lval::ConcreteIntKind:
339 if (isa<lval::ConcreteInt>(RHS)) {
340 bool b = cast<lval::ConcreteInt>(this)->getValue() ==
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000341 cast<lval::ConcreteInt>(RHS).getValue();
342
Ted Kremenek0806acf2008-02-05 23:08:41 +0000343 return NonLValue::GetIntTruthValue(ValMgr, b);
344 }
345 else if (isa<lval::SymbolVal>(RHS)) {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000346
Ted Kremenek0806acf2008-02-05 23:08:41 +0000347 const SymIntConstraint& C =
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000348 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
349 BinaryOperator::EQ,
350 cast<lval::ConcreteInt>(this)->getValue());
Ted Kremenek0806acf2008-02-05 23:08:41 +0000351
352 return nonlval::SymIntConstraintVal(C);
353 }
354
355 break;
356
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000357 case lval::SymbolValKind: {
358 if (isa<lval::ConcreteInt>(RHS)) {
359
360 const SymIntConstraint& C =
Ted Kremenek0806acf2008-02-05 23:08:41 +0000361 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
362 BinaryOperator::EQ,
363 cast<lval::ConcreteInt>(RHS).getValue());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000364
365 return nonlval::SymIntConstraintVal(C);
366 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000367
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000368 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement unification.");
369
370 break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000371 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000372
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000373 case lval::DeclValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000374 if (isa<lval::DeclVal>(RHS)) {
375 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
376 return NonLValue::GetIntTruthValue(ValMgr, b);
377 }
378
379 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000380 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000381
382 return NonLValue::GetIntTruthValue(ValMgr, false);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000383}
384
385NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000386 switch (getSubKind()) {
387 default:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000388 assert(false && "NE not implemented for this LValue.");
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000389 return cast<NonLValue>(InvalidValue());
390
Ted Kremenek0806acf2008-02-05 23:08:41 +0000391 case lval::ConcreteIntKind:
392 if (isa<lval::ConcreteInt>(RHS)) {
393 bool b = cast<lval::ConcreteInt>(this)->getValue() !=
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000394 cast<lval::ConcreteInt>(RHS).getValue();
Ted Kremenek0806acf2008-02-05 23:08:41 +0000395
396 return NonLValue::GetIntTruthValue(ValMgr, b);
397 }
398 else if (isa<lval::SymbolVal>(RHS)) {
399
400 const SymIntConstraint& C =
401 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
402 BinaryOperator::NE,
403 cast<lval::ConcreteInt>(this)->getValue());
404
405 return nonlval::SymIntConstraintVal(C);
406 }
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000407
Ted Kremenek0806acf2008-02-05 23:08:41 +0000408 break;
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000409
Ted Kremenek0806acf2008-02-05 23:08:41 +0000410 case lval::SymbolValKind: {
411 if (isa<lval::ConcreteInt>(RHS)) {
412
413 const SymIntConstraint& C =
414 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
415 BinaryOperator::NE,
416 cast<lval::ConcreteInt>(RHS).getValue());
417
418 return nonlval::SymIntConstraintVal(C);
419 }
420
421 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement sym !=.");
422
423 break;
424 }
425
426 case lval::DeclValKind:
427 if (isa<lval::DeclVal>(RHS)) {
428 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
429 return NonLValue::GetIntTruthValue(ValMgr, b);
430 }
431
432 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000433 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000434
435 return NonLValue::GetIntTruthValue(ValMgr, true);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000436}
437
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000438 // Casts.
439
440RValue LValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
441 if (CastExpr->getType()->isPointerType())
442 return *this;
443
444 assert (CastExpr->getType()->isIntegerType());
445
446 if (!isa<lval::ConcreteInt>(*this))
447 return InvalidValue();
448
449 APSInt V = cast<lval::ConcreteInt>(this)->getValue();
450 QualType T = CastExpr->getType();
451 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
452 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
453 return nonlval::ConcreteInt(ValMgr.getValue(V));
454}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000455
456//===----------------------------------------------------------------------===//
457// Utility methods for constructing Non-LValues.
458//===----------------------------------------------------------------------===//
459
460NonLValue NonLValue::GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
461 SourceLocation Loc) {
462
Ted Kremenek329f8542008-02-05 21:52:21 +0000463 return nonlval::ConcreteInt(ValMgr.getValue(X, T, Loc));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000464}
465
466NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000467 return nonlval::ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
468 I->getType()->isUnsignedIntegerType())));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000469}
470
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000471NonLValue NonLValue::GetIntTruthValue(ValueManager& ValMgr, bool b) {
472 return nonlval::ConcreteInt(ValMgr.getTruthValue(b));
473}
474
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000475RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
476 QualType T = D->getType();
477
478 if (T->isPointerType() || T->isReferenceType())
Ted Kremenek329f8542008-02-05 21:52:21 +0000479 return lval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000480 else
Ted Kremenek329f8542008-02-05 21:52:21 +0000481 return nonlval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000482}
483
Ted Kremenek5b6dc2d2008-02-07 01:08:27 +0000484void RValue::print() const {
485 print(*llvm::cerr.stream());
486}
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000487
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000488//===----------------------------------------------------------------------===//
489// Pretty-Printing.
490//===----------------------------------------------------------------------===//
491
492void RValue::print(std::ostream& Out) const {
493 switch (getBaseKind()) {
494 case InvalidKind:
495 Out << "Invalid";
496 break;
497
498 case NonLValueKind:
499 cast<NonLValue>(this)->print(Out);
500 break;
501
502 case LValueKind:
503 cast<LValue>(this)->print(Out);
504 break;
505
506 case UninitializedKind:
507 Out << "Uninitialized";
508 break;
509
510 default:
511 assert (false && "Invalid RValue.");
512 }
513}
514
Ted Kremenek0806acf2008-02-05 23:08:41 +0000515static void printOpcode(std::ostream& Out, BinaryOperator::Opcode Op) {
516 switch (Op) {
517 case BinaryOperator::EQ: Out << "=="; break;
518 case BinaryOperator::NE: Out << "!="; break;
519 default: assert(false && "Not yet implemented.");
520 }
521}
522
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000523void NonLValue::print(std::ostream& Out) const {
524 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000525 case nonlval::ConcreteIntKind:
526 Out << cast<nonlval::ConcreteInt>(this)->getValue().toString();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000527
528 if (cast<nonlval::ConcreteInt>(this)->getValue().isUnsigned())
529 Out << 'U';
530
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000531 break;
532
Ted Kremenek329f8542008-02-05 21:52:21 +0000533 case nonlval::SymbolValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000534 Out << '$' << cast<nonlval::SymbolVal>(this)->getSymbol();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000535 break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000536
537 case nonlval::SymIntConstraintValKind: {
538 const nonlval::SymIntConstraintVal& C =
539 *cast<nonlval::SymIntConstraintVal>(this);
540
541 Out << '$' << C.getConstraint().getSymbol() << ' ';
542 printOpcode(Out, C.getConstraint().getOpcode());
543 Out << ' ' << C.getConstraint().getInt().toString();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000544
545 if (C.getConstraint().getInt().isUnsigned())
546 Out << 'U';
547
Ted Kremenek0806acf2008-02-05 23:08:41 +0000548 break;
549 }
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000550
551 default:
552 assert (false && "Pretty-printed not implemented for this NonLValue.");
553 break;
554 }
555}
556
Ted Kremenek0806acf2008-02-05 23:08:41 +0000557
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000558void LValue::print(std::ostream& Out) const {
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000559 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000560 case lval::ConcreteIntKind:
561 Out << cast<lval::ConcreteInt>(this)->getValue().toString()
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000562 << " (LValue)";
563 break;
564
Ted Kremenek329f8542008-02-05 21:52:21 +0000565 case lval::SymbolValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000566 Out << '$' << cast<lval::SymbolVal>(this)->getSymbol();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000567 break;
Ted Kremenek08b66252008-02-06 04:31:33 +0000568
Ted Kremenek329f8542008-02-05 21:52:21 +0000569 case lval::DeclValKind:
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000570 Out << '&'
Ted Kremenek329f8542008-02-05 21:52:21 +0000571 << cast<lval::DeclVal>(this)->getDecl()->getIdentifier()->getName();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000572 break;
573
574 default:
575 assert (false && "Pretty-printed not implemented for this LValue.");
576 break;
577 }
578}