clang 20.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
21namespace clang {
22
23namespace ento {
24
25/// SValVisitor - this class implements a simple visitor for SVal
26/// subclasses.
27template <typename ImplClass, typename RetTy = void> class SValVisitor {
28 ImplClass &derived() { return *static_cast<ImplClass *>(this); }
29
30public:
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.
66template <typename ImplClass, typename RetTy = void> class SymExprVisitor {
67public:
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.
96template <typename ImplClass, typename RetTy = void> class MemRegionVisitor {
97public:
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.
127template <typename ImplClass, typename RetTy = void>
128class FullSValVisitor : public SValVisitor<ImplClass, RetTy>,
129 public SymExprVisitor<ImplClass, RetTy>,
130 public MemRegionVisitor<ImplClass, RetTy> {
131public:
132 using SValVisitor<ImplClass, RetTy>::Visit;
133 using SymExprVisitor<ImplClass, RetTy>::Visit;
134 using MemRegionVisitor<ImplClass, RetTy>::Visit;
135};
136
137} // end namespace ento
138
139} // end namespace clang
140
141#endif
#define V(N, I)
Definition: ASTContext.h:3341
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:97
Kind getKind() const
Definition: MemRegion.h:175
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.