clang  19.0.0git
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  ImplClass &derived() { return *static_cast<ImplClass *>(this); }
29 
30 public:
31  RetTy Visit(SVal V) {
32  // Dispatch to VisitFooVal for each FooVal.
33  switch (V.getKind()) {
34 #define BASIC_SVAL(Id, Parent) \
35  case SVal::Id##Kind: \
36  return derived().Visit##Id(V.castAs<Id>());
37 #define LOC_SVAL(Id, Parent) \
38  case SVal::Loc##Id##Kind: \
39  return derived().Visit##Id(V.castAs<loc::Id>());
40 #define NONLOC_SVAL(Id, Parent) \
41  case SVal::NonLoc##Id##Kind: \
42  return derived().Visit##Id(V.castAs<nonloc::Id>());
43 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
44  }
45  llvm_unreachable("Unknown SVal kind!");
46  }
47 
48  // Dispatch to the more generic handler as a default implementation.
49 #define BASIC_SVAL(Id, Parent) \
50  RetTy Visit##Id(Id V) { return derived().Visit##Parent(V.castAs<Id>()); }
51 #define ABSTRACT_SVAL(Id, Parent) BASIC_SVAL(Id, Parent)
52 #define LOC_SVAL(Id, Parent) \
53  RetTy Visit##Id(loc::Id V) { return derived().VisitLoc(V.castAs<Loc>()); }
54 #define NONLOC_SVAL(Id, Parent) \
55  RetTy Visit##Id(nonloc::Id V) { \
56  return derived().VisitNonLoc(V.castAs<NonLoc>()); \
57  }
58 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
59 
60  // Base case, ignore it. :)
61  RetTy VisitSVal(SVal V) { return RetTy(); }
62 };
63 
64 /// SymExprVisitor - this class implements a simple visitor for SymExpr
65 /// subclasses.
66 template <typename ImplClass, typename RetTy = void> class SymExprVisitor {
67 public:
68 
69 #define DISPATCH(CLASS) \
70  return static_cast<ImplClass *>(this)->Visit ## CLASS(cast<CLASS>(S))
71 
72  RetTy Visit(SymbolRef S) {
73  // Dispatch to VisitSymbolFoo for each SymbolFoo.
74  switch (S->getKind()) {
75 #define SYMBOL(Id, Parent) \
76  case SymExpr::Id ## Kind: DISPATCH(Id);
77 #include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def"
78  }
79  llvm_unreachable("Unknown SymExpr kind!");
80  }
81 
82  // If the implementation chooses not to implement a certain visit method, fall
83  // back on visiting the superclass.
84 #define SYMBOL(Id, Parent) RetTy Visit ## Id(const Id *S) { DISPATCH(Parent); }
85 #define ABSTRACT_SYMBOL(Id, Parent) SYMBOL(Id, Parent)
86 #include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def"
87 
88  // Base case, ignore it. :)
89  RetTy VisitSymExpr(SymbolRef S) { return RetTy(); }
90 
91 #undef DISPATCH
92 };
93 
94 /// MemRegionVisitor - this class implements a simple visitor for MemRegion
95 /// subclasses.
96 template <typename ImplClass, typename RetTy = void> class MemRegionVisitor {
97 public:
98 
99 #define DISPATCH(CLASS) \
100  return static_cast<ImplClass *>(this)->Visit ## CLASS(cast<CLASS>(R))
101 
102  RetTy Visit(const MemRegion *R) {
103  // Dispatch to VisitFooRegion for each FooRegion.
104  switch (R->getKind()) {
105 #define REGION(Id, Parent) case MemRegion::Id ## Kind: DISPATCH(Id);
106 #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
107  }
108  llvm_unreachable("Unknown MemRegion kind!");
109  }
110 
111  // If the implementation chooses not to implement a certain visit method, fall
112  // back on visiting the superclass.
113 #define REGION(Id, Parent) \
114  RetTy Visit ## Id(const Id *R) { DISPATCH(Parent); }
115 #define ABSTRACT_REGION(Id, Parent) \
116  REGION(Id, Parent)
117 #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
118 
119  // Base case, ignore it. :)
120  RetTy VisitMemRegion(const MemRegion *R) { return RetTy(); }
121 
122 #undef DISPATCH
123 };
124 
125 /// FullSValVisitor - a convenient mixed visitor for all three:
126 /// SVal, SymExpr and MemRegion subclasses.
127 template <typename ImplClass, typename RetTy = void>
128 class FullSValVisitor : public SValVisitor<ImplClass, RetTy>,
129  public SymExprVisitor<ImplClass, RetTy>,
130  public MemRegionVisitor<ImplClass, RetTy> {
131 public:
135 };
136 
137 } // end namespace ento
138 
139 } // end namespace clang
140 
141 #endif
#define V(N, I)
Definition: ASTContext.h:3299
FullSValVisitor - a convenient mixed visitor for all three: SVal, SymExpr and MemRegion subclasses.
Definition: SValVisitor.h:130
MemRegionVisitor - this class implements a simple visitor for MemRegion subclasses.
Definition: SValVisitor.h:96
RetTy Visit(const MemRegion *R)
Definition: SValVisitor.h:102
RetTy VisitMemRegion(const MemRegion *R)
Definition: SValVisitor.h:120
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:96
Kind getKind() const
Definition: MemRegion.h:172
SValVisitor - this class implements a simple visitor for SVal subclasses.
Definition: SValVisitor.h:27
RetTy VisitSVal(SVal V)
Definition: SValVisitor.h:61
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition: SVals.h:55
SymExprVisitor - this class implements a simple visitor for SymExpr subclasses.
Definition: SValVisitor.h:66
RetTy Visit(SymbolRef S)
Definition: SValVisitor.h:72
RetTy VisitSymExpr(SymbolRef S)
Definition: SValVisitor.h:89
Symbolic value.
Definition: SymExpr.h:30
The JSON file list parser is used to communicate input to InstallAPI.