blob: f4b8a3d34067f039817c1e428a5d4071775b3eb1 [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 Kremenek53c641a2008-02-08 03:02:48 +0000135 case UninitializedKind: case UnknownKind: break;
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000136 }
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
Ted Kremenek22031182008-02-08 02:57:34 +0000152 if (isa<UnknownVal>(this) || isa<UnknownVal>(RHS))
153 return cast<NonLValue>(UnknownVal());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000154
Ted Kremenek22031182008-02-08 02:57:34 +0000155 if (isa<UninitializedVal>(this) || isa<UninitializedVal>(RHS))
156 return cast<NonLValue>(UninitializedVal());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000157
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 }
Ted Kremenek22031182008-02-08 02:57:34 +0000169 else if(isa<UnknownVal>(RHS))
170 return cast<NonLValue>(UnknownVal());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000171 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
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000214 case BinaryOperator::Shl:
Ted Kremenek59c2d262008-02-08 07:14:58 +0000215 return ValMgr.getValue( V1.operator<<( (unsigned) V2.getZExtValue() ));
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000216
217 case BinaryOperator::Shr:
Ted Kremenek59c2d262008-02-08 07:14:58 +0000218 return ValMgr.getValue( V1.operator>>( (unsigned) V2.getZExtValue() ));
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000219
220 case BinaryOperator::LT:
221 return ValMgr.getTruthValue( V1 < V2 );
222
223 case BinaryOperator::GT:
224 return ValMgr.getTruthValue( V1 > V2 );
225
226 case BinaryOperator::LE:
227 return ValMgr.getTruthValue( V1 <= V2 );
228
229 case BinaryOperator::GE:
230 return ValMgr.getTruthValue( V1 >= V2 );
231
232 case BinaryOperator::EQ:
233 return ValMgr.getTruthValue( V1 == V2 );
234
235 case BinaryOperator::NE:
236 return ValMgr.getTruthValue( V1 != V2 );
237
238 // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
239
240 case BinaryOperator::And:
241 return ValMgr.getValue( V1 & V2 );
242
243 case BinaryOperator::Or:
244 return ValMgr.getValue( V1 | V2 );
245 }
246}
247
248nonlval::ConcreteInt
249nonlval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
250 BinaryOperator::Opcode Op,
251 const nonlval::ConcreteInt& RHS) const {
252
253 return EvaluateAPSInt(ValMgr, Op, getValue(), RHS.getValue());
254}
255
256
257 // Bitwise-Complement.
258
259NonLValue NonLValue::EvalComplement(ValueManager& ValMgr) const {
260 switch (getSubKind()) {
261 case nonlval::ConcreteIntKind:
262 return cast<nonlval::ConcreteInt>(this)->EvalComplement(ValMgr);
263 default:
Ted Kremenek22031182008-02-08 02:57:34 +0000264 return cast<NonLValue>(UnknownVal());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000265 }
266}
267
268nonlval::ConcreteInt
269nonlval::ConcreteInt::EvalComplement(ValueManager& ValMgr) const {
270 return ValMgr.getValue(~getValue());
271}
272
273 // Casts.
274
275RValue NonLValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
Ted Kremenek329f8542008-02-05 21:52:21 +0000276 if (!isa<nonlval::ConcreteInt>(this))
Ted Kremenek22031182008-02-08 02:57:34 +0000277 return UnknownVal();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000278
Ted Kremenek329f8542008-02-05 21:52:21 +0000279 APSInt V = cast<nonlval::ConcreteInt>(this)->getValue();
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000280 QualType T = CastExpr->getType();
Ted Kremenek08b66252008-02-06 04:31:33 +0000281 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000282 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
283
284 if (CastExpr->getType()->isPointerType())
Ted Kremenek329f8542008-02-05 21:52:21 +0000285 return lval::ConcreteInt(ValMgr.getValue(V));
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000286 else
Ted Kremenek329f8542008-02-05 21:52:21 +0000287 return nonlval::ConcreteInt(ValMgr.getValue(V));
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000288}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000289
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000290 // Unary Minus.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000291
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000292NonLValue NonLValue::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000293 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000294 case nonlval::ConcreteIntKind:
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000295 return cast<nonlval::ConcreteInt>(this)->EvalMinus(ValMgr, U);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000296 default:
Ted Kremenek22031182008-02-08 02:57:34 +0000297 return cast<NonLValue>(UnknownVal());
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000298 }
299}
300
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000301nonlval::ConcreteInt
302nonlval::ConcreteInt::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
303 assert (U->getType() == U->getSubExpr()->getType());
304 assert (U->getType()->isIntegerType());
305 return ValMgr.getValue(-getValue());
Ted Kremenekc5d3b4c2008-02-04 16:58:30 +0000306}
307
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000308//===----------------------------------------------------------------------===//
309// Transfer function dispatch for LValues.
310//===----------------------------------------------------------------------===//
311
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000312 // Binary Operators (except assignments and comma).
313
314RValue LValue::EvalBinaryOp(ValueManager& ValMgr,
315 BinaryOperator::Opcode Op,
316 const LValue& RHS) const {
317
318 switch (Op) {
319 default:
320 assert (false && "Not yet implemented.");
321
322 case BinaryOperator::EQ:
323 return EQ(ValMgr, RHS);
324
325 case BinaryOperator::NE:
326 return NE(ValMgr, RHS);
327 }
328}
329
330
331lval::ConcreteInt
332lval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
333 BinaryOperator::Opcode Op,
334 const lval::ConcreteInt& RHS) const {
335
336 assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
337 (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));
338
339 return EvaluateAPSInt(ValMgr, Op, getValue(), RHS.getValue());
340}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000341
342NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000343 switch (getSubKind()) {
344 default:
345 assert(false && "EQ not implemented for this LValue.");
Ted Kremenek22031182008-02-08 02:57:34 +0000346 return cast<NonLValue>(UnknownVal());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000347
Ted Kremenek0806acf2008-02-05 23:08:41 +0000348 case lval::ConcreteIntKind:
349 if (isa<lval::ConcreteInt>(RHS)) {
350 bool b = cast<lval::ConcreteInt>(this)->getValue() ==
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000351 cast<lval::ConcreteInt>(RHS).getValue();
352
Ted Kremenek0806acf2008-02-05 23:08:41 +0000353 return NonLValue::GetIntTruthValue(ValMgr, b);
354 }
355 else if (isa<lval::SymbolVal>(RHS)) {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000356
Ted Kremenek0806acf2008-02-05 23:08:41 +0000357 const SymIntConstraint& C =
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000358 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
359 BinaryOperator::EQ,
360 cast<lval::ConcreteInt>(this)->getValue());
Ted Kremenek0806acf2008-02-05 23:08:41 +0000361
362 return nonlval::SymIntConstraintVal(C);
363 }
364
365 break;
366
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000367 case lval::SymbolValKind: {
368 if (isa<lval::ConcreteInt>(RHS)) {
369
370 const SymIntConstraint& C =
Ted Kremenek0806acf2008-02-05 23:08:41 +0000371 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
372 BinaryOperator::EQ,
373 cast<lval::ConcreteInt>(RHS).getValue());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000374
375 return nonlval::SymIntConstraintVal(C);
376 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000377
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000378 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement unification.");
379
380 break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000381 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000382
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000383 case lval::DeclValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000384 if (isa<lval::DeclVal>(RHS)) {
385 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
386 return NonLValue::GetIntTruthValue(ValMgr, b);
387 }
388
389 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000390 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000391
392 return NonLValue::GetIntTruthValue(ValMgr, false);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000393}
394
395NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000396 switch (getSubKind()) {
397 default:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000398 assert(false && "NE not implemented for this LValue.");
Ted Kremenek22031182008-02-08 02:57:34 +0000399 return cast<NonLValue>(UnknownVal());
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000400
Ted Kremenek0806acf2008-02-05 23:08:41 +0000401 case lval::ConcreteIntKind:
402 if (isa<lval::ConcreteInt>(RHS)) {
403 bool b = cast<lval::ConcreteInt>(this)->getValue() !=
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000404 cast<lval::ConcreteInt>(RHS).getValue();
Ted Kremenek0806acf2008-02-05 23:08:41 +0000405
406 return NonLValue::GetIntTruthValue(ValMgr, b);
407 }
408 else if (isa<lval::SymbolVal>(RHS)) {
409
410 const SymIntConstraint& C =
411 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
412 BinaryOperator::NE,
413 cast<lval::ConcreteInt>(this)->getValue());
414
415 return nonlval::SymIntConstraintVal(C);
416 }
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000417
Ted Kremenek0806acf2008-02-05 23:08:41 +0000418 break;
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000419
Ted Kremenek0806acf2008-02-05 23:08:41 +0000420 case lval::SymbolValKind: {
421 if (isa<lval::ConcreteInt>(RHS)) {
422
423 const SymIntConstraint& C =
424 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
425 BinaryOperator::NE,
426 cast<lval::ConcreteInt>(RHS).getValue());
427
428 return nonlval::SymIntConstraintVal(C);
429 }
430
431 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement sym !=.");
432
433 break;
434 }
435
436 case lval::DeclValKind:
437 if (isa<lval::DeclVal>(RHS)) {
438 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
439 return NonLValue::GetIntTruthValue(ValMgr, b);
440 }
441
442 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000443 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000444
445 return NonLValue::GetIntTruthValue(ValMgr, true);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000446}
447
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000448 // Casts.
449
450RValue LValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
451 if (CastExpr->getType()->isPointerType())
452 return *this;
453
454 assert (CastExpr->getType()->isIntegerType());
455
456 if (!isa<lval::ConcreteInt>(*this))
Ted Kremenek22031182008-02-08 02:57:34 +0000457 return UnknownVal();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000458
459 APSInt V = cast<lval::ConcreteInt>(this)->getValue();
460 QualType T = CastExpr->getType();
461 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
462 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
463 return nonlval::ConcreteInt(ValMgr.getValue(V));
464}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000465
466//===----------------------------------------------------------------------===//
467// Utility methods for constructing Non-LValues.
468//===----------------------------------------------------------------------===//
469
470NonLValue NonLValue::GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
471 SourceLocation Loc) {
472
Ted Kremenek329f8542008-02-05 21:52:21 +0000473 return nonlval::ConcreteInt(ValMgr.getValue(X, T, Loc));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000474}
475
476NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000477 return nonlval::ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
478 I->getType()->isUnsignedIntegerType())));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000479}
480
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000481NonLValue NonLValue::GetIntTruthValue(ValueManager& ValMgr, bool b) {
482 return nonlval::ConcreteInt(ValMgr.getTruthValue(b));
483}
484
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000485RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
486 QualType T = D->getType();
487
488 if (T->isPointerType() || T->isReferenceType())
Ted Kremenek329f8542008-02-05 21:52:21 +0000489 return lval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000490 else
Ted Kremenek329f8542008-02-05 21:52:21 +0000491 return nonlval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000492}
493
Ted Kremenek5b6dc2d2008-02-07 01:08:27 +0000494void RValue::print() const {
495 print(*llvm::cerr.stream());
496}
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000497
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000498//===----------------------------------------------------------------------===//
499// Pretty-Printing.
500//===----------------------------------------------------------------------===//
501
502void RValue::print(std::ostream& Out) const {
503 switch (getBaseKind()) {
Ted Kremenek53c641a2008-02-08 03:02:48 +0000504 case UnknownKind:
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000505 Out << "Invalid";
506 break;
507
508 case NonLValueKind:
509 cast<NonLValue>(this)->print(Out);
510 break;
511
512 case LValueKind:
513 cast<LValue>(this)->print(Out);
514 break;
515
516 case UninitializedKind:
517 Out << "Uninitialized";
518 break;
519
520 default:
521 assert (false && "Invalid RValue.");
522 }
523}
524
Ted Kremenek0806acf2008-02-05 23:08:41 +0000525static void printOpcode(std::ostream& Out, BinaryOperator::Opcode Op) {
Ted Kremenek7e593362008-02-07 15:20:13 +0000526 switch (Op) {
527 case BinaryOperator::Add: Out << "+" ; break;
528 case BinaryOperator::Sub: Out << "-" ; break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000529 case BinaryOperator::EQ: Out << "=="; break;
530 case BinaryOperator::NE: Out << "!="; break;
531 default: assert(false && "Not yet implemented.");
532 }
533}
534
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000535void NonLValue::print(std::ostream& Out) const {
536 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000537 case nonlval::ConcreteIntKind:
538 Out << cast<nonlval::ConcreteInt>(this)->getValue().toString();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000539
540 if (cast<nonlval::ConcreteInt>(this)->getValue().isUnsigned())
541 Out << 'U';
542
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000543 break;
544
Ted Kremenek329f8542008-02-05 21:52:21 +0000545 case nonlval::SymbolValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000546 Out << '$' << cast<nonlval::SymbolVal>(this)->getSymbol();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000547 break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000548
549 case nonlval::SymIntConstraintValKind: {
550 const nonlval::SymIntConstraintVal& C =
551 *cast<nonlval::SymIntConstraintVal>(this);
552
553 Out << '$' << C.getConstraint().getSymbol() << ' ';
554 printOpcode(Out, C.getConstraint().getOpcode());
555 Out << ' ' << C.getConstraint().getInt().toString();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000556
557 if (C.getConstraint().getInt().isUnsigned())
558 Out << 'U';
559
Ted Kremenek0806acf2008-02-05 23:08:41 +0000560 break;
561 }
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000562
563 default:
564 assert (false && "Pretty-printed not implemented for this NonLValue.");
565 break;
566 }
567}
568
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000569
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000570void LValue::print(std::ostream& Out) const {
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000571 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000572 case lval::ConcreteIntKind:
573 Out << cast<lval::ConcreteInt>(this)->getValue().toString()
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000574 << " (LValue)";
575 break;
576
Ted Kremenek329f8542008-02-05 21:52:21 +0000577 case lval::SymbolValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000578 Out << '$' << cast<lval::SymbolVal>(this)->getSymbol();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000579 break;
Ted Kremenek08b66252008-02-06 04:31:33 +0000580
Ted Kremenek329f8542008-02-05 21:52:21 +0000581 case lval::DeclValKind:
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000582 Out << '&'
Ted Kremenek329f8542008-02-05 21:52:21 +0000583 << cast<lval::DeclVal>(this)->getDecl()->getIdentifier()->getName();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000584 break;
585
586 default:
587 assert (false && "Pretty-printed not implemented for this LValue.");
588 break;
589 }
590}
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000591