SVals.h revision 2fdf555af136cb017f4dc0c26d5d3415d122e1ff
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;
319e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass GRStateManager;
329e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek
331c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SVal {
34a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
351c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  enum BaseKind { UndefinedKind, UnknownKind, LocKind, NonLocKind };
36aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  enum { BaseBits = 2, BaseMask = 0x3 };
37a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
3890e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenekprotected:
39a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  void* Data;
40a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  unsigned Kind;
41a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
42a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
431c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  SVal(const void* d, bool isLoc, unsigned ValKind)
44a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  : Data(const_cast<void*>(d)),
451c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
46a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
471c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  explicit SVal(BaseKind k, void* D = NULL)
4805a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek    : Data(D), Kind(k) {}
49a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
50a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
516764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  SVal() : Data(0), Kind(0) {}
521c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  ~SVal() {};
53a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
541c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  /// BufferTy - A temporary buffer to hold a set of SVals.
551c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  typedef llvm::SmallVector<SVal,5> BufferTy;
56a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
57aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline unsigned getRawKind() const { return Kind; }
58aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
59aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
60a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
61aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline void Profile(llvm::FoldingSetNodeID& ID) const {
62a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek    ID.AddInteger((unsigned) getRawKind());
63a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek    ID.AddPointer(reinterpret_cast<void*>(Data));
64a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
656764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
661c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  inline bool operator==(const SVal& R) const {
67aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() == R.getRawKind() && Data == R.Data;
68a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
69a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
70dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek
711c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  inline bool operator!=(const SVal& R) const {
72dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek    return !(*this == R);
73dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek  }
74dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek
751c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static SVal GetSymbolValue(SymbolManager& SymMgr, VarDecl *D);
76eabf776661662a8e652eb692084d20fddffd5ccaZhongxing Xu  static SVal getSymbolValue(SymbolManager& SymMgr, const MemRegion* R,
77eabf776661662a8e652eb692084d20fddffd5ccaZhongxing Xu                             const llvm::APSInt* Idx, QualType T);
78eabf776661662a8e652eb692084d20fddffd5ccaZhongxing Xu  static SVal getSymbolValue(SymbolManager& SymMgr, const MemRegion* R,
79eabf776661662a8e652eb692084d20fddffd5ccaZhongxing Xu                             const FieldDecl* FD, QualType T);
80a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
81aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool isUnknown() const {
82aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() == UnknownKind;
83aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
84aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
854a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek  inline bool isUndef() const {
864a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek    return getRawKind() == UndefinedKind;
87aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
88aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
894a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek  inline bool isUnknownOrUndef() const {
90aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() <= UnknownKind;
91aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
92cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
93aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool isValid() const {
94aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() > UnknownKind;
95aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
96a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
9740fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek  bool isZeroConstant() const;
9840fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek
99a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  void print(std::ostream& OS) const;
1009012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu  void print(llvm::raw_ostream& OS) const;
101d8e9f0dc737133d4e8342f39389064620f5a7f8fTed Kremenek  void printStdErr() const;
102a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1030d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek  class symbol_iterator {
10496f560b96ba3fb7b9a5408db22b481206b211f1cTed Kremenek    SymbolRef SingleRef;
10596f560b96ba3fb7b9a5408db22b481206b211f1cTed Kremenek    const SymbolRef* sptr;
1060d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek  public:
1070d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek
1080d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek    bool operator==(const symbol_iterator& X) {
10996f560b96ba3fb7b9a5408db22b481206b211f1cTed Kremenek      return SingleRef == X.SingleRef && sptr == X.sptr;
1100d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek    }
1110d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek
1120d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek    bool operator!=(const symbol_iterator& X) {
11396f560b96ba3fb7b9a5408db22b481206b211f1cTed Kremenek      return SingleRef != X.SingleRef || sptr != X.sptr;
1140d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek    }
1150d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek
1160d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek    symbol_iterator& operator++() {
11796f560b96ba3fb7b9a5408db22b481206b211f1cTed Kremenek      if (sptr)
1180d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek        ++sptr;
1190d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek      else
12096f560b96ba3fb7b9a5408db22b481206b211f1cTed Kremenek        SingleRef = SymbolRef();
1210d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek
1220d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek      return *this;
1230d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek    }
1240d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek
1252dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek    SymbolRef operator*() const {
12696f560b96ba3fb7b9a5408db22b481206b211f1cTed Kremenek      if (sptr)
1270d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek        return *sptr;
1280d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek
12996f560b96ba3fb7b9a5408db22b481206b211f1cTed Kremenek      return SingleRef;
1300d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek    }
1310d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek
13296f560b96ba3fb7b9a5408db22b481206b211f1cTed Kremenek    symbol_iterator(SymbolRef x) : SingleRef(x), sptr(0) {}
13396f560b96ba3fb7b9a5408db22b481206b211f1cTed Kremenek    symbol_iterator() : sptr(0) {}
13496f560b96ba3fb7b9a5408db22b481206b211f1cTed Kremenek    symbol_iterator(const SymbolRef* x) : sptr(x) {}
1350d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek  };
1360d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek
13790e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek  symbol_iterator symbol_begin() const;
1380d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek  symbol_iterator symbol_end() const;
13990e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek
140a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
1411c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal*) { return true; }
142a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
143a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1441c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass UnknownVal : public SVal {
145a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
1461c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  UnknownVal() : SVal(UnknownKind) {}
147a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1481c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
1492203118815997a0efcf19217e057bd20e33303e7Ted Kremenek    return V->getBaseKind() == UnknownKind;
150a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
151a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
152a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1531c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass UndefinedVal : public SVal {
154a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
1551c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  UndefinedVal() : SVal(UndefinedKind) {}
1561c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  UndefinedVal(void* D) : SVal(UndefinedKind, D) {}
157a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1581c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
1594a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek    return V->getBaseKind() == UndefinedKind;
16005a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek  }
16105a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek
16205a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek  void* getData() const { return Data; }
163a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
164a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1651c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass NonLoc : public SVal {
166a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
1671c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  NonLoc(unsigned SubKind, const void* d) : SVal(d, false, SubKind) {}
168a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
169a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
1709012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu  void print(llvm::raw_ostream& Out) const;
171a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1721c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  // Utility methods to create NonLocs.
1736613d08a19aa6ce9b6330487f3bfac841d4b8a4dZhongxing Xu
1746613d08a19aa6ce9b6330487f3bfac841d4b8a4dZhongxing Xu  static NonLoc MakeVal(BasicValueFactory& BasicVals, unsigned X,
1756613d08a19aa6ce9b6330487f3bfac841d4b8a4dZhongxing Xu                        bool isUnsigned);
1766613d08a19aa6ce9b6330487f3bfac841d4b8a4dZhongxing Xu
1778b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu  static NonLoc MakeVal(BasicValueFactory& BasicVals, uint64_t X,
1788b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu                        unsigned BitWidth, bool isUnsigned);
1798b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu
1801c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static NonLoc MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T);
181a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1821c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static NonLoc MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I);
183e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu
184e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu  static NonLoc MakeVal(BasicValueFactory& BasicVals, const llvm::APInt& I,
185e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu                        bool isUnsigned);
1868b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu
1878b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu  static NonLoc MakeVal(BasicValueFactory& BasicVals, const llvm::APSInt& I);
188a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek
1891c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static NonLoc MakeIntTruthVal(BasicValueFactory& BasicVals, bool b);
1906764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
191632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek  static NonLoc MakeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals,
1926764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu                                BasicValueFactory& BasicVals);
1936764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
194a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
1951c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
1961c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind;
197a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
198a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
199a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
2001c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass Loc : public SVal {
201a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
2021c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  Loc(unsigned SubKind, const void* D)
2031c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    : SVal(const_cast<void*>(D), true, SubKind) {}
204aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
205a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Equality operators.
2061c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  NonLoc EQ(BasicValueFactory& BasicVals, const Loc& R) const;
2071c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  NonLoc NE(BasicValueFactory& BasicVals, const Loc& R) const;
208a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
209cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenekpublic:
2109012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu  void print(llvm::raw_ostream& Out) const;
2112fdf555af136cb017f4dc0c26d5d3415d122e1ffZhongxing Xu
2122fdf555af136cb017f4dc0c26d5d3415d122e1ffZhongxing Xu  static Loc MakeVal(const MemRegion* R);
213d59cccc0b6cd4485897526699fe98514805c1883Ted Kremenek
2141c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static Loc MakeVal(AddrLabelExpr* E);
2152a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted 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
2330fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenekenum Kind { ConcreteIntKind, SymbolValKind, SymIntConstraintValKind,
2346764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu            LocAsIntegerKind, CompoundValKind };
235329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
2361c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SymbolVal : public NonLoc {
237aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
238aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  SymbolVal(unsigned SymID)
2391c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    : NonLoc(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
240aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2412dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek  SymbolRef getSymbol() const {
2422dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek    return (SymbolRef) reinterpret_cast<uintptr_t>(Data);
243aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
244aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2451c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2461c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
247aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == SymbolValKind;
248aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
249aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2501c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
251aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == SymbolValKind;
252aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
253aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
2549466aa8cf38aa8e87fe3e2cd8005fc245d04f9b7Ted Kremenek
2551c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SymIntConstraintVal : public NonLoc {
256aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
257aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  SymIntConstraintVal(const SymIntConstraint& C)
2581c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    : NonLoc(SymIntConstraintValKind, reinterpret_cast<const void*>(&C)) {}
259329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
260aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const SymIntConstraint& getConstraint() const {
261aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return *reinterpret_cast<SymIntConstraint*>(Data);
262aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
263aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2641c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2651c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
266aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == SymIntConstraintValKind;
267aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
268aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2691c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
270aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == SymIntConstraintValKind;
271aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
272aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
273aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2741c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass ConcreteInt : public NonLoc {
275aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
2761c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {}
277aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
278aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const llvm::APSInt& getValue() const {
279aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return *static_cast<llvm::APSInt*>(Data);
280aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
281aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
282aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Transfer functions for binary/unary operations on ConcreteInts.
2831c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
2848cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek                 const ConcreteInt& R) const;
285aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
286240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek  ConcreteInt EvalComplement(BasicValueFactory& BasicVals) const;
287aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
288240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek  ConcreteInt EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const;
289aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
290aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
2911c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2921c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
293aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == ConcreteIntKind;
294aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
295aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2961c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
297aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == ConcreteIntKind;
298aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
299aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
300a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
3011c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass LocAsInteger : public NonLoc {
3021c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  LocAsInteger(const std::pair<SVal, uintptr_t>& data) :
3031c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    NonLoc(LocAsIntegerKind, &data) {
3041c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu      assert (isa<Loc>(data.first));
305718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    }
3060fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3070fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenekpublic:
3080fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3091c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  Loc getLoc() const {
3101c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return cast<Loc>(((std::pair<SVal, uintptr_t>*) Data)->first);
3110fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3120fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3131c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  const Loc& getPersistentLoc() const {
3141c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    const SVal& V = ((std::pair<SVal, uintptr_t>*) Data)->first;
3151c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return cast<Loc>(V);
3160fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3170fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3180fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  unsigned getNumBits() const {
3191c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return ((std::pair<SVal, unsigned>*) Data)->second;
3200fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3210fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3220fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  // Implement isa<T> support.
3231c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
3241c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
3251c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu           V->getSubKind() == LocAsIntegerKind;
3260fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3270fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3281c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
3291c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getSubKind() == LocAsIntegerKind;
3300fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3310fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
332632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek  static LocAsInteger Make(BasicValueFactory& Vals, Loc V, unsigned Bits);
3330fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek};
3346764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3356764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xuclass CompoundVal : public NonLoc {
3366764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  friend class NonLoc;
3376764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3386764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {}
3396764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3406764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xupublic:
341a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  const CompoundValData* getValue() const {
3426764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    return static_cast<CompoundValData*>(Data);
3436764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
344a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek
345a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  typedef llvm::ImmutableList<SVal>::iterator iterator;
346a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  iterator begin() const;
347a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  iterator end() const;
3486764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3496764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  static bool classof(const SVal* V) {
3506764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind;
3516764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
3526764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3536764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  static bool classof(const NonLoc* V) {
3546764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    return V->getSubKind() == CompoundValKind;
3556764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
3566764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu};
3570fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
3581c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu} // end namespace clang::nonloc
359516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
360516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek//==------------------------------------------------------------------------==//
3611c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//  Subclasses of Loc.
3621c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==//
363516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
3641c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunamespace loc {
365516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
3669e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekenum Kind { SymbolValKind, GotoLabelKind, MemRegionKind, FuncValKind,
367197fa58ab40e3fee2137715e96d9bb1c59340837Zhongxing Xu            ConcreteIntKind };
368aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
3691c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SymbolVal : public Loc {
370aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
371aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  SymbolVal(unsigned SymID)
3721c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  : Loc(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
3732a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
3742dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek  SymbolRef getSymbol() const {
3752dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek    return (SymbolRef) reinterpret_cast<uintptr_t>(Data);
376aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
377aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
3781c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
3791c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
380aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == SymbolValKind;
381aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
382aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
3831c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
384aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == SymbolValKind;
385aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
386aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
387329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
3881c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass GotoLabel : public Loc {
389aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
3901c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  GotoLabel(LabelStmt* Label) : Loc(GotoLabelKind, Label) {}
391aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
392aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  LabelStmt* getLabel() const {
393aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return static_cast<LabelStmt*>(Data);
394aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
395aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
3961c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
3971c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
398aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == GotoLabelKind;
399aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
400aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4011c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
402aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == GotoLabelKind;
403aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
404aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
405aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
406cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
4071c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass MemRegionVal : public Loc {
408aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
4091c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {}
4109e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek
411993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  const MemRegion* getRegion() const {
4129e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return static_cast<MemRegion*>(Data);
413aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
414aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
415993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  template <typename REGION>
416993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  const REGION* getRegionAs() const {
417993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek    return llvm::dyn_cast<REGION>(getRegion());
418993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  }
419993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek
4209e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek  inline bool operator==(const MemRegionVal& R) const {
4219e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return getRegion() == R.getRegion();
422aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
423aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4249e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek  inline bool operator!=(const MemRegionVal& R) const {
4259e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return getRegion() != R.getRegion();
426aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
427aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
428aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
4291c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
4301c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
4319e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek           V->getSubKind() == MemRegionKind;
432aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
433aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4341c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
4359e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return V->getSubKind() == MemRegionKind;
436aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
437aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
438aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4391c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass FuncVal : public Loc {
440aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
4411c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  FuncVal(const FunctionDecl* fd) : Loc(FuncValKind, fd) {}
442aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
443aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  FunctionDecl* getDecl() const {
444aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return static_cast<FunctionDecl*>(Data);
445aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
446aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
447aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool operator==(const FuncVal& R) const {
448aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getDecl() == R.getDecl();
449aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
450aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
451aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool operator!=(const FuncVal& R) const {
452aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getDecl() != R.getDecl();
453aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
454aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
455aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
4561c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
4571c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
458aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == FuncValKind;
459aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
460aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4611c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
462aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == FuncValKind;
463aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
464aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
465aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4661c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass ConcreteInt : public Loc {
467aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
4681c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {}
469aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
470aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const llvm::APSInt& getValue() const {
471aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return *static_cast<llvm::APSInt*>(Data);
472aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4732a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
474aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Transfer functions for binary/unary operations on ConcreteInts.
4751c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
4768cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek                 const ConcreteInt& R) const;
477aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
478aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
4791c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
4801c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
481aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == ConcreteIntKind;
482aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
483aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4841c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
485aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == ConcreteIntKind;
486aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
487aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
488aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4891c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu} // end clang::loc namespace
490a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} // end clang namespace
491a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
492a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#endif
493