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 | |