SVals.h revision 9c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1c
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
181309f9a3b225ea846e5822691c39a77423125505Ted Kremenek#include "clang/Checker/PathSensitive/SymbolManager.h"
19a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#include "llvm/Support/Casting.h"
20632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek#include "llvm/ADT/ImmutableList.h"
216f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek
226f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremeneknamespace llvm {
236f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek  class raw_ostream;
246f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek}
256f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek
260f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremenek//==------------------------------------------------------------------------==//
271c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//  Base SVal types.
281c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==//
29a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
300f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremeneknamespace clang {
31632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek
32632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenekclass CompoundValData;
33a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekclass LazyCompoundValData;
34a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekclass GRState;
35632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenekclass BasicValueFactory;
369e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass MemRegion;
37a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekclass TypedRegion;
38a1718c78770db93d1b762620f07728a56786f2aeZhongxing Xuclass MemRegionManager;
399e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass GRStateManager;
40d91ee27950ef5c321db1ac2aa5becb75ffe7cb14Zhongxing Xuclass ValueManager;
411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
42834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan/// SVal - This represents a symbolic expression, which can be either
43834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan///  an L-value or an R-value.
44834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan///
451c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SVal {
46a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
47834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan  enum BaseKind {
48834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan    // The enumerators must be representable using 2 bits.
49834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan    UndefinedKind = 0,  // for subclass UndefinedVal (an uninitialized value)
50834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan    UnknownKind = 1,    // for subclass UnknownVal (a void value)
51834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan    LocKind = 2,        // for subclass Loc (an L-value)
52834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan    NonLocKind = 3      // for subclass NonLoc (an R-value that's not
53834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan                        //   an L-value)
54834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan  };
55aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  enum { BaseBits = 2, BaseMask = 0x3 };
561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5790e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenekprotected:
5803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const void* Data;
59834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan
60834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan  /// The lowest 2 bits are a BaseKind (0 -- 3).
61834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan  ///  The higher bits are an unsigned "kind" value.
62a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  unsigned Kind;
631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
64a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
651c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  SVal(const void* d, bool isLoc, unsigned ValKind)
6603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  : Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  explicit SVal(BaseKind k, const void* D = NULL)
6905a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek    : Data(D), Kind(k) {}
701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
71a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
726764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  SVal() : Data(0), Kind(0) {}
737177dee8aee4b432911c91f1b788963bec0cac9fDaniel Dunbar  ~SVal() {}
741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
751c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  /// BufferTy - A temporary buffer to hold a set of SVals.
761c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  typedef llvm::SmallVector<SVal,5> BufferTy;
771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
78aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline unsigned getRawKind() const { return Kind; }
79aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
80aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
82aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline void Profile(llvm::FoldingSetNodeID& ID) const {
83a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek    ID.AddInteger((unsigned) getRawKind());
8403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    ID.AddPointer(Data);
85a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
866764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
871c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  inline bool operator==(const SVal& R) const {
88aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() == R.getRawKind() && Data == R.Data;
89a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
911c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  inline bool operator!=(const SVal& R) const {
92dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek    return !(*this == R);
93dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek  }
944193eca10ce0cc8b2dae887e935a43b26f492b5bZhongxing Xu
95aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool isUnknown() const {
96aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() == UnknownKind;
97aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
98aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
994a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek  inline bool isUndef() const {
1004a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek    return getRawKind() == UndefinedKind;
101aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
102aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
1034a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek  inline bool isUnknownOrUndef() const {
104aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() <= UnknownKind;
105aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
1061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
107aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline bool isValid() const {
108aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return getRawKind() > UnknownKind;
109aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
1101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
111b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu  bool isConstant() const;
112b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu
113db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Care  bool isConstant(int I) const;
114db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Care
11540fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek  bool isZeroConstant() const;
116369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu
117264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu  /// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true;
118264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu  bool hasConjuredSymbol() const;
119264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu
120369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu  /// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a
1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl.
122369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu  /// Otherwise return 0.
123369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu  const FunctionDecl* getAsFunctionDecl() const;
1241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
126d6db976dd4c48b556862d093fb564b9cbc09aae3Jordy Rose  ///  wraps a symbol, return that SymbolRef.  Otherwise return NULL.
12794c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  SymbolRef getAsLocSymbol() const;
1281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
129c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu  /// Get the symbol in the SVal or its base region.
130c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu  SymbolRef getLocSymbolInBase() const;
131c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu
13294c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  /// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
13394c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  ///  Otherwise return a SymbolRef where 'isValid()' returns false.
13494c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  SymbolRef getAsSymbol() const;
135e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek
136e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
137e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  ///  return that expression.  Otherwise return NULL.
138e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  const SymExpr *getAsSymbolicExpression() const;
139edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu
140edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu  const MemRegion *getAsRegion() const;
1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1426f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek  void dumpToStream(llvm::raw_ostream& OS) const;
1436f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek  void dump() const;
144e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek
145e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  // Iterators.
1460d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek  class symbol_iterator {
147e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    llvm::SmallVector<const SymExpr*, 5> itr;
148e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    void expand();
1490d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek  public:
150e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    symbol_iterator() {}
151e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    symbol_iterator(const SymExpr* SE);
1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
153e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    symbol_iterator& operator++();
154e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    SymbolRef operator*();
1551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
156e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    bool operator==(const symbol_iterator& X) const;
157e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    bool operator!=(const symbol_iterator& X) const;
1580d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek  };
1591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
160e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  symbol_iterator symbol_begin() const {
161e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    const SymExpr *SE = getAsSymbolicExpression();
162e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    if (SE)
163e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek      return symbol_iterator(SE);
164e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    else
165e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek      return symbol_iterator();
166e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  }
1671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
168e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  symbol_iterator symbol_end() const { return symbol_iterator(); }
1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
170a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
1711c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal*) { return true; }
172a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
173a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
174a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1751c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass UndefinedVal : public SVal {
176a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
1771c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  UndefinedVal() : SVal(UndefinedKind) {}
17803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  UndefinedVal(const void* D) : SVal(UndefinedKind, D) {}
1791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1801c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
1814a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek    return V->getBaseKind() == UndefinedKind;
18205a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek  }
1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const void* getData() const { return Data; }
185a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
1861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1875b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekclass DefinedOrUnknownSVal : public SVal {
1885b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekprivate:
1895b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  // Do not implement.  We want calling these methods to be a compiler
1905b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  // error since they are tautologically false.
1915b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  bool isUndef() const;
1925b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  bool isValid() const;
1935b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek
194c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenekprotected:
1955b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  explicit DefinedOrUnknownSVal(const void* d, bool isLoc, unsigned ValKind)
196c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek    : SVal(d, isLoc, ValKind) {}
1975b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek
1985b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL)
1995b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek    : SVal(k, D) {}
2005b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek
2015b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekpublic:
2025b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek    // Implement isa<T> support.
2035b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  static inline bool classof(const SVal *V) {
2045b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek    return !V->isUndef();
2055b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  }
2065b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek};
2075b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek
2085b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekclass UnknownVal : public DefinedOrUnknownSVal {
2095b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekpublic:
2105b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  UnknownVal() : DefinedOrUnknownSVal(UnknownKind) {}
2115b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek
2125b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  static inline bool classof(const SVal *V) {
2135b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek    return V->getBaseKind() == UnknownKind;
2145b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  }
2155b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek};
216834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan
2175b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekclass DefinedSVal : public DefinedOrUnknownSVal {
2185b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekprivate:
2195b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  // Do not implement.  We want calling these methods to be a compiler
2205b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  // error since they are tautologically true/false.
2215b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  bool isUnknown() const;
2225b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  bool isUnknownOrUndef() const;
2235b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  bool isValid() const;
2245b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekprotected:
2255b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  DefinedSVal(const void* d, bool isLoc, unsigned ValKind)
2265b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek    : DefinedOrUnknownSVal(d, isLoc, ValKind) {}
22708780078183ae4b2534c69a3e0ded596cdb695baTed Kremenekpublic:
228c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek  // Implement isa<T> support.
229c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek  static inline bool classof(const SVal *V) {
230c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek    return !V->isUnknownOrUndef();
2311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
232c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek};
233a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
234c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenekclass NonLoc : public DefinedSVal {
235a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
236c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek  NonLoc(unsigned SubKind, const void* d) : DefinedSVal(d, false, SubKind) {}
2371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
238a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
2396f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek  void dumpToStream(llvm::raw_ostream& Out) const;
2401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
241a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
2421c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2431c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind;
244a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
245a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
246a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
247c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenekclass Loc : public DefinedSVal {
248a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
2491c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  Loc(unsigned SubKind, const void* D)
250c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek  : DefinedSVal(const_cast<void*>(D), true, SubKind) {}
251da9ae6088b9543134a6561a412b79530e290408dTed Kremenek
252cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenekpublic:
2536f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek  void dumpToStream(llvm::raw_ostream& Out) const;
2542fdf555af136cb017f4dc0c26d5d3415d122e1ffZhongxing Xu
255c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek  Loc(const Loc& X) : DefinedSVal(X.Data, true, X.getSubKind()) {}
256be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek  Loc& operator=(const Loc& X) { memcpy(this, &X, sizeof(Loc)); return *this; }
2571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
258a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
2591c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2601c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind;
261a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
2621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2631c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool IsLocType(QualType T) {
264852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    return T->isAnyPointerType() || T->isBlockPointerType() ||
265852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek           T->isReferenceType();
2660e470a5326ccf2f6a7c3d12b2aa54a7af2292837Ted Kremenek  }
267a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
2681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
269a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//==------------------------------------------------------------------------==//
2701c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//  Subclasses of NonLoc.
2711c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==//
272a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
2731c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunamespace nonloc {
2741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
275e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekenum Kind { ConcreteIntKind, SymbolValKind, SymExprValKind,
276a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek            LocAsIntegerKind, CompoundValKind, LazyCompoundValKind };
277329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
2781c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SymbolVal : public NonLoc {
279aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
280e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {}
2811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2822dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek  SymbolRef getSymbol() const {
283e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    return (const SymbolData*) Data;
284aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
2851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2861c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return V->getBaseKind() == NonLocKind &&
288aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == SymbolValKind;
289aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
2901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2911c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
292aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == SymbolValKind;
293aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
294aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
2959466aa8cf38aa8e87fe3e2cd8005fc245d04f9b7Ted Kremenek
2961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass SymExprVal : public NonLoc {
297aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
298e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  SymExprVal(const SymExpr *SE)
299e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    : NonLoc(SymExprValKind, reinterpret_cast<const void*>(SE)) {}
300329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
301e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  const SymExpr *getSymbolicExpression() const {
30203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return reinterpret_cast<const SymExpr*>(Data);
303aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
3041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3051c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
3061c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
307e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek           V->getSubKind() == SymExprValKind;
308aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
3091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3101c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
311e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    return V->getSubKind() == SymExprValKind;
312aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
313aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
314aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
3151c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass ConcreteInt : public NonLoc {
316aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
3171c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {}
3181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
319aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const llvm::APSInt& getValue() const {
32003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return *static_cast<const llvm::APSInt*>(Data);
321aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
3221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
323aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Transfer functions for binary/unary operations on ConcreteInts.
3246c07bdba93b095b66e2c8c82dd5ed458fa8285eaTed Kremenek  SVal evalBinOp(ValueManager &ValMgr, BinaryOperator::Opcode Op,
3258cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek                 const ConcreteInt& R) const;
3261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3276c07bdba93b095b66e2c8c82dd5ed458fa8285eaTed Kremenek  ConcreteInt evalComplement(ValueManager &ValMgr) const;
3281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3296c07bdba93b095b66e2c8c82dd5ed458fa8285eaTed Kremenek  ConcreteInt evalMinus(ValueManager &ValMgr) const;
3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
331aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
3321c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
3331c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
334aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == ConcreteIntKind;
335aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
3361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3371c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
338aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == ConcreteIntKind;
339aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
340aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
3411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3421c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass LocAsInteger : public NonLoc {
343d91ee27950ef5c321db1ac2aa5becb75ffe7cb14Zhongxing Xu  friend class clang::ValueManager;
344d91ee27950ef5c321db1ac2aa5becb75ffe7cb14Zhongxing Xu
3451c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  LocAsInteger(const std::pair<SVal, uintptr_t>& data) :
3461c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    NonLoc(LocAsIntegerKind, &data) {
3471c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu      assert (isa<Loc>(data.first));
348718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    }
3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3500fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenekpublic:
3511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3521c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  Loc getLoc() const {
3531c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return cast<Loc>(((std::pair<SVal, uintptr_t>*) Data)->first);
3540fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3561c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  const Loc& getPersistentLoc() const {
3571c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    const SVal& V = ((std::pair<SVal, uintptr_t>*) Data)->first;
3581c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return cast<Loc>(V);
3591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
3601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3610fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  unsigned getNumBits() const {
3621c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return ((std::pair<SVal, unsigned>*) Data)->second;
3630fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3650fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  // Implement isa<T> support.
3661c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
3671c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
3681c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu           V->getSubKind() == LocAsIntegerKind;
3690fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3711c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
3721c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getSubKind() == LocAsIntegerKind;
3730fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3740fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek};
3756764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3766764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xuclass CompoundVal : public NonLoc {
377d91ee27950ef5c321db1ac2aa5becb75ffe7cb14Zhongxing Xu  friend class clang::ValueManager;
3786764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3796764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {}
3806764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3816764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xupublic:
382a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  const CompoundValData* getValue() const {
38303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return static_cast<const CompoundValData*>(Data);
3846764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
3851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
386a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  typedef llvm::ImmutableList<SVal>::iterator iterator;
387a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  iterator begin() const;
3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  iterator end() const;
3896764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3906764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  static bool classof(const SVal* V) {
3916764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind;
3926764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
3936764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3946764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  static bool classof(const NonLoc* V) {
3956764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    return V->getSubKind() == CompoundValKind;
3966764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
3976764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu};
3981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
399a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekclass LazyCompoundVal : public NonLoc {
400a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  friend class clang::ValueManager;
401a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek
402a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  LazyCompoundVal(const LazyCompoundValData *D)
403a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek    : NonLoc(LazyCompoundValKind, D) {}
404a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekpublic:
405451ac091cd1868433985396a25cbbf2092ae8ca9Ted Kremenek  const LazyCompoundValData *getCVData() const {
406451ac091cd1868433985396a25cbbf2092ae8ca9Ted Kremenek    return static_cast<const LazyCompoundValData*>(Data);
407451ac091cd1868433985396a25cbbf2092ae8ca9Ted Kremenek  }
408bfcaf8048d1673320de60a22ca9c297d7484b2a8Zhongxing Xu  const void *getStore() const;
409a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  const TypedRegion *getRegion() const;
4101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
411a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  static bool classof(const SVal *V) {
4121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return V->getBaseKind() == NonLocKind &&
413a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek           V->getSubKind() == LazyCompoundValKind;
414a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  }
415a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  static bool classof(const NonLoc *V) {
416a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek    return V->getSubKind() == LazyCompoundValKind;
417a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  }
418a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek};
4191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4201c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu} // end namespace clang::nonloc
421516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
422516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek//==------------------------------------------------------------------------==//
4231c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//  Subclasses of Loc.
4241c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==//
425516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
4261c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunamespace loc {
4271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4285cbe5f9105eae5968229fa2d82fc258e61e27153Zhongxing Xuenum Kind { GotoLabelKind, MemRegionKind, ConcreteIntKind };
429329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
4301c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass GotoLabel : public Loc {
431aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
4321c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  GotoLabel(LabelStmt* Label) : Loc(GotoLabelKind, Label) {}
4331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const LabelStmt* getLabel() const {
43503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return static_cast<const LabelStmt*>(Data);
436aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4381c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
4391c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
440aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == GotoLabelKind;
441aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4431c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
444aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == GotoLabelKind;
4451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
446aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
4471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
448cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
4491c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass MemRegionVal : public Loc {
450aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
4511c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {}
4529e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek
453993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  const MemRegion* getRegion() const {
45403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return static_cast<const MemRegion*>(Data);
455aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
457479529e679957fbb92b56e116e3c86734429331eZhongxing Xu  const MemRegion* StripCasts() const;
4581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
459993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  template <typename REGION>
460993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  const REGION* getRegionAs() const {
461993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek    return llvm::dyn_cast<REGION>(getRegion());
4621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
4631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4649e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek  inline bool operator==(const MemRegionVal& R) const {
4659e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return getRegion() == R.getRegion();
466aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4689e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek  inline bool operator!=(const MemRegionVal& R) const {
4699e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return getRegion() != R.getRegion();
470aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
472aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
4731c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
4741c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
4759e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek           V->getSubKind() == MemRegionKind;
476aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4781c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
4799e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return V->getSubKind() == MemRegionKind;
4801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
481aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
482aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4831c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass ConcreteInt : public Loc {
484aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
4851c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {}
4861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
487aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const llvm::APSInt& getValue() const {
48803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return *static_cast<const llvm::APSInt*>(Data);
489aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4902a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
491aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Transfer functions for binary/unary operations on ConcreteInts.
4929c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  SVal evalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
4938cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek                 const ConcreteInt& R) const;
4941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
495aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
4961c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
4971c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
498aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == ConcreteIntKind;
499aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
5001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5011c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
502aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == ConcreteIntKind;
503aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
504aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
5051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5061c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu} // end clang::loc namespace
5071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} // end clang namespace
508a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
5096f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremeneknamespace llvm {
5106f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenekstatic inline llvm::raw_ostream& operator<<(llvm::raw_ostream& os,
5116f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek                                            clang::SVal V) {
5126f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek  V.dumpToStream(os);
5136f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek  return os;
5146f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek}
5156f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek} // end llvm namespace
516a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#endif
517