1d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek//== SymbolManager.h - Management of Symbolic Values ------------*- C++ -*--==// 2d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek// 3d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek// The LLVM Compiler Infrastructure 4d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek// 5d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek// This file is distributed under the University of Illinois Open Source 6d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek// License. See LICENSE.TXT for details. 7d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek// 8d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek//===----------------------------------------------------------------------===// 9d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek// 10843e934ba8c6ebc00d2f6969a50af7074597e8e3Gabor Greif// This file defines SymbolManager, a class that manages symbolic values 11d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis// created for use by ExprEngine and related classes. 12d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek// 13d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek//===----------------------------------------------------------------------===// 14d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek 15176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMBOLMANAGER_H 16176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMBOLMANAGER_H 17d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek 18d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek#include "clang/AST/Decl.h" 19d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek#include "clang/AST/Expr.h" 205e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramer#include "clang/Analysis/AnalysisContext.h" 21d47d3b0cfeb7e8564ff77f48130fe63282b6d127Chris Lattner#include "clang/Basic/LLVM.h" 22882998923889a2fcce9b49696506c499e22cf38fTed Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h" 23882998923889a2fcce9b49696506c499e22cf38fTed Kremenek#include "llvm/ADT/DenseMap.h" 2430a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "llvm/ADT/DenseSet.h" 2530a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "llvm/ADT/FoldingSet.h" 26651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/Support/Allocator.h" 2730a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "llvm/Support/DataTypes.h" 28d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek 291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpnamespace clang { 30e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek class ASTContext; 315a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis class StackFrameContext; 325a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 339ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremeneknamespace ento { 34e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek class BasicValueFactory; 35edeb5b6b50e773b243e0ee0d84589cd1f7dea9b0Ted Kremenek class MemRegion; 3632f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose class SubRegion; 379697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek class TypedValueRegion; 38edeb5b6b50e773b243e0ee0d84589cd1f7dea9b0Ted Kremenek class VarRegion; 391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 403cdf584e068056540769dab56cad333e95a89750Anna Zaks/// \brief Symbolic value. These values used to capture symbolic execution of 413cdf584e068056540769dab56cad333e95a89750Anna Zaks/// the program. 42e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekclass SymExpr : public llvm::FoldingSetNode { 4399ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie virtual void anchor(); 44d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenekpublic: 45882998923889a2fcce9b49696506c499e22cf38fTed Kremenek enum Kind { RegionValueKind, ConjuredKind, DerivedKind, ExtentKind, 46bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose MetadataKind, 47882998923889a2fcce9b49696506c499e22cf38fTed Kremenek BEGIN_SYMBOLS = RegionValueKind, 48882998923889a2fcce9b49696506c499e22cf38fTed Kremenek END_SYMBOLS = MetadataKind, 494de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes SymIntKind, IntSymKind, SymSymKind, 504de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes BEGIN_BINARYSYMEXPRS = SymIntKind, 514de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes END_BINARYSYMEXPRS = SymSymKind, 524de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes CastSymbolKind }; 53e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekprivate: 54e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek Kind K; 55d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek 56e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekprotected: 571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump SymExpr(Kind k) : K(k) {} 581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 59d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenekpublic: 60e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek virtual ~SymExpr() {} 611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Kind getKind() const { return K; } 631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 643352ea914644edb2b56e999c94319ce915d68707Anna Zaks virtual void dump() const; 651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 66f75823f3d4dc84630a9d814479140145e62accf3Bill Wendling virtual void dumpToStream(raw_ostream &os) const {} 671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 68732cdf383f9030ff2b9fb28dfbdae2285ded80c6Ted Kremenek virtual QualType getType() const = 0; 69e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek virtual void Profile(llvm::FoldingSetNodeID& profile) = 0; 701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 71a91efb14cbf6af999dee02d9b611a57c7b52e209Anna Zaks /// \brief Iterator over symbols that the current symbol depends on. 72a91efb14cbf6af999dee02d9b611a57c7b52e209Anna Zaks /// 73a91efb14cbf6af999dee02d9b611a57c7b52e209Anna Zaks /// For SymbolData, it's the symbol itself; for expressions, it's the 74a91efb14cbf6af999dee02d9b611a57c7b52e209Anna Zaks /// expression symbol and all the operands in it. Note, SymbolDerived is 75a91efb14cbf6af999dee02d9b611a57c7b52e209Anna Zaks /// treated as SymbolData - the iterator will NOT visit the parent region. 761d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks class symbol_iterator { 771d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks SmallVector<const SymExpr*, 5> itr; 781d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks void expand(); 791d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks public: 801d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks symbol_iterator() {} 811d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks symbol_iterator(const SymExpr *SE); 821d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks 831d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks symbol_iterator &operator++(); 841d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks const SymExpr* operator*(); 851d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks 861d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks bool operator==(const symbol_iterator &X) const; 871d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks bool operator!=(const symbol_iterator &X) const; 881d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks }; 891d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks 901d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks symbol_iterator symbol_begin() const { 911d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks return symbol_iterator(this); 921d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks } 931d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks static symbol_iterator symbol_end() { return symbol_iterator(); } 94baeaa9ad120f60b1c5b6f1a84286b507dbe2b55dAnna Zaks 95baeaa9ad120f60b1c5b6f1a84286b507dbe2b55dAnna Zaks unsigned computeComplexity() const; 96e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek}; 971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 983cdf584e068056540769dab56cad333e95a89750Anna Zakstypedef const SymExpr* SymbolRef; 99cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenkotypedef SmallVector<SymbolRef, 2> SymbolRefSmallVectorTy; 1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1013cdf584e068056540769dab56cad333e95a89750Anna Zakstypedef unsigned SymbolID; 1023cdf584e068056540769dab56cad333e95a89750Anna Zaks/// \brief A symbol representing data which can be stored in a memory location 1033cdf584e068056540769dab56cad333e95a89750Anna Zaks/// (region). 104e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekclass SymbolData : public SymExpr { 105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void anchor() override; 106e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymbolID Sym; 1071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 108d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenekprotected: 1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {} 11000a3a5f024ac54088ab887712b292171188064f0Ted Kremenek 111d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenekpublic: 11233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ~SymbolData() override {} 1131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 114e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek SymbolID getSymbolID() const { return Sym; } 1158800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenek 116d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek // Implement isa<T> support. 1179c378f705405d37f49795d5e915989de774fe11fTed Kremenek static inline bool classof(const SymExpr *SE) { 118e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek Kind k = SE->getKind(); 119882998923889a2fcce9b49696506c499e22cf38fTed Kremenek return k >= BEGIN_SYMBOLS && k <= END_SYMBOLS; 120e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek } 121d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek}; 122e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek 1235fc7def35ee858791e591d005b4ae343632ca931Anna Zaks///\brief A symbol representing the value stored at a MemRegion. 124d9b6ad609ef0b90527e848ba69dc2e492771be4fZhongxing Xuclass SymbolRegionValue : public SymbolData { 1259697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek const TypedValueRegion *R; 12645257c37a4e9a8f915661e0f964aec375909eb4cZhongxing Xu 127d763eb91aab5bdecd11825fadb35d6d8cc905f63Ted Kremenekpublic: 1289697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek SymbolRegionValue(SymbolID sym, const TypedValueRegion *r) 12914d2328ecfc5102b077fa2c2c129dce1574c8831Zhongxing Xu : SymbolData(RegionValueKind, sym), R(r) {} 1301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1319697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek const TypedValueRegion* getRegion() const { return R; } 1329ab6b9cfb76ee56a61829e2bdb08e5cdc288726eTed Kremenek 1339697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek static void Profile(llvm::FoldingSetNodeID& profile, const TypedValueRegion* R) { 134d9b6ad609ef0b90527e848ba69dc2e492771be4fZhongxing Xu profile.AddInteger((unsigned) RegionValueKind); 1359ab6b9cfb76ee56a61829e2bdb08e5cdc288726eTed Kremenek profile.AddPointer(R); 13600a3a5f024ac54088ab887712b292171188064f0Ted Kremenek } 1371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Profile(llvm::FoldingSetNodeID& profile) override { 13914d2328ecfc5102b077fa2c2c129dce1574c8831Zhongxing Xu Profile(profile, R); 14000a3a5f024ac54088ab887712b292171188064f0Ted Kremenek } 1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void dumpToStream(raw_ostream &os) const override; 1431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType getType() const override; 1459ab6b9cfb76ee56a61829e2bdb08e5cdc288726eTed Kremenek 146d763eb91aab5bdecd11825fadb35d6d8cc905f63Ted Kremenek // Implement isa<T> support. 1479c378f705405d37f49795d5e915989de774fe11fTed Kremenek static inline bool classof(const SymExpr *SE) { 148d9b6ad609ef0b90527e848ba69dc2e492771be4fZhongxing Xu return SE->getKind() == RegionValueKind; 149eabf776661662a8e652eb692084d20fddffd5ccaZhongxing Xu } 150eabf776661662a8e652eb692084d20fddffd5ccaZhongxing Xu}; 151eabf776661662a8e652eb692084d20fddffd5ccaZhongxing Xu 1523cdf584e068056540769dab56cad333e95a89750Anna Zaks/// A symbol representing the result of an expression in the case when we do 1533cdf584e068056540769dab56cad333e95a89750Anna Zaks/// not know anything about what the expression is. 154361fa8ecd122a5b06c2c59d44419e202f42e1c5dTed Kremenekclass SymbolConjured : public SymbolData { 1559c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Stmt *S; 15660a6e0ce72a24d6247602625c631fc3dc7bfd8d4Ted Kremenek QualType T; 15700a3a5f024ac54088ab887712b292171188064f0Ted Kremenek unsigned Count; 1583133f79cf451e6302dd05262b4bb53a3e4fd6300Ted Kremenek const LocationContext *LCtx; 1599c378f705405d37f49795d5e915989de774fe11fTed Kremenek const void *SymbolTag; 16000a3a5f024ac54088ab887712b292171188064f0Ted Kremenek 16100a3a5f024ac54088ab887712b292171188064f0Ted Kremenekpublic: 1623133f79cf451e6302dd05262b4bb53a3e4fd6300Ted Kremenek SymbolConjured(SymbolID sym, const Stmt *s, const LocationContext *lctx, 1633133f79cf451e6302dd05262b4bb53a3e4fd6300Ted Kremenek QualType t, unsigned count, 1649c378f705405d37f49795d5e915989de774fe11fTed Kremenek const void *symbolTag) 165e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek : SymbolData(ConjuredKind, sym), S(s), T(t), Count(count), 1663133f79cf451e6302dd05262b4bb53a3e4fd6300Ted Kremenek LCtx(lctx), 167a880b66d6e0e446501fcbc27b87a1ec0e4ecde4cTed Kremenek SymbolTag(symbolTag) {} 1681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1699c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Stmt *getStmt() const { return S; } 170a880b66d6e0e446501fcbc27b87a1ec0e4ecde4cTed Kremenek unsigned getCount() const { return Count; } 1719c378f705405d37f49795d5e915989de774fe11fTed Kremenek const void *getTag() const { return SymbolTag; } 1721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType getType() const override; 1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void dumpToStream(raw_ostream &os) const override; 1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1779c378f705405d37f49795d5e915989de774fe11fTed Kremenek static void Profile(llvm::FoldingSetNodeID& profile, const Stmt *S, 1783133f79cf451e6302dd05262b4bb53a3e4fd6300Ted Kremenek QualType T, unsigned Count, const LocationContext *LCtx, 1793133f79cf451e6302dd05262b4bb53a3e4fd6300Ted Kremenek const void *SymbolTag) { 180361fa8ecd122a5b06c2c59d44419e202f42e1c5dTed Kremenek profile.AddInteger((unsigned) ConjuredKind); 181b5abb429e7aac731c3b4363a6118a6b3a6e27abcTed Kremenek profile.AddPointer(S); 1823133f79cf451e6302dd05262b4bb53a3e4fd6300Ted Kremenek profile.AddPointer(LCtx); 18360a6e0ce72a24d6247602625c631fc3dc7bfd8d4Ted Kremenek profile.Add(T); 18400a3a5f024ac54088ab887712b292171188064f0Ted Kremenek profile.AddInteger(Count); 185a880b66d6e0e446501fcbc27b87a1ec0e4ecde4cTed Kremenek profile.AddPointer(SymbolTag); 18600a3a5f024ac54088ab887712b292171188064f0Ted Kremenek } 187a880b66d6e0e446501fcbc27b87a1ec0e4ecde4cTed Kremenek 188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Profile(llvm::FoldingSetNodeID& profile) override { 1893133f79cf451e6302dd05262b4bb53a3e4fd6300Ted Kremenek Profile(profile, S, T, Count, LCtx, SymbolTag); 19000a3a5f024ac54088ab887712b292171188064f0Ted Kremenek } 191a880b66d6e0e446501fcbc27b87a1ec0e4ecde4cTed Kremenek 19200a3a5f024ac54088ab887712b292171188064f0Ted Kremenek // Implement isa<T> support. 1939c378f705405d37f49795d5e915989de774fe11fTed Kremenek static inline bool classof(const SymExpr *SE) { 194e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return SE->getKind() == ConjuredKind; 1951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 19600a3a5f024ac54088ab887712b292171188064f0Ted Kremenek}; 1971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19875eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks/// A symbol representing the value of a MemRegion whose parent region has 19975eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks/// symbolic value. 200fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenekclass SymbolDerived : public SymbolData { 201fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenek SymbolRef parentSymbol; 2029697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek const TypedValueRegion *R; 2031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 204fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenekpublic: 2059697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek SymbolDerived(SymbolID sym, SymbolRef parent, const TypedValueRegion *r) 206fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenek : SymbolData(DerivedKind, sym), parentSymbol(parent), R(r) {} 207fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenek 208fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenek SymbolRef getParentSymbol() const { return parentSymbol; } 2099697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek const TypedValueRegion *getRegion() const { return R; } 2101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType getType() const override; 2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void dumpToStream(raw_ostream &os) const override; 2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 215fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenek static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent, 2169697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek const TypedValueRegion *r) { 217fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenek profile.AddInteger((unsigned) DerivedKind); 218fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenek profile.AddPointer(r); 219fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenek profile.AddPointer(parent); 220fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenek } 2211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Profile(llvm::FoldingSetNodeID& profile) override { 223fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenek Profile(profile, parentSymbol, R); 224fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenek } 2251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 226fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenek // Implement isa<T> support. 2279c378f705405d37f49795d5e915989de774fe11fTed Kremenek static inline bool classof(const SymExpr *SE) { 228fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenek return SE->getKind() == DerivedKind; 2291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 230fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenek}; 231d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek 232bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose/// SymbolExtent - Represents the extent (size in bytes) of a bounded region. 233bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose/// Clients should not ask the SymbolManager for a region's extent. Always use 234bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose/// SubRegion::getExtent instead -- the value returned may not be a symbol. 23532f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Roseclass SymbolExtent : public SymbolData { 23632f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose const SubRegion *R; 23732f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose 23832f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rosepublic: 23932f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose SymbolExtent(SymbolID sym, const SubRegion *r) 24032f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose : SymbolData(ExtentKind, sym), R(r) {} 24132f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose 24232f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose const SubRegion *getRegion() const { return R; } 24332f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose 244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType getType() const override; 24532f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose 246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void dumpToStream(raw_ostream &os) const override; 24732f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose 24832f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose static void Profile(llvm::FoldingSetNodeID& profile, const SubRegion *R) { 24932f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose profile.AddInteger((unsigned) ExtentKind); 25032f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose profile.AddPointer(R); 25132f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose } 25232f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose 253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Profile(llvm::FoldingSetNodeID& profile) override { 25432f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose Profile(profile, R); 25532f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose } 25632f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose 25732f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose // Implement isa<T> support. 2589c378f705405d37f49795d5e915989de774fe11fTed Kremenek static inline bool classof(const SymExpr *SE) { 25932f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose return SE->getKind() == ExtentKind; 26032f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose } 26132f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose}; 26232f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose 263bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose/// SymbolMetadata - Represents path-dependent metadata about a specific region. 264bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose/// Metadata symbols remain live as long as they are marked as in use before 265bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose/// dead-symbol sweeping AND their associated regions are still alive. 266bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose/// Intended for use by checkers. 267bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Roseclass SymbolMetadata : public SymbolData { 268bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose const MemRegion* R; 2699c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Stmt *S; 270bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose QualType T; 271bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose unsigned Count; 2729c378f705405d37f49795d5e915989de774fe11fTed Kremenek const void *Tag; 273bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rosepublic: 2749c378f705405d37f49795d5e915989de774fe11fTed Kremenek SymbolMetadata(SymbolID sym, const MemRegion* r, const Stmt *s, QualType t, 2759c378f705405d37f49795d5e915989de774fe11fTed Kremenek unsigned count, const void *tag) 276bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose : SymbolData(MetadataKind, sym), R(r), S(s), T(t), Count(count), Tag(tag) {} 277bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose 278bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose const MemRegion *getRegion() const { return R; } 2799c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Stmt *getStmt() const { return S; } 280bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose unsigned getCount() const { return Count; } 2819c378f705405d37f49795d5e915989de774fe11fTed Kremenek const void *getTag() const { return Tag; } 282bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose 283651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType getType() const override; 284bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose 285651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void dumpToStream(raw_ostream &os) const override; 286bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose 287bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion *R, 288bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose const Stmt *S, QualType T, unsigned Count, 289bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose const void *Tag) { 290bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose profile.AddInteger((unsigned) MetadataKind); 291bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose profile.AddPointer(R); 292bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose profile.AddPointer(S); 293bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose profile.Add(T); 294bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose profile.AddInteger(Count); 295bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose profile.AddPointer(Tag); 296bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose } 297bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose 298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Profile(llvm::FoldingSetNodeID& profile) override { 299bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose Profile(profile, R, S, T, Count, Tag); 300bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose } 301bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose 302bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose // Implement isa<T> support. 3039c378f705405d37f49795d5e915989de774fe11fTed Kremenek static inline bool classof(const SymExpr *SE) { 304bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose return SE->getKind() == MetadataKind; 305bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose } 306bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose}; 307bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose 308aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks/// \brief Represents a cast expression. 309aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaksclass SymbolCast : public SymExpr { 310aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks const SymExpr *Operand; 311aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks /// Type of the operand. 312aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks QualType FromTy; 313aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks /// The type of the result. 314aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks QualType ToTy; 315aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks 316aace9ef279be3dadd53b481aee568bd7701178b4Anna Zakspublic: 317aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks SymbolCast(const SymExpr *In, QualType From, QualType To) : 318aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks SymExpr(CastSymbolKind), Operand(In), FromTy(From), ToTy(To) { } 319aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks 320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType getType() const override { return ToTy; } 321aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks 3224617e2843e711136746865d7d6d27c7cead21f2bEli Friedman const SymExpr *getOperand() const { return Operand; } 323aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks 324651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void dumpToStream(raw_ostream &os) const override; 325aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks 326aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks static void Profile(llvm::FoldingSetNodeID& ID, 327aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks const SymExpr *In, QualType From, QualType To) { 328aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks ID.AddInteger((unsigned) CastSymbolKind); 329aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks ID.AddPointer(In); 330aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks ID.Add(From); 331aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks ID.Add(To); 332aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks } 333aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks 334651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Profile(llvm::FoldingSetNodeID& ID) override { 335aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks Profile(ID, Operand, FromTy, ToTy); 336aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks } 337aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks 338aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks // Implement isa<T> support. 339aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks static inline bool classof(const SymExpr *SE) { 340aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks return SE->getKind() == CastSymbolKind; 341aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks } 342aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks}; 343aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks 3444de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes/// \brief Represents a symbolic expression involving a binary operator 3454de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostesclass BinarySymExpr : public SymExpr { 346a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu BinaryOperator::Opcode Op; 347a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu QualType T; 348a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu 3494de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostesprotected: 3504de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes BinarySymExpr(Kind k, BinaryOperator::Opcode op, QualType t) 3514de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes : SymExpr(k), Op(op), T(t) {} 352a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu 3534de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostespublic: 354e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek // FIXME: We probably need to make this out-of-line to avoid redundant 355e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek // generation of virtual functions. 356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType getType() const override { return T; } 3571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 358e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek BinaryOperator::Opcode getOpcode() const { return Op; } 3591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3604de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes // Implement isa<T> support. 3614de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes static inline bool classof(const SymExpr *SE) { 3624de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes Kind k = SE->getKind(); 3634de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes return k >= BEGIN_BINARYSYMEXPRS && k <= END_BINARYSYMEXPRS; 3644de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes } 3654de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes}; 3664de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes 3674de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes/// \brief Represents a symbolic expression like 'x' + 3. 3684de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostesclass SymIntExpr : public BinarySymExpr { 3694de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes const SymExpr *LHS; 3704de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes const llvm::APSInt& RHS; 3714de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes 3724de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostespublic: 3734de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes SymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, 3744de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes const llvm::APSInt& rhs, QualType t) 3754de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes : BinarySymExpr(SymIntKind, op, t), LHS(lhs), RHS(rhs) {} 3764de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes 377651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void dumpToStream(raw_ostream &os) const override; 3781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 379e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymExpr *getLHS() const { return LHS; } 380e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const llvm::APSInt &getRHS() const { return RHS; } 381a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu 3821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs, 383e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek BinaryOperator::Opcode op, const llvm::APSInt& rhs, 384a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu QualType t) { 385e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek ID.AddInteger((unsigned) SymIntKind); 386e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek ID.AddPointer(lhs); 387a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu ID.AddInteger(op); 388e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek ID.AddPointer(&rhs); 389a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu ID.Add(t); 390a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu } 391a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu 392651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Profile(llvm::FoldingSetNodeID& ID) override { 3934de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes Profile(ID, LHS, getOpcode(), RHS, getType()); 394a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu } 3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 396e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek // Implement isa<T> support. 3979c378f705405d37f49795d5e915989de774fe11fTed Kremenek static inline bool classof(const SymExpr *SE) { 398e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return SE->getKind() == SymIntKind; 3991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 400a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu}; 401a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu 4024de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes/// \brief Represents a symbolic expression like 3 - 'x'. 4034de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostesclass IntSymExpr : public BinarySymExpr { 4046d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks const llvm::APSInt& LHS; 4056d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks const SymExpr *RHS; 4066d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks 4076d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zakspublic: 4086d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks IntSymExpr(const llvm::APSInt& lhs, BinaryOperator::Opcode op, 4096d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks const SymExpr *rhs, QualType t) 4104de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes : BinarySymExpr(IntSymKind, op, t), LHS(lhs), RHS(rhs) {} 4116d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks 412651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void dumpToStream(raw_ostream &os) const override; 4136d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks 4146d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks const SymExpr *getRHS() const { return RHS; } 4156d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks const llvm::APSInt &getLHS() const { return LHS; } 4166d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks 4176d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks static void Profile(llvm::FoldingSetNodeID& ID, const llvm::APSInt& lhs, 4186d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks BinaryOperator::Opcode op, const SymExpr *rhs, 4196d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks QualType t) { 4206d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks ID.AddInteger((unsigned) IntSymKind); 4216d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks ID.AddPointer(&lhs); 4226d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks ID.AddInteger(op); 4236d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks ID.AddPointer(rhs); 4246d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks ID.Add(t); 4256d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks } 4266d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks 427651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Profile(llvm::FoldingSetNodeID& ID) override { 4284de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes Profile(ID, LHS, getOpcode(), RHS, getType()); 4296d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks } 4306d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks 4316d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks // Implement isa<T> support. 4326d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks static inline bool classof(const SymExpr *SE) { 4336d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks return SE->getKind() == IntSymKind; 4346d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks } 4356d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks}; 4366d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks 4374de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes/// \brief Represents a symbolic expression like 'x' + 'y'. 4384de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostesclass SymSymExpr : public BinarySymExpr { 439e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymExpr *LHS; 440e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymExpr *RHS; 441a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu 442a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xupublic: 443e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek SymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, 444e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek QualType t) 4454de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes : BinarySymExpr(SymSymKind, op, t), LHS(lhs), RHS(rhs) {} 446a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu 447e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymExpr *getLHS() const { return LHS; } 448e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymExpr *getRHS() const { return RHS; } 4491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 450651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void dumpToStream(raw_ostream &os) const override; 4511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 452e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs, 453d9b6ad609ef0b90527e848ba69dc2e492771be4fZhongxing Xu BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) { 454e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek ID.AddInteger((unsigned) SymSymKind); 455e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek ID.AddPointer(lhs); 456a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu ID.AddInteger(op); 457e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek ID.AddPointer(rhs); 458a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu ID.Add(t); 459a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu } 460a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu 461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Profile(llvm::FoldingSetNodeID& ID) override { 4624de561f470be0cffeff5a92a286e9d6bf9bd8cffRyan Govostes Profile(ID, LHS, getOpcode(), RHS, getType()); 463a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu } 4641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 465e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek // Implement isa<T> support. 4669c378f705405d37f49795d5e915989de774fe11fTed Kremenek static inline bool classof(const SymExpr *SE) { 467e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return SE->getKind() == SymSymKind; 4681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 469d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek}; 470d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek 471d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenekclass SymbolManager { 472e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek typedef llvm::FoldingSet<SymExpr> DataSetTy; 473579ad7ac56f7940cc543b7216ee1b1a7de1ed712Anna Zaks typedef llvm::DenseMap<SymbolRef, SymbolRefSmallVectorTy*> SymbolDependTy; 47475eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks 4751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump DataSetTy DataSet; 47689f920940de4b414616cabb310c37fa84ed2476aAnna Zaks /// Stores the extra dependencies between symbols: the data should be kept 47789f920940de4b414616cabb310c37fa84ed2476aAnna Zaks /// alive as long as the key is live. 47889f920940de4b414616cabb310c37fa84ed2476aAnna Zaks SymbolDependTy SymbolDependencies; 47900a3a5f024ac54088ab887712b292171188064f0Ted Kremenek unsigned SymbolCounter; 48000a3a5f024ac54088ab887712b292171188064f0Ted Kremenek llvm::BumpPtrAllocator& BPAlloc; 481e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek BasicValueFactory &BV; 4829c378f705405d37f49795d5e915989de774fe11fTed Kremenek ASTContext &Ctx; 4831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 484d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenekpublic: 4859c378f705405d37f49795d5e915989de774fe11fTed Kremenek SymbolManager(ASTContext &ctx, BasicValueFactory &bv, 486e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek llvm::BumpPtrAllocator& bpalloc) 487579ad7ac56f7940cc543b7216ee1b1a7de1ed712Anna Zaks : SymbolDependencies(16), SymbolCounter(0), 488579ad7ac56f7940cc543b7216ee1b1a7de1ed712Anna Zaks BPAlloc(bpalloc), BV(bv), Ctx(ctx) {} 4891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 490d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek ~SymbolManager(); 4911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 492693de5d7feb92c096431c98ea6ee637494bfe6fbTed Kremenek static bool canSymbolicate(QualType T); 4934193eca10ce0cc8b2dae887e935a43b26f492b5bZhongxing Xu 49475eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// \brief Make a unique symbol for MemRegion R according to its kind. 4959697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek const SymbolRegionValue* getRegionValueSymbol(const TypedValueRegion* R); 49614d2328ecfc5102b077fa2c2c129dce1574c8831Zhongxing Xu 4973b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek const SymbolConjured* conjureSymbol(const Stmt *E, 4983b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek const LocationContext *LCtx, 4993b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek QualType T, 5003b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek unsigned VisitCount, 5016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const void *SymbolTag = nullptr); 5023b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek 5033b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek const SymbolConjured* conjureSymbol(const Expr *E, 5043b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek const LocationContext *LCtx, 5053b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek unsigned VisitCount, 5066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const void *SymbolTag = nullptr) { 5073b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek return conjureSymbol(E, LCtx, E->getType(), VisitCount, SymbolTag); 50860a6e0ce72a24d6247602625c631fc3dc7bfd8d4Ted Kremenek } 5091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 510fb91c70e24e20f8704edf9bc5049ffbe7e234a38Ted Kremenek const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol, 5119697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek const TypedValueRegion *R); 512a129eb974d8ff0ad4a4dd94ad1e6c5f98897ddb4Zhongxing Xu 51332f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose const SymbolExtent *getExtentSymbol(const SubRegion *R); 51432f2656b90900ac04c4b50e87c16749d0ceb9ef2Jordy Rose 51575eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// \brief Creates a metadata symbol associated with a specific region. 51675eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// 5173f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks /// VisitCount can be used to differentiate regions corresponding to 5183f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks /// different loop iterations, thus, making the symbol path-dependent. 5196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const SymbolMetadata *getMetadataSymbol(const MemRegion *R, const Stmt *S, 520bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose QualType T, unsigned VisitCount, 5216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const void *SymbolTag = nullptr); 522bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose 523aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks const SymbolCast* getCastSymbol(const SymExpr *Operand, 524aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks QualType From, QualType To); 525aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks 526d9b6ad609ef0b90527e848ba69dc2e492771be4fZhongxing Xu const SymIntExpr *getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, 527e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const llvm::APSInt& rhs, QualType t); 5281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 529e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymIntExpr *getSymIntExpr(const SymExpr &lhs, BinaryOperator::Opcode op, 530e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const llvm::APSInt& rhs, QualType t) { 531e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return getSymIntExpr(&lhs, op, rhs, t); 532e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek } 533e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek 5346d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks const IntSymExpr *getIntSymExpr(const llvm::APSInt& lhs, 5356d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks BinaryOperator::Opcode op, 5366d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks const SymExpr *rhs, QualType t); 5376d6a83c3754b449ac24cb83bc6d3a50b10535061Anna Zaks 538e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymSymExpr *getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, 539e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymExpr *rhs, QualType t); 5401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 541e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek QualType getType(const SymExpr *SE) const { 542732cdf383f9030ff2b9fb28dfbdae2285ded80c6Ted Kremenek return SE->getType(); 543d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek } 5441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 54589f920940de4b414616cabb310c37fa84ed2476aAnna Zaks /// \brief Add artificial symbol dependency. 54689f920940de4b414616cabb310c37fa84ed2476aAnna Zaks /// 54789f920940de4b414616cabb310c37fa84ed2476aAnna Zaks /// The dependent symbol should stay alive as long as the primary is alive. 54889f920940de4b414616cabb310c37fa84ed2476aAnna Zaks void addSymbolDependency(const SymbolRef Primary, const SymbolRef Dependent); 54989f920940de4b414616cabb310c37fa84ed2476aAnna Zaks 55089f920940de4b414616cabb310c37fa84ed2476aAnna Zaks const SymbolRefSmallVectorTy *getDependentSymbols(const SymbolRef Primary); 55189f920940de4b414616cabb310c37fa84ed2476aAnna Zaks 552e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek ASTContext &getContext() { return Ctx; } 553e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek BasicValueFactory &getBasicVals() { return BV; } 554d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek}; 5551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 556914edfbb07c34d8cad8d0451193b4f9dd02a2d5aDavid Blaikie/// \brief A class responsible for cleaning up unused symbols. 557241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenekclass SymbolReaper { 558579ad7ac56f7940cc543b7216ee1b1a7de1ed712Anna Zaks enum SymbolStatus { 559579ad7ac56f7940cc543b7216ee1b1a7de1ed712Anna Zaks NotProcessed, 560579ad7ac56f7940cc543b7216ee1b1a7de1ed712Anna Zaks HaveMarkedDependents 561579ad7ac56f7940cc543b7216ee1b1a7de1ed712Anna Zaks }; 562579ad7ac56f7940cc543b7216ee1b1a7de1ed712Anna Zaks 563bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek typedef llvm::DenseSet<SymbolRef> SymbolSetTy; 564579ad7ac56f7940cc543b7216ee1b1a7de1ed712Anna Zaks typedef llvm::DenseMap<SymbolRef, SymbolStatus> SymbolMapTy; 565bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek typedef llvm::DenseSet<const MemRegion *> RegionSetTy; 5661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 567579ad7ac56f7940cc543b7216ee1b1a7de1ed712Anna Zaks SymbolMapTy TheLiving; 568bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek SymbolSetTy MetadataInUse; 569bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek SymbolSetTy TheDead; 570bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek 571bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek RegionSetTy RegionRoots; 572bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek 5737fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek const StackFrameContext *LCtx; 5747dadf79bd809cc01fe275f9a7243593bc2af5c10Jordy Rose const Stmt *Loc; 575241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenek SymbolManager& SymMgr; 576882998923889a2fcce9b49696506c499e22cf38fTed Kremenek StoreRef reapedStore; 577882998923889a2fcce9b49696506c499e22cf38fTed Kremenek llvm::DenseMap<const MemRegion *, unsigned> includedRegionCache; 5781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 579241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenekpublic: 5800b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks /// \brief Construct a reaper object, which removes everything which is not 5810b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks /// live before we execute statement s in the given location context. 5820b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks /// 5830b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks /// If the statement is NULL, everything is this and parent contexts is 5840b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks /// considered live. 5858501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks /// If the stack frame context is NULL, everything on stack is considered 5868501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks /// dead. 5878501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks SymbolReaper(const StackFrameContext *Ctx, const Stmt *s, SymbolManager& symmgr, 588882998923889a2fcce9b49696506c499e22cf38fTed Kremenek StoreManager &storeMgr) 5898501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks : LCtx(Ctx), Loc(s), SymMgr(symmgr), 5906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines reapedStore(nullptr, storeMgr) {} 5911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 592c179a7fbb294fe3ff6cf5479f6239a10f39628c7Zhongxing Xu const LocationContext *getLocationContext() const { return LCtx; } 593c179a7fbb294fe3ff6cf5479f6239a10f39628c7Zhongxing Xu 594241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenek bool isLive(SymbolRef sym); 595bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek bool isLiveRegion(const MemRegion *region); 5965eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek bool isLive(const Stmt *ExprVal, const LocationContext *LCtx) const; 597882998923889a2fcce9b49696506c499e22cf38fTed Kremenek bool isLive(const VarRegion *VR, bool includeStoreBindings = false) const; 598bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose 59975eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// \brief Unconditionally marks a symbol as live. 60075eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// 60175eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// This should never be 60275eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// used by checkers, only by the state infrastructure such as the store and 60375eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// environment. Checkers should instead use metadata symbols and markInUse. 604241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenek void markLive(SymbolRef sym); 605bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose 60675eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// \brief Marks a symbol as important to a checker. 60775eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// 60875eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// For metadata symbols, 60975eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// this will keep the symbol alive as long as its associated region is also 61075eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// live. For other symbols, this has no effect; checkers are not permitted 61175eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// to influence the life of other symbols. This should be used before any 61275eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// symbol marking has occurred, i.e. in the MarkLiveSymbols callback. 613bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose void markInUse(SymbolRef sym); 614bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose 61575eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// \brief If a symbol is known to be live, marks the symbol as live. 61675eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// 61775eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// Otherwise, if the symbol cannot be proven live, it is marked as dead. 61875eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// Returns true if the symbol is dead, false if live. 619241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenek bool maybeDead(SymbolRef sym); 6201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 621bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek typedef SymbolSetTy::const_iterator dead_iterator; 622241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenek dead_iterator dead_begin() const { return TheDead.begin(); } 623241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenek dead_iterator dead_end() const { return TheDead.end(); } 6241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 625241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenek bool hasDeadSymbols() const { 626a97d54c165ca6b6e57b9f333059a84c2188dd591Ted Kremenek return !TheDead.empty(); 627241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenek } 628bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek 629bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek typedef RegionSetTy::const_iterator region_iterator; 630bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek region_iterator region_begin() const { return RegionRoots.begin(); } 631bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek region_iterator region_end() const { return RegionRoots.end(); } 632bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose 63375eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// \brief Returns whether or not a symbol has been confirmed dead. 63475eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// 63575eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// This should only be called once all marking of dead symbols has completed. 63675eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// (For checkers, this means only in the evalDeadSymbols callback.) 637bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose bool isDead(SymbolRef sym) const { 638bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose return TheDead.count(sym); 639bd533aa4ff8895c676d4634d0d3de254962569d0Jordy Rose } 640882998923889a2fcce9b49696506c499e22cf38fTed Kremenek 641bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek void markLive(const MemRegion *region); 642bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek 64375eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// \brief Set to the value of the symbolic store after 644882998923889a2fcce9b49696506c499e22cf38fTed Kremenek /// StoreManager::removeDeadBindings has been called. 645882998923889a2fcce9b49696506c499e22cf38fTed Kremenek void setReapedStore(StoreRef st) { reapedStore = st; } 64689f920940de4b414616cabb310c37fa84ed2476aAnna Zaks 64789f920940de4b414616cabb310c37fa84ed2476aAnna Zaksprivate: 64889f920940de4b414616cabb310c37fa84ed2476aAnna Zaks /// Mark the symbols dependent on the input symbol as live. 64989f920940de4b414616cabb310c37fa84ed2476aAnna Zaks void markDependentsLive(SymbolRef sym); 650241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenek}; 6511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6525216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenekclass SymbolVisitor { 6535216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenekpublic: 65418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek /// \brief A visitor method invoked by ProgramStateManager::scanReachableSymbols. 65575eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// 65675eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// The method returns \c true if symbols should continue be scanned and \c 65775eeeb173cd3f6425247d3686c19e49117834fc3Anna Zaks /// false otherwise. 6585216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenek virtual bool VisitSymbol(SymbolRef sym) = 0; 659cb9657cfba92d5a3009e1b37109e03258c20d327Bill Wendling virtual bool VisitMemRegion(const MemRegion *region) { return true; } 6605216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenek virtual ~SymbolVisitor(); 6615216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenek}; 6621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6635a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis} // end GR namespace 6645a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 665d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek} // end clang namespace 666d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek 667e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremeneknamespace llvm { 6689c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic inline raw_ostream &operator<<(raw_ostream &os, 6693352ea914644edb2b56e999c94319ce915d68707Anna Zaks const clang::ento::SymExpr *SE) { 6708800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenek SE->dumpToStream(os); 6718800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenek return os; 672e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek} 6738800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenek} // end llvm namespace 674d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek#endif 675