SVals.h revision 369f447eded97e6048ced02c0c2be3842f61fc1c
122ab7a4d900ed53285fd0b6720e7b43af84724d8Zhongxing Xu//== SVals.h - Abstract Values for Static Analysis ---------*- C++ -*--==// 2a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 3a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// The LLVM Compiler Infrastructure 4a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 5a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// This file is distributed under the University of Illinois Open Source 6a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// License. See LICENSE.TXT for details. 7a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 8a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===// 9a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 101c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu// This file defines SVal, Loc, and NonLoc, classes that represent 11a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// abstract r-values for use with path-sensitive value tracking. 12a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 13a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===// 14a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 15a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H 16a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#define LLVM_CLANG_ANALYSIS_RVALUE_H 17a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 18632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek#include "clang/Analysis/PathSensitive/SymbolManager.h" 19a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#include "llvm/Support/Casting.h" 20632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek#include "llvm/ADT/ImmutableList.h" 21d131c4ff6133c691f91d8a82e7197d97b187425fTed Kremenek 220f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremenek//==------------------------------------------------------------------------==// 231c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu// Base SVal types. 241c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==// 25a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 260f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremeneknamespace clang { 27632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek 28632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenekclass CompoundValData; 29632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenekclass BasicValueFactory; 309e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass MemRegion; 31a1718c78770db93d1b762620f07728a56786f2aeZhongxing Xuclass MemRegionManager; 329e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass GRStateManager; 339e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 341c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SVal { 35a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 361c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu enum BaseKind { UndefinedKind, UnknownKind, LocKind, NonLocKind }; 37aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek enum { BaseBits = 2, BaseMask = 0x3 }; 38a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 3990e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenekprotected: 40a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek void* Data; 41a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek unsigned Kind; 42a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 43a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected: 441c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu SVal(const void* d, bool isLoc, unsigned ValKind) 45a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek : Data(const_cast<void*>(d)), 461c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {} 47a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 481c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu explicit SVal(BaseKind k, void* D = NULL) 4905a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek : Data(D), Kind(k) {} 50a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 51a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 526764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu SVal() : Data(0), Kind(0) {} 531c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu ~SVal() {}; 54a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 551c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu /// BufferTy - A temporary buffer to hold a set of SVals. 561c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu typedef llvm::SmallVector<SVal,5> BufferTy; 57a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 58aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline unsigned getRawKind() const { return Kind; } 59aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); } 60aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; } 61a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 62aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline void Profile(llvm::FoldingSetNodeID& ID) const { 63a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek ID.AddInteger((unsigned) getRawKind()); 64a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek ID.AddPointer(reinterpret_cast<void*>(Data)); 65a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 666764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 671c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu inline bool operator==(const SVal& R) const { 68aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getRawKind() == R.getRawKind() && Data == R.Data; 69a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 7094c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek 711c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu inline bool operator!=(const SVal& R) const { 72dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek return !(*this == R); 73dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek } 744193eca10ce0cc8b2dae887e935a43b26f492b5bZhongxing Xu 75aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline bool isUnknown() const { 76aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getRawKind() == UnknownKind; 77aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 78aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 794a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek inline bool isUndef() const { 804a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek return getRawKind() == UndefinedKind; 81aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 82aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 834a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek inline bool isUnknownOrUndef() const { 84aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getRawKind() <= UnknownKind; 85aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 86cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 87aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline bool isValid() const { 88aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getRawKind() > UnknownKind; 89aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 90a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 9140fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek bool isZeroConstant() const; 92369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu 93369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu /// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a 94369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu /// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl. 95369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu /// Otherwise return 0. 96369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu const FunctionDecl* getAsFunctionDecl() const; 9740fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek 9894c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek /// getAsLocSymbol - If this SVal is a location (subclasses Loc) and 99e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek /// wraps a symbol, return that SymbolRef. Otherwise return a SymbolData* 10094c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek SymbolRef getAsLocSymbol() const; 10194c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek 10294c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek /// getAsSymbol - If this Sval wraps a symbol return that SymbolRef. 10394c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek /// Otherwise return a SymbolRef where 'isValid()' returns false. 10494c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek SymbolRef getAsSymbol() const; 105e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek 106e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then 107e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek /// return that expression. Otherwise return NULL. 108e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymExpr *getAsSymbolicExpression() const; 10994c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek 110a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek void print(std::ostream& OS) const; 1119012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu void print(llvm::raw_ostream& OS) const; 112d8e9f0dc737133d4e8342f39389064620f5a7f8fTed Kremenek void printStdErr() const; 113e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek 114e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek // Iterators. 1150d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek class symbol_iterator { 116e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek llvm::SmallVector<const SymExpr*, 5> itr; 117e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek void expand(); 1180d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek public: 119e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek symbol_iterator() {} 120e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek symbol_iterator(const SymExpr* SE); 1210d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek 122e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek symbol_iterator& operator++(); 123e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek SymbolRef operator*(); 1240d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek 125e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek bool operator==(const symbol_iterator& X) const; 126e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek bool operator!=(const symbol_iterator& X) const; 1270d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek }; 1280d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek 129e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek symbol_iterator symbol_begin() const { 130e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymExpr *SE = getAsSymbolicExpression(); 131e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek if (SE) 132e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return symbol_iterator(SE); 133e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek else 134e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return symbol_iterator(); 135e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek } 136e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek 137e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek symbol_iterator symbol_end() const { return symbol_iterator(); } 13890e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek 139a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek // Implement isa<T> support. 1401c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal*) { return true; } 141a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 142a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 1431c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass UnknownVal : public SVal { 144a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 1451c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu UnknownVal() : SVal(UnknownKind) {} 146a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 1471c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 1482203118815997a0efcf19217e057bd20e33303e7Ted Kremenek return V->getBaseKind() == UnknownKind; 149a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 150a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 151a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 1521c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass UndefinedVal : public SVal { 153a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 1541c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu UndefinedVal() : SVal(UndefinedKind) {} 1551c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu UndefinedVal(void* D) : SVal(UndefinedKind, D) {} 156a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 1571c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 1584a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek return V->getBaseKind() == UndefinedKind; 15905a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek } 16005a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek 16105a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek void* getData() const { return Data; } 162a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 163a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 1641c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass NonLoc : public SVal { 165a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected: 1661c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu NonLoc(unsigned SubKind, const void* d) : SVal(d, false, SubKind) {} 167a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 168a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 1699012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu void print(llvm::raw_ostream& Out) const; 170a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 1711c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu // Utility methods to create NonLocs. 172a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu 17314553abd17d303b0b310b3ab1523eb0d30d8121cTed Kremenek static NonLoc MakeIntVal(BasicValueFactory& BasicVals, uint64_t X, 17414553abd17d303b0b310b3ab1523eb0d30d8121cTed Kremenek bool isUnsigned); 1756613d08a19aa6ce9b6330487f3bfac841d4b8a4dZhongxing Xu 1768b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu static NonLoc MakeVal(BasicValueFactory& BasicVals, uint64_t X, 1778b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu unsigned BitWidth, bool isUnsigned); 1788b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu 1791c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static NonLoc MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T); 180a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 1811c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static NonLoc MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I); 182e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu 183e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu static NonLoc MakeVal(BasicValueFactory& BasicVals, const llvm::APInt& I, 184e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu bool isUnsigned); 1858b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu 1868b8627380638d0889d6924d1ec10d42a9c743593Zhongxing Xu static NonLoc MakeVal(BasicValueFactory& BasicVals, const llvm::APSInt& I); 187a548846b471f7ca05ec6038c7d9d3b4d0de777ccTed Kremenek 1881c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static NonLoc MakeIntTruthVal(BasicValueFactory& BasicVals, bool b); 1896764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 190632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek static NonLoc MakeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals, 1916764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu BasicValueFactory& BasicVals); 1926764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 193a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek // Implement isa<T> support. 1941c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 1951c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == NonLocKind; 196a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 197a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 198a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 1991c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass Loc : public SVal { 200a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected: 2011c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu Loc(unsigned SubKind, const void* D) 202be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek : SVal(const_cast<void*>(D), true, SubKind) {} 203da9ae6088b9543134a6561a412b79530e290408dTed Kremenek 204cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenekpublic: 2059012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu void print(llvm::raw_ostream& Out) const; 2062fdf555af136cb017f4dc0c26d5d3415d122e1ffZhongxing Xu 207be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek Loc(const Loc& X) : SVal(X.Data, true, X.getSubKind()) {} 208be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek Loc& operator=(const Loc& X) { memcpy(this, &X, sizeof(Loc)); return *this; } 209be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek 2102fdf555af136cb017f4dc0c26d5d3415d122e1ffZhongxing Xu static Loc MakeVal(const MemRegion* R); 211d59cccc0b6cd4485897526699fe98514805c1883Ted Kremenek 2121c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static Loc MakeVal(AddrLabelExpr* E); 2134193eca10ce0cc8b2dae887e935a43b26f492b5bZhongxing Xu 214da9ae6088b9543134a6561a412b79530e290408dTed Kremenek static Loc MakeNull(BasicValueFactory &BasicVals); 215da9ae6088b9543134a6561a412b79530e290408dTed Kremenek 216a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek // Implement isa<T> support. 2171c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 2181c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == LocKind; 219a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 2200e470a5326ccf2f6a7c3d12b2aa54a7af2292837Ted Kremenek 2211c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool IsLocType(QualType T) { 222dfd296bae332d10a854620c059f5d9cef98764b8Ted Kremenek return T->isPointerType() || T->isObjCQualifiedIdType() 223dfd296bae332d10a854620c059f5d9cef98764b8Ted Kremenek || T->isBlockPointerType(); 2240e470a5326ccf2f6a7c3d12b2aa54a7af2292837Ted Kremenek } 225a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 226a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 227a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//==------------------------------------------------------------------------==// 2281c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu// Subclasses of NonLoc. 2291c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==// 230a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 2311c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunamespace nonloc { 232329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek 233e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekenum Kind { ConcreteIntKind, SymbolValKind, SymExprValKind, 2346764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu LocAsIntegerKind, CompoundValKind }; 235329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek 2361c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SymbolVal : public NonLoc { 237aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 238e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {} 239aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 2402dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek SymbolRef getSymbol() const { 241e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return (const SymbolData*) Data; 242aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 243aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 2441c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 2451c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == NonLocKind && 246aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == SymbolValKind; 247aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 248aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 2491c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const NonLoc* V) { 250aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == SymbolValKind; 251aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 252aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 2539466aa8cf38aa8e87fe3e2cd8005fc245d04f9b7Ted Kremenek 254e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekclass SymExprVal : public NonLoc { 255aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 256e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek SymExprVal(const SymExpr *SE) 257e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek : NonLoc(SymExprValKind, reinterpret_cast<const void*>(SE)) {} 258329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek 259e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymExpr *getSymbolicExpression() const { 260e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return reinterpret_cast<SymExpr*>(Data); 261aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 262aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 2631c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 2641c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == NonLocKind && 265e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek V->getSubKind() == SymExprValKind; 266aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 267aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 2681c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const NonLoc* V) { 269e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return V->getSubKind() == SymExprValKind; 270aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 271aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 272aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 2731c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass ConcreteInt : public NonLoc { 274aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 2751c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {} 276aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 277aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek const llvm::APSInt& getValue() const { 278aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return *static_cast<llvm::APSInt*>(Data); 279aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 280aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 281aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Transfer functions for binary/unary operations on ConcreteInts. 2821c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op, 2838cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek const ConcreteInt& R) const; 284aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 285240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek ConcreteInt EvalComplement(BasicValueFactory& BasicVals) const; 286aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 287240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek ConcreteInt EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const; 288aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 289aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Implement isa<T> support. 2901c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 2911c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == NonLocKind && 292aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == ConcreteIntKind; 293aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 294aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 2951c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const NonLoc* V) { 296aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == ConcreteIntKind; 297aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 298aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 299a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 3001c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass LocAsInteger : public NonLoc { 3011c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu LocAsInteger(const std::pair<SVal, uintptr_t>& data) : 3021c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu NonLoc(LocAsIntegerKind, &data) { 3031c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu assert (isa<Loc>(data.first)); 304718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek } 3050fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek 3060fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenekpublic: 3070fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek 3081c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu Loc getLoc() const { 3091c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return cast<Loc>(((std::pair<SVal, uintptr_t>*) Data)->first); 3100fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek } 3110fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek 3121c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu const Loc& getPersistentLoc() const { 3131c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu const SVal& V = ((std::pair<SVal, uintptr_t>*) Data)->first; 3141c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return cast<Loc>(V); 3150fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek } 3160fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek 3170fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek unsigned getNumBits() const { 3181c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return ((std::pair<SVal, unsigned>*) Data)->second; 3190fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek } 3200fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek 3210fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek // Implement isa<T> support. 3221c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 3231c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == NonLocKind && 3241c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu V->getSubKind() == LocAsIntegerKind; 3250fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek } 3260fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek 3271c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const NonLoc* V) { 3281c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getSubKind() == LocAsIntegerKind; 3290fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek } 3300fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek 331632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek static LocAsInteger Make(BasicValueFactory& Vals, Loc V, unsigned Bits); 3320fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek}; 3336764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 3346764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xuclass CompoundVal : public NonLoc { 3356764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu friend class NonLoc; 3366764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 3376764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {} 3386764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 3396764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xupublic: 340a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek const CompoundValData* getValue() const { 3416764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu return static_cast<CompoundValData*>(Data); 3426764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu } 343a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek 344a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek typedef llvm::ImmutableList<SVal>::iterator iterator; 345a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek iterator begin() const; 346a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek iterator end() const; 3476764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 3486764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu static bool classof(const SVal* V) { 3496764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind; 3506764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu } 3516764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 3526764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu static bool classof(const NonLoc* V) { 3536764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu return V->getSubKind() == CompoundValKind; 3546764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu } 3556764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu}; 3560fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek 3571c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu} // end namespace clang::nonloc 358516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek 359516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek//==------------------------------------------------------------------------==// 3601c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu// Subclasses of Loc. 3611c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==// 362516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek 3631c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunamespace loc { 364516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek 3653330dcb0da654fb06e78dc410ba15ab90c1b08e7Zhongxing Xuenum Kind { GotoLabelKind, MemRegionKind, FuncValKind, ConcreteIntKind }; 366329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek 3671c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass GotoLabel : public Loc { 368aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 3691c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu GotoLabel(LabelStmt* Label) : Loc(GotoLabelKind, Label) {} 370aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 371aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek LabelStmt* getLabel() const { 372aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return static_cast<LabelStmt*>(Data); 373aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 374aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 3751c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 3761c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == LocKind && 377aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == GotoLabelKind; 378aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 379aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 3801c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const Loc* V) { 381aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == GotoLabelKind; 382aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 383aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 384aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 385cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 3861c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass MemRegionVal : public Loc { 387aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 3881c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {} 3899e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 390993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek const MemRegion* getRegion() const { 3919e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek return static_cast<MemRegion*>(Data); 392aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 393aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 394993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek template <typename REGION> 395993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek const REGION* getRegionAs() const { 396993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek return llvm::dyn_cast<REGION>(getRegion()); 397993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek } 398993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek 3999e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek inline bool operator==(const MemRegionVal& R) const { 4009e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek return getRegion() == R.getRegion(); 401aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 402aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 4039e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek inline bool operator!=(const MemRegionVal& R) const { 4049e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek return getRegion() != R.getRegion(); 405aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 406aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 407aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Implement isa<T> support. 4081c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 4091c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == LocKind && 4109e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek V->getSubKind() == MemRegionKind; 411aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 412aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 4131c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const Loc* V) { 4149e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek return V->getSubKind() == MemRegionKind; 415aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 416aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 417aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 4181c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass FuncVal : public Loc { 419aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 4201c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu FuncVal(const FunctionDecl* fd) : Loc(FuncValKind, fd) {} 421aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 422aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek FunctionDecl* getDecl() const { 423aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return static_cast<FunctionDecl*>(Data); 424aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 425aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 426aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline bool operator==(const FuncVal& R) const { 427aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getDecl() == R.getDecl(); 428aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 429aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 430aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline bool operator!=(const FuncVal& R) const { 431aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getDecl() != R.getDecl(); 432aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 433aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 434aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Implement isa<T> support. 4351c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 4361c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == LocKind && 437aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == FuncValKind; 438aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 439aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 4401c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const Loc* V) { 441aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == FuncValKind; 442aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 443aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 444aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 4451c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass ConcreteInt : public Loc { 446aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 4471c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {} 448aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 449aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek const llvm::APSInt& getValue() const { 450aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return *static_cast<llvm::APSInt*>(Data); 451aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 4522a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek 453aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Transfer functions for binary/unary operations on ConcreteInts. 4541c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op, 4558cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek const ConcreteInt& R) const; 456aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 457aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Implement isa<T> support. 4581c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 4591c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == LocKind && 460aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == ConcreteIntKind; 461aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 462aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 4631c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const Loc* V) { 464aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == ConcreteIntKind; 465aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 466aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 467aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 4681c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu} // end clang::loc namespace 469a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} // end clang namespace 470a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 471a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#endif 472