blob: a9b44eb3d2a9f8c4f6234a5f31266b452a23c823 [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 Kremenek90e14812008-02-14 23:25:54 +0000126//===----------------------------------------------------------------------===//
127// Symbol Iteration.
128//===----------------------------------------------------------------------===//
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000129
Ted Kremenek90e14812008-02-14 23:25:54 +0000130RValue::symbol_iterator RValue::symbol_begin() const {
131 if (isa<LValue>(this)) {
132 if (isa<lval::SymbolVal>(this))
133 return (symbol_iterator) (&Data);
134 }
135 else {
136 if (isa<nonlval::SymbolVal>(this))
137 return (symbol_iterator) (&Data);
138 else if (isa<nonlval::SymIntConstraintVal>(this)) {
139 const SymIntConstraint& C =
140 cast<nonlval::SymIntConstraintVal>(this)->getConstraint();
141 return (symbol_iterator) &C.getSymbol();
142 }
143 }
144
145 return NULL;
146}
147
148RValue::symbol_iterator RValue::symbol_end() const {
149 symbol_iterator X = symbol_begin();
150 return X ? X+1 : NULL;
151}
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000152
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000153//===----------------------------------------------------------------------===//
154// Transfer function dispatch for Non-LValues.
155//===----------------------------------------------------------------------===//
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000156
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000157static const
158llvm::APSInt& EvaluateAPSInt(ValueManager& ValMgr, BinaryOperator::Opcode Op,
159 const llvm::APSInt& V1, const llvm::APSInt& V2) {
160
161 switch (Op) {
162 default:
163 assert (false && "Invalid Opcode.");
164
165 case BinaryOperator::Mul:
166 return ValMgr.getValue( V1 * V2 );
167
168 case BinaryOperator::Div:
169 return ValMgr.getValue( V1 / V2 );
170
171 case BinaryOperator::Rem:
172 return ValMgr.getValue( V1 % V2 );
173
174 case BinaryOperator::Add:
175 return ValMgr.getValue( V1 + V2 );
176
177 case BinaryOperator::Sub:
178 return ValMgr.getValue( V1 - V2 );
179
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000180 case BinaryOperator::Shl:
Ted Kremenek59c2d262008-02-08 07:14:58 +0000181 return ValMgr.getValue( V1.operator<<( (unsigned) V2.getZExtValue() ));
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000182
183 case BinaryOperator::Shr:
Ted Kremenek59c2d262008-02-08 07:14:58 +0000184 return ValMgr.getValue( V1.operator>>( (unsigned) V2.getZExtValue() ));
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000185
186 case BinaryOperator::LT:
187 return ValMgr.getTruthValue( V1 < V2 );
188
189 case BinaryOperator::GT:
190 return ValMgr.getTruthValue( V1 > V2 );
191
192 case BinaryOperator::LE:
193 return ValMgr.getTruthValue( V1 <= V2 );
194
195 case BinaryOperator::GE:
196 return ValMgr.getTruthValue( V1 >= V2 );
197
198 case BinaryOperator::EQ:
199 return ValMgr.getTruthValue( V1 == V2 );
200
201 case BinaryOperator::NE:
202 return ValMgr.getTruthValue( V1 != V2 );
203
204 // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
205
206 case BinaryOperator::And:
207 return ValMgr.getValue( V1 & V2 );
208
209 case BinaryOperator::Or:
210 return ValMgr.getValue( V1 | V2 );
211 }
212}
213
214nonlval::ConcreteInt
215nonlval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
216 BinaryOperator::Opcode Op,
217 const nonlval::ConcreteInt& RHS) const {
218
219 return EvaluateAPSInt(ValMgr, Op, getValue(), RHS.getValue());
220}
221
222
223 // Bitwise-Complement.
224
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000225
226nonlval::ConcreteInt
227nonlval::ConcreteInt::EvalComplement(ValueManager& ValMgr) const {
228 return ValMgr.getValue(~getValue());
229}
230
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000231 // Unary Minus.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000232
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000233nonlval::ConcreteInt
234nonlval::ConcreteInt::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
235 assert (U->getType() == U->getSubExpr()->getType());
236 assert (U->getType()->isIntegerType());
237 return ValMgr.getValue(-getValue());
Ted Kremenekc5d3b4c2008-02-04 16:58:30 +0000238}
239
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000240//===----------------------------------------------------------------------===//
241// Transfer function dispatch for LValues.
242//===----------------------------------------------------------------------===//
243
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000244lval::ConcreteInt
245lval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
246 BinaryOperator::Opcode Op,
247 const lval::ConcreteInt& RHS) const {
248
249 assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
250 (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));
251
252 return EvaluateAPSInt(ValMgr, Op, getValue(), RHS.getValue());
253}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000254
255NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000256 switch (getSubKind()) {
257 default:
258 assert(false && "EQ not implemented for this LValue.");
Ted Kremenek22031182008-02-08 02:57:34 +0000259 return cast<NonLValue>(UnknownVal());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000260
Ted Kremenek0806acf2008-02-05 23:08:41 +0000261 case lval::ConcreteIntKind:
262 if (isa<lval::ConcreteInt>(RHS)) {
263 bool b = cast<lval::ConcreteInt>(this)->getValue() ==
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000264 cast<lval::ConcreteInt>(RHS).getValue();
265
Ted Kremenek0806acf2008-02-05 23:08:41 +0000266 return NonLValue::GetIntTruthValue(ValMgr, b);
267 }
268 else if (isa<lval::SymbolVal>(RHS)) {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000269
Ted Kremenek0806acf2008-02-05 23:08:41 +0000270 const SymIntConstraint& C =
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000271 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
272 BinaryOperator::EQ,
273 cast<lval::ConcreteInt>(this)->getValue());
Ted Kremenek0806acf2008-02-05 23:08:41 +0000274
275 return nonlval::SymIntConstraintVal(C);
276 }
277
278 break;
279
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000280 case lval::SymbolValKind: {
281 if (isa<lval::ConcreteInt>(RHS)) {
282
283 const SymIntConstraint& C =
Ted Kremenek0806acf2008-02-05 23:08:41 +0000284 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
285 BinaryOperator::EQ,
286 cast<lval::ConcreteInt>(RHS).getValue());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000287
288 return nonlval::SymIntConstraintVal(C);
289 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000290
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000291 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement unification.");
292
293 break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000294 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000295
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000296 case lval::DeclValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000297 if (isa<lval::DeclVal>(RHS)) {
298 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
299 return NonLValue::GetIntTruthValue(ValMgr, b);
300 }
301
302 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000303 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000304
305 return NonLValue::GetIntTruthValue(ValMgr, false);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000306}
307
308NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000309 switch (getSubKind()) {
310 default:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000311 assert(false && "NE not implemented for this LValue.");
Ted Kremenek22031182008-02-08 02:57:34 +0000312 return cast<NonLValue>(UnknownVal());
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000313
Ted Kremenek0806acf2008-02-05 23:08:41 +0000314 case lval::ConcreteIntKind:
315 if (isa<lval::ConcreteInt>(RHS)) {
316 bool b = cast<lval::ConcreteInt>(this)->getValue() !=
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000317 cast<lval::ConcreteInt>(RHS).getValue();
Ted Kremenek0806acf2008-02-05 23:08:41 +0000318
319 return NonLValue::GetIntTruthValue(ValMgr, b);
320 }
321 else if (isa<lval::SymbolVal>(RHS)) {
322
323 const SymIntConstraint& C =
324 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
325 BinaryOperator::NE,
326 cast<lval::ConcreteInt>(this)->getValue());
327
328 return nonlval::SymIntConstraintVal(C);
329 }
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000330
Ted Kremenek0806acf2008-02-05 23:08:41 +0000331 break;
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000332
Ted Kremenek0806acf2008-02-05 23:08:41 +0000333 case lval::SymbolValKind: {
334 if (isa<lval::ConcreteInt>(RHS)) {
335
336 const SymIntConstraint& C =
337 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
338 BinaryOperator::NE,
339 cast<lval::ConcreteInt>(RHS).getValue());
340
341 return nonlval::SymIntConstraintVal(C);
342 }
343
344 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement sym !=.");
345
346 break;
347 }
348
349 case lval::DeclValKind:
350 if (isa<lval::DeclVal>(RHS)) {
351 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
352 return NonLValue::GetIntTruthValue(ValMgr, b);
353 }
354
355 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000356 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000357
358 return NonLValue::GetIntTruthValue(ValMgr, true);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000359}
360
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000361
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000362
363//===----------------------------------------------------------------------===//
364// Utility methods for constructing Non-LValues.
365//===----------------------------------------------------------------------===//
366
367NonLValue NonLValue::GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
368 SourceLocation Loc) {
369
Ted Kremenek329f8542008-02-05 21:52:21 +0000370 return nonlval::ConcreteInt(ValMgr.getValue(X, T, Loc));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000371}
372
373NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000374 return nonlval::ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
375 I->getType()->isUnsignedIntegerType())));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000376}
377
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000378NonLValue NonLValue::GetIntTruthValue(ValueManager& ValMgr, bool b) {
379 return nonlval::ConcreteInt(ValMgr.getTruthValue(b));
380}
381
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000382RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
383 QualType T = D->getType();
384
385 if (T->isPointerType() || T->isReferenceType())
Ted Kremenek329f8542008-02-05 21:52:21 +0000386 return lval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000387 else
Ted Kremenek329f8542008-02-05 21:52:21 +0000388 return nonlval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000389}
390
Ted Kremenek2a502572008-02-12 21:37:56 +0000391//===----------------------------------------------------------------------===//
392// Utility methods for constructing LValues.
393//===----------------------------------------------------------------------===//
394
395LValue LValue::GetValue(AddrLabelExpr* E) {
396 return lval::GotoLabel(E->getLabel());
Ted Kremenek5b6dc2d2008-02-07 01:08:27 +0000397}
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000398
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000399//===----------------------------------------------------------------------===//
400// Pretty-Printing.
401//===----------------------------------------------------------------------===//
402
Ted Kremenek2a502572008-02-12 21:37:56 +0000403void RValue::print() const {
404 print(*llvm::cerr.stream());
405}
406
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000407void RValue::print(std::ostream& Out) const {
408 switch (getBaseKind()) {
Ted Kremenek53c641a2008-02-08 03:02:48 +0000409 case UnknownKind:
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000410 Out << "Invalid";
411 break;
412
413 case NonLValueKind:
414 cast<NonLValue>(this)->print(Out);
415 break;
416
417 case LValueKind:
418 cast<LValue>(this)->print(Out);
419 break;
420
421 case UninitializedKind:
422 Out << "Uninitialized";
423 break;
424
425 default:
426 assert (false && "Invalid RValue.");
427 }
428}
429
Ted Kremenek0806acf2008-02-05 23:08:41 +0000430static void printOpcode(std::ostream& Out, BinaryOperator::Opcode Op) {
Ted Kremenek50d0ac22008-02-15 22:09:30 +0000431 switch (Op) {
432 case BinaryOperator::Mul: Out << "*"; break;
433 case BinaryOperator::Div: Out << "/"; break;
434 case BinaryOperator::Rem: Out << "%" ; break;
Ted Kremenek7e593362008-02-07 15:20:13 +0000435 case BinaryOperator::Add: Out << "+" ; break;
436 case BinaryOperator::Sub: Out << "-" ; break;
Ted Kremenek50d0ac22008-02-15 22:09:30 +0000437 case BinaryOperator::Shl: Out << "<<" ; break;
438 case BinaryOperator::Shr: Out << ">>" ; break;
439 case BinaryOperator::LT: Out << "<" ; break;
440 case BinaryOperator::GT: Out << ">" ; break;
441 case BinaryOperator::LE: Out << "<=" ; break;
442 case BinaryOperator::GE: Out << ">=" ; break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000443 case BinaryOperator::EQ: Out << "=="; break;
444 case BinaryOperator::NE: Out << "!="; break;
Ted Kremenek50d0ac22008-02-15 22:09:30 +0000445 case BinaryOperator::And: Out << "&" ; break;
446 case BinaryOperator::Xor: Out << "^" ; break;
447 case BinaryOperator::Or: Out << "|" ; break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000448 default: assert(false && "Not yet implemented.");
449 }
450}
451
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000452void NonLValue::print(std::ostream& Out) const {
453 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000454 case nonlval::ConcreteIntKind:
455 Out << cast<nonlval::ConcreteInt>(this)->getValue().toString();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000456
457 if (cast<nonlval::ConcreteInt>(this)->getValue().isUnsigned())
458 Out << 'U';
459
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000460 break;
461
Ted Kremenek329f8542008-02-05 21:52:21 +0000462 case nonlval::SymbolValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000463 Out << '$' << cast<nonlval::SymbolVal>(this)->getSymbol();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000464 break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000465
466 case nonlval::SymIntConstraintValKind: {
467 const nonlval::SymIntConstraintVal& C =
468 *cast<nonlval::SymIntConstraintVal>(this);
469
470 Out << '$' << C.getConstraint().getSymbol() << ' ';
471 printOpcode(Out, C.getConstraint().getOpcode());
472 Out << ' ' << C.getConstraint().getInt().toString();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000473
474 if (C.getConstraint().getInt().isUnsigned())
475 Out << 'U';
476
Ted Kremenek0806acf2008-02-05 23:08:41 +0000477 break;
478 }
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000479
480 default:
481 assert (false && "Pretty-printed not implemented for this NonLValue.");
482 break;
483 }
484}
485
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000486
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000487void LValue::print(std::ostream& Out) const {
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000488 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000489 case lval::ConcreteIntKind:
490 Out << cast<lval::ConcreteInt>(this)->getValue().toString()
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000491 << " (LValue)";
492 break;
493
Ted Kremenek329f8542008-02-05 21:52:21 +0000494 case lval::SymbolValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000495 Out << '$' << cast<lval::SymbolVal>(this)->getSymbol();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000496 break;
Ted Kremenek2a502572008-02-12 21:37:56 +0000497
498 case lval::GotoLabelKind:
499 Out << "&&"
500 << cast<lval::GotoLabel>(this)->getLabel()->getID()->getName();
501 break;
Ted Kremenek08b66252008-02-06 04:31:33 +0000502
Ted Kremenek329f8542008-02-05 21:52:21 +0000503 case lval::DeclValKind:
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000504 Out << '&'
Ted Kremenek329f8542008-02-05 21:52:21 +0000505 << cast<lval::DeclVal>(this)->getDecl()->getIdentifier()->getName();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000506 break;
507
508 default:
509 assert (false && "Pretty-printed not implemented for this LValue.");
510 break;
511 }
512}
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000513