1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALVISITOR_H |
15 | #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALVISITOR_H |
16 | |
17 | #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" |
18 | #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" |
19 | #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" |
20 | |
21 | namespace clang { |
22 | |
23 | namespace ento { |
24 | |
25 | |
26 | |
27 | template <typename ImplClass, typename RetTy = void> class SValVisitor { |
28 | public: |
29 | |
30 | #define DISPATCH(NAME, CLASS) \ |
31 | return static_cast<ImplClass *>(this)->Visit ## NAME(V.castAs<CLASS>()) |
32 | |
33 | RetTy Visit(SVal V) { |
34 | |
35 | |
36 | switch (V.getBaseKind()) { |
37 | #define BASIC_SVAL(Id, Parent) case SVal::Id ## Kind: DISPATCH(Id, Id); |
38 | #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def" |
39 | case SVal::LocKind: |
40 | switch (V.getSubKind()) { |
41 | #define LOC_SVAL(Id, Parent) \ |
42 | case loc::Id ## Kind: DISPATCH(Loc ## Id, loc :: Id); |
43 | #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def" |
44 | } |
45 | llvm_unreachable("Unknown Loc sub-kind!"); |
46 | case SVal::NonLocKind: |
47 | switch (V.getSubKind()) { |
48 | #define NONLOC_SVAL(Id, Parent) \ |
49 | case nonloc::Id ## Kind: DISPATCH(NonLoc ## Id, nonloc :: Id); |
50 | #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def" |
51 | } |
52 | llvm_unreachable("Unknown NonLoc sub-kind!"); |
53 | } |
54 | llvm_unreachable("Unknown SVal kind!"); |
55 | } |
56 | |
57 | #define BASIC_SVAL(Id, Parent) \ |
58 | RetTy Visit ## Id(Id V) { DISPATCH(Parent, Id); } |
59 | #define ABSTRACT_SVAL(Id, Parent) \ |
60 | BASIC_SVAL(Id, Parent) |
61 | #define LOC_SVAL(Id, Parent) \ |
62 | RetTy VisitLoc ## Id(loc::Id V) { DISPATCH(Parent, Parent); } |
63 | #define NONLOC_SVAL(Id, Parent) \ |
64 | RetTy VisitNonLoc ## Id(nonloc::Id V) { DISPATCH(Parent, Parent); } |
65 | #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def" |
66 | |
67 | |
68 | RetTy VisitSVal(SVal V) { return RetTy(); } |
69 | |
70 | #undef DISPATCH |
71 | }; |
72 | |
73 | |
74 | |
75 | template <typename ImplClass, typename RetTy = void> class SymExprVisitor { |
76 | public: |
77 | |
78 | #define DISPATCH(CLASS) \ |
79 | return static_cast<ImplClass *>(this)->Visit ## CLASS(cast<CLASS>(S)) |
80 | |
81 | RetTy Visit(SymbolRef S) { |
82 | |
83 | switch (S->getKind()) { |
84 | #define SYMBOL(Id, Parent) \ |
85 | case SymExpr::Id ## Kind: DISPATCH(Id); |
86 | #include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def" |
87 | } |
88 | llvm_unreachable("Unknown SymExpr kind!"); |
89 | } |
90 | |
91 | |
92 | |
93 | #define SYMBOL(Id, Parent) RetTy Visit ## Id(const Id *S) { DISPATCH(Parent); } |
94 | #define ABSTRACT_SYMBOL(Id, Parent) SYMBOL(Id, Parent) |
95 | #include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def" |
96 | |
97 | |
98 | RetTy VisitSymExpr(SymbolRef S) { return RetTy(); } |
99 | |
100 | #undef DISPATCH |
101 | }; |
102 | |
103 | |
104 | |
105 | template <typename ImplClass, typename RetTy = void> class MemRegionVisitor { |
106 | public: |
107 | |
108 | #define DISPATCH(CLASS) \ |
109 | return static_cast<ImplClass *>(this)->Visit ## CLASS(cast<CLASS>(R)) |
110 | |
111 | RetTy Visit(const MemRegion *R) { |
112 | |
113 | switch (R->getKind()) { |
114 | #define REGION(Id, Parent) case MemRegion::Id ## Kind: DISPATCH(Id); |
115 | #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def" |
116 | } |
117 | llvm_unreachable("Unknown MemRegion kind!"); |
118 | } |
119 | |
120 | |
121 | |
122 | #define REGION(Id, Parent) \ |
123 | RetTy Visit ## Id(const Id *R) { DISPATCH(Parent); } |
124 | #define ABSTRACT_REGION(Id, Parent) \ |
125 | REGION(Id, Parent) |
126 | #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def" |
127 | |
128 | |
129 | RetTy VisitMemRegion(const MemRegion *R) { return RetTy(); } |
130 | |
131 | #undef DISPATCH |
132 | }; |
133 | |
134 | |
135 | |
136 | template <typename ImplClass, typename RetTy = void> |
137 | class FullSValVisitor : public SValVisitor<ImplClass, RetTy>, |
138 | public SymExprVisitor<ImplClass, RetTy>, |
139 | public MemRegionVisitor<ImplClass, RetTy> { |
140 | public: |
141 | using SValVisitor<ImplClass, RetTy>::Visit; |
142 | using SymExprVisitor<ImplClass, RetTy>::Visit; |
143 | using MemRegionVisitor<ImplClass, RetTy>::Visit; |
144 | }; |
145 | |
146 | } |
147 | |
148 | } |
149 | |
150 | #endif |
151 | |