SVals.h revision 19e88c02889017753747e64606d9b1ad0041f11a
19cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner//== SVals.h - Abstract Values for Static Analysis ---------*- C++ -*--==//
20dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar//
30dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar//                     The LLVM Compiler Infrastructure
40dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar//
50dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar// This file is distributed under the University of Illinois Open Source
60dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar// License. See LICENSE.TXT for details.
70dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar//
80dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar//===----------------------------------------------------------------------===//
90dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar//
100dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar//  This file defines SVal, Loc, and NonLoc, classes that represent
110dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar//  abstract r-values for use with path-sensitive value tracking.
120dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar//
130dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar//===----------------------------------------------------------------------===//
140dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar
150dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar#ifndef LLVM_CLANG_GR_RVALUE_H
164c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall#define LLVM_CLANG_GR_RVALUE_H
17ce93399f26f23735b8e291321f18ad54f64cb58aChris Lattner
180dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar#include "clang/Basic/LLVM.h"
19b768807c49a1c7085def099b848631856af766faDaniel Dunbar#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
20de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
216b1da0ea19c12346192f5ea4d70872c13bfcc82aDaniel Dunbar#include "llvm/ADT/ImmutableList.h"
220dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar
23f6f8ae561ef78af169cbd2c067cae7ee4b2044e9Anders Carlsson//==------------------------------------------------------------------------==//
240dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar//  Base SVal types.
2506057cef0bcd7804e80f3ce2bbe352178396c715Chandler Carruth//==------------------------------------------------------------------------==//
26d0646bd7c11c12b34971b55e5c1bdd8439401b4cDevang Patel
27d14151d5f52fa9048d41d7539299243e05755ec4Daniel Dunbarnamespace clang {
2854d1ccbfcf19ddf39444f1b4018dd79487cc847bDaniel Dunbar
29f85e193739c953358c865005855253af4f68a497John McCallnamespace ento {
3097cb5a4a21866610227963fc3dcce9d89b2f7990Eli Friedman
310dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbarclass CompoundValData;
320dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbarclass LazyCompoundValData;
330dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbarclass ProgramState;
340dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbarclass BasicValueFactory;
350dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbarclass MemRegion;
3604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCallclass TypedRegion;
3704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCallclass MemRegionManager;
3804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCallclass ProgramStateManager;
3904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCallclass SValBuilder;
4004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall
41f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor/// SVal - This represents a symbolic expression, which can be either
42414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov///  an L-value or an R-value.
43414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov///
4452fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchikclass SVal {
4504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCallpublic:
4604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  enum BaseKind {
4704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    // The enumerators must be representable using 2 bits.
480b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall    UndefinedKind = 0,  // for subclass UndefinedVal (an uninitialized value)
490b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall    UnknownKind = 1,    // for subclass UnknownVal (a void value)
500b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall    LocKind = 2,        // for subclass Loc (an L-value)
51ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    NonLocKind = 3      // for subclass NonLoc (an R-value that's not
52ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall                        //   an L-value)
53ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  };
540b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall  enum { BaseBits = 2, BaseMask = 0x3 };
550b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall
560b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCallprotected:
57ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  const void *Data;
58ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
59ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  /// The lowest 2 bits are a BaseKind (0 -- 3).
600b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall  ///  The higher bits are an unsigned "kind" value.
610b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall  unsigned Kind;
620b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall
630b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall  explicit SVal(const void *d, bool isLoc, unsigned ValKind)
640b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall  : Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
650b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall
66ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  explicit SVal(BaseKind k, const void *D = NULL)
67ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall    : Data(D), Kind(k) {}
680b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall
690b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCallpublic:
700f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  explicit SVal() : Data(0), Kind(0) {}
710f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  ~SVal() {}
720b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall
730f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  /// BufferTy - A temporary buffer to hold a set of SVals.
74de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  typedef SmallVector<SVal,5> BufferTy;
75de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
760f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  inline unsigned getRawKind() const { return Kind; }
770f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
780f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
790f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
80de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  // This method is required for using SVal in a FoldingSetNode.  It
81de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  // extracts a unique signature for this SVal object.
820f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  inline void Profile(llvm::FoldingSetNodeID& ID) const {
830f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    ID.AddInteger((unsigned) getRawKind());
840f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    ID.AddPointer(Data);
850f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  }
860f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
870f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  inline bool operator==(const SVal& R) const {
880f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    return getRawKind() == R.getRawKind() && Data == R.Data;
890f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  }
90541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar
9145c25ba11cbf8c9a461def5b03f6ee9481e06769Daniel Dunbar  inline bool operator!=(const SVal& R) const {
920f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    return !(*this == R);
93de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
940f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
950f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  inline bool isUnknown() const {
960f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    return getRawKind() == UnknownKind;
970f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  }
980f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
990f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  inline bool isUndef() const {
1000f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    return getRawKind() == UndefinedKind;
1010f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  }
1020f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
1030f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  inline bool isUnknownOrUndef() const {
1040f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    return getRawKind() <= UnknownKind;
1050f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  }
1060f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
1070f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  inline bool isValid() const {
1088f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov    return getRawKind() > UnknownKind;
1098f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov  }
1108f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov
1118f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov  bool isConstant() const;
1128f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov
1138f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov  bool isConstant(int I) const;
1140f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
1150f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  bool isZeroConstant() const;
1160f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
1170f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  /// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true;
1180f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  bool hasConjuredSymbol() const;
1190f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
1200f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  /// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a
1210f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  /// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl.
1228f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov  /// Otherwise return 0.
1230f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  const FunctionDecl *getAsFunctionDecl() const;
1240b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall
1250b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall  /// If this SVal is a location (subclasses Loc) and
126de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  /// wraps a symbol, return that SymbolRef.  Otherwise return 0.
1270f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  SymbolRef getAsLocSymbol() const;
1280b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall
1290f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  /// Get the symbol in the SVal or its base region.
130de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  SymbolRef getLocSymbolInBase() const;
1310f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
132bac7c250c9b098ee3d637c8ed77da62e860d9244Daniel Dunbar  /// If this SVal wraps a symbol return that SymbolRef.
133bac7c250c9b098ee3d637c8ed77da62e860d9244Daniel Dunbar  /// Otherwise, return 0.
13404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  SymbolRef getAsSymbol() const;
135bac7c250c9b098ee3d637c8ed77da62e860d9244Daniel Dunbar
136bac7c250c9b098ee3d637c8ed77da62e860d9244Daniel Dunbar  /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
13704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  ///  return that expression.  Otherwise return NULL.
138bac7c250c9b098ee3d637c8ed77da62e860d9244Daniel Dunbar  const SymExpr *getAsSymbolicExpression() const;
139bac7c250c9b098ee3d637c8ed77da62e860d9244Daniel Dunbar
14004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  const SymExpr* getAsSymExpr() const;
141bac7c250c9b098ee3d637c8ed77da62e860d9244Daniel Dunbar
142f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  const MemRegion *getAsRegion() const;
143f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor
144f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  void dumpToStream(raw_ostream &OS) const;
14552fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  void dump() const;
14652fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik
14752fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  SymExpr::symbol_iterator symbol_begin() const {
148414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    const SymExpr *SE = getAsSymbolicExpression();
149414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (SE)
150414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return SE->symbol_begin();
15104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    else
15245c25ba11cbf8c9a461def5b03f6ee9481e06769Daniel Dunbar      return SymExpr::symbol_iterator();
15345c25ba11cbf8c9a461def5b03f6ee9481e06769Daniel Dunbar  }
154de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
155de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  SymExpr::symbol_iterator symbol_end() const {
156de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return SymExpr::symbol_end();
157de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
158de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
159de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  // Implement isa<T> support.
160de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  static inline bool classof(const SVal*) { return true; }
161de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall};
1620b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall
163375c31c4673f83f925de221752cf801c2fbbb246Anders Carlsson
164de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallclass UndefinedVal : public SVal {
1650b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCallpublic:
1660f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  UndefinedVal() : SVal(UndefinedKind) {}
1679c6082fe89c61af697f017aa80937581cc2128d8Tilmann Scheller  UndefinedVal(const void *D) : SVal(UndefinedKind, D) {}
168375c31c4673f83f925de221752cf801c2fbbb246Anders Carlsson
169375c31c4673f83f925de221752cf801c2fbbb246Anders Carlsson  static inline bool classof(const SVal* V) {
170de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return V->getBaseKind() == UndefinedKind;
171de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
172de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
173de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  const void *getData() const { return Data; }
174de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall};
175de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
176fc4002872864e3c29c896000519ae989b6fdb7ddJohn McCallclass DefinedOrUnknownSVal : public SVal {
177fc4002872864e3c29c896000519ae989b6fdb7ddJohn McCallprivate:
178fc4002872864e3c29c896000519ae989b6fdb7ddJohn McCall  // Do not implement.  We want calling these methods to be a compiler
179de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  // error since they are tautologically false.
1801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool isUndef() const;
181de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  bool isValid() const;
182de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
183de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallprotected:
184de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  explicit DefinedOrUnknownSVal(const void *d, bool isLoc, unsigned ValKind)
185de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    : SVal(d, isLoc, ValKind) {}
1860f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
187f6f8ae561ef78af169cbd2c067cae7ee4b2044e9Anders Carlsson  explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL)
188f6f8ae561ef78af169cbd2c067cae7ee4b2044e9Anders Carlsson    : SVal(k, D) {}
189de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
190de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallpublic:
191de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    // Implement isa<T> support.
192de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  static inline bool classof(const SVal *V) {
193de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return !V->isUndef();
194de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
195de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall};
196de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
197f6c56e2323c3f973253805a2f35629f3253ebed4Anders Carlssonclass UnknownVal : public DefinedOrUnknownSVal {
198de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallpublic:
1990b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall  explicit UnknownVal() : DefinedOrUnknownSVal(UnknownKind) {}
2004c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall
2014c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  static inline bool classof(const SVal *V) {
202de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return V->getBaseKind() == UnknownKind;
203de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
2044c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall};
2054c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall
206de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallclass DefinedSVal : public DefinedOrUnknownSVal {
2074c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCallprivate:
2080f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  // Do not implement.  We want calling these methods to be a compiler
2098f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov  // error since they are tautologically true/false.
2100f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  bool isUnknown() const;
211f6c56e2323c3f973253805a2f35629f3253ebed4Anders Carlsson  bool isUnknownOrUndef() const;
212f6c56e2323c3f973253805a2f35629f3253ebed4Anders Carlsson  bool isValid() const;
213de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallprotected:
214de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  explicit DefinedSVal(const void *d, bool isLoc, unsigned ValKind)
215de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    : DefinedOrUnknownSVal(d, isLoc, ValKind) {}
216de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallpublic:
217de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  // Implement isa<T> support.
218de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  static inline bool classof(const SVal *V) {
219de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return !V->isUnknownOrUndef();
220de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
221de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall};
2224c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall
223de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallclass NonLoc : public DefinedSVal {
2240b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCallprotected:
2254c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  explicit NonLoc(unsigned SubKind, const void *d)
2264c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall    : DefinedSVal(d, false, SubKind) {}
2278f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov
2284c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCallpublic:
2290f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  void dumpToStream(raw_ostream &Out) const;
2308f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov
2310f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  // Implement isa<T> support.
2320f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  static inline bool classof(const SVal* V) {
233f6c56e2323c3f973253805a2f35629f3253ebed4Anders Carlsson    return V->getBaseKind() == NonLocKind;
234f6c56e2323c3f973253805a2f35629f3253ebed4Anders Carlsson  }
235de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall};
236de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
237de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallclass Loc : public DefinedSVal {
238de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallprotected:
2393eb67ca786ef75bad43d30349c7334b921ba0dbcChris Lattner  explicit Loc(unsigned SubKind, const void *D)
240f6f8ae561ef78af169cbd2c067cae7ee4b2044e9Anders Carlsson  : DefinedSVal(const_cast<void*>(D), true, SubKind) {}
241de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
2421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic:
243ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  void dumpToStream(raw_ostream &Out) const;
244de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
245ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  Loc(const Loc& X) : DefinedSVal(X.Data, true, X.getSubKind()) {}
246de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
247de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  // Implement isa<T> support.
248de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  static inline bool classof(const SVal* V) {
249de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return V->getBaseKind() == LocKind;
250de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
2510f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
2520f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  static inline bool isLocType(QualType T) {
2530f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    return T->isAnyPointerType() || T->isBlockPointerType() ||
2540f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall           T->isReferenceType();
255de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
256de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall};
257ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
2580f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall//==------------------------------------------------------------------------==//
2590dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar//  Subclasses of NonLoc.
2600dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar//==------------------------------------------------------------------------==//
261de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
262de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallnamespace nonloc {
263de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
264de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallenum Kind { ConcreteIntKind, SymbolValKind, SymExprValKind,
265de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall            LocAsIntegerKind, CompoundValKind, LazyCompoundValKind };
266de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
267de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall/// \brief Represents symbolic expression.
268de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallclass SymbolVal : public NonLoc {
269de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallpublic:
270de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {}
271de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
272de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  SymbolRef getSymbol() const {
273de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return (const SymExpr*) Data;
274de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
275de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
276de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  bool isExpression() {
277de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return !isa<SymbolData>(getSymbol());
278de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
279de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
280de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  static inline bool classof(const SVal* V) {
281de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return V->getBaseKind() == NonLocKind &&
282541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar           V->getSubKind() == SymbolValKind;
283491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  }
2840b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall
285de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  static inline bool classof(const NonLoc* V) {
2860b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall    return V->getSubKind() == SymbolValKind;
287f85e193739c953358c865005855253af4f68a497John McCall  }
288f85e193739c953358c865005855253af4f68a497John McCall};
289f85e193739c953358c865005855253af4f68a497John McCall
290f85e193739c953358c865005855253af4f68a497John McCall/// \brief Value representing integer constant.
2914e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikieclass ConcreteInt : public NonLoc {
292f85e193739c953358c865005855253af4f68a497John McCallpublic:
293f85e193739c953358c865005855253af4f68a497John McCall  explicit ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {}
294f85e193739c953358c865005855253af4f68a497John McCall
295de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  const llvm::APSInt& getValue() const {
296de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return *static_cast<const llvm::APSInt*>(Data);
297de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
2980f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
2990f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  // Transfer functions for binary/unary operations on ConcreteInts.
3000dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar  SVal evalBinOp(SValBuilder &svalBuilder, BinaryOperator::Opcode Op,
3010dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar                 const ConcreteInt& R) const;
302de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
303de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  ConcreteInt evalComplement(SValBuilder &svalBuilder) const;
304b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson
305b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson  ConcreteInt evalMinus(SValBuilder &svalBuilder) const;
3069cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer
307b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson  // Implement isa<T> support.
308de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  static inline bool classof(const SVal* V) {
309b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson    return V->getBaseKind() == NonLocKind &&
310b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson           V->getSubKind() == ConcreteIntKind;
311de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
312de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
313de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  static inline bool classof(const NonLoc* V) {
314de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return V->getSubKind() == ConcreteIntKind;
3159cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer  }
316de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall};
317de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
318de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallclass LocAsInteger : public NonLoc {
319de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  friend class ento::SValBuilder;
320de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
3210f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  explicit LocAsInteger(const std::pair<SVal, uintptr_t>& data) :
3220f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    NonLoc(LocAsIntegerKind, &data) {
323de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall      assert (isa<Loc>(data.first));
324de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    }
325de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
326de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallpublic:
327de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
328de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  Loc getLoc() const {
329de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    const std::pair<SVal, uintptr_t> *D =
330de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall      static_cast<const std::pair<SVal, uintptr_t> *>(Data);
331de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return cast<Loc>(D->first);
3320f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  }
3330f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
334b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson  const Loc& getPersistentLoc() const {
335b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson    const std::pair<SVal, uintptr_t> *D =
336de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall      static_cast<const std::pair<SVal, uintptr_t> *>(Data);
3370f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    const SVal& V = D->first;
3380f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    return cast<Loc>(V);
3390f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  }
3400f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
341541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar  unsigned getNumBits() const {
342de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    const std::pair<SVal, uintptr_t> *D =
343de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall      static_cast<const std::pair<SVal, uintptr_t> *>(Data);
344725ad31086e3d6c41afa10c43db44f2e7060a961Daniel Dunbar    return D->second;
345de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
3460f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
3470f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  // Implement isa<T> support.
3480f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  static inline bool classof(const SVal* V) {
3490f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    return V->getBaseKind() == NonLocKind &&
3500f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall           V->getSubKind() == LocAsIntegerKind;
3510f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  }
3520f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
3530f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  static inline bool classof(const NonLoc* V) {
3540f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    return V->getSubKind() == LocAsIntegerKind;
3550f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  }
3560f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall};
3570f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
3580f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCallclass CompoundVal : public NonLoc {
3590f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  friend class ento::SValBuilder;
3600f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
3610f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  explicit CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {}
3628f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov
3630f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCallpublic:
3640f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  const CompoundValData* getValue() const {
3650dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar    return static_cast<const CompoundValData*>(Data);
3660dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar  }
367de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
368de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  typedef llvm::ImmutableList<SVal>::iterator iterator;
369de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  iterator begin() const;
370de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  iterator end() const;
371de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
372541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar  static bool classof(const SVal* V) {
373de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind;
374de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
375bb36d331f439f49859efcfb4435c61762fbba6f9Daniel Dunbar
376de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  static bool classof(const NonLoc* V) {
377de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return V->getSubKind() == CompoundValKind;
378de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
379de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall};
3800f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall
3810f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCallclass LazyCompoundVal : public NonLoc {
382541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar  friend class ento::SValBuilder;
383541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar
384de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  explicit LazyCompoundVal(const LazyCompoundValData *D)
3850f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    : NonLoc(LazyCompoundValKind, D) {}
3860f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCallpublic:
387d26bc76c98006609002d9930f8840490e88ac5b5John McCall  const LazyCompoundValData *getCVData() const {
388d26bc76c98006609002d9930f8840490e88ac5b5John McCall    return static_cast<const LazyCompoundValData*>(Data);
389de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
390de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  const void *getStore() const;
391de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  const TypedRegion *getRegion() const;
392de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
3930f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  static bool classof(const SVal *V) {
3940f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    return V->getBaseKind() == NonLocKind &&
3950f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall           V->getSubKind() == LazyCompoundValKind;
3960f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall  }
397ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall  static bool classof(const NonLoc *V) {
398de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return V->getSubKind() == LazyCompoundValKind;
399de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
400ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall};
401ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall
402ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall} // end namespace ento::nonloc
403de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
40404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall//==------------------------------------------------------------------------==//
40540a6be686e5d5bb4198f1affda574e8a4b3a7710Daniel Dunbar//  Subclasses of Loc.
40640a6be686e5d5bb4198f1affda574e8a4b3a7710Daniel Dunbar//==------------------------------------------------------------------------==//
407de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
40840a6be686e5d5bb4198f1affda574e8a4b3a7710Daniel Dunbarnamespace loc {
409de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
410de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallenum Kind { GotoLabelKind, MemRegionKind, ConcreteIntKind, ObjCPropRefKind };
41140a6be686e5d5bb4198f1affda574e8a4b3a7710Daniel Dunbar
41240a6be686e5d5bb4198f1affda574e8a4b3a7710Daniel Dunbarclass GotoLabel : public Loc {
41340a6be686e5d5bb4198f1affda574e8a4b3a7710Daniel Dunbarpublic:
414de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  explicit GotoLabel(LabelDecl *Label) : Loc(GotoLabelKind, Label) {}
415de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
416de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  const LabelDecl *getLabel() const {
417541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar    return static_cast<const LabelDecl*>(Data);
418de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
419de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
42071305cc81bd379ddb8aa0d49e268267383202ca9Chris Lattner  static inline bool classof(const SVal* V) {
42188c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbar    return V->getBaseKind() == LocKind && V->getSubKind() == GotoLabelKind;
422ee5dcd064a811edc90f6c1fb31a837b6c961fed7Chris Lattner  }
4239cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer
424800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner  static inline bool classof(const Loc* V) {
425800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner    return V->getSubKind() == GotoLabelKind;
426800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner  }
427de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall};
428de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
429de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
4309cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencerclass MemRegionVal : public Loc {
431800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattnerpublic:
432800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner  explicit MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {}
433800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner
4349cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  /// \brief Get the underlining region.
4359cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer  const MemRegion* getRegion() const {
436de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return static_cast<const MemRegion*>(Data);
437de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
438d26c07142710790b820a66245939668f62eaf2d9Chris Lattner
43988c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbar  /// \brief Get the underlining region and strip casts.
4400dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar  const MemRegion* stripCasts() const;
44117b708d61827cd86278e9580b041dd6cbadf07d3Daniel Dunbar
442de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  template <typename REGION>
443de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  const REGION* getRegionAs() const {
444de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return llvm::dyn_cast<REGION>(getRegion());
445de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
446de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
447de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  inline bool operator==(const MemRegionVal& R) const {
448de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return getRegion() == R.getRegion();
449de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
450de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
451de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  inline bool operator!=(const MemRegionVal& R) const {
452de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return getRegion() != R.getRegion();
453de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
454de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
455de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  // Implement isa<T> support.
456de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  static inline bool classof(const SVal* V) {
457de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return V->getBaseKind() == LocKind &&
458de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall           V->getSubKind() == MemRegionKind;
459de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
460de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
461de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  static inline bool classof(const Loc* V) {
462de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return V->getSubKind() == MemRegionKind;
46388c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbar  }
46488c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbar};
46588c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbar
46688c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbarclass ConcreteInt : public Loc {
46742e06119496e84e74cfc60230b18fcb53b35eb1cJohn McCallpublic:
4685f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  explicit ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {}
469194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson
470194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson  const llvm::APSInt& getValue() const {
471194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson    return *static_cast<const llvm::APSInt*>(Data);
472194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson  }
473eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov
474194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson  // Transfer functions for binary/unary operations on ConcreteInts.
475194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson  SVal evalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
476194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson                 const ConcreteInt& R) const;
477eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov
478eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov  // Implement isa<T> support.
479eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov  static inline bool classof(const SVal* V) {
480eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov    return V->getBaseKind() == LocKind &&
481eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov           V->getSubKind() == ConcreteIntKind;
482eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov  }
483eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov
484eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov  static inline bool classof(const Loc* V) {
485581deb3da481053c4993c7600f97acf7768caac5David Blaikie    return V->getSubKind() == ConcreteIntKind;
486eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov  }
487eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov};
488eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov
489eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov/// \brief Pseudo-location SVal used by the ExprEngine to simulate a "load" or
490eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov/// "store" of an ObjC property for the dot syntax.
491eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikovclass ObjCPropRef : public Loc {
492eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikovpublic:
493eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov  explicit ObjCPropRef(const ObjCPropertyRefExpr *E)
494eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov    : Loc(ObjCPropRefKind, E) {}
495eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov
496eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov  const ObjCPropertyRefExpr *getPropRefExpr() const {
497eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov    return static_cast<const ObjCPropertyRefExpr *>(Data);
498eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov  }
499581deb3da481053c4993c7600f97acf7768caac5David Blaikie
500eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov  // Implement isa<T> support.
501581deb3da481053c4993c7600f97acf7768caac5David Blaikie  static inline bool classof(const SVal* V) {
502eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov    return V->getBaseKind() == LocKind &&
503194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson           V->getSubKind() == ObjCPropRefKind;
504194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson  }
505194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson
506194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson  static inline bool classof(const Loc* V) {
507194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson    return V->getSubKind() == ObjCPropRefKind;
508194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson  }
509194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson};
5105627377df5439a1d3d46a4e4cef4ae44f84a322bDaniel Dunbar
5115627377df5439a1d3d46a4e4cef4ae44f84a322bDaniel Dunbar} // end ento::loc namespace
5121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} // end GR namespace
5135627377df5439a1d3d46a4e4cef4ae44f84a322bDaniel Dunbar
5145627377df5439a1d3d46a4e4cef4ae44f84a322bDaniel Dunbar} // end clang namespace
5151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpnamespace llvm {
517194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilsonstatic inline raw_ostream &operator<<(raw_ostream &os,
518194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson                                            clang::ento::SVal V) {
519194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson  V.dumpToStream(os);
520194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson  return os;
521194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson}
522377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman
523194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson} // end llvm namespace
524194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson
525194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson#endif
526eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov