clang  6.0.0svn
SValVisitor.h
Go to the documentation of this file.
1 //===--- SValVisitor.h - Visitor for SVal subclasses ------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the SValVisitor, SymExprVisitor, and MemRegionVisitor
11 // interfaces, and also FullSValVisitor, which visits all three hierarchies.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALVISITOR_H
16 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALVISITOR_H
17 
21 
22 namespace clang {
23 
24 namespace ento {
25 
26 /// SValVisitor - this class implements a simple visitor for SVal
27 /// subclasses.
28 template <typename ImplClass, typename RetTy = void> class SValVisitor {
29 public:
30 
31 #define DISPATCH(NAME, CLASS) \
32  return static_cast<ImplClass *>(this)->Visit ## NAME(V.castAs<CLASS>())
33 
34  RetTy Visit(SVal V) {
35  // Dispatch to VisitFooVal for each FooVal.
36  // Take namespaces (loc:: and nonloc::) into account.
37  switch (V.getBaseKind()) {
38 #define BASIC_SVAL(Id, Parent) case SVal::Id ## Kind: DISPATCH(Id, Id);
39 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
40  case SVal::LocKind:
41  switch (V.getSubKind()) {
42 #define LOC_SVAL(Id, Parent) \
43  case loc::Id ## Kind: DISPATCH(Loc ## Id, loc :: Id);
44 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
45  }
46  llvm_unreachable("Unknown Loc sub-kind!");
47  case SVal::NonLocKind:
48  switch (V.getSubKind()) {
49 #define NONLOC_SVAL(Id, Parent) \
50  case nonloc::Id ## Kind: DISPATCH(NonLoc ## Id, nonloc :: Id);
51 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
52  }
53  llvm_unreachable("Unknown NonLoc sub-kind!");
54  }
55  llvm_unreachable("Unknown SVal kind!");
56  }
57 
58 #define BASIC_SVAL(Id, Parent) \
59  RetTy Visit ## Id(Id V) { DISPATCH(Parent, Id); }
60 #define ABSTRACT_SVAL(Id, Parent) \
61  BASIC_SVAL(Id, Parent)
62 #define LOC_SVAL(Id, Parent) \
63  RetTy VisitLoc ## Id(loc::Id V) { DISPATCH(Parent, Parent); }
64 #define NONLOC_SVAL(Id, Parent) \
65  RetTy VisitNonLoc ## Id(nonloc::Id V) { DISPATCH(Parent, Parent); }
66 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
67 
68  // Base case, ignore it. :)
69  RetTy VisitSVal(SVal V) { return RetTy(); }
70 
71 #undef DISPATCH
72 };
73 
74 /// SymExprVisitor - this class implements a simple visitor for SymExpr
75 /// subclasses.
76 template <typename ImplClass, typename RetTy = void> class SymExprVisitor {
77 public:
78 
79 #define DISPATCH(CLASS) \
80  return static_cast<ImplClass *>(this)->Visit ## CLASS(cast<CLASS>(S))
81 
82  RetTy Visit(SymbolRef S) {
83  // Dispatch to VisitSymbolFoo for each SymbolFoo.
84  switch (S->getKind()) {
85 #define SYMBOL(Id, Parent) \
86  case SymExpr::Id ## Kind: DISPATCH(Id);
87 #include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def"
88  }
89  llvm_unreachable("Unknown SymExpr kind!");
90  }
91 
92  // If the implementation chooses not to implement a certain visit method, fall
93  // back on visiting the superclass.
94 #define SYMBOL(Id, Parent) RetTy Visit ## Id(const Id *S) { DISPATCH(Parent); }
95 #define ABSTRACT_SYMBOL(Id, Parent) SYMBOL(Id, Parent)
96 #include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def"
97 
98  // Base case, ignore it. :)
99  RetTy VisitSymExpr(SymbolRef S) { return RetTy(); }
100 
101 #undef DISPATCH
102 };
103 
104 /// MemRegionVisitor - this class implements a simple visitor for MemRegion
105 /// subclasses.
106 template <typename ImplClass, typename RetTy = void> class MemRegionVisitor {
107 public:
108 
109 #define DISPATCH(CLASS) \
110  return static_cast<ImplClass *>(this)->Visit ## CLASS(cast<CLASS>(R))
111 
112  RetTy Visit(const MemRegion *R) {
113  // Dispatch to VisitFooRegion for each FooRegion.
114  switch (R->getKind()) {
115 #define REGION(Id, Parent) case MemRegion::Id ## Kind: DISPATCH(Id);
116 #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
117  }
118  llvm_unreachable("Unknown MemRegion kind!");
119  }
120 
121  // If the implementation chooses not to implement a certain visit method, fall
122  // back on visiting the superclass.
123 #define REGION(Id, Parent) \
124  RetTy Visit ## Id(const Id *R) { DISPATCH(Parent); }
125 #define ABSTRACT_REGION(Id, Parent) \
126  REGION(Id, Parent)
127 #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
128 
129  // Base case, ignore it. :)
130  RetTy VisitMemRegion(const MemRegion *R) { return RetTy(); }
131 
132 #undef DISPATCH
133 };
134 
135 /// FullSValVisitor - a convenient mixed visitor for all three:
136 /// SVal, SymExpr and MemRegion subclasses.
137 template <typename ImplClass, typename RetTy = void>
138 class FullSValVisitor : public SValVisitor<ImplClass, RetTy>,
139  public SymExprVisitor<ImplClass, RetTy>,
140  public MemRegionVisitor<ImplClass, RetTy> {
141 public:
145 };
146 
147 } // end namespace ento
148 
149 } // end namespace clang
150 
151 #endif
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:79
MemRegionVisitor - this class implements a simple visitor for MemRegion subclasses.
Definition: SValVisitor.h:106
Symbolic value.
Definition: SymExpr.h:29
FullSValVisitor - a convenient mixed visitor for all three: SVal, SymExpr and MemRegion subclasses...
Definition: SValVisitor.h:138
SymExprVisitor - this class implements a simple visitor for SymExpr subclasses.
Definition: SValVisitor.h:76
RetTy VisitMemRegion(const MemRegion *R)
Definition: SValVisitor.h:130
unsigned getSubKind() const
Definition: SVals.h:108
RetTy Visit(SymbolRef S)
Definition: SValVisitor.h:82
RetTy Visit(const MemRegion *R)
Definition: SValVisitor.h:112
RetTy VisitSymExpr(SymbolRef S)
Definition: SValVisitor.h:99
SValVisitor - this class implements a simple visitor for SVal subclasses.
Definition: SValVisitor.h:28
Kind getKind() const
Definition: MemRegion.h:148
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:63
BaseKind getBaseKind() const
Definition: SVals.h:107
Dataflow Directional Tag Classes.
RetTy VisitSVal(SVal V)
Definition: SValVisitor.h:69
Kind getKind() const
Definition: SymExpr.h:54