blob: 9aa2f11e1996e8e7ac5add7ffc4dd6abb7d5e5a4 [file] [log] [blame]
Ted Kremeneka90ccfe2008-01-31 19:34:24 +00001//== RValues.h - 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#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H
16#define LLVM_CLANG_ANALYSIS_RVALUE_H
17
18// FIXME: reduce the number of includes.
19
20#include "clang/Analysis/PathSensitive/GREngine.h"
21#include "clang/AST/Expr.h"
22#include "clang/AST/Decl.h"
23#include "clang/AST/ASTContext.h"
24#include "clang/Analysis/Analyses/LiveVariables.h"
25
26#include "llvm/Support/Casting.h"
27#include "llvm/Support/DataTypes.h"
28#include "llvm/ADT/APSInt.h"
29#include "llvm/ADT/FoldingSet.h"
30#include "llvm/ADT/ImmutableMap.h"
31#include "llvm/ADT/SmallVector.h"
32#include "llvm/ADT/SmallPtrSet.h"
33#include "llvm/Support/Allocator.h"
34#include "llvm/Support/Compiler.h"
35#include "llvm/Support/Streams.h"
36
37#include <functional>
38
39//==------------------------------------------------------------------------==//
Ted Kremenek1fbdb022008-02-05 21:32:43 +000040// Values and ValueManager.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000041//==------------------------------------------------------------------------==//
42
43namespace clang {
44
45class SymbolID {
46 unsigned Data;
47public:
48 SymbolID() : Data(~0) {}
49 SymbolID(unsigned x) : Data(x) {}
50
51 bool isInitialized() const { return Data != (unsigned) ~0; }
52 operator unsigned() const { assert (isInitialized()); return Data; }
Ted Kremenek174aea42008-02-05 18:51:06 +000053
Ted Kremenek1fbdb022008-02-05 21:32:43 +000054 void Profile(llvm::FoldingSetNodeID& ID) const {
55 assert (isInitialized());
56 ID.AddInteger(Data);
57 }
Ted Kremenek174aea42008-02-05 18:51:06 +000058
59 static inline void Profile(llvm::FoldingSetNodeID& ID, SymbolID X) {
60 X.Profile(ID);
61 }
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000062};
63
Ted Kremenekd131c4f2008-02-07 05:48:01 +000064 // SymbolData: Used to record meta data about symbols.
65
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000066class SymbolData {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000067public:
Ted Kremenekd131c4f2008-02-07 05:48:01 +000068 enum Kind { UninitKind, ParmKind, ContentsOfKind };
69
70private:
71 uintptr_t Data;
72 Kind K;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000073
Ted Kremenekd131c4f2008-02-07 05:48:01 +000074protected:
75 SymbolData(uintptr_t D, Kind k) : Data(D), K(k) {}
76 SymbolData(void* D, Kind k) : Data(reinterpret_cast<uintptr_t>(D)), K(k) {}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000077
Ted Kremenekd131c4f2008-02-07 05:48:01 +000078 void* getPtr() const {
79 assert (K != UninitKind);
80 return reinterpret_cast<void*>(Data);
81 }
Ted Kremenekfeb01f62008-02-06 17:32:17 +000082
Ted Kremenekd131c4f2008-02-07 05:48:01 +000083 uintptr_t getInt() const {
84 assert (K != UninitKind);
85 return Data;
86 }
87
88public:
89 SymbolData() : Data(0), K(UninitKind) {}
90
91 Kind getKind() const { return K; }
92
93 inline bool operator==(const SymbolData& R) const {
94 return K == R.K && Data == R.Data;
95 }
96
97 QualType getType() const;
98
99 // Implement isa<T> support.
100 static inline bool classof(const SymbolData*) { return true; }
101};
102
103class SymbolDataParmVar : public SymbolData {
104public:
105 SymbolDataParmVar(ParmVarDecl* VD) : SymbolData(VD, ParmKind) {}
106
107 ParmVarDecl* getDecl() const { return (ParmVarDecl*) getPtr(); }
108
109 // Implement isa<T> support.
110 static inline bool classof(const SymbolData* D) {
111 return D->getKind() == ParmKind;
112 }
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000113};
Ted Kremenek1fbdb022008-02-05 21:32:43 +0000114
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000115class SymbolDataContentsOf : public SymbolData {
116public:
117 SymbolDataContentsOf(SymbolID ID) : SymbolData(ID, ContentsOfKind) {}
118
119 SymbolID getSymbol() const { return (SymbolID) getInt(); }
120
121 // Implement isa<T> support.
122 static inline bool classof(const SymbolData* D) {
123 return D->getKind() == ContentsOfKind;
124 }
125};
126
127 // Constraints on symbols. Usually wrapped by RValues.
Ted Kremenek1fbdb022008-02-05 21:32:43 +0000128
129class SymIntConstraint : public llvm::FoldingSetNode {
130 SymbolID Symbol;
131 BinaryOperator::Opcode Op;
132 const llvm::APSInt& Val;
133public:
134 SymIntConstraint(SymbolID sym, BinaryOperator::Opcode op,
135 const llvm::APSInt& V)
136 : Symbol(sym),
137 Op(op), Val(V) {}
138
139 BinaryOperator::Opcode getOpcode() const { return Op; }
140 SymbolID getSymbol() const { return Symbol; }
141 const llvm::APSInt& getInt() const { return Val; }
142
143 static inline void Profile(llvm::FoldingSetNodeID& ID,
144 const SymbolID& Symbol,
145 BinaryOperator::Opcode Op,
146 const llvm::APSInt& Val) {
147 Symbol.Profile(ID);
148 ID.AddInteger(Op);
149 ID.AddPointer(&Val);
150 }
151
152 void Profile(llvm::FoldingSetNodeID& ID) {
153 Profile(ID, Symbol, Op, Val);
154 }
155};
156
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000157
158class SymbolManager {
159 std::vector<SymbolData> SymbolToData;
160
161 typedef llvm::DenseMap<void*,SymbolID> MapTy;
162 MapTy DataToSymbol;
163
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000164 void* getKey(void* P) const {
165 return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(P) | 0x1);
166 }
167
168 void* getKey(SymbolID sym) const {
169 return reinterpret_cast<void*>((uintptr_t) (sym << 1));
170 }
171
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000172public:
173 SymbolManager();
174 ~SymbolManager();
175
Ted Kremenekfeb01f62008-02-06 17:32:17 +0000176 SymbolID getSymbol(ParmVarDecl* D);
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000177 SymbolID getContentsOfSymbol(SymbolID sym);
Ted Kremenekfeb01f62008-02-06 17:32:17 +0000178
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000179 inline const SymbolData& getSymbolData(SymbolID ID) const {
Ted Kremenekfeb01f62008-02-06 17:32:17 +0000180 assert (ID < SymbolToData.size());
181 return SymbolToData[ID];
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000182 }
183
Ted Kremenekfeb01f62008-02-06 17:32:17 +0000184 inline QualType getType(SymbolID ID) const {
185 return getSymbolData(ID).getType();
186 }
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000187};
Ted Kremenek1fbdb022008-02-05 21:32:43 +0000188
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000189
190class ValueManager {
191 typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
192 APSIntSetTy;
193
Ted Kremenek1fbdb022008-02-05 21:32:43 +0000194 typedef llvm::FoldingSet<SymIntConstraint>
195 SymIntCSetTy;
196
197
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000198 ASTContext& Ctx;
Ted Kremenek768ad162008-02-05 05:15:51 +0000199 llvm::BumpPtrAllocator& BPAlloc;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000200
Ted Kremenek1fbdb022008-02-05 21:32:43 +0000201 APSIntSetTy APSIntSet;
202 SymIntCSetTy SymIntCSet;
203
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000204public:
Ted Kremenek768ad162008-02-05 05:15:51 +0000205 ValueManager(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc)
206 : Ctx(ctx), BPAlloc(Alloc) {}
207
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000208 ~ValueManager();
209
210 ASTContext& getContext() const { return Ctx; }
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000211
Ted Kremenek1fbdb022008-02-05 21:32:43 +0000212 const llvm::APSInt& getValue(const llvm::APSInt& X);
213 const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
214 const llvm::APSInt& getValue(uint64_t X, QualType T,
215 SourceLocation Loc = SourceLocation());
216
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000217 inline const llvm::APSInt& getZeroWithPtrWidth() {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000218 return getValue( 0,
219 Ctx.getTypeSize(Ctx.VoidPtrTy, SourceLocation()),
220 true );
221 }
222
223 inline const llvm::APSInt& getTruthValue(bool b) {
224 return getValue( b ? 1 : 0,
225 Ctx.getTypeSize(Ctx.IntTy, SourceLocation()),
226 false );
227
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000228 }
229
Ted Kremenek1fbdb022008-02-05 21:32:43 +0000230 const SymIntConstraint& getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
231 const llvm::APSInt& V);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000232};
Ted Kremenek0f10d502008-02-05 22:21:54 +0000233
234} // end clang namespace
235
236//==------------------------------------------------------------------------==//
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000237// Base RValue types.
238//==------------------------------------------------------------------------==//
239
Ted Kremenek0f10d502008-02-05 22:21:54 +0000240namespace clang {
241
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000242class RValue {
243public:
244 enum BaseKind { LValueKind=0x0,
245 NonLValueKind=0x1,
246 UninitializedKind=0x2,
Ted Kremenek22031182008-02-08 02:57:34 +0000247 UnknownKind=0x3 };
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000248
249 enum { BaseBits = 2,
250 BaseMask = 0x3 };
251
252private:
253 void* Data;
254 unsigned Kind;
255
256protected:
257 RValue(const void* d, bool isLValue, unsigned ValKind)
258 : Data(const_cast<void*>(d)),
259 Kind((isLValue ? LValueKind : NonLValueKind) | (ValKind << BaseBits)) {}
260
261 explicit RValue(BaseKind k)
262 : Data(0), Kind(k) {}
263
264 void* getRawPtr() const {
265 return reinterpret_cast<void*>(Data);
266 }
267
268public:
269 ~RValue() {};
270
Ted Kremenekcba2e432008-02-05 19:35:18 +0000271 /// BufferTy - A temporary buffer to hold a set of RValues.
272 typedef llvm::SmallVector<RValue,5> BufferTy;
273
274
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000275 RValue EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000276
277 unsigned getRawKind() const { return Kind; }
278 BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
279 unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
280
281 void Profile(llvm::FoldingSetNodeID& ID) const {
282 ID.AddInteger((unsigned) getRawKind());
283 ID.AddPointer(reinterpret_cast<void*>(Data));
284 }
285
286 bool operator==(const RValue& RHS) const {
287 return getRawKind() == RHS.getRawKind() && Data == RHS.Data;
288 }
289
290 static RValue GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl *D);
291
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000292
Ted Kremenek22031182008-02-08 02:57:34 +0000293 inline bool isKnown() const { return getRawKind() != UnknownKind; }
294 inline bool isUnknown() const { return getRawKind() == UnknownKind; }
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000295
296 void print(std::ostream& OS) const;
Ted Kremenek5b6dc2d2008-02-07 01:08:27 +0000297 void print() const;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000298
299 // Implement isa<T> support.
300 static inline bool classof(const RValue*) { return true; }
301};
302
Ted Kremenek22031182008-02-08 02:57:34 +0000303class UnknownVal : public RValue {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000304public:
Ted Kremenek22031182008-02-08 02:57:34 +0000305 UnknownVal() : RValue(UnknownKind) {}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000306
307 static inline bool classof(const RValue* V) {
Ted Kremenek22031182008-02-08 02:57:34 +0000308 return V->getBaseKind() == UnknownKind;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000309 }
310};
311
Ted Kremenek22031182008-02-08 02:57:34 +0000312class UninitializedVal : public RValue {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000313public:
Ted Kremenek22031182008-02-08 02:57:34 +0000314 UninitializedVal() : RValue(UninitializedKind) {}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000315
316 static inline bool classof(const RValue* V) {
317 return V->getBaseKind() == UninitializedKind;
318 }
319};
320
321class NonLValue : public RValue {
322protected:
323 NonLValue(unsigned SubKind, const void* d) : RValue(d, false, SubKind) {}
324
325public:
326 void print(std::ostream& Out) const;
327
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000328 NonLValue EvalBinaryOp(ValueManager& ValMgr,
329 BinaryOperator::Opcode Op,
330 const NonLValue& RHS) const;
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000331
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000332 RValue EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
333 NonLValue EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
334 NonLValue EvalComplement(ValueManager& ValMgr) const;
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000335
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000336 // Utility methods to create NonLValues.
337 static NonLValue GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
338 SourceLocation Loc = SourceLocation());
339
340 static NonLValue GetValue(ValueManager& ValMgr, IntegerLiteral* I);
341
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000342 static NonLValue GetIntTruthValue(ValueManager& ValMgr, bool b);
343
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000344 // Implement isa<T> support.
345 static inline bool classof(const RValue* V) {
346 return V->getBaseKind() >= NonLValueKind;
347 }
348};
349
350class LValue : public RValue {
351protected:
Ted Kremenek516f91b2008-01-31 22:17:03 +0000352 LValue(unsigned SubKind, const void* D) : RValue(const_cast<void*>(D),
353 true, SubKind) {}
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000354
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000355 // Equality operators.
356 NonLValue EQ(ValueManager& ValMgr, const LValue& RHS) const;
357 NonLValue NE(ValueManager& ValMgr, const LValue& RHS) const;
358
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000359public:
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000360 void print(std::ostream& Out) const;
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000361
362 RValue EvalBinaryOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
363 const LValue& RHS) const;
364
365 RValue EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
366
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000367 // Implement isa<T> support.
368 static inline bool classof(const RValue* V) {
Ted Kremenek3271f8d2008-02-07 04:16:04 +0000369 return V->getBaseKind() != NonLValueKind;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000370 }
371};
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000372
373//==------------------------------------------------------------------------==//
374// Subclasses of NonLValue.
375//==------------------------------------------------------------------------==//
376
Ted Kremenek329f8542008-02-05 21:52:21 +0000377namespace nonlval {
378
379 enum Kind { SymbolValKind,
Ted Kremenek9466aa82008-02-05 22:10:48 +0000380 SymIntConstraintValKind,
Ted Kremenek329f8542008-02-05 21:52:21 +0000381 ConcreteIntKind,
382 NumKind };
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000383
Ted Kremenek329f8542008-02-05 21:52:21 +0000384 class SymbolVal : public NonLValue {
385 public:
386 SymbolVal(unsigned SymID)
387 : NonLValue(SymbolValKind,
388 reinterpret_cast<void*>((uintptr_t) SymID)) {}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000389
Ted Kremenek0806acf2008-02-05 23:08:41 +0000390 SymbolID getSymbol() const {
Ted Kremenek329f8542008-02-05 21:52:21 +0000391 return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
392 }
393
394 static inline bool classof(const RValue* V) {
Ted Kremenek9466aa82008-02-05 22:10:48 +0000395 return isa<NonLValue>(V) && V->getSubKind() == SymbolValKind;
396 }
397 };
398
399 class SymIntConstraintVal : public NonLValue {
400 public:
401 SymIntConstraintVal(const SymIntConstraint& C)
402 : NonLValue(SymIntConstraintValKind, reinterpret_cast<const void*>(&C)) {}
403
404 const SymIntConstraint& getConstraint() const {
405 return *reinterpret_cast<SymIntConstraint*>(getRawPtr());
406 }
407
408 static inline bool classof(const RValue* V) {
409 return isa<NonLValue>(V) && V->getSubKind() == SymIntConstraintValKind;
410 }
Ted Kremenek329f8542008-02-05 21:52:21 +0000411 };
412
413 class ConcreteInt : public NonLValue {
414 public:
415 ConcreteInt(const llvm::APSInt& V) : NonLValue(ConcreteIntKind, &V) {}
416
417 const llvm::APSInt& getValue() const {
418 return *static_cast<llvm::APSInt*>(getRawPtr());
419 }
420
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000421 // Transfer functions for binary/unary operations on ConcreteInts.
422 ConcreteInt EvalBinaryOp(ValueManager& ValMgr,
423 BinaryOperator::Opcode Op,
424 const ConcreteInt& RHS) const;
Ted Kremenek329f8542008-02-05 21:52:21 +0000425
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000426 ConcreteInt EvalComplement(ValueManager& ValMgr) const;
427 ConcreteInt EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
Ted Kremenek329f8542008-02-05 21:52:21 +0000428
429 // Implement isa<T> support.
430 static inline bool classof(const RValue* V) {
Ted Kremenek9466aa82008-02-05 22:10:48 +0000431 return isa<NonLValue>(V) && V->getSubKind() == ConcreteIntKind;
Ted Kremenek329f8542008-02-05 21:52:21 +0000432 }
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000433
434 static inline bool classof(const NonLValue* V) {
435 return V->getSubKind() == ConcreteIntKind;
436 }
Ted Kremenek329f8542008-02-05 21:52:21 +0000437 };
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000438
Ted Kremenek329f8542008-02-05 21:52:21 +0000439} // end namespace clang::nonlval
Ted Kremenek516f91b2008-01-31 22:17:03 +0000440
441//==------------------------------------------------------------------------==//
442// Subclasses of LValue.
443//==------------------------------------------------------------------------==//
444
Ted Kremenek329f8542008-02-05 21:52:21 +0000445namespace lval {
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000446
Ted Kremenek329f8542008-02-05 21:52:21 +0000447 enum Kind { SymbolValKind,
448 DeclValKind,
449 ConcreteIntKind,
450 NumKind };
Ted Kremenek516f91b2008-01-31 22:17:03 +0000451
Ted Kremenek329f8542008-02-05 21:52:21 +0000452 class SymbolVal : public LValue {
453 public:
454 SymbolVal(unsigned SymID)
455 : LValue(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
456
Ted Kremenek0806acf2008-02-05 23:08:41 +0000457 SymbolID getSymbol() const {
Ted Kremenek329f8542008-02-05 21:52:21 +0000458 return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
459 }
460
461 static inline bool classof(const RValue* V) {
Ted Kremenek8158a0e2008-02-11 23:12:59 +0000462 return isa<LValue>(V) && V->getSubKind() == SymbolValKind;
Ted Kremenek329f8542008-02-05 21:52:21 +0000463 }
464 };
Ted Kremenek0806acf2008-02-05 23:08:41 +0000465
Ted Kremenek329f8542008-02-05 21:52:21 +0000466 class DeclVal : public LValue {
467 public:
468 DeclVal(const ValueDecl* vd) : LValue(DeclValKind,vd) {}
469
470 ValueDecl* getDecl() const {
471 return static_cast<ValueDecl*>(getRawPtr());
472 }
473
474 inline bool operator==(const DeclVal& R) const {
475 return getDecl() == R.getDecl();
476 }
477
478 inline bool operator!=(const DeclVal& R) const {
479 return getDecl() != R.getDecl();
480 }
481
482 // Implement isa<T> support.
483 static inline bool classof(const RValue* V) {
Ted Kremenek8158a0e2008-02-11 23:12:59 +0000484 return isa<LValue>(V) && V->getSubKind() == DeclValKind;
Ted Kremenek329f8542008-02-05 21:52:21 +0000485 }
486 };
Ted Kremenek516f91b2008-01-31 22:17:03 +0000487
Ted Kremenek329f8542008-02-05 21:52:21 +0000488 class ConcreteInt : public LValue {
489 public:
490 ConcreteInt(const llvm::APSInt& V) : LValue(ConcreteIntKind, &V) {}
491
492 const llvm::APSInt& getValue() const {
493 return *static_cast<llvm::APSInt*>(getRawPtr());
494 }
495
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000496
497 // Transfer functions for binary/unary operations on ConcreteInts.
498 ConcreteInt EvalBinaryOp(ValueManager& ValMgr,
499 BinaryOperator::Opcode Op,
500 const ConcreteInt& RHS) const;
501
Ted Kremenek329f8542008-02-05 21:52:21 +0000502 // Implement isa<T> support.
503 static inline bool classof(const RValue* V) {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000504 return isa<LValue>(V) && V->getSubKind() == ConcreteIntKind;
505 }
506
507 static inline bool classof(const LValue* V) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000508 return V->getSubKind() == ConcreteIntKind;
509 }
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000510
Ted Kremenek329f8542008-02-05 21:52:21 +0000511 };
512} // end clang::lval namespace
Ted Kremenek516f91b2008-01-31 22:17:03 +0000513
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000514
515} // end clang namespace
516
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000517#endif