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