blob: ffc5e4a57d4630e25e418a1c7d59660d0f9629d6 [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 Kremenek2a502572008-02-12 21:37:56 +0000367 static LValue GetValue(AddrLabelExpr* E);
368
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000369 // Implement isa<T> support.
370 static inline bool classof(const RValue* V) {
Ted Kremenek3271f8d2008-02-07 04:16:04 +0000371 return V->getBaseKind() != NonLValueKind;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000372 }
373};
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000374
375//==------------------------------------------------------------------------==//
376// Subclasses of NonLValue.
377//==------------------------------------------------------------------------==//
378
Ted Kremenek329f8542008-02-05 21:52:21 +0000379namespace nonlval {
380
381 enum Kind { SymbolValKind,
Ted Kremenek9466aa82008-02-05 22:10:48 +0000382 SymIntConstraintValKind,
Ted Kremenek329f8542008-02-05 21:52:21 +0000383 ConcreteIntKind,
384 NumKind };
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000385
Ted Kremenek329f8542008-02-05 21:52:21 +0000386 class SymbolVal : public NonLValue {
387 public:
388 SymbolVal(unsigned SymID)
389 : NonLValue(SymbolValKind,
390 reinterpret_cast<void*>((uintptr_t) SymID)) {}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000391
Ted Kremenek0806acf2008-02-05 23:08:41 +0000392 SymbolID getSymbol() const {
Ted Kremenek329f8542008-02-05 21:52:21 +0000393 return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
394 }
395
396 static inline bool classof(const RValue* V) {
Ted Kremenek9466aa82008-02-05 22:10:48 +0000397 return isa<NonLValue>(V) && V->getSubKind() == SymbolValKind;
398 }
399 };
400
401 class SymIntConstraintVal : public NonLValue {
402 public:
403 SymIntConstraintVal(const SymIntConstraint& C)
404 : NonLValue(SymIntConstraintValKind, reinterpret_cast<const void*>(&C)) {}
405
406 const SymIntConstraint& getConstraint() const {
407 return *reinterpret_cast<SymIntConstraint*>(getRawPtr());
408 }
409
410 static inline bool classof(const RValue* V) {
411 return isa<NonLValue>(V) && V->getSubKind() == SymIntConstraintValKind;
412 }
Ted Kremenek329f8542008-02-05 21:52:21 +0000413 };
414
415 class ConcreteInt : public NonLValue {
416 public:
417 ConcreteInt(const llvm::APSInt& V) : NonLValue(ConcreteIntKind, &V) {}
418
419 const llvm::APSInt& getValue() const {
420 return *static_cast<llvm::APSInt*>(getRawPtr());
421 }
422
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000423 // Transfer functions for binary/unary operations on ConcreteInts.
424 ConcreteInt EvalBinaryOp(ValueManager& ValMgr,
425 BinaryOperator::Opcode Op,
426 const ConcreteInt& RHS) const;
Ted Kremenek329f8542008-02-05 21:52:21 +0000427
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000428 ConcreteInt EvalComplement(ValueManager& ValMgr) const;
429 ConcreteInt EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
Ted Kremenek329f8542008-02-05 21:52:21 +0000430
431 // Implement isa<T> support.
432 static inline bool classof(const RValue* V) {
Ted Kremenek9466aa82008-02-05 22:10:48 +0000433 return isa<NonLValue>(V) && V->getSubKind() == ConcreteIntKind;
Ted Kremenek329f8542008-02-05 21:52:21 +0000434 }
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000435
436 static inline bool classof(const NonLValue* V) {
437 return V->getSubKind() == ConcreteIntKind;
438 }
Ted Kremenek329f8542008-02-05 21:52:21 +0000439 };
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000440
Ted Kremenek329f8542008-02-05 21:52:21 +0000441} // end namespace clang::nonlval
Ted Kremenek516f91b2008-01-31 22:17:03 +0000442
443//==------------------------------------------------------------------------==//
444// Subclasses of LValue.
445//==------------------------------------------------------------------------==//
446
Ted Kremenek329f8542008-02-05 21:52:21 +0000447namespace lval {
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000448
Ted Kremenek329f8542008-02-05 21:52:21 +0000449 enum Kind { SymbolValKind,
Ted Kremenek2a502572008-02-12 21:37:56 +0000450 GotoLabelKind,
Ted Kremenek329f8542008-02-05 21:52:21 +0000451 DeclValKind,
452 ConcreteIntKind,
453 NumKind };
Ted Kremenek516f91b2008-01-31 22:17:03 +0000454
Ted Kremenek329f8542008-02-05 21:52:21 +0000455 class SymbolVal : public LValue {
456 public:
457 SymbolVal(unsigned SymID)
458 : LValue(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
459
Ted Kremenek0806acf2008-02-05 23:08:41 +0000460 SymbolID getSymbol() const {
Ted Kremenek329f8542008-02-05 21:52:21 +0000461 return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
462 }
463
464 static inline bool classof(const RValue* V) {
Ted Kremenek8158a0e2008-02-11 23:12:59 +0000465 return isa<LValue>(V) && V->getSubKind() == SymbolValKind;
Ted Kremenek2a502572008-02-12 21:37:56 +0000466 }
467
468 static inline bool classof(const LValue* V) {
469 return V->getSubKind() == SymbolValKind;
470 }
Ted Kremenek329f8542008-02-05 21:52:21 +0000471 };
Ted Kremenek0806acf2008-02-05 23:08:41 +0000472
Ted Kremenek2a502572008-02-12 21:37:56 +0000473 class GotoLabel : public LValue {
474 public:
475 GotoLabel(LabelStmt* Label) : LValue(GotoLabelKind, Label) {}
476
477 LabelStmt* getLabel() const {
478 return static_cast<LabelStmt*>(getRawPtr());
479 }
480
481 static inline bool classof(const RValue* V) {
482 return isa<LValue>(V) && V->getSubKind() == GotoLabelKind;
483 }
484
485 static inline bool classof(const LValue* V) {
486 return V->getSubKind() == GotoLabelKind;
487 }
488 };
489
490
Ted Kremenek329f8542008-02-05 21:52:21 +0000491 class DeclVal : public LValue {
492 public:
493 DeclVal(const ValueDecl* vd) : LValue(DeclValKind,vd) {}
494
495 ValueDecl* getDecl() const {
496 return static_cast<ValueDecl*>(getRawPtr());
497 }
498
499 inline bool operator==(const DeclVal& R) const {
500 return getDecl() == R.getDecl();
501 }
502
503 inline bool operator!=(const DeclVal& R) const {
504 return getDecl() != R.getDecl();
505 }
506
507 // Implement isa<T> support.
508 static inline bool classof(const RValue* V) {
Ted Kremenek8158a0e2008-02-11 23:12:59 +0000509 return isa<LValue>(V) && V->getSubKind() == DeclValKind;
Ted Kremenek329f8542008-02-05 21:52:21 +0000510 }
Ted Kremenek2a502572008-02-12 21:37:56 +0000511
512 static inline bool classof(const LValue* V) {
513 return V->getSubKind() == DeclValKind;
514 }
Ted Kremenek329f8542008-02-05 21:52:21 +0000515 };
Ted Kremenek516f91b2008-01-31 22:17:03 +0000516
Ted Kremenek329f8542008-02-05 21:52:21 +0000517 class ConcreteInt : public LValue {
518 public:
519 ConcreteInt(const llvm::APSInt& V) : LValue(ConcreteIntKind, &V) {}
520
521 const llvm::APSInt& getValue() const {
522 return *static_cast<llvm::APSInt*>(getRawPtr());
523 }
524
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000525
526 // Transfer functions for binary/unary operations on ConcreteInts.
527 ConcreteInt EvalBinaryOp(ValueManager& ValMgr,
528 BinaryOperator::Opcode Op,
529 const ConcreteInt& RHS) const;
530
Ted Kremenek329f8542008-02-05 21:52:21 +0000531 // Implement isa<T> support.
532 static inline bool classof(const RValue* V) {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000533 return isa<LValue>(V) && V->getSubKind() == ConcreteIntKind;
534 }
535
536 static inline bool classof(const LValue* V) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000537 return V->getSubKind() == ConcreteIntKind;
538 }
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000539
Ted Kremenek329f8542008-02-05 21:52:21 +0000540 };
541} // end clang::lval namespace
Ted Kremenek2a502572008-02-12 21:37:56 +0000542
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000543} // end clang namespace
544
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000545#endif