blob: 12bf7959722d4775f6e2ba80f2e55750f9abf0a9 [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//
Zhongxing Xu1c96b242008-10-17 05:57:07 +000010// This file defines SVal, Loc, and NonLoc, classes that represent
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000011// abstract r-values for use with path-sensitive value tracking.
12//
13//===----------------------------------------------------------------------===//
14
Ted Kremenek9e240492008-10-04 05:50:14 +000015#include "clang/Analysis/PathSensitive/GRState.h"
Daniel Dunbarc4a1dea2008-08-11 05:35:13 +000016#include "clang/Basic/IdentifierTable.h"
Ted Kremenekd70d0b02008-02-16 01:12:31 +000017#include "llvm/Support/Streams.h"
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000018
19using namespace clang;
20using llvm::dyn_cast;
21using llvm::cast;
22using llvm::APSInt;
23
24//===----------------------------------------------------------------------===//
Ted Kremenek90e14812008-02-14 23:25:54 +000025// Symbol Iteration.
26//===----------------------------------------------------------------------===//
Ted Kremeneka6e4d212008-02-01 06:36:40 +000027
Zhongxing Xu1c96b242008-10-17 05:57:07 +000028SVal::symbol_iterator SVal::symbol_begin() const {
Ted Kremenek718c4f72008-04-29 22:17:41 +000029 // FIXME: This is a rat's nest. Cleanup.
30
Zhongxing Xu1c96b242008-10-17 05:57:07 +000031 if (isa<loc::SymbolVal>(this))
Ted Kremenek2dabd432008-12-05 02:27:51 +000032 return symbol_iterator(SymbolRef((uintptr_t)Data));
Zhongxing Xu1c96b242008-10-17 05:57:07 +000033 else if (isa<nonloc::SymbolVal>(this))
Ted Kremenek2dabd432008-12-05 02:27:51 +000034 return symbol_iterator(SymbolRef((uintptr_t)Data));
Zhongxing Xu1c96b242008-10-17 05:57:07 +000035 else if (isa<nonloc::SymIntConstraintVal>(this)) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000036 const SymIntConstraint& C =
Ted Kremenek0d958e72008-10-27 23:39:39 +000037 cast<nonloc::SymIntConstraintVal>(this)->getConstraint();
38 return symbol_iterator(C.getSymbol());
Ted Kremenek90e14812008-02-14 23:25:54 +000039 }
Zhongxing Xu1c96b242008-10-17 05:57:07 +000040 else if (isa<nonloc::LocAsInteger>(this)) {
41 const nonloc::LocAsInteger& V = cast<nonloc::LocAsInteger>(*this);
42 return V.getPersistentLoc().symbol_begin();
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000043 }
Ted Kremenek0d958e72008-10-27 23:39:39 +000044 else if (isa<loc::MemRegionVal>(this)) {
45 const MemRegion* R = cast<loc::MemRegionVal>(this)->getRegion();
46 if (const SymbolicRegion* S = dyn_cast<SymbolicRegion>(R))
47 return symbol_iterator(S->getSymbol());
48 }
Ted Kremenekd9bc33e2008-10-17 00:51:01 +000049
Ted Kremenek0d958e72008-10-27 23:39:39 +000050 return symbol_iterator();
Ted Kremenek90e14812008-02-14 23:25:54 +000051}
52
Zhongxing Xu1c96b242008-10-17 05:57:07 +000053SVal::symbol_iterator SVal::symbol_end() const {
Ted Kremenek0d958e72008-10-27 23:39:39 +000054 return symbol_iterator();
Ted Kremenek90e14812008-02-14 23:25:54 +000055}
Ted Kremeneka6e4d212008-02-01 06:36:40 +000056
Ted Kremenek94c96982009-03-03 22:06:47 +000057/// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
58/// wraps a symbol, return that SymbolRef. Otherwise return a SymbolRef
59/// where 'isValid()' returns false.
60SymbolRef SVal::getAsLocSymbol() const {
61 if (const loc::SymbolVal *X = dyn_cast<loc::SymbolVal>(this))
62 return X->getSymbol();
63
64 if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) {
65 const MemRegion *R = X->getRegion();
66
67 while (R) {
68 // Blast through region views.
69 if (const TypedViewRegion *View = dyn_cast<TypedViewRegion>(R)) {
70 R = View->getSuperRegion();
71 continue;
72 }
73
74 if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
75 return SymR->getSymbol();
76
77 break;
78 }
79 }
80
81 return SymbolRef();
82}
83
84/// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
85/// Otherwise return a SymbolRef where 'isValid()' returns false.
86SymbolRef SVal::getAsSymbol() const {
87 if (const nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(this))
88 return X->getSymbol();
89
90 return getAsLocSymbol();
91}
92
Ted Kremenekcf78b6a2008-02-06 22:50:25 +000093//===----------------------------------------------------------------------===//
Ted Kremeneka6fac4e2008-10-30 18:01:28 +000094// Other Iterators.
95//===----------------------------------------------------------------------===//
96
97nonloc::CompoundVal::iterator nonloc::CompoundVal::begin() const {
98 return getValue()->begin();
99}
100
101nonloc::CompoundVal::iterator nonloc::CompoundVal::end() const {
102 return getValue()->end();
103}
104
105//===----------------------------------------------------------------------===//
Ted Kremenek40fc5c72008-07-18 15:54:51 +0000106// Useful predicates.
107//===----------------------------------------------------------------------===//
108
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000109bool SVal::isZeroConstant() const {
110 if (isa<loc::ConcreteInt>(*this))
111 return cast<loc::ConcreteInt>(*this).getValue() == 0;
112 else if (isa<nonloc::ConcreteInt>(*this))
113 return cast<nonloc::ConcreteInt>(*this).getValue() == 0;
Ted Kremenek40fc5c72008-07-18 15:54:51 +0000114 else
115 return false;
116}
117
118
119//===----------------------------------------------------------------------===//
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000120// Transfer function dispatch for Non-Locs.
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000121//===----------------------------------------------------------------------===//
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000122
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000123SVal nonloc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals,
Ted Kremenek75b0a1c2008-07-18 15:59:33 +0000124 BinaryOperator::Opcode Op,
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000125 const nonloc::ConcreteInt& R) const {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000126
Ted Kremenek75b0a1c2008-07-18 15:59:33 +0000127 const llvm::APSInt* X =
128 BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue());
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000129
130 if (X)
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000131 return nonloc::ConcreteInt(*X);
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000132 else
133 return UndefinedVal();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000134}
135
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000136 // Bitwise-Complement.
137
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000138nonloc::ConcreteInt
139nonloc::ConcreteInt::EvalComplement(BasicValueFactory& BasicVals) const {
Ted Kremenek240f1f02008-03-07 20:13:31 +0000140 return BasicVals.getValue(~getValue());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000141}
142
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000143 // Unary Minus.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000144
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000145nonloc::ConcreteInt
146nonloc::ConcreteInt::EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000147 assert (U->getType() == U->getSubExpr()->getType());
148 assert (U->getType()->isIntegerType());
Ted Kremenek240f1f02008-03-07 20:13:31 +0000149 return BasicVals.getValue(-getValue());
Ted Kremenekc5d3b4c2008-02-04 16:58:30 +0000150}
151
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000152//===----------------------------------------------------------------------===//
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000153// Transfer function dispatch for Locs.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000154//===----------------------------------------------------------------------===//
155
Ted Kremenekccaad9d2008-10-30 17:53:23 +0000156SVal loc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals,
157 BinaryOperator::Opcode Op,
158 const loc::ConcreteInt& R) const {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000159
160 assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
161 (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));
162
Ted Kremenek240f1f02008-03-07 20:13:31 +0000163 const llvm::APSInt* X = BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue());
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000164
165 if (X)
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000166 return loc::ConcreteInt(*X);
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000167 else
168 return UndefinedVal();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000169}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000170
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000171NonLoc Loc::EQ(BasicValueFactory& BasicVals, const Loc& R) const {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000172
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000173 switch (getSubKind()) {
174 default:
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000175 assert(false && "EQ not implemented for this Loc.");
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000176 break;
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000177
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000178 case loc::ConcreteIntKind:
179 if (isa<loc::ConcreteInt>(R)) {
180 bool b = cast<loc::ConcreteInt>(this)->getValue() ==
181 cast<loc::ConcreteInt>(R).getValue();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000182
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000183 return NonLoc::MakeIntTruthVal(BasicVals, b);
Ted Kremenek0806acf2008-02-05 23:08:41 +0000184 }
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000185 else if (isa<loc::SymbolVal>(R)) {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000186
Ted Kremenek0806acf2008-02-05 23:08:41 +0000187 const SymIntConstraint& C =
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000188 BasicVals.getConstraint(cast<loc::SymbolVal>(R).getSymbol(),
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000189 BinaryOperator::EQ,
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000190 cast<loc::ConcreteInt>(this)->getValue());
Ted Kremenek0806acf2008-02-05 23:08:41 +0000191
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000192 return nonloc::SymIntConstraintVal(C);
Ted Kremenek0806acf2008-02-05 23:08:41 +0000193 }
194
195 break;
196
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000197 case loc::SymbolValKind: {
198 if (isa<loc::ConcreteInt>(R)) {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000199
200 const SymIntConstraint& C =
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000201 BasicVals.getConstraint(cast<loc::SymbolVal>(this)->getSymbol(),
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000202 BinaryOperator::EQ,
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000203 cast<loc::ConcreteInt>(R).getValue());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000204
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000205 return nonloc::SymIntConstraintVal(C);
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000206 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000207
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000208 assert (!isa<loc::SymbolVal>(R) && "FIXME: Implement unification.");
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000209
210 break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000211 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000212
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000213 case loc::MemRegionKind:
214 if (isa<loc::MemRegionVal>(R)) {
215 bool b = cast<loc::MemRegionVal>(*this) == cast<loc::MemRegionVal>(R);
216 return NonLoc::MakeIntTruthVal(BasicVals, b);
Ted Kremenek0806acf2008-02-05 23:08:41 +0000217 }
218
219 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000220 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000221
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000222 return NonLoc::MakeIntTruthVal(BasicVals, false);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000223}
224
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000225NonLoc Loc::NE(BasicValueFactory& BasicVals, const Loc& R) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000226 switch (getSubKind()) {
227 default:
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000228 assert(false && "NE not implemented for this Loc.");
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000229 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000230
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000231 case loc::ConcreteIntKind:
232 if (isa<loc::ConcreteInt>(R)) {
233 bool b = cast<loc::ConcreteInt>(this)->getValue() !=
234 cast<loc::ConcreteInt>(R).getValue();
Ted Kremenek0806acf2008-02-05 23:08:41 +0000235
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000236 return NonLoc::MakeIntTruthVal(BasicVals, b);
Ted Kremenek0806acf2008-02-05 23:08:41 +0000237 }
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000238 else if (isa<loc::SymbolVal>(R)) {
Ted Kremenek0806acf2008-02-05 23:08:41 +0000239
240 const SymIntConstraint& C =
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000241 BasicVals.getConstraint(cast<loc::SymbolVal>(R).getSymbol(),
Ted Kremenek0806acf2008-02-05 23:08:41 +0000242 BinaryOperator::NE,
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000243 cast<loc::ConcreteInt>(this)->getValue());
Ted Kremenek0806acf2008-02-05 23:08:41 +0000244
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000245 return nonloc::SymIntConstraintVal(C);
Ted Kremenek0806acf2008-02-05 23:08:41 +0000246 }
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000247
Ted Kremenek0806acf2008-02-05 23:08:41 +0000248 break;
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000249
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000250 case loc::SymbolValKind: {
251 if (isa<loc::ConcreteInt>(R)) {
Ted Kremenek0806acf2008-02-05 23:08:41 +0000252
253 const SymIntConstraint& C =
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000254 BasicVals.getConstraint(cast<loc::SymbolVal>(this)->getSymbol(),
Ted Kremenek0806acf2008-02-05 23:08:41 +0000255 BinaryOperator::NE,
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000256 cast<loc::ConcreteInt>(R).getValue());
Ted Kremenek0806acf2008-02-05 23:08:41 +0000257
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000258 return nonloc::SymIntConstraintVal(C);
Ted Kremenek0806acf2008-02-05 23:08:41 +0000259 }
260
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000261 assert (!isa<loc::SymbolVal>(R) && "FIXME: Implement sym !=.");
Ted Kremenek0806acf2008-02-05 23:08:41 +0000262
263 break;
264 }
265
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000266 case loc::MemRegionKind:
267 if (isa<loc::MemRegionVal>(R)) {
268 bool b = cast<loc::MemRegionVal>(*this)==cast<loc::MemRegionVal>(R);
269 return NonLoc::MakeIntTruthVal(BasicVals, b);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000270 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000271
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000272 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000273 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000274
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000275 return NonLoc::MakeIntTruthVal(BasicVals, true);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000276}
277
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000278//===----------------------------------------------------------------------===//
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000279// Utility methods for constructing Non-Locs.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000280//===----------------------------------------------------------------------===//
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000281
282NonLoc NonLoc::MakeVal(SymbolRef sym) {
283 return nonloc::SymbolVal(sym);
284}
285
Ted Kremenek14553ab2009-01-30 00:08:43 +0000286NonLoc NonLoc::MakeIntVal(BasicValueFactory& BasicVals, uint64_t X,
287 bool isUnsigned) {
288 return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned));
Zhongxing Xu6613d082008-11-24 02:18:56 +0000289}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000290
Zhongxing Xu8b862732008-11-24 09:38:21 +0000291NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, uint64_t X,
292 unsigned BitWidth, bool isUnsigned) {
293 return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned));
294}
295
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000296NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T) {
297 return nonloc::ConcreteInt(BasicVals.getValue(X, T));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000298}
299
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000300NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000301
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000302 return nonloc::ConcreteInt(BasicVals.getValue(APSInt(I->getValue(),
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000303 I->getType()->isUnsignedIntegerType())));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000304}
305
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000306NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, const llvm::APInt& I,
307 bool isUnsigned) {
308 return nonloc::ConcreteInt(BasicVals.getValue(I, isUnsigned));
309}
310
Zhongxing Xu8b862732008-11-24 09:38:21 +0000311NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, const llvm::APSInt& I) {
312 return nonloc::ConcreteInt(BasicVals.getValue(I));
313}
314
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000315NonLoc NonLoc::MakeIntTruthVal(BasicValueFactory& BasicVals, bool b) {
316 return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000317}
318
Ted Kremenek632e8b82008-10-30 17:44:46 +0000319NonLoc NonLoc::MakeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals,
Zhongxing Xu6764b722008-10-30 04:58:00 +0000320 BasicValueFactory& BasicVals) {
Ted Kremenek632e8b82008-10-30 17:44:46 +0000321 return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
Zhongxing Xu6764b722008-10-30 04:58:00 +0000322}
323
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000324SVal SVal::GetRValueSymbolVal(SymbolManager& SymMgr, const MemRegion* R) {
325 SymbolRef sym = SymMgr.getRegionRValueSymbol(R);
326
Ted Kremenekec099f12009-03-18 22:10:22 +0000327 if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) {
328 QualType T = TR->getRValueType(SymMgr.getContext());
329
330 if (Loc::IsLocType(T))
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000331 return Loc::MakeVal(sym);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000332
Ted Kremenekec099f12009-03-18 22:10:22 +0000333 // Only handle integers for now.
334 if (T->isIntegerType())
335 return NonLoc::MakeVal(sym);
336 }
337
338 return UnknownVal();
Zhongxing Xueabf7762008-11-19 11:03:17 +0000339}
340
Ted Kremenekbb9b2712009-03-20 20:10:45 +0000341SVal SVal::GetConjuredSymbolVal(SymbolManager &SymMgr, const Expr* E,
342 unsigned Count) {
343
344 QualType T = E->getType();
345
346 if (Loc::IsLocType(T)) {
347 SymbolRef Sym = SymMgr.getConjuredSymbol(E, Count);
348 return loc::SymbolVal(Sym);
349 }
350 else if (T->isIntegerType() && T->isScalarType()) {
351 SymbolRef Sym = SymMgr.getConjuredSymbol(E, Count);
352 return nonloc::SymbolVal(Sym);
353 }
354
355 return UnknownVal();
356}
357
Ted Kremenek632e8b82008-10-30 17:44:46 +0000358nonloc::LocAsInteger nonloc::LocAsInteger::Make(BasicValueFactory& Vals, Loc V,
359 unsigned Bits) {
360 return LocAsInteger(Vals.getPersistentSValWithData(V, Bits));
361}
362
Ted Kremenek2a502572008-02-12 21:37:56 +0000363//===----------------------------------------------------------------------===//
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000364// Utility methods for constructing Locs.
Ted Kremenek2a502572008-02-12 21:37:56 +0000365//===----------------------------------------------------------------------===//
366
Zhongxing Xu2fdf5552008-12-09 10:51:19 +0000367Loc Loc::MakeVal(const MemRegion* R) { return loc::MemRegionVal(R); }
368
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000369Loc Loc::MakeVal(AddrLabelExpr* E) { return loc::GotoLabel(E->getLabel()); }
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000370
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000371Loc Loc::MakeVal(SymbolRef sym) { return loc::SymbolVal(sym); }
372
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000373//===----------------------------------------------------------------------===//
374// Pretty-Printing.
375//===----------------------------------------------------------------------===//
376
Daniel Dunbar4a77edb2009-03-10 18:00:19 +0000377void SVal::printStdErr() const { print(llvm::errs()); }
Ted Kremenek2a502572008-02-12 21:37:56 +0000378
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000379void SVal::print(std::ostream& Out) const {
Ted Kremenekb8b41612008-10-30 18:35:10 +0000380 llvm::raw_os_ostream out(Out);
381 print(out);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000382}
383
Zhongxing Xu9012bff2008-10-24 06:00:12 +0000384void SVal::print(llvm::raw_ostream& Out) const {
385
386 switch (getBaseKind()) {
387
388 case UnknownKind:
389 Out << "Invalid"; break;
390
391 case NonLocKind:
392 cast<NonLoc>(this)->print(Out); break;
393
394 case LocKind:
395 cast<Loc>(this)->print(Out); break;
396
397 case UndefinedKind:
398 Out << "Undefined"; break;
399
400 default:
401 assert (false && "Invalid SVal.");
402 }
403}
404
405static void printOpcode(llvm::raw_ostream& Out, BinaryOperator::Opcode Op) {
406
407 switch (Op) {
408 case BinaryOperator::Mul: Out << '*' ; break;
409 case BinaryOperator::Div: Out << '/' ; break;
410 case BinaryOperator::Rem: Out << '%' ; break;
411 case BinaryOperator::Add: Out << '+' ; break;
412 case BinaryOperator::Sub: Out << '-' ; break;
413 case BinaryOperator::Shl: Out << "<<" ; break;
414 case BinaryOperator::Shr: Out << ">>" ; break;
415 case BinaryOperator::LT: Out << "<" ; break;
416 case BinaryOperator::GT: Out << '>' ; break;
417 case BinaryOperator::LE: Out << "<=" ; break;
418 case BinaryOperator::GE: Out << ">=" ; break;
419 case BinaryOperator::EQ: Out << "==" ; break;
420 case BinaryOperator::NE: Out << "!=" ; break;
421 case BinaryOperator::And: Out << '&' ; break;
422 case BinaryOperator::Xor: Out << '^' ; break;
423 case BinaryOperator::Or: Out << '|' ; break;
424
425 default: assert(false && "Not yet implemented.");
426 }
427}
428
429void NonLoc::print(llvm::raw_ostream& Out) const {
430
431 switch (getSubKind()) {
432
433 case nonloc::ConcreteIntKind:
434 Out << cast<nonloc::ConcreteInt>(this)->getValue().getZExtValue();
435
436 if (cast<nonloc::ConcreteInt>(this)->getValue().isUnsigned())
437 Out << 'U';
438
439 break;
440
441 case nonloc::SymbolValKind:
442 Out << '$' << cast<nonloc::SymbolVal>(this)->getSymbol();
443 break;
444
445 case nonloc::SymIntConstraintValKind: {
446 const nonloc::SymIntConstraintVal& C =
447 *cast<nonloc::SymIntConstraintVal>(this);
448
449 Out << '$' << C.getConstraint().getSymbol() << ' ';
450 printOpcode(Out, C.getConstraint().getOpcode());
451 Out << ' ' << C.getConstraint().getInt().getZExtValue();
452
453 if (C.getConstraint().getInt().isUnsigned())
454 Out << 'U';
455
456 break;
457 }
458
459 case nonloc::LocAsIntegerKind: {
460 const nonloc::LocAsInteger& C = *cast<nonloc::LocAsInteger>(this);
461 C.getLoc().print(Out);
462 Out << " [as " << C.getNumBits() << " bit integer]";
463 break;
464 }
465
Ted Kremeneka6fac4e2008-10-30 18:01:28 +0000466 case nonloc::CompoundValKind: {
467 const nonloc::CompoundVal& C = *cast<nonloc::CompoundVal>(this);
Ted Kremenekb8b41612008-10-30 18:35:10 +0000468 Out << " {";
469 bool first = true;
470 for (nonloc::CompoundVal::iterator I=C.begin(), E=C.end(); I!=E; ++I) {
471 if (first) { Out << ' '; first = false; }
472 else Out << ", ";
Ted Kremeneka6fac4e2008-10-30 18:01:28 +0000473 (*I).print(Out);
Ted Kremenekb8b41612008-10-30 18:35:10 +0000474 }
Ted Kremeneka6fac4e2008-10-30 18:01:28 +0000475 Out << " }";
476 break;
477 }
478
Zhongxing Xu9012bff2008-10-24 06:00:12 +0000479 default:
480 assert (false && "Pretty-printed not implemented for this NonLoc.");
481 break;
482 }
483}
484
485void Loc::print(llvm::raw_ostream& Out) const {
486
487 switch (getSubKind()) {
488
489 case loc::ConcreteIntKind:
490 Out << cast<loc::ConcreteInt>(this)->getValue().getZExtValue()
491 << " (Loc)";
492 break;
493
494 case loc::SymbolValKind:
495 Out << '$' << cast<loc::SymbolVal>(this)->getSymbol();
496 break;
497
498 case loc::GotoLabelKind:
499 Out << "&&"
500 << cast<loc::GotoLabel>(this)->getLabel()->getID()->getName();
501 break;
502
503 case loc::MemRegionKind:
504 Out << '&' << cast<loc::MemRegionVal>(this)->getRegion()->getString();
505 break;
506
507 case loc::FuncValKind:
508 Out << "function "
509 << cast<loc::FuncVal>(this)->getDecl()->getIdentifier()->getName();
510 break;
511
Zhongxing Xu9012bff2008-10-24 06:00:12 +0000512 default:
513 assert (false && "Pretty-printing not implemented for this Loc.");
514 break;
515 }
516}