SVals.h revision 0e470a5326ccf2f6a7c3d12b2aa54a7af2292837
1a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//== RValues.h - Abstract RValues for Path-Sens. Value Tracking -*- C++ -*--==//
2a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//
3a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//                     The LLVM Compiler Infrastructure
4a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//
5a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// This file is distributed under the University of Illinois Open Source
6a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// License. See LICENSE.TXT for details.
7a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//
8a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===//
9a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//
10843e934ba8c6ebc00d2f6969a50af7074597e8e3Gabor Greif//  This file defines RVal, LVal, and NonLVal, classes that represent
11a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//  abstract r-values for use with path-sensitive value tracking.
12a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//
13a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===//
14a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
15a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H
16a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#define LLVM_CLANG_ANALYSIS_RVALUE_H
17a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
18240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
19a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#include "llvm/Support/Casting.h"
20d131c4ff6133c691f91d8a82e7197d97b187425fTed Kremenek
210f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremenek//==------------------------------------------------------------------------==//
22aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek//  Base RVal types.
23a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//==------------------------------------------------------------------------==//
24a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
250f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremeneknamespace clang {
260f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremenek
27aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass RVal {
28a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
294a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek  enum BaseKind { UndefinedKind, UnknownKind, LValKind, NonLValKind };
30aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  enum { BaseBits = 2, BaseMask = 0x3 };
31a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
3290e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenekprotected:
33a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  void* Data;
34a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  unsigned Kind;
35a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
36a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
37aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  RVal(const void* d, bool isLVal, unsigned ValKind)
38a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  : Data(const_cast<void*>(d)),
39aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    Kind((isLVal ? LValKind : NonLValKind) | (ValKind << BaseBits)) {}
40a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
4105a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek  explicit RVal(BaseKind k, void* D = NULL)
4205a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek    : Data(D), Kind(k) {}
43a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
44a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
45aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  ~RVal() {};
46a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
47aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  /// BufferTy - A temporary buffer to hold a set of RVals.
48aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  typedef llvm::SmallVector<RVal,5> BufferTy;
49a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
50aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline unsigned getRawKind() const { return Kind; }
51aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
52aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
53a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
54aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline void Profile(llvm::FoldingSetNodeID& ID) const {
55a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek    ID.AddInteger((unsigned) getRawKind());
56a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek    ID.AddPointer(reinterpret_cast<void*>(Data));
57a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
58a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
59aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool operator==(const RVal& R) const {
60aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() == R.getRawKind() && Data == R.Data;
61a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
62a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
63dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek
64dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek  inline bool operator!=(const RVal& R) const {
65dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek    return !(*this == R);
66dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek  }
67dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek
68d763eb91aab5bdecd11825fadb35d6d8cc905f63Ted Kremenek  static RVal GetSymbolValue(SymbolManager& SymMgr, VarDecl *D);
69a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
70aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool isUnknown() const {
71aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() == UnknownKind;
72aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
73aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
744a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek  inline bool isUndef() const {
754a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek    return getRawKind() == UndefinedKind;
76aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
77aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
784a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek  inline bool isUnknownOrUndef() const {
79aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() <= UnknownKind;
80aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
81cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
82aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool isValid() const {
83aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() > UnknownKind;
84aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
85a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
86a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  void print(std::ostream& OS) const;
87d8e9f0dc737133d4e8342f39389064620f5a7f8fTed Kremenek  void printStdErr() const;
88a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
8990e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek  typedef const SymbolID* symbol_iterator;
9090e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek  symbol_iterator symbol_begin() const;
9190e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek  symbol_iterator symbol_end() const;
9290e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek
939b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek  static RVal MakeVal(BasicValueFactory& BasicVals, DeclRefExpr* E);
949b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek
95a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
96aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal*) { return true; }
97a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
98a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
99aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass UnknownVal : public RVal {
100a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
101aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  UnknownVal() : RVal(UnknownKind) {}
102a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
103aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
1042203118815997a0efcf19217e057bd20e33303e7Ted Kremenek    return V->getBaseKind() == UnknownKind;
105a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
106a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
107a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1084a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenekclass UndefinedVal : public RVal {
109a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
1104a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek  UndefinedVal() : RVal(UndefinedKind) {}
1114a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek  UndefinedVal(void* D) : RVal(UndefinedKind, D) {}
112a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
113aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
1144a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek    return V->getBaseKind() == UndefinedKind;
11505a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek  }
11605a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek
11705a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek  void* getData() const { return Data; }
118a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
119a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
120aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass NonLVal : public RVal {
121a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
122aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  NonLVal(unsigned SubKind, const void* d) : RVal(d, false, SubKind) {}
123a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
124a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
125a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  void print(std::ostream& Out) const;
126a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
127aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Utility methods to create NonLVals.
128240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek  static NonLVal MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T);
129a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
130240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek  static NonLVal MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I);
131a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek
132240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek  static NonLVal MakeIntTruthVal(BasicValueFactory& BasicVals, bool b);
133cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
134a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
135aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
136aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == NonLValKind;
137a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
138a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
139a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
140aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass LVal : public RVal {
141a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
142aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  LVal(unsigned SubKind, const void* D)
143aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    : RVal(const_cast<void*>(D), true, SubKind) {}
144aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
145a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Equality operators.
146240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek  NonLVal EQ(BasicValueFactory& BasicVals, const LVal& R) const;
147240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek  NonLVal NE(BasicValueFactory& BasicVals, const LVal& R) const;
148a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
149cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenekpublic:
150d131c4ff6133c691f91d8a82e7197d97b187425fTed Kremenek  void print(std::ostream& Out) const;
151d59cccc0b6cd4485897526699fe98514805c1883Ted Kremenek
152aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static LVal MakeVal(AddrLabelExpr* E);
1532a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
154a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek  static LVal MakeVal(StringLiteral* S);
155a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek
156a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
157aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
158aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == LValKind;
159a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
1600e470a5326ccf2f6a7c3d12b2aa54a7af2292837Ted Kremenek
1610e470a5326ccf2f6a7c3d12b2aa54a7af2292837Ted Kremenek  static inline bool IsLValType(QualType T) {
1620e470a5326ccf2f6a7c3d12b2aa54a7af2292837Ted Kremenek    return T->isPointerType() || T->isObjCQualifiedIdType();
1630e470a5326ccf2f6a7c3d12b2aa54a7af2292837Ted Kremenek  }
164a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
165a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
166a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//==------------------------------------------------------------------------==//
167aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek//  Subclasses of NonLVal.
168a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//==------------------------------------------------------------------------==//
169a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
170329f854f217d72594a3ec5572eba6320f81a5efaTed Kremeneknamespace nonlval {
171329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
1720fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenekenum Kind { ConcreteIntKind, SymbolValKind, SymIntConstraintValKind,
1730fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek            LValAsIntegerKind };
174329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
175aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass SymbolVal : public NonLVal {
176aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
177aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  SymbolVal(unsigned SymID)
178aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    : NonLVal(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
179aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
180aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  SymbolID getSymbol() const {
181aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return (SymbolID) reinterpret_cast<uintptr_t>(Data);
182aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
183aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
184aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
185aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == NonLValKind &&
186aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == SymbolValKind;
187aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
188aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
189aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const NonLVal* V) {
190aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == SymbolValKind;
191aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
192aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
1939466aa8cf38aa8e87fe3e2cd8005fc245d04f9b7Ted Kremenek
194aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass SymIntConstraintVal : public NonLVal {
195aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
196aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  SymIntConstraintVal(const SymIntConstraint& C)
197aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    : NonLVal(SymIntConstraintValKind, reinterpret_cast<const void*>(&C)) {}
198329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
199aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const SymIntConstraint& getConstraint() const {
200aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return *reinterpret_cast<SymIntConstraint*>(Data);
201aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
202aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
203aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
204aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == NonLValKind &&
205aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == SymIntConstraintValKind;
206aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
207aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
208aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const NonLVal* V) {
209aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == SymIntConstraintValKind;
210aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
211aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
212aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
213aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass ConcreteInt : public NonLVal {
214aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
215aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  ConcreteInt(const llvm::APSInt& V) : NonLVal(ConcreteIntKind, &V) {}
216aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
217aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const llvm::APSInt& getValue() const {
218aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return *static_cast<llvm::APSInt*>(Data);
219aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
220aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
221aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Transfer functions for binary/unary operations on ConcreteInts.
222240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek  RVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
2238cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek                 const ConcreteInt& R) const;
224aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
225240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek  ConcreteInt EvalComplement(BasicValueFactory& BasicVals) const;
226aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
227240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek  ConcreteInt EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const;
228aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
229aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
230aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
231aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == NonLValKind &&
232aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == ConcreteIntKind;
233aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
234aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
235aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const NonLVal* V) {
236aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == ConcreteIntKind;
237aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
238aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
239a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
2400fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenekclass LValAsInteger : public NonLVal {
241718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  LValAsInteger(const std::pair<RVal, uintptr_t>& data) :
242718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    NonLVal(LValAsIntegerKind, &data) {
243718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek      assert (isa<LVal>(data.first));
244718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    }
2450fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
2460fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenekpublic:
2470fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
2480fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  LVal getLVal() const {
249718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    return cast<LVal>(((std::pair<RVal, uintptr_t>*) Data)->first);
2500fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
2510fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
2520fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  const LVal& getPersistentLVal() const {
253718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    const RVal& V = ((std::pair<RVal, uintptr_t>*) Data)->first;
254718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    return cast<LVal>(V);
2550fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
2560fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
2570fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  unsigned getNumBits() const {
2580fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek    return ((std::pair<RVal, unsigned>*) Data)->second;
2590fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
2600fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
2610fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  // Implement isa<T> support.
2620fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  static inline bool classof(const RVal* V) {
2630fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek    return V->getBaseKind() == NonLValKind &&
2640fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek           V->getSubKind() == LValAsIntegerKind;
2650fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
2660fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
2670fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  static inline bool classof(const NonLVal* V) {
2680fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek    return V->getSubKind() == LValAsIntegerKind;
2690fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
2700fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
2710fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  static inline LValAsInteger Make(BasicValueFactory& Vals, LVal V,
2720fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek                                   unsigned Bits) {
273718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    return LValAsInteger(Vals.getPersistentRValWithData(V, Bits));
2740fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
2750fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek};
2760fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
277329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek} // end namespace clang::nonlval
278516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
279516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek//==------------------------------------------------------------------------==//
280aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek//  Subclasses of LVal.
281516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek//==------------------------------------------------------------------------==//
282516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
283329f854f217d72594a3ec5572eba6320f81a5efaTed Kremeneknamespace lval {
284516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
285aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekenum Kind { SymbolValKind, GotoLabelKind, DeclValKind, FuncValKind,
2864d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek            ConcreteIntKind, StringLiteralValKind, FieldOffsetKind,
2874d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek            ArrayOffsetKind };
288aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
289aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass SymbolVal : public LVal {
290aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
291aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  SymbolVal(unsigned SymID)
292aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  : LVal(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
2932a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
294aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  SymbolID getSymbol() const {
295aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return (SymbolID) reinterpret_cast<uintptr_t>(Data);
296aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
297aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
298aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
299aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == LValKind &&
300aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == SymbolValKind;
301aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
302aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
303aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const LVal* V) {
304aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == SymbolValKind;
305aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
306aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
307329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
308aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass GotoLabel : public LVal {
309aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
310aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  GotoLabel(LabelStmt* Label) : LVal(GotoLabelKind, Label) {}
311aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
312aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  LabelStmt* getLabel() const {
313aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return static_cast<LabelStmt*>(Data);
314aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
315aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
316aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
317aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == LValKind &&
318aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == GotoLabelKind;
319aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
320aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
321aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const LVal* V) {
322aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == GotoLabelKind;
323aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
324aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
325aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
326cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
327aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass DeclVal : public LVal {
328aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
329aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  DeclVal(const VarDecl* vd) : LVal(DeclValKind, vd) {}
330aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
331aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  VarDecl* getDecl() const {
332aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return static_cast<VarDecl*>(Data);
333aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
334aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
335aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool operator==(const DeclVal& R) const {
336aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getDecl() == R.getDecl();
337aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
338aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
339aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool operator!=(const DeclVal& R) const {
340aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getDecl() != R.getDecl();
341aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
342aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
343aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
344aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
345aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == LValKind &&
346aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == DeclValKind;
347aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
348aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
349aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const LVal* V) {
350aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == DeclValKind;
351aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
352aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
353aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
354aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass FuncVal : public LVal {
355aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
356aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  FuncVal(const FunctionDecl* fd) : LVal(FuncValKind, fd) {}
357aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
358aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  FunctionDecl* getDecl() const {
359aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return static_cast<FunctionDecl*>(Data);
360aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
361aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
362aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool operator==(const FuncVal& R) const {
363aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getDecl() == R.getDecl();
364aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
365aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
366aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool operator!=(const FuncVal& R) const {
367aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getDecl() != R.getDecl();
368aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
369aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
370aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
371aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
372aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == LValKind &&
373aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == FuncValKind;
374aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
375aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
376aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const LVal* V) {
377aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == FuncValKind;
378aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
379aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
380aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
381aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass ConcreteInt : public LVal {
382aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
383aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  ConcreteInt(const llvm::APSInt& V) : LVal(ConcreteIntKind, &V) {}
384aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
385aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const llvm::APSInt& getValue() const {
386aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return *static_cast<llvm::APSInt*>(Data);
387aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
3882a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
389aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Transfer functions for binary/unary operations on ConcreteInts.
390240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek  RVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
3918cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek                 const ConcreteInt& R) const;
392aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
393aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
394aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
395aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == LValKind &&
396aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == ConcreteIntKind;
397aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
398aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
399aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const LVal* V) {
400aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == ConcreteIntKind;
401aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
402aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
403aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
404a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenekclass StringLiteralVal : public LVal {
405a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenekpublic:
406a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek  StringLiteralVal(StringLiteral* L) : LVal(StringLiteralValKind, L) {}
407a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek
408a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek  StringLiteral* getLiteral() const { return (StringLiteral*) Data; }
409a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek
410a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek  // Implement isa<T> support.
411a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek  static inline bool classof(const RVal* V) {
412a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek    return V->getBaseKind() == LValKind &&
413a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek           V->getSubKind() == StringLiteralValKind;
414a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek  }
415a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek
416a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek  static inline bool classof(const LVal* V) {
417a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek    return V->getSubKind() == StringLiteralValKind;
418a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek  }
419a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek};
420718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek
421718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenekclass FieldOffset : public LVal {
422718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  FieldOffset(const std::pair<RVal, uintptr_t>& data)
4234d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    : LVal(FieldOffsetKind, &data) {}
424718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek
425718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenekpublic:
426718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek
427718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  LVal getBase() const {
428718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    return reinterpret_cast<const std::pair<LVal,uintptr_t>*> (Data)->first;
429718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  }
430718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek
431718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  const LVal& getPersistentBase() const {
432718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    return reinterpret_cast<const std::pair<LVal,uintptr_t>*> (Data)->first;
433718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  }
434718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek
435718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek
436718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  FieldDecl* getFieldDecl() const {
437718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    return (FieldDecl*)
438718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek      reinterpret_cast<const std::pair<LVal,uintptr_t>*> (Data)->second;
439718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  }
440718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek
441718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  // Implement isa<T> support.
442718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  static inline bool classof(const RVal* V) {
443718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    return V->getBaseKind() == LValKind &&
444718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek           V->getSubKind() == FieldOffsetKind;
445718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  }
446718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek
447718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  static inline bool classof(const LVal* V) {
448718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    return V->getSubKind() == FieldOffsetKind;
449718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  }
450718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek
451718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  static inline RVal Make(BasicValueFactory& Vals, RVal Base, FieldDecl* D) {
452718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek
453718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    if (Base.isUnknownOrUndef())
454718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek      return Base;
455a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek
456718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    return FieldOffset(Vals.getPersistentRValWithData(cast<LVal>(Base),
457718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek                                                      (uintptr_t) D));
458718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  }
459718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek};
460a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek
4614d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenekclass ArrayOffset : public LVal {
4624d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  ArrayOffset(const std::pair<RVal,RVal>& data) : LVal(ArrayOffsetKind,&data) {}
4634d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenekpublic:
4644d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
4654d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  LVal getBase() const {
4664d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    return reinterpret_cast<const std::pair<LVal,RVal>*> (Data)->first;
4674d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  }
4684d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
4694d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  const LVal& getPersistentBase() const {
4704d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    return reinterpret_cast<const std::pair<LVal,RVal>*> (Data)->first;
4714d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  }
4724d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
4734d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  RVal getOffset() const {
4744d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    return reinterpret_cast<const std::pair<LVal,RVal>*> (Data)->second;
4754d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  }
4764d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
4774d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  const RVal& getPersistentOffset() const {
4784d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    return reinterpret_cast<const std::pair<LVal,RVal>*> (Data)->second;
4794d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  }
4804d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
4814d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
4824d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  // Implement isa<T> support.
4834d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  static inline bool classof(const RVal* V) {
4844d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    return V->getBaseKind() == LValKind &&
4854d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek           V->getSubKind() == ArrayOffsetKind;
4864d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  }
4874d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
4884d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  static inline bool classof(const LVal* V) {
4894d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    return V->getSubKind() == ArrayOffsetKind;
4904d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  }
4914d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
4924d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  static inline RVal Make(BasicValueFactory& Vals, RVal Base, RVal Offset) {
4934d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
4944d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    if (Base.isUnknownOrUndef())
4954d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek      return Base;
4964d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
4974d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    if (Offset.isUndef())
4984d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek      return Offset;
4994d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
5004d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    return ArrayOffset(Vals.getPersistentRValPair(cast<LVal>(Base), Offset));
5014d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  }
5024d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek};
5034d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
504aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek} // end clang::lval namespace
505a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} // end clang namespace
506a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
507a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#endif
508