SVals.h revision a1718c78770db93d1b762620f07728a56786f2ae
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
759ab6b9cfb76ee56a61829e2bdb08e5cdc288726eTed Kremenek  /// GetRValueSymbolVal - make a unique symbol for value of R.
76a1718c78770db93d1b762620f07728a56786f2aeZhongxing Xu  static SVal GetRValueSymbolVal(SymbolManager& SymMgr, MemRegionManager& MRMgr,
77a1718c78770db93d1b762620f07728a56786f2aeZhongxing Xu                                 const MemRegion* R);
784193eca10ce0cc8b2dae887e935a43b26f492b5bZhongxing Xu
79bb9b2711ded08d39f9c9aa08b06ac5e288f32c62Ted Kremenek  static SVal GetConjuredSymbolVal(SymbolManager& SymMgr, const Expr *E,
80bb9b2711ded08d39f9c9aa08b06ac5e288f32c62Ted Kremenek                                   unsigned Count);
81bb9b2711ded08d39f9c9aa08b06ac5e288f32c62Ted Kremenek
82aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool isUnknown() const {
83aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() == UnknownKind;
84aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
85aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
864a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek  inline bool isUndef() const {
874a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek    return getRawKind() == UndefinedKind;
88aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
89aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
904a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek  inline bool isUnknownOrUndef() const {
91aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() <= UnknownKind;
92aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
93cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
94aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool isValid() const {
95aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() > UnknownKind;
96aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
97a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
9840fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek  bool isZeroConstant() const;
9940fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek
10094c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  /// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
101e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  ///  wraps a symbol, return that SymbolRef.  Otherwise return a SymbolData*
10294c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  SymbolRef getAsLocSymbol() const;
10394c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek
10494c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  /// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
10594c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  ///  Otherwise return a SymbolRef where 'isValid()' returns false.
10694c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  SymbolRef getAsSymbol() const;
107e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek
108e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
109e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  ///  return that expression.  Otherwise return NULL.
110e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  const SymExpr *getAsSymbolicExpression() const;
11194c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek
112a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  void print(std::ostream& OS) const;
1139012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu  void print(llvm::raw_ostream& OS) const;
114d8e9f0dc737133d4e8342f39389064620f5a7f8fTed Kremenek  void printStdErr() const;
115e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek
116e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  // Iterators.
1170d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek  class symbol_iterator {
118e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    llvm::SmallVector<const SymExpr*, 5> itr;
119e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    void expand();
1200d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek  public:
121e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    symbol_iterator() {}
122e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    symbol_iterator(const SymExpr* SE);
1230d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek
124e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    symbol_iterator& operator++();
125e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    SymbolRef operator*();
1260d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek
127e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    bool operator==(const symbol_iterator& X) const;
128e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    bool operator!=(const symbol_iterator& X) const;
1290d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek  };
1300d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek
131e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  symbol_iterator symbol_begin() const {
132e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    const SymExpr *SE = getAsSymbolicExpression();
133e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    if (SE)
134e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek      return symbol_iterator(SE);
135e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    else
136e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek      return symbol_iterator();
137e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  }
138e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek
139e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  symbol_iterator symbol_end() const { return symbol_iterator(); }
14090e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek
141a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
1421c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal*) { return true; }
143a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
144a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1451c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass UnknownVal : public SVal {
146a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
1471c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  UnknownVal() : SVal(UnknownKind) {}
148a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1491c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
1502203118815997a0efcf19217e057bd20e33303e7Ted Kremenek    return V->getBaseKind() == UnknownKind;
151a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
152a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
153a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1541c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass UndefinedVal : public SVal {
155a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
1561c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  UndefinedVal() : SVal(UndefinedKind) {}
1571c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  UndefinedVal(void* D) : SVal(UndefinedKind, D) {}
158a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1591c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
1604a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek    return V->getBaseKind() == UndefinedKind;
16105a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek  }
16205a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek
16305a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek  void* getData() const { return Data; }
164a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
165a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1661c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass NonLoc : public SVal {
167a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
1681c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  NonLoc(unsigned SubKind, const void* d) : SVal(d, false, SubKind) {}
169a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
170a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
1719012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu  void print(llvm::raw_ostream& Out) const;
172a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1731c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  // Utility methods to create NonLocs.
1744193eca10ce0cc8b2dae887e935a43b26f492b5bZhongxing Xu  static NonLoc MakeVal(SymbolRef sym);
1754193eca10ce0cc8b2dae887e935a43b26f492b5bZhongxing Xu
176e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  static NonLoc MakeVal(SymbolManager& SymMgr, const SymExpr *lhs,
177e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek                        BinaryOperator::Opcode op, const llvm::APSInt& rhs,
178e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek                        QualType T);
179a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu
180e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  static NonLoc MakeVal(SymbolManager& SymMgr, const SymExpr *lhs,
181e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek                        BinaryOperator::Opcode op, const SymExpr *rhs,
182e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek                        QualType T);
183a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu
18414553abd17d303b0b310b3ab1523eb0d30d8121cTed Kremenek  static NonLoc MakeIntVal(BasicValueFactory& BasicVals, uint64_t X,
18514553abd17d303b0b310b3ab1523eb0d30d8121cTed Kremenek                           bool isUnsigned);
1866613d08a19aa6ce9b6330487f3bfac841d4b8a4dZhongxing Xu
1878b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu  static NonLoc MakeVal(BasicValueFactory& BasicVals, uint64_t X,
1888b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu                        unsigned BitWidth, bool isUnsigned);
1898b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu
1901c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static NonLoc MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T);
191a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1921c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static NonLoc MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I);
193e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu
194e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu  static NonLoc MakeVal(BasicValueFactory& BasicVals, const llvm::APInt& I,
195e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu                        bool isUnsigned);
1968b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu
1978b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu  static NonLoc MakeVal(BasicValueFactory& BasicVals, const llvm::APSInt& I);
198a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek
1991c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static NonLoc MakeIntTruthVal(BasicValueFactory& BasicVals, bool b);
2006764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
201632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek  static NonLoc MakeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals,
2026764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu                                BasicValueFactory& BasicVals);
2036764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
204a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
2051c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2061c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind;
207a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
208a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
209a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
2101c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass Loc : public SVal {
211a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
2121c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  Loc(unsigned SubKind, const void* D)
213be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek  : SVal(const_cast<void*>(D), true, SubKind) {}
214aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
215be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek//  // Equality operators.
216be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek//  NonLoc EQ(SymbolManager& SM, Loc R) const;
217be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek//  NonLoc NE(SymbolManager& SM, Loc R) const;
218a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
219cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenekpublic:
2209012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu  void print(llvm::raw_ostream& Out) const;
2212fdf555af136cb017f4dc0c26d5d3415d122e1ffZhongxing Xu
222be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek  Loc(const Loc& X) : SVal(X.Data, true, X.getSubKind()) {}
223be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek  Loc& operator=(const Loc& X) { memcpy(this, &X, sizeof(Loc)); return *this; }
224be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek
2252fdf555af136cb017f4dc0c26d5d3415d122e1ffZhongxing Xu  static Loc MakeVal(const MemRegion* R);
226d59cccc0b6cd4485897526699fe98514805c1883Ted Kremenek
2271c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static Loc MakeVal(AddrLabelExpr* E);
2284193eca10ce0cc8b2dae887e935a43b26f492b5bZhongxing Xu
2294193eca10ce0cc8b2dae887e935a43b26f492b5bZhongxing Xu  static Loc MakeVal(SymbolRef sym);
2302a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
231a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
2321c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2331c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind;
234a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
2350e470a5326ccf2f6a7c3d12b2aa54a7af2292837Ted Kremenek
2361c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool IsLocType(QualType T) {
237dfd296bae332d10a854620c059f5d9cef98764b8Ted Kremenek    return T->isPointerType() || T->isObjCQualifiedIdType()
238dfd296bae332d10a854620c059f5d9cef98764b8Ted Kremenek      || T->isBlockPointerType();
2390e470a5326ccf2f6a7c3d12b2aa54a7af2292837Ted Kremenek  }
240a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
241a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
242a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//==------------------------------------------------------------------------==//
2431c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//  Subclasses of NonLoc.
2441c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==//
245a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
2461c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunamespace nonloc {
247329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
248e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekenum Kind { ConcreteIntKind, SymbolValKind, SymExprValKind,
2496764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu            LocAsIntegerKind, CompoundValKind };
250329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
2511c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SymbolVal : public NonLoc {
252aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
253e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {}
254aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2552dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek  SymbolRef getSymbol() const {
256e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    return (const SymbolData*) Data;
257aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
258aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2591c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2601c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
261aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == SymbolValKind;
262aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
263aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2641c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
265aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == SymbolValKind;
266aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
267aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
2689466aa8cf38aa8e87fe3e2cd8005fc245d04f9b7Ted Kremenek
269e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekclass SymExprVal : public NonLoc {
270aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
271e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  SymExprVal(const SymExpr *SE)
272e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    : NonLoc(SymExprValKind, reinterpret_cast<const void*>(SE)) {}
273329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
274e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  const SymExpr *getSymbolicExpression() const {
275e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    return reinterpret_cast<SymExpr*>(Data);
276aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
277aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2781c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2791c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
280e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek           V->getSubKind() == SymExprValKind;
281aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
282aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2831c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
284e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    return V->getSubKind() == SymExprValKind;
285aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
286aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
287aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2881c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass ConcreteInt : public NonLoc {
289aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
2901c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {}
291aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
292aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const llvm::APSInt& getValue() const {
293aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return *static_cast<llvm::APSInt*>(Data);
294aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
295aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
296aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Transfer functions for binary/unary operations on ConcreteInts.
2971c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
2988cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek                 const ConcreteInt& R) const;
299aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
300240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek  ConcreteInt EvalComplement(BasicValueFactory& BasicVals) const;
301aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
302240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek  ConcreteInt EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const;
303aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
304aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
3051c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
3061c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
307aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == ConcreteIntKind;
308aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
309aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
3101c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
311aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == ConcreteIntKind;
312aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
313aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
314a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
3151c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass LocAsInteger : public NonLoc {
3161c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  LocAsInteger(const std::pair<SVal, uintptr_t>& data) :
3171c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    NonLoc(LocAsIntegerKind, &data) {
3181c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu      assert (isa<Loc>(data.first));
319718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    }
3200fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3210fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenekpublic:
3220fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3231c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  Loc getLoc() const {
3241c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return cast<Loc>(((std::pair<SVal, uintptr_t>*) Data)->first);
3250fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3260fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3271c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  const Loc& getPersistentLoc() const {
3281c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    const SVal& V = ((std::pair<SVal, uintptr_t>*) Data)->first;
3291c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return cast<Loc>(V);
3300fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3310fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3320fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  unsigned getNumBits() const {
3331c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return ((std::pair<SVal, unsigned>*) Data)->second;
3340fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3350fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3360fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  // Implement isa<T> support.
3371c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
3381c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
3391c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu           V->getSubKind() == LocAsIntegerKind;
3400fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3410fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3421c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
3431c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getSubKind() == LocAsIntegerKind;
3440fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3450fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
346632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek  static LocAsInteger Make(BasicValueFactory& Vals, Loc V, unsigned Bits);
3470fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek};
3486764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3496764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xuclass CompoundVal : public NonLoc {
3506764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  friend class NonLoc;
3516764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3526764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {}
3536764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3546764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xupublic:
355a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  const CompoundValData* getValue() const {
3566764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    return static_cast<CompoundValData*>(Data);
3576764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
358a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek
359a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  typedef llvm::ImmutableList<SVal>::iterator iterator;
360a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  iterator begin() const;
361a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  iterator end() const;
3626764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3636764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  static bool classof(const SVal* V) {
3646764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind;
3656764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
3666764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3676764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  static bool classof(const NonLoc* V) {
3686764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    return V->getSubKind() == CompoundValKind;
3696764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
3706764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu};
3710fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3721c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu} // end namespace clang::nonloc
373516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
374516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek//==------------------------------------------------------------------------==//
3751c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//  Subclasses of Loc.
3761c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==//
377516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
3781c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunamespace loc {
379516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
3809e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekenum Kind { SymbolValKind, GotoLabelKind, MemRegionKind, FuncValKind,
381197fa58ab40e3fee2137715e96d9bb1c59340837Zhongxing Xu            ConcreteIntKind };
382aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
3831c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SymbolVal : public Loc {
384aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
385e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  SymbolVal(SymbolRef sym) : Loc(SymbolValKind, sym) {}
3862a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
387e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  SymbolRef getSymbol() const { return (SymbolRef) Data; }
388aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
3891c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
3901c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
391aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == SymbolValKind;
392aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
393aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
3941c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
395aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == SymbolValKind;
396aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
397aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
398329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
3991c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass GotoLabel : public Loc {
400aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
4011c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  GotoLabel(LabelStmt* Label) : Loc(GotoLabelKind, Label) {}
402aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
403aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  LabelStmt* getLabel() const {
404aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return static_cast<LabelStmt*>(Data);
405aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
406aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4071c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
4081c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
409aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == GotoLabelKind;
410aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
411aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4121c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
413aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == GotoLabelKind;
414aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
415aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
416aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
417cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
4181c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass MemRegionVal : public Loc {
419aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
4201c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {}
4219e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek
422993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  const MemRegion* getRegion() const {
4239e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return static_cast<MemRegion*>(Data);
424aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
425aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
426993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  template <typename REGION>
427993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  const REGION* getRegionAs() const {
428993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek    return llvm::dyn_cast<REGION>(getRegion());
429993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  }
430993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek
4319e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek  inline bool operator==(const MemRegionVal& R) const {
4329e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return getRegion() == R.getRegion();
433aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
434aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4359e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek  inline bool operator!=(const MemRegionVal& R) const {
4369e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return getRegion() != R.getRegion();
437aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
438aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
439aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
4401c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
4411c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
4429e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek           V->getSubKind() == MemRegionKind;
443aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
444aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4451c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
4469e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return V->getSubKind() == MemRegionKind;
447aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
448aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
449aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4501c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass FuncVal : public Loc {
451aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
4521c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  FuncVal(const FunctionDecl* fd) : Loc(FuncValKind, fd) {}
453aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
454aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  FunctionDecl* getDecl() const {
455aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return static_cast<FunctionDecl*>(Data);
456aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
457aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
458aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool operator==(const FuncVal& R) const {
459aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getDecl() == R.getDecl();
460aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
461aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
462aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool operator!=(const FuncVal& R) const {
463aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getDecl() != R.getDecl();
464aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
465aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
466aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
4671c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
4681c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
469aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == FuncValKind;
470aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
471aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4721c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
473aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == FuncValKind;
474aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
475aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
476aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4771c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass ConcreteInt : public Loc {
478aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
4791c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {}
480aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
481aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const llvm::APSInt& getValue() const {
482aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return *static_cast<llvm::APSInt*>(Data);
483aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4842a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
485aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Transfer functions for binary/unary operations on ConcreteInts.
4861c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
4878cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek                 const ConcreteInt& R) const;
488aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
489aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
4901c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
4911c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
492aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == ConcreteIntKind;
493aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
494aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4951c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
496aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == ConcreteIntKind;
497aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
498aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
499aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
5001c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu} // end clang::loc namespace
501a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} // end clang namespace
502a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
503a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#endif
504