SVals.h revision dc3936b0557ce7377905b387d3c69bc8fa484b9c
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//
10aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek//  This files 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
18d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek#include "clang/Analysis/PathSensitive/ValueManager.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:
29aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  enum BaseKind { UninitializedKind, 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
41aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  explicit RVal(BaseKind k)
42a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek    : Data(0), 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
68aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static RVal GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl *D);
69a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
70aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool isUnknown() const {
71aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() == UnknownKind;
72aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
73aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
74aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool isUninit() const {
75aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() == UninitializedKind;
76aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
77aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
78aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool isUnknownOrUninit() 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
93a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
94aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal*) { return true; }
95a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
96a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
97aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass UnknownVal : public RVal {
98a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
99aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  UnknownVal() : RVal(UnknownKind) {}
100a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
101aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
1022203118815997a0efcf19217e057bd20e33303e7Ted Kremenek    return V->getBaseKind() == UnknownKind;
103a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
104a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
105a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
106aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass UninitializedVal : public RVal {
107a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
108aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  UninitializedVal() : RVal(UninitializedKind) {}
109a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
110aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
111a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek    return V->getBaseKind() == UninitializedKind;
112a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
113a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
114a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
115aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass NonLVal : public RVal {
116a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
117aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  NonLVal(unsigned SubKind, const void* d) : RVal(d, false, SubKind) {}
118a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
119a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
120a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  void print(std::ostream& Out) const;
121a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
122aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Utility methods to create NonLVals.
123aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static NonLVal MakeVal(ValueManager& ValMgr, uint64_t X, QualType T,
124aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek                         SourceLocation Loc = SourceLocation());
125a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
126aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static NonLVal MakeVal(ValueManager& ValMgr, IntegerLiteral* I);
127a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
128aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static NonLVal MakeIntTruthVal(ValueManager& ValMgr, bool b);
129cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
130a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
131aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
132aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == NonLValKind;
133a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
134a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
135a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
136aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass LVal : public RVal {
137a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
138aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  LVal(unsigned SubKind, const void* D)
139aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    : RVal(const_cast<void*>(D), true, SubKind) {}
140aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
141a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Equality operators.
142aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  NonLVal EQ(ValueManager& ValMgr, const LVal& R) const;
143aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  NonLVal NE(ValueManager& ValMgr, const LVal& R) const;
144a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
145cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenekpublic:
146d131c4ff6133c691f91d8a82e7197d97b187425fTed Kremenek  void print(std::ostream& Out) const;
147d59cccc0b6cd4485897526699fe98514805c1883Ted Kremenek
148aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static LVal MakeVal(AddrLabelExpr* E);
1492a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
150a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
151aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
152aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == LValKind;
153a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
154a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
155a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
156a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//==------------------------------------------------------------------------==//
157aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek//  Subclasses of NonLVal.
158a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//==------------------------------------------------------------------------==//
159a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
160329f854f217d72594a3ec5572eba6320f81a5efaTed Kremeneknamespace nonlval {
161329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
162aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekenum Kind { ConcreteIntKind, SymbolValKind, SymIntConstraintValKind };
163329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
164aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass SymbolVal : public NonLVal {
165aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
166aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  SymbolVal(unsigned SymID)
167aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    : NonLVal(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
168aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
169aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  SymbolID getSymbol() const {
170aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return (SymbolID) reinterpret_cast<uintptr_t>(Data);
171aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
172aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
173aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
174aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == NonLValKind &&
175aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == SymbolValKind;
176aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
177aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
178aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const NonLVal* V) {
179aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == SymbolValKind;
180aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
181aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
1829466aa8cf38aa8e87fe3e2cd8005fc245d04f9b7Ted Kremenek
183aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass SymIntConstraintVal : public NonLVal {
184aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
185aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  SymIntConstraintVal(const SymIntConstraint& C)
186aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    : NonLVal(SymIntConstraintValKind, reinterpret_cast<const void*>(&C)) {}
187329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
188aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const SymIntConstraint& getConstraint() const {
189aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return *reinterpret_cast<SymIntConstraint*>(Data);
190aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
191aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
192aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
193aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == NonLValKind &&
194aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == SymIntConstraintValKind;
195aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
196aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
197aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const NonLVal* V) {
198aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == SymIntConstraintValKind;
199aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
200aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
201aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
202aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass ConcreteInt : public NonLVal {
203aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
204aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  ConcreteInt(const llvm::APSInt& V) : NonLVal(ConcreteIntKind, &V) {}
205aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
206aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const llvm::APSInt& getValue() const {
207aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return *static_cast<llvm::APSInt*>(Data);
208aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
209aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
210aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Transfer functions for binary/unary operations on ConcreteInts.
211aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  ConcreteInt EvalBinOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
212aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek                        const ConcreteInt& R) const;
213aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
214aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  ConcreteInt EvalComplement(ValueManager& ValMgr) const;
215aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
216aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  ConcreteInt EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
217aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
218aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
219aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
220aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == NonLValKind &&
221aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == ConcreteIntKind;
222aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
223aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
224aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const NonLVal* V) {
225aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == ConcreteIntKind;
226aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
227aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
228a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
229329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek} // end namespace clang::nonlval
230516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
231516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek//==------------------------------------------------------------------------==//
232aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek//  Subclasses of LVal.
233516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek//==------------------------------------------------------------------------==//
234516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
235329f854f217d72594a3ec5572eba6320f81a5efaTed Kremeneknamespace lval {
236516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
237aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekenum Kind { SymbolValKind, GotoLabelKind, DeclValKind, FuncValKind,
238aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek            ConcreteIntKind };
239aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
240aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass SymbolVal : public LVal {
241aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
242aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  SymbolVal(unsigned SymID)
243aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  : LVal(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
2442a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
245aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  SymbolID getSymbol() const {
246aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return (SymbolID) reinterpret_cast<uintptr_t>(Data);
247aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
248aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
249aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
250aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == LValKind &&
251aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == SymbolValKind;
252aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
253aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
254aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const LVal* V) {
255aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == SymbolValKind;
256aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
257aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
258329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
259aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass GotoLabel : public LVal {
260aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
261aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  GotoLabel(LabelStmt* Label) : LVal(GotoLabelKind, Label) {}
262aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
263aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  LabelStmt* getLabel() const {
264aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return static_cast<LabelStmt*>(Data);
265aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
266aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
267aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
268aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == LValKind &&
269aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == GotoLabelKind;
270aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
271aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
272aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const LVal* V) {
273aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == GotoLabelKind;
274aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
275aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
276aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
277cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
278aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass DeclVal : public LVal {
279aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
280aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  DeclVal(const VarDecl* vd) : LVal(DeclValKind, vd) {}
281aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
282aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  VarDecl* getDecl() const {
283aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return static_cast<VarDecl*>(Data);
284aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
285aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
286aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool operator==(const DeclVal& R) const {
287aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getDecl() == R.getDecl();
288aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
289aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
290aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool operator!=(const DeclVal& R) const {
291aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getDecl() != R.getDecl();
292aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
293aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
294aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
295aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
296aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == LValKind &&
297aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == DeclValKind;
298aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
299aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
300aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const LVal* V) {
301aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == DeclValKind;
302aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
303aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
304aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
305aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass FuncVal : public LVal {
306aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
307aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  FuncVal(const FunctionDecl* fd) : LVal(FuncValKind, fd) {}
308aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
309aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  FunctionDecl* getDecl() const {
310aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return static_cast<FunctionDecl*>(Data);
311aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
312aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
313aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool operator==(const FuncVal& R) const {
314aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getDecl() == R.getDecl();
315aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
316aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
317aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool operator!=(const FuncVal& R) const {
318aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getDecl() != R.getDecl();
319aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
320aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
321aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
322aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
323aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == LValKind &&
324aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == FuncValKind;
325aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
326aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
327aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const LVal* V) {
328aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == FuncValKind;
329aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
330aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
331aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
332aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass ConcreteInt : public LVal {
333aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
334aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  ConcreteInt(const llvm::APSInt& V) : LVal(ConcreteIntKind, &V) {}
335aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
336aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const llvm::APSInt& getValue() const {
337aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return *static_cast<llvm::APSInt*>(Data);
338aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
3392a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
340aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Transfer functions for binary/unary operations on ConcreteInts.
341aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  ConcreteInt EvalBinOp(ValueManager& ValMgr,
342aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek                           BinaryOperator::Opcode Op,
343aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek                           const ConcreteInt& R) const;
344aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
345aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
346aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const RVal* V) {
347aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getBaseKind() == LValKind &&
348aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == ConcreteIntKind;
349aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
350aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
351aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  static inline bool classof(const LVal* V) {
352aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == ConcreteIntKind;
353aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
354aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
355aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
356aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek} // end clang::lval namespace
357a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} // end clang namespace
358a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
359a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#endif
360