SVals.h revision 8bef8238181a30e52dea380789a7e2d760eac532
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
155a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis#ifndef LLVM_CLANG_GR_RVALUE_H
165a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis#define LLVM_CLANG_GR_RVALUE_H
17a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
18d47d3b0cfeb7e8564ff77f48130fe63282b6d127Chris Lattner#include "clang/Basic/LLVM.h"
199b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
208bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
21632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek#include "llvm/ADT/ImmutableList.h"
226f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek
230f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremenek//==------------------------------------------------------------------------==//
241c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//  Base SVal types.
251c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==//
26a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
270f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremeneknamespace clang {
28632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek
299ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremeneknamespace ento {
305a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis
31632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenekclass CompoundValData;
32a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekclass LazyCompoundValData;
3318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekclass ProgramState;
34632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenekclass BasicValueFactory;
359e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass MemRegion;
36a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekclass TypedRegion;
37a1718c78770db93d1b762620f07728a56786f2aeZhongxing Xuclass MemRegionManager;
3818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekclass ProgramStateManager;
39c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenekclass SValBuilder;
401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
41834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan/// SVal - This represents a symbolic expression, which can be either
42834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan///  an L-value or an R-value.
43834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan///
441c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SVal {
45a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
46834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan  enum BaseKind {
47834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan    // The enumerators must be representable using 2 bits.
48834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan    UndefinedKind = 0,  // for subclass UndefinedVal (an uninitialized value)
49834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan    UnknownKind = 1,    // for subclass UnknownVal (a void value)
50834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan    LocKind = 2,        // for subclass Loc (an L-value)
51834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan    NonLocKind = 3      // for subclass NonLoc (an R-value that's not
52834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan                        //   an L-value)
53834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan  };
54aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  enum { BaseBits = 2, BaseMask = 0x3 };
551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5690e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenekprotected:
579c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const void *Data;
58834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan
59834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan  /// The lowest 2 bits are a BaseKind (0 -- 3).
60834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan  ///  The higher bits are an unsigned "kind" value.
61a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  unsigned Kind;
621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
639c378f705405d37f49795d5e915989de774fe11fTed Kremenek  explicit SVal(const void *d, bool isLoc, unsigned ValKind)
6403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  : Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
669c378f705405d37f49795d5e915989de774fe11fTed Kremenek  explicit SVal(BaseKind k, const void *D = NULL)
6705a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek    : Data(D), Kind(k) {}
681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
69a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
700074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek  explicit SVal() : Data(0), Kind(0) {}
717177dee8aee4b432911c91f1b788963bec0cac9fDaniel Dunbar  ~SVal() {}
721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
731c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  /// BufferTy - A temporary buffer to hold a set of SVals.
74686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVector<SVal,5> BufferTy;
751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
76aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline unsigned getRawKind() const { return Kind; }
77aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
78aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
807dfc9420babe83e236a47e752f8723bd06070d9dZhanyong Wan  // This method is required for using SVal in a FoldingSetNode.  It
817dfc9420babe83e236a47e752f8723bd06070d9dZhanyong Wan  // extracts a unique signature for this SVal object.
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.
1239c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const FunctionDecl *getAsFunctionDecl() const;
1241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
125fc06f988da35df75e623e0c1c4e4db4d36c0b43bAnna Zaks  /// If this SVal is a location (subclasses Loc) and
126fc06f988da35df75e623e0c1c4e4db4d36c0b43bAnna Zaks  /// wraps a symbol, return that SymbolRef.  Otherwise return 0.
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
132fc06f988da35df75e623e0c1c4e4db4d36c0b43bAnna Zaks  /// If this SVal wraps a symbol return that SymbolRef.
133fc06f988da35df75e623e0c1c4e4db4d36c0b43bAnna Zaks  /// Otherwise, return 0.
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
14064595fad45abbaa75778609196b9223bf6f2ece3Anna Zaks  const SymExpr* getAsSymExpr() const;
14164595fad45abbaa75778609196b9223bf6f2ece3Anna Zaks
142edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu  const MemRegion *getAsRegion() const;
1431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1449c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void dumpToStream(raw_ostream &OS) const;
1456f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek  void dump() const;
146e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek
1471d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks  SymExpr::symbol_iterator symbol_begin() const {
148e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    const SymExpr *SE = getAsSymbolicExpression();
149e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    if (SE)
1501d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks      return SE->symbol_begin();
151e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    else
1521d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks      return SymExpr::symbol_iterator();
153e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  }
1541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1551d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks  SymExpr::symbol_iterator symbol_end() const {
1561d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks    return SymExpr::symbol_end();
1571d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks  }
1581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
159a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
1601c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal*) { return true; }
161a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
162a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
163a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1641c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass UndefinedVal : public SVal {
165a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
1661c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  UndefinedVal() : SVal(UndefinedKind) {}
1679c378f705405d37f49795d5e915989de774fe11fTed Kremenek  UndefinedVal(const void *D) : SVal(UndefinedKind, D) {}
1681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1691c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
1704a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek    return V->getBaseKind() == UndefinedKind;
17105a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek  }
1721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1739c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const void *getData() const { return Data; }
174a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1765b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekclass DefinedOrUnknownSVal : public SVal {
1775b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekprivate:
1785b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  // Do not implement.  We want calling these methods to be a compiler
1795b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  // error since they are tautologically false.
1805b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  bool isUndef() const;
1815b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  bool isValid() const;
1825b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek
183c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenekprotected:
1849c378f705405d37f49795d5e915989de774fe11fTed Kremenek  explicit DefinedOrUnknownSVal(const void *d, bool isLoc, unsigned ValKind)
185c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek    : SVal(d, isLoc, ValKind) {}
1865b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek
1875b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL)
1885b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek    : SVal(k, D) {}
1895b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek
1905b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekpublic:
1915b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek    // Implement isa<T> support.
1925b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  static inline bool classof(const SVal *V) {
1935b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek    return !V->isUndef();
1945b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  }
1955b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek};
1965b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek
1975b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekclass UnknownVal : public DefinedOrUnknownSVal {
1985b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekpublic:
1990074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek  explicit UnknownVal() : DefinedOrUnknownSVal(UnknownKind) {}
2005b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek
2015b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  static inline bool classof(const SVal *V) {
2025b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek    return V->getBaseKind() == UnknownKind;
2035b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  }
2045b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek};
205834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan
2065b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekclass DefinedSVal : public DefinedOrUnknownSVal {
2075b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekprivate:
2085b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  // Do not implement.  We want calling these methods to be a compiler
2095b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  // error since they are tautologically true/false.
2105b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  bool isUnknown() const;
2115b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  bool isUnknownOrUndef() const;
2125b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  bool isValid() const;
2135b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekprotected:
2149c378f705405d37f49795d5e915989de774fe11fTed Kremenek  explicit DefinedSVal(const void *d, bool isLoc, unsigned ValKind)
2155b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek    : DefinedOrUnknownSVal(d, isLoc, ValKind) {}
21608780078183ae4b2534c69a3e0ded596cdb695baTed Kremenekpublic:
217c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek  // Implement isa<T> support.
218c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek  static inline bool classof(const SVal *V) {
219c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek    return !V->isUnknownOrUndef();
2201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
221c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek};
222a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
223c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenekclass NonLoc : public DefinedSVal {
224a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
2259c378f705405d37f49795d5e915989de774fe11fTed Kremenek  explicit NonLoc(unsigned SubKind, const void *d)
2260074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek    : DefinedSVal(d, false, SubKind) {}
2271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
228a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic:
2299c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void dumpToStream(raw_ostream &Out) const;
2301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
231a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
2321c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2331c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind;
234a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
235a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
236a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
237c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenekclass Loc : public DefinedSVal {
238a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected:
2399c378f705405d37f49795d5e915989de774fe11fTed Kremenek  explicit Loc(unsigned SubKind, const void *D)
240c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek  : DefinedSVal(const_cast<void*>(D), true, SubKind) {}
241da9ae6088b9543134a6561a412b79530e290408dTed Kremenek
242cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenekpublic:
2439c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void dumpToStream(raw_ostream &Out) const;
2442fdf555af136cb017f4dc0c26d5d3415d122e1ffZhongxing Xu
245c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek  Loc(const Loc& X) : DefinedSVal(X.Data, true, X.getSubKind()) {}
2461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
247a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  // Implement isa<T> support.
2481c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2491c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind;
250a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
2511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2527dfc9420babe83e236a47e752f8723bd06070d9dZhanyong Wan  static inline bool isLocType(QualType T) {
253852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    return T->isAnyPointerType() || T->isBlockPointerType() ||
254852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek           T->isReferenceType();
2550e470a5326ccf2f6a7c3d12b2aa54a7af2292837Ted Kremenek  }
256a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek};
2571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
258a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//==------------------------------------------------------------------------==//
2591c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//  Subclasses of NonLoc.
2601c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==//
261a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
2621c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunamespace nonloc {
2631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
264e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekenum Kind { ConcreteIntKind, SymbolValKind, SymExprValKind,
265a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek            LocAsIntegerKind, CompoundValKind, LazyCompoundValKind };
266329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
2675344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks/// \brief Represents symbolic expression.
2681c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SymbolVal : public NonLoc {
269aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
270e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {}
2711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2722dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek  SymbolRef getSymbol() const {
2733cdf584e068056540769dab56cad333e95a89750Anna Zaks    return (const SymExpr*) Data;
274aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
2751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2765344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks  bool isExpression() {
2775344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks    return !isa<SymbolData>(getSymbol());
278aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
2791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2801c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
2811c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
2825344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks           V->getSubKind() == SymbolValKind;
283aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
2841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2851c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
2865344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks    return V->getSubKind() == SymbolValKind;
287aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
288aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
289aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
290aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks/// \brief Value representing integer constant.
2911c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass ConcreteInt : public NonLoc {
292aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
2930074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek  explicit ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {}
2941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
295aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const llvm::APSInt& getValue() const {
29603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return *static_cast<const llvm::APSInt*>(Data);
297aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
2981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
299aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Transfer functions for binary/unary operations on ConcreteInts.
300c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal evalBinOp(SValBuilder &svalBuilder, BinaryOperator::Opcode Op,
3018cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek                 const ConcreteInt& R) const;
3021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
303c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  ConcreteInt evalComplement(SValBuilder &svalBuilder) const;
3041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
305c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  ConcreteInt evalMinus(SValBuilder &svalBuilder) const;
3061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
307aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
3081c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
3091c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
310aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == ConcreteIntKind;
311aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3131c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
314aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == ConcreteIntKind;
315aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
316aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
3171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3181c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass LocAsInteger : public NonLoc {
3199ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek  friend class ento::SValBuilder;
320d91ee27950ef5c321db1ac2aa5becb75ffe7cb14Zhongxing Xu
3210074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek  explicit LocAsInteger(const std::pair<SVal, uintptr_t>& data) :
3221c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    NonLoc(LocAsIntegerKind, &data) {
3231c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu      assert (isa<Loc>(data.first));
324718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    }
3251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3260fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenekpublic:
3271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3281c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  Loc getLoc() const {
3291c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return cast<Loc>(((std::pair<SVal, uintptr_t>*) Data)->first);
3300fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3321c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  const Loc& getPersistentLoc() const {
3331c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    const SVal& V = ((std::pair<SVal, uintptr_t>*) Data)->first;
3341c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return cast<Loc>(V);
3351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
3361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3370fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  unsigned getNumBits() const {
3381c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return ((std::pair<SVal, unsigned>*) Data)->second;
3390fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3410fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  // Implement isa<T> support.
3421c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
3431c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == NonLocKind &&
3441c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu           V->getSubKind() == LocAsIntegerKind;
3450fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3471c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const NonLoc* V) {
3481c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getSubKind() == LocAsIntegerKind;
3490fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
3500fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek};
3516764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3526764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xuclass CompoundVal : public NonLoc {
3539ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek  friend class ento::SValBuilder;
3546764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3550074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek  explicit CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {}
3566764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3576764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xupublic:
358a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  const CompoundValData* getValue() const {
35903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return static_cast<const CompoundValData*>(Data);
3606764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
3611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
362a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  typedef llvm::ImmutableList<SVal>::iterator iterator;
363a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  iterator begin() const;
3641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  iterator end() const;
3656764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3666764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  static bool classof(const SVal* V) {
3676764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind;
3686764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
3696764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
3706764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  static bool classof(const NonLoc* V) {
3716764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    return V->getSubKind() == CompoundValKind;
3726764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
3736764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu};
3741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
375a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekclass LazyCompoundVal : public NonLoc {
3769ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek  friend class ento::SValBuilder;
377a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek
3780074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek  explicit LazyCompoundVal(const LazyCompoundValData *D)
379a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek    : NonLoc(LazyCompoundValKind, D) {}
380a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekpublic:
381451ac091cd1868433985396a25cbbf2092ae8ca9Ted Kremenek  const LazyCompoundValData *getCVData() const {
382451ac091cd1868433985396a25cbbf2092ae8ca9Ted Kremenek    return static_cast<const LazyCompoundValData*>(Data);
383451ac091cd1868433985396a25cbbf2092ae8ca9Ted Kremenek  }
384bfcaf8048d1673320de60a22ca9c297d7484b2a8Zhongxing Xu  const void *getStore() const;
385a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  const TypedRegion *getRegion() const;
3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
387a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  static bool classof(const SVal *V) {
3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return V->getBaseKind() == NonLocKind &&
389a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek           V->getSubKind() == LazyCompoundValKind;
390a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  }
391a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  static bool classof(const NonLoc *V) {
392a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek    return V->getSubKind() == LazyCompoundValKind;
393a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  }
394a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek};
3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3969ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek} // end namespace ento::nonloc
397516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
398516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek//==------------------------------------------------------------------------==//
3991c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//  Subclasses of Loc.
4001c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==//
401516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek
4021c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunamespace loc {
4031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40414429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidisenum Kind { GotoLabelKind, MemRegionKind, ConcreteIntKind, ObjCPropRefKind };
405329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek
4061c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass GotoLabel : public Loc {
407aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
408ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner  explicit GotoLabel(LabelDecl *Label) : Loc(GotoLabelKind, Label) {}
4091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
410ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner  const LabelDecl *getLabel() const {
411ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner    return static_cast<const LabelDecl*>(Data);
412aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4141c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
415ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner    return V->getBaseKind() == LocKind && V->getSubKind() == GotoLabelKind;
416aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4181c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
419aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == GotoLabelKind;
4201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
421aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
4221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
423cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
4241c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass MemRegionVal : public Loc {
425aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
4260074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek  explicit MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {}
4279e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek
428993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  const MemRegion* getRegion() const {
42903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return static_cast<const MemRegion*>(Data);
430aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4327dfc9420babe83e236a47e752f8723bd06070d9dZhanyong Wan  const MemRegion* stripCasts() const;
4331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
434993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  template <typename REGION>
435993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek  const REGION* getRegionAs() const {
436993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek    return llvm::dyn_cast<REGION>(getRegion());
4371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
4381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4399e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek  inline bool operator==(const MemRegionVal& R) const {
4409e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return getRegion() == R.getRegion();
441aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4439e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek  inline bool operator!=(const MemRegionVal& R) const {
4449e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return getRegion() != R.getRegion();
445aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
447aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
4481c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
4491c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
4509e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek           V->getSubKind() == MemRegionKind;
451aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4531c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
4549e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek    return V->getSubKind() == MemRegionKind;
4551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
456aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
457aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
4581c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass ConcreteInt : public Loc {
459aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic:
4600074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek  explicit ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {}
4611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
462aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  const llvm::APSInt& getValue() const {
46303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    return *static_cast<const llvm::APSInt*>(Data);
464aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4652a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
466aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Transfer functions for binary/unary operations on ConcreteInts.
4679c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  SVal evalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
4688cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek                 const ConcreteInt& R) const;
4691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
470aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  // Implement isa<T> support.
4711c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const SVal* V) {
4721c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return V->getBaseKind() == LocKind &&
473aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek           V->getSubKind() == ConcreteIntKind;
474aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
4751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4761c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline bool classof(const Loc* V) {
477aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return V->getSubKind() == ConcreteIntKind;
478aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  }
479aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek};
4801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
48114429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis/// \brief Pseudo-location SVal used by the ExprEngine to simulate a "load" or
48214429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis/// "store" of an ObjC property for the dot syntax.
48314429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidisclass ObjCPropRef : public Loc {
48414429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidispublic:
48514429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis  explicit ObjCPropRef(const ObjCPropertyRefExpr *E)
48614429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis    : Loc(ObjCPropRefKind, E) {}
48714429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis
48814429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis  const ObjCPropertyRefExpr *getPropRefExpr() const {
48914429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis    return static_cast<const ObjCPropertyRefExpr *>(Data);
49014429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis  }
49114429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis
49214429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis  // Implement isa<T> support.
49314429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis  static inline bool classof(const SVal* V) {
49414429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis    return V->getBaseKind() == LocKind &&
49514429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis           V->getSubKind() == ObjCPropRefKind;
49614429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis  }
49714429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis
49814429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis  static inline bool classof(const Loc* V) {
49914429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis    return V->getSubKind() == ObjCPropRefKind;
50014429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis  }
50114429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis};
50214429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis
5039ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek} // end ento::loc namespace
5045a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis} // end GR namespace
5055a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis
5061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} // end clang namespace
507a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
5086f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremeneknamespace llvm {
5099c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic inline raw_ostream &operator<<(raw_ostream &os,
5109ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek                                            clang::ento::SVal V) {
5116f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek  V.dumpToStream(os);
5126f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek  return os;
5136f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek}
5145a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis
5156f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek} // end llvm namespace
5165a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis
517a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#endif
518