| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMEXPR_H |
| 14 | #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMEXPR_H |
| 15 | |
| 16 | #include "clang/AST/Type.h" |
| 17 | #include "clang/Basic/LLVM.h" |
| 18 | #include "llvm/ADT/FoldingSet.h" |
| 19 | #include "llvm/ADT/SmallVector.h" |
| 20 | #include <cassert> |
| 21 | |
| 22 | namespace clang { |
| 23 | namespace ento { |
| 24 | |
| 25 | class MemRegion; |
| 26 | |
| 27 | |
| 28 | |
| 29 | class SymExpr : public llvm::FoldingSetNode { |
| 30 | virtual void anchor(); |
| 31 | |
| 32 | public: |
| 33 | enum Kind { |
| 34 | #define SYMBOL(Id, Parent) Id##Kind, |
| 35 | #define SYMBOL_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last, |
| 36 | #include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def" |
| 37 | }; |
| 38 | |
| 39 | private: |
| 40 | Kind K; |
| 41 | |
| 42 | protected: |
| 43 | SymExpr(Kind k) : K(k) {} |
| 44 | |
| 45 | static bool isValidTypeForSymbol(QualType T) { |
| 46 | |
| 47 | |
| 48 | return !T.isNull() && !T->isVoidType(); |
| 49 | } |
| 50 | |
| 51 | mutable unsigned Complexity = 0; |
| 52 | |
| 53 | public: |
| 54 | virtual ~SymExpr() = default; |
| 55 | |
| 56 | Kind getKind() const { return K; } |
| 57 | |
| 58 | virtual void dump() const; |
| 59 | |
| 60 | virtual void dumpToStream(raw_ostream &os) const {} |
| 61 | |
| 62 | virtual QualType getType() const = 0; |
| 63 | virtual void Profile(llvm::FoldingSetNodeID &profile) = 0; |
| 64 | |
| 65 | |
| 66 | |
| 67 | |
| 68 | |
| 69 | |
| 70 | class symbol_iterator { |
| 71 | SmallVector<const SymExpr *, 5> itr; |
| 72 | |
| 73 | void expand(); |
| 74 | |
| 75 | public: |
| 76 | symbol_iterator() = default; |
| 77 | symbol_iterator(const SymExpr *SE); |
| 78 | |
| 79 | symbol_iterator &operator++(); |
| 80 | const SymExpr *operator*(); |
| 81 | |
| 82 | bool operator==(const symbol_iterator &X) const; |
| 83 | bool operator!=(const symbol_iterator &X) const; |
| 84 | }; |
| 85 | |
| 86 | symbol_iterator symbol_begin() const { return symbol_iterator(this); } |
| 87 | static symbol_iterator symbol_end() { return symbol_iterator(); } |
| 88 | |
| 89 | virtual unsigned computeComplexity() const = 0; |
| 90 | |
| 91 | |
| 92 | |
| 93 | |
| 94 | |
| 95 | |
| 96 | |
| 97 | |
| 98 | |
| 99 | |
| 100 | |
| 101 | virtual const MemRegion *getOriginRegion() const { return nullptr; } |
| 102 | }; |
| 103 | |
| 104 | inline raw_ostream &operator<<(raw_ostream &os, |
| 105 | const clang::ento::SymExpr *SE) { |
| 106 | SE->dumpToStream(os); |
| 107 | return os; |
| 108 | } |
| 109 | |
| 110 | using SymbolRef = const SymExpr *; |
| 111 | using SymbolRefSmallVectorTy = SmallVector<SymbolRef, 2>; |
| 112 | using SymbolID = unsigned; |
| 113 | |
| 114 | |
| 115 | |
| 116 | class SymbolData : public SymExpr { |
| 117 | const SymbolID Sym; |
| 118 | |
| 119 | void anchor() override; |
| 120 | |
| 121 | protected: |
| 122 | SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) { |
| 123 | assert(classof(this)); |
| 124 | } |
| 125 | |
| 126 | public: |
| 127 | ~SymbolData() override = default; |
| 128 | |
| 129 | SymbolID getSymbolID() const { return Sym; } |
| 130 | |
| 131 | unsigned computeComplexity() const override { |
| 132 | return 1; |
| 133 | }; |
| 134 | |
| 135 | |
| 136 | static inline bool classof(const SymExpr *SE) { |
| 137 | Kind k = SE->getKind(); |
| 138 | return k >= BEGIN_SYMBOLS && k <= END_SYMBOLS; |
| 139 | } |
| 140 | }; |
| 141 | |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | #endif |
| 146 | |