blob: 387a30cf63f921048b8deda55540bb607ca6960e [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) {
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//===----------------------------------------------------------------------===//
127// Transfer function for Casts.
128//===----------------------------------------------------------------------===//
129
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000130RValue RValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000131 switch (getBaseKind()) {
132 default: assert(false && "Invalid RValue."); break;
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000133 case LValueKind: return cast<LValue>(this)->EvalCast(ValMgr, CastExpr);
134 case NonLValueKind: return cast<NonLValue>(this)->EvalCast(ValMgr, CastExpr);
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000135 case UninitializedKind: case InvalidKind: break;
136 }
137
138 return *this;
139}
140
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000141
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000142//===----------------------------------------------------------------------===//
143// Transfer function dispatch for Non-LValues.
144//===----------------------------------------------------------------------===//
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000145
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000146 // Binary Operators (except assignments and comma).
147
148NonLValue NonLValue::EvalBinaryOp(ValueManager& ValMgr,
149 BinaryOperator::Opcode Op,
150 const NonLValue& RHS) const {
151
152 if (isa<InvalidValue>(this) || isa<InvalidValue>(RHS))
153 return cast<NonLValue>(InvalidValue());
154
155 if (isa<UninitializedValue>(this) || isa<UninitializedValue>(RHS))
156 return cast<NonLValue>(UninitializedValue());
157
158 switch (getSubKind()) {
159 default:
160 assert (false && "Binary Operators not implemented for this NonLValue");
161
162 case nonlval::ConcreteIntKind:
163
164 if (isa<nonlval::ConcreteInt>(RHS)) {
165 nonlval::ConcreteInt& self = cast<nonlval::ConcreteInt>(*this);
166 return self.EvalBinaryOp(ValMgr, Op,
167 cast<nonlval::ConcreteInt>(RHS));
168 }
169 else if(isa<InvalidValue>(RHS))
170 return cast<NonLValue>(InvalidValue());
171 else
172 return RHS.EvalBinaryOp(ValMgr, Op, *this);
173
174 case nonlval::SymbolValKind: {
175 const nonlval::SymbolVal& self = cast<nonlval::SymbolVal>(*this);
176
177 switch (RHS.getSubKind()) {
178 default: assert ("Not Implemented." && false);
179 case nonlval::ConcreteIntKind: {
180 const SymIntConstraint& C =
181 ValMgr.getConstraint(self.getSymbol(), Op,
182 cast<nonlval::ConcreteInt>(RHS).getValue());
183
184 return nonlval::SymIntConstraintVal(C);
185 }
186 }
187 }
188 }
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000189}
190
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000191static const
192llvm::APSInt& EvaluateAPSInt(ValueManager& ValMgr, BinaryOperator::Opcode Op,
193 const llvm::APSInt& V1, const llvm::APSInt& V2) {
194
195 switch (Op) {
196 default:
197 assert (false && "Invalid Opcode.");
198
199 case BinaryOperator::Mul:
200 return ValMgr.getValue( V1 * V2 );
201
202 case BinaryOperator::Div:
203 return ValMgr.getValue( V1 / V2 );
204
205 case BinaryOperator::Rem:
206 return ValMgr.getValue( V1 % V2 );
207
208 case BinaryOperator::Add:
209 return ValMgr.getValue( V1 + V2 );
210
211 case BinaryOperator::Sub:
212 return ValMgr.getValue( V1 - V2 );
213
214#if 0
215 case BinaryOperator::Shl:
216 return ValMgr.getValue( V1 << V2 );
217
218 case BinaryOperator::Shr:
219 return ValMgr.getValue( V1 >> V2 );
220#endif
221
222 case BinaryOperator::LT:
223 return ValMgr.getTruthValue( V1 < V2 );
224
225 case BinaryOperator::GT:
226 return ValMgr.getTruthValue( V1 > V2 );
227
228 case BinaryOperator::LE:
229 return ValMgr.getTruthValue( V1 <= V2 );
230
231 case BinaryOperator::GE:
232 return ValMgr.getTruthValue( V1 >= V2 );
233
234 case BinaryOperator::EQ:
235 return ValMgr.getTruthValue( V1 == V2 );
236
237 case BinaryOperator::NE:
238 return ValMgr.getTruthValue( V1 != V2 );
239
240 // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
241
242 case BinaryOperator::And:
243 return ValMgr.getValue( V1 & V2 );
244
245 case BinaryOperator::Or:
246 return ValMgr.getValue( V1 | V2 );
247 }
248}
249
250nonlval::ConcreteInt
251nonlval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
252 BinaryOperator::Opcode Op,
253 const nonlval::ConcreteInt& RHS) const {
254
255 return EvaluateAPSInt(ValMgr, Op, getValue(), RHS.getValue());
256}
257
258
259 // Bitwise-Complement.
260
261NonLValue NonLValue::EvalComplement(ValueManager& ValMgr) const {
262 switch (getSubKind()) {
263 case nonlval::ConcreteIntKind:
264 return cast<nonlval::ConcreteInt>(this)->EvalComplement(ValMgr);
265 default:
266 return cast<NonLValue>(InvalidValue());
267 }
268}
269
270nonlval::ConcreteInt
271nonlval::ConcreteInt::EvalComplement(ValueManager& ValMgr) const {
272 return ValMgr.getValue(~getValue());
273}
274
275 // Casts.
276
277RValue NonLValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
Ted Kremenek329f8542008-02-05 21:52:21 +0000278 if (!isa<nonlval::ConcreteInt>(this))
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000279 return InvalidValue();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000280
Ted Kremenek329f8542008-02-05 21:52:21 +0000281 APSInt V = cast<nonlval::ConcreteInt>(this)->getValue();
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000282 QualType T = CastExpr->getType();
Ted Kremenek08b66252008-02-06 04:31:33 +0000283 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000284 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
285
286 if (CastExpr->getType()->isPointerType())
Ted Kremenek329f8542008-02-05 21:52:21 +0000287 return lval::ConcreteInt(ValMgr.getValue(V));
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000288 else
Ted Kremenek329f8542008-02-05 21:52:21 +0000289 return nonlval::ConcreteInt(ValMgr.getValue(V));
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000290}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000291
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000292 // Unary Minus.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000293
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000294NonLValue NonLValue::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000295 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000296 case nonlval::ConcreteIntKind:
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000297 return cast<nonlval::ConcreteInt>(this)->EvalMinus(ValMgr, U);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000298 default:
299 return cast<NonLValue>(InvalidValue());
300 }
301}
302
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000303nonlval::ConcreteInt
304nonlval::ConcreteInt::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
305 assert (U->getType() == U->getSubExpr()->getType());
306 assert (U->getType()->isIntegerType());
307 return ValMgr.getValue(-getValue());
Ted Kremenekc5d3b4c2008-02-04 16:58:30 +0000308}
309
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000310//===----------------------------------------------------------------------===//
311// Transfer function dispatch for LValues.
312//===----------------------------------------------------------------------===//
313
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000314 // Binary Operators (except assignments and comma).
315
316RValue LValue::EvalBinaryOp(ValueManager& ValMgr,
317 BinaryOperator::Opcode Op,
318 const LValue& RHS) const {
319
320 switch (Op) {
321 default:
322 assert (false && "Not yet implemented.");
323
324 case BinaryOperator::EQ:
325 return EQ(ValMgr, RHS);
326
327 case BinaryOperator::NE:
328 return NE(ValMgr, RHS);
329 }
330}
331
332
333lval::ConcreteInt
334lval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
335 BinaryOperator::Opcode Op,
336 const lval::ConcreteInt& RHS) const {
337
338 assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
339 (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));
340
341 return EvaluateAPSInt(ValMgr, Op, getValue(), RHS.getValue());
342}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000343
344NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000345 switch (getSubKind()) {
346 default:
347 assert(false && "EQ not implemented for this LValue.");
348 return cast<NonLValue>(InvalidValue());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000349
Ted Kremenek0806acf2008-02-05 23:08:41 +0000350 case lval::ConcreteIntKind:
351 if (isa<lval::ConcreteInt>(RHS)) {
352 bool b = cast<lval::ConcreteInt>(this)->getValue() ==
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000353 cast<lval::ConcreteInt>(RHS).getValue();
354
Ted Kremenek0806acf2008-02-05 23:08:41 +0000355 return NonLValue::GetIntTruthValue(ValMgr, b);
356 }
357 else if (isa<lval::SymbolVal>(RHS)) {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000358
Ted Kremenek0806acf2008-02-05 23:08:41 +0000359 const SymIntConstraint& C =
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000360 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
361 BinaryOperator::EQ,
362 cast<lval::ConcreteInt>(this)->getValue());
Ted Kremenek0806acf2008-02-05 23:08:41 +0000363
364 return nonlval::SymIntConstraintVal(C);
365 }
366
367 break;
368
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000369 case lval::SymbolValKind: {
370 if (isa<lval::ConcreteInt>(RHS)) {
371
372 const SymIntConstraint& C =
Ted Kremenek0806acf2008-02-05 23:08:41 +0000373 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
374 BinaryOperator::EQ,
375 cast<lval::ConcreteInt>(RHS).getValue());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000376
377 return nonlval::SymIntConstraintVal(C);
378 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000379
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000380 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement unification.");
381
382 break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000383 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000384
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000385 case lval::DeclValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000386 if (isa<lval::DeclVal>(RHS)) {
387 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
388 return NonLValue::GetIntTruthValue(ValMgr, b);
389 }
390
391 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000392 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000393
394 return NonLValue::GetIntTruthValue(ValMgr, false);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000395}
396
397NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000398 switch (getSubKind()) {
399 default:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000400 assert(false && "NE not implemented for this LValue.");
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000401 return cast<NonLValue>(InvalidValue());
402
Ted Kremenek0806acf2008-02-05 23:08:41 +0000403 case lval::ConcreteIntKind:
404 if (isa<lval::ConcreteInt>(RHS)) {
405 bool b = cast<lval::ConcreteInt>(this)->getValue() !=
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000406 cast<lval::ConcreteInt>(RHS).getValue();
Ted Kremenek0806acf2008-02-05 23:08:41 +0000407
408 return NonLValue::GetIntTruthValue(ValMgr, b);
409 }
410 else if (isa<lval::SymbolVal>(RHS)) {
411
412 const SymIntConstraint& C =
413 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
414 BinaryOperator::NE,
415 cast<lval::ConcreteInt>(this)->getValue());
416
417 return nonlval::SymIntConstraintVal(C);
418 }
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000419
Ted Kremenek0806acf2008-02-05 23:08:41 +0000420 break;
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000421
Ted Kremenek0806acf2008-02-05 23:08:41 +0000422 case lval::SymbolValKind: {
423 if (isa<lval::ConcreteInt>(RHS)) {
424
425 const SymIntConstraint& C =
426 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
427 BinaryOperator::NE,
428 cast<lval::ConcreteInt>(RHS).getValue());
429
430 return nonlval::SymIntConstraintVal(C);
431 }
432
433 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement sym !=.");
434
435 break;
436 }
437
438 case lval::DeclValKind:
439 if (isa<lval::DeclVal>(RHS)) {
440 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
441 return NonLValue::GetIntTruthValue(ValMgr, b);
442 }
443
444 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000445 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000446
447 return NonLValue::GetIntTruthValue(ValMgr, true);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000448}
449
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000450 // Casts.
451
452RValue LValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
453 if (CastExpr->getType()->isPointerType())
454 return *this;
455
456 assert (CastExpr->getType()->isIntegerType());
457
458 if (!isa<lval::ConcreteInt>(*this))
459 return InvalidValue();
460
461 APSInt V = cast<lval::ConcreteInt>(this)->getValue();
462 QualType T = CastExpr->getType();
463 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
464 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
465 return nonlval::ConcreteInt(ValMgr.getValue(V));
466}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000467
468//===----------------------------------------------------------------------===//
469// Utility methods for constructing Non-LValues.
470//===----------------------------------------------------------------------===//
471
472NonLValue NonLValue::GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
473 SourceLocation Loc) {
474
Ted Kremenek329f8542008-02-05 21:52:21 +0000475 return nonlval::ConcreteInt(ValMgr.getValue(X, T, Loc));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000476}
477
478NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000479 return nonlval::ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
480 I->getType()->isUnsignedIntegerType())));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000481}
482
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000483NonLValue NonLValue::GetIntTruthValue(ValueManager& ValMgr, bool b) {
484 return nonlval::ConcreteInt(ValMgr.getTruthValue(b));
485}
486
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000487RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
488 QualType T = D->getType();
489
490 if (T->isPointerType() || T->isReferenceType())
Ted Kremenek329f8542008-02-05 21:52:21 +0000491 return lval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000492 else
Ted Kremenek329f8542008-02-05 21:52:21 +0000493 return nonlval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000494}
495
Ted Kremenek5b6dc2d2008-02-07 01:08:27 +0000496void RValue::print() const {
497 print(*llvm::cerr.stream());
498}
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000499
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000500//===----------------------------------------------------------------------===//
501// Pretty-Printing.
502//===----------------------------------------------------------------------===//
503
504void RValue::print(std::ostream& Out) const {
505 switch (getBaseKind()) {
506 case InvalidKind:
507 Out << "Invalid";
508 break;
509
510 case NonLValueKind:
511 cast<NonLValue>(this)->print(Out);
512 break;
513
514 case LValueKind:
515 cast<LValue>(this)->print(Out);
516 break;
517
518 case UninitializedKind:
519 Out << "Uninitialized";
520 break;
521
522 default:
523 assert (false && "Invalid RValue.");
524 }
525}
526
Ted Kremenek0806acf2008-02-05 23:08:41 +0000527static void printOpcode(std::ostream& Out, BinaryOperator::Opcode Op) {
Ted Kremenek7e593362008-02-07 15:20:13 +0000528 switch (Op) {
529 case BinaryOperator::Add: Out << "+" ; break;
530 case BinaryOperator::Sub: Out << "-" ; break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000531 case BinaryOperator::EQ: Out << "=="; break;
532 case BinaryOperator::NE: Out << "!="; break;
533 default: assert(false && "Not yet implemented.");
534 }
535}
536
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000537void NonLValue::print(std::ostream& Out) const {
538 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000539 case nonlval::ConcreteIntKind:
540 Out << cast<nonlval::ConcreteInt>(this)->getValue().toString();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000541
542 if (cast<nonlval::ConcreteInt>(this)->getValue().isUnsigned())
543 Out << 'U';
544
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000545 break;
546
Ted Kremenek329f8542008-02-05 21:52:21 +0000547 case nonlval::SymbolValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000548 Out << '$' << cast<nonlval::SymbolVal>(this)->getSymbol();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000549 break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000550
551 case nonlval::SymIntConstraintValKind: {
552 const nonlval::SymIntConstraintVal& C =
553 *cast<nonlval::SymIntConstraintVal>(this);
554
555 Out << '$' << C.getConstraint().getSymbol() << ' ';
556 printOpcode(Out, C.getConstraint().getOpcode());
557 Out << ' ' << C.getConstraint().getInt().toString();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000558
559 if (C.getConstraint().getInt().isUnsigned())
560 Out << 'U';
561
Ted Kremenek0806acf2008-02-05 23:08:41 +0000562 break;
563 }
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000564
565 default:
566 assert (false && "Pretty-printed not implemented for this NonLValue.");
567 break;
568 }
569}
570
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000571
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000572void LValue::print(std::ostream& Out) const {
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000573 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000574 case lval::ConcreteIntKind:
575 Out << cast<lval::ConcreteInt>(this)->getValue().toString()
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000576 << " (LValue)";
577 break;
578
Ted Kremenek329f8542008-02-05 21:52:21 +0000579 case lval::SymbolValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000580 Out << '$' << cast<lval::SymbolVal>(this)->getSymbol();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000581 break;
Ted Kremenek08b66252008-02-06 04:31:33 +0000582
Ted Kremenek329f8542008-02-05 21:52:21 +0000583 case lval::DeclValKind:
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000584 Out << '&'
Ted Kremenek329f8542008-02-05 21:52:21 +0000585 << cast<lval::DeclVal>(this)->getDecl()->getIdentifier()->getName();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000586 break;
587
588 default:
589 assert (false && "Pretty-printed not implemented for this LValue.");
590 break;
591 }
592}
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000593