clang  10.0.0svn
SValVisitor.h
Go to the documentation of this file.
1 //===--- SValVisitor.h - Visitor for SVal subclasses ------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the SValVisitor, SymExprVisitor, and MemRegionVisitor
10 // interfaces, and also FullSValVisitor, which visits all three hierarchies.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALVISITOR_H
15 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALVISITOR_H
16 
20 
21 namespace clang {
22 
23 namespace ento {
24 
25 /// SValVisitor - this class implements a simple visitor for SVal
26 /// subclasses.
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  // Dispatch to VisitFooVal for each FooVal.
35  // Take namespaces (loc:: and nonloc::) into account.
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  // Base case, ignore it. :)
68  RetTy VisitSVal(SVal V) { return RetTy(); }
69 
70 #undef DISPATCH
71 };
72 
73 /// SymExprVisitor - this class implements a simple visitor for SymExpr
74 /// subclasses.
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  // Dispatch to VisitSymbolFoo for each SymbolFoo.
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  // If the implementation chooses not to implement a certain visit method, fall
92  // back on visiting the superclass.
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  // Base case, ignore it. :)
98  RetTy VisitSymExpr(SymbolRef S) { return RetTy(); }
99 
100 #undef DISPATCH
101 };
102 
103 /// MemRegionVisitor - this class implements a simple visitor for MemRegion
104 /// subclasses.
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  // Dispatch to VisitFooRegion for each FooRegion.
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  // If the implementation chooses not to implement a certain visit method, fall
121  // back on visiting the superclass.
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  // Base case, ignore it. :)
129  RetTy VisitMemRegion(const MemRegion *R) { return RetTy(); }
130 
131 #undef DISPATCH
132 };
133 
134 /// FullSValVisitor - a convenient mixed visitor for all three:
135 /// SVal, SymExpr and MemRegion subclasses.
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:
144 };
145 
146 } // end namespace ento
147 
148 } // end namespace clang
149 
150 #endif
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:94
MemRegionVisitor - this class implements a simple visitor for MemRegion subclasses.
Definition: SValVisitor.h:105
Symbolic value.
Definition: SymExpr.h:29
FullSValVisitor - a convenient mixed visitor for all three: SVal, SymExpr and MemRegion subclasses...
Definition: SValVisitor.h:137
SymExprVisitor - this class implements a simple visitor for SymExpr subclasses.
Definition: SValVisitor.h:75
RetTy VisitMemRegion(const MemRegion *R)
Definition: SValVisitor.h:129
unsigned getSubKind() const
Definition: SVals.h:119
RetTy Visit(SymbolRef S)
Definition: SValVisitor.h:81
#define V(N, I)
Definition: ASTContext.h:2921
RetTy Visit(const MemRegion *R)
Definition: SValVisitor.h:111
RetTy VisitSymExpr(SymbolRef S)
Definition: SValVisitor.h:98
SValVisitor - this class implements a simple visitor for SVal subclasses.
Definition: SValVisitor.h:27
Kind getKind() const
Definition: MemRegion.h:169
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:75
BaseKind getBaseKind() const
Definition: SVals.h:118
Dataflow Directional Tag Classes.
RetTy VisitSVal(SVal V)
Definition: SValVisitor.h:68
Kind getKind() const
Definition: SymExpr.h:56