SVals.h revision 369f447eded97e6048ced02c0c2be3842f61fc1c
122ab7a4d900ed53285fd0b6720e7b43af84724d8Zhongxing Xu//== SVals.h - Abstract Values for Static Analysis ---------*- 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//
101c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//  This file defines SVal, Loc, and NonLoc, 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
18632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek#include "clang/Analysis/PathSensitive/SymbolManager.h"
19a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#include "llvm/Support/Casting.h"
20632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek#include "llvm/ADT/ImmutableList.h"
21d131c4ff6133c691f91d8a82e7197d97b187425fTed Kremenek
220f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremenek//==------------------------------------------------------------------------==//
231c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//  Base SVal types.
241c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==//
25a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
260f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremeneknamespace clang {
27632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek
28632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenekclass CompoundValData;
29632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenekclass BasicValueFactory;
309e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass MemRegion;
31a1718c78770db93d1b762620f07728a56786f2aeZhongxing Xuclass MemRegionManager;
329e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass GRStateManager;
339e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek
341c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SVal {
35a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
361c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  enum BaseKind { UndefinedKind, UnknownKind, LocKind, NonLocKind };
37aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  enum { BaseBits = 2, BaseMask = 0x3 };
38a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
3990e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenekprotected:
40a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  void* Data;
41a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  unsigned Kind;
42a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
43a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
441c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  SVal(const void* d, bool isLoc, unsigned ValKind)
45a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  : Data(const_cast<void*>(d)),
461c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
47a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
481c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  explicit SVal(BaseKind k, void* D = NULL)
4905a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek    : Data(D), Kind(k) {}
50a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
51a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
526764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  SVal() : Data(0), Kind(0) {}
531c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  ~SVal() {};
54a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
551c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  /// BufferTy - A temporary buffer to hold a set of SVals.
561c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  typedef llvm::SmallVector<SVal,5> BufferTy;
57a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
58aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline unsigned getRawKind() const { return Kind; }
59aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
60aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
61a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
62aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline void Profile(llvm::FoldingSetNodeID& ID) const {
63a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek    ID.AddInteger((unsigned) getRawKind());
64a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek    ID.AddPointer(reinterpret_cast<void*>(Data));
65a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
666764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
671c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  inline bool operator==(const SVal& R) const {
68aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() == R.getRawKind() && Data == R.Data;
69a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
7094c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek
711c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  inline bool operator!=(const SVal& R) const {
72dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek    return !(*this == R);
73dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek  }
744193eca10ce0cc8b2dae887e935a43b26f492b5bZhongxing Xu
75aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool isUnknown() const {
76aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() == UnknownKind;
77aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
78aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
794a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek  inline bool isUndef() const {
804a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek    return getRawKind() == UndefinedKind;
81aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
82aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
834a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek  inline bool isUnknownOrUndef() const {
84aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() <= UnknownKind;
85aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
86cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
87aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool isValid() const {
88aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() > UnknownKind;
89aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
90a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
9140fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek  bool isZeroConstant() const;
92369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu
93369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu  /// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a
94369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu  /// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl.
95369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu  /// Otherwise return 0.
96369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu  const FunctionDecl* getAsFunctionDecl() const;
9740fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek
9894c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  /// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
99e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  ///  wraps a symbol, return that SymbolRef.  Otherwise return a SymbolData*
10094c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  SymbolRef getAsLocSymbol() const;
10194c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek
10294c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  /// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
10394c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  ///  Otherwise return a SymbolRef where 'isValid()' returns false.
10494c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  SymbolRef getAsSymbol() const;
105e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek
106e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
107e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  ///  return that expression.  Otherwise return NULL.
108e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  const SymExpr *getAsSymbolicExpression() const;
10994c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek
110a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  void print(std::ostream& OS) const;
1119012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu  void print(llvm::raw_ostream& OS) const;
112d8e9f0dc737133d4e8342f39389064620f5a7f8fTed Kremenek  void printStdErr() const;
113e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek
114e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  // Iterators.
1150d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek  class symbol_iterator {
116e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    llvm::SmallVector<const SymExpr*, 5> itr;
117e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    void expand();
1180d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek  public:
119e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    symbol_iterator() {}
120e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    symbol_iterator(const SymExpr* SE);
1210d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek
122e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    symbol_iterator& operator++();
123e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    SymbolRef operator*();
1240d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek
125e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    bool operator==(const symbol_iterator& X) const;
126e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    bool operator!=(const symbol_iterator& X) const;
1270d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek  };
1280d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek
129e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  symbol_iterator symbol_begin() const {
130e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    const SymExpr *SE = getAsSymbolicExpression();
131e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    if (SE)
132e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek      return symbol_iterator(SE);
133e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    else
134e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek      return symbol_iterator();
135e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  }
136e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek
137e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  symbol_iterator symbol_end() const { return symbol_iterator(); }
13890e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek
139a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
1401c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal*) { return true; }
141a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
142a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1431c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass UnknownVal : public SVal {
144a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
1451c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  UnknownVal() : SVal(UnknownKind) {}
146a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1471c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
1482203118815997a0efcf19217e057bd20e33303e7Ted Kremenek    return V->getBaseKind() == UnknownKind;
149a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
150a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
151a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1521c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass UndefinedVal : public SVal {
153a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
1541c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  UndefinedVal() : SVal(UndefinedKind) {}
1551c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  UndefinedVal(void* D) : SVal(UndefinedKind, D) {}
156a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1571c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
1584a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek    return V->getBaseKind() == UndefinedKind;
15905a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek  }
16005a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek
16105a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek  void* getData() const { return Data; }
162a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
163a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1641c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass NonLoc : public SVal {
165a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
1661c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  NonLoc(unsigned SubKind, const void* d) : SVal(d, false, SubKind) {}
167a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
168a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
1699012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu  void print(llvm::raw_ostream& Out) const;
170a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1711c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  // Utility methods to create NonLocs.
172a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu
17314553abd17d303b0b310b3ab1523eb0d30d8121cTed Kremenek  static NonLoc MakeIntVal(BasicValueFactory& BasicVals, uint64_t X,
17414553abd17d303b0b310b3ab1523eb0d30d8121cTed Kremenek                           bool isUnsigned);
1756613d08a19aa6ce9b6330487f3bfac841d4b8a4dZhongxing Xu
1768b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu  static NonLoc MakeVal(BasicValueFactory& BasicVals, uint64_t X,
1778b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu                        unsigned BitWidth, bool isUnsigned);
1788b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu
1791c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static NonLoc MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T);
180a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1811c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static NonLoc MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I);
182e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu
183e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu  static NonLoc MakeVal(BasicValueFactory& BasicVals, const llvm::APInt& I,
184e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu                        bool isUnsigned);
1858b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu
1868b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu  static NonLoc MakeVal(BasicValueFactory& BasicVals, const llvm::APSInt& I);
187a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek
1881c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static NonLoc MakeIntTruthVal(BasicValueFactory& BasicVals, bool b);
1896764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
190632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek  static NonLoc MakeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals,
1916764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu                                BasicValueFactory& BasicVals);
1926764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
193a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
1941c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
1951c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind;
196a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
197a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
198a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1991c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass Loc : public SVal {
200a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
2011c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  Loc(unsigned SubKind, const void* D)
202be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek  : SVal(const_cast<void*>(D), true, SubKind) {}
203da9ae6088b9543134a6561a412b79530e290408dTed Kremenek
204cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenekpublic:
2059012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu  void print(llvm::raw_ostream& Out) const;
2062fdf555af136cb017f4dc0c26d5d3415d122e1ffZhongxing Xu
207be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek  Loc(const Loc& X) : SVal(X.Data, true, X.getSubKind()) {}
208be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek  Loc& operator=(const Loc& X) { memcpy(this, &X, sizeof(Loc)); return *this; }
209be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek
2102fdf555af136cb017f4dc0c26d5d3415d122e1ffZhongxing Xu  static Loc MakeVal(const MemRegion* R);
211d59cccc0b6cd4485897526699fe98514805c1883Ted Kremenek
2121c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static Loc MakeVal(AddrLabelExpr* E);
2134193eca10ce0cc8b2dae887e935a43b26f492b5bZhongxing Xu
214da9ae6088b9543134a6561a412b79530e290408dTed Kremenek  static Loc MakeNull(BasicValueFactory &BasicVals);
215da9ae6088b9543134a6561a412b79530e290408dTed Kremenek
216a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
2171c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2181c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind;
219a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
2200e470a5326ccf2f6a7c3d12b2aa54a7af2292837Ted Kremenek
2211c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool IsLocType(QualType T) {
222dfd296bae332d10a854620c059f5d9cef98764b8Ted Kremenek    return T->isPointerType() || T->isObjCQualifiedIdType()
223dfd296bae332d10a854620c059f5d9cef98764b8Ted Kremenek      || T->isBlockPointerType();
2240e470a5326ccf2f6a7c3d12b2aa54a7af2292837Ted Kremenek  }
225a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
226a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
227a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//==------------------------------------------------------------------------==//
2281c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//  Subclasses of NonLoc.
2291c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==//
230a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
2311c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunamespace nonloc {
232329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
233e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekenum Kind { ConcreteIntKind, SymbolValKind, SymExprValKind,
2346764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu            LocAsIntegerKind, CompoundValKind };
235329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
2361c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SymbolVal : public NonLoc {
237aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
238e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {}
239aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2402dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek  SymbolRef getSymbol() const {
241e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    return (const SymbolData*) Data;
242aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
243aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2441c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2451c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
246aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == SymbolValKind;
247aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
248aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2491c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
250aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == SymbolValKind;
251aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
252aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
2539466aa8cf38aa8e87fe3e2cd8005fc245d04f9b7Ted Kremenek
254e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekclass SymExprVal : public NonLoc {
255aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
256e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  SymExprVal(const SymExpr *SE)
257e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    : NonLoc(SymExprValKind, reinterpret_cast<const void*>(SE)) {}
258329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
259e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  const SymExpr *getSymbolicExpression() const {
260e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    return reinterpret_cast<SymExpr*>(Data);
261aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
262aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2631c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2641c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
265e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek           V->getSubKind() == SymExprValKind;
266aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
267aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2681c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
269e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    return V->getSubKind() == SymExprValKind;
270aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
271aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
272aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2731c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass ConcreteInt : public NonLoc {
274aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
2751c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {}
276aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
277aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const llvm::APSInt& getValue() const {
278aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return *static_cast<llvm::APSInt*>(Data);
279aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
280aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
281aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Transfer functions for binary/unary operations on ConcreteInts.
2821c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
2838cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek                 const ConcreteInt& R) const;
284aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
285240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek  ConcreteInt EvalComplement(BasicValueFactory& BasicVals) const;
286aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
287240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek  ConcreteInt EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const;
288aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
289aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
2901c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2911c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
292aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == ConcreteIntKind;
293aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
294aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2951c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
296aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == ConcreteIntKind;
297aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
298aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
299a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
3001c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass LocAsInteger : public NonLoc {
3011c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  LocAsInteger(const std::pair<SVal, uintptr_t>& data) :
3021c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    NonLoc(LocAsIntegerKind, &data) {
3031c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu      assert (isa<Loc>(data.first));
304718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    }
3050fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3060fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenekpublic:
3070fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3081c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  Loc getLoc() const {
3091c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return cast<Loc>(((std::pair<SVal, uintptr_t>*) Data)->first);
3100fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3110fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3121c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  const Loc& getPersistentLoc() const {
3131c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    const SVal& V = ((std::pair<SVal, uintptr_t>*) Data)->first;
3141c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return cast<Loc>(V);
3150fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3160fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3170fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  unsigned getNumBits() const {
3181c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return ((std::pair<SVal, unsigned>*) Data)->second;
3190fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3200fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3210fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  // Implement isa<T> support.
3221c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
3231c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
3241c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu           V->getSubKind() == LocAsIntegerKind;
3250fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3260fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3271c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
3281c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getSubKind() == LocAsIntegerKind;
3290fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3300fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
331632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek  static LocAsInteger Make(BasicValueFactory& Vals, Loc V, unsigned Bits);
3320fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek};
3336764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3346764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xuclass CompoundVal : public NonLoc {
3356764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  friend class NonLoc;
3366764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3376764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {}
3386764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3396764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xupublic:
340a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  const CompoundValData* getValue() const {
3416764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    return static_cast<CompoundValData*>(Data);
3426764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
343a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek
344a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  typedef llvm::ImmutableList<SVal>::iterator iterator;
345a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  iterator begin() const;
346a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  iterator end() const;
3476764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3486764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  static bool classof(const SVal* V) {
3496764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind;
3506764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
3516764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3526764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  static bool classof(const NonLoc* V) {
3536764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    return V->getSubKind() == CompoundValKind;
3546764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
3556764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu};
3560fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3571c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu} // end namespace clang::nonloc
358516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
359516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek//==------------------------------------------------------------------------==//
3601c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//  Subclasses of Loc.
3611c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==//
362516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
3631c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunamespace loc {
364516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
3653330dcb0da654fb06e78dc410ba15ab90c1b08e7Zhongxing Xuenum Kind { GotoLabelKind, MemRegionKind, FuncValKind, ConcreteIntKind };
366329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
3671c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass GotoLabel : public Loc {
368aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
3691c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  GotoLabel(LabelStmt* Label) : Loc(GotoLabelKind, Label) {}
370aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
371aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  LabelStmt* getLabel() const {
372aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return static_cast<LabelStmt*>(Data);
373aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
374aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
3751c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
3761c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
377aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == GotoLabelKind;
378aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
379aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
3801c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
381aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == GotoLabelKind;
382aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
383aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
384aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
385cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
3861c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass MemRegionVal : public Loc {
387aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
3881c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {}
3899e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek
390993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  const MemRegion* getRegion() const {
3919e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return static_cast<MemRegion*>(Data);
392aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
393aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
394993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  template <typename REGION>
395993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  const REGION* getRegionAs() const {
396993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek    return llvm::dyn_cast<REGION>(getRegion());
397993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  }
398993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek
3999e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek  inline bool operator==(const MemRegionVal& R) const {
4009e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return getRegion() == R.getRegion();
401aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
402aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4039e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek  inline bool operator!=(const MemRegionVal& R) const {
4049e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return getRegion() != R.getRegion();
405aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
406aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
407aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
4081c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
4091c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
4109e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek           V->getSubKind() == MemRegionKind;
411aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
412aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4131c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
4149e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return V->getSubKind() == MemRegionKind;
415aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
416aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
417aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4181c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass FuncVal : public Loc {
419aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
4201c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  FuncVal(const FunctionDecl* fd) : Loc(FuncValKind, fd) {}
421aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
422aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  FunctionDecl* getDecl() const {
423aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return static_cast<FunctionDecl*>(Data);
424aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
425aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
426aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool operator==(const FuncVal& R) const {
427aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getDecl() == R.getDecl();
428aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
429aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
430aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool operator!=(const FuncVal& R) const {
431aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getDecl() != R.getDecl();
432aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
433aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
434aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
4351c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
4361c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
437aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == FuncValKind;
438aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
439aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4401c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
441aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == FuncValKind;
442aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
443aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
444aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4451c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass ConcreteInt : public Loc {
446aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
4471c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {}
448aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
449aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const llvm::APSInt& getValue() const {
450aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return *static_cast<llvm::APSInt*>(Data);
451aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4522a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
453aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Transfer functions for binary/unary operations on ConcreteInts.
4541c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
4558cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek                 const ConcreteInt& R) const;
456aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
457aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
4581c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
4591c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
460aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == ConcreteIntKind;
461aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
462aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4631c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
464aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == ConcreteIntKind;
465aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
466aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
467aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4681c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu} // end clang::loc namespace
469a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} // end clang namespace
470a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
471a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#endif
472