File indexing completed on 2026-05-10 08:37:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALVISITOR_H
0015 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALVISITOR_H
0016
0017 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
0018 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
0019 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
0020
0021 namespace clang {
0022
0023 namespace ento {
0024
0025
0026
0027 template <typename ImplClass, typename RetTy = void> class SValVisitor {
0028 ImplClass &derived() { return *static_cast<ImplClass *>(this); }
0029
0030 public:
0031 RetTy Visit(SVal V) {
0032
0033 switch (V.getKind()) {
0034 #define BASIC_SVAL(Id, Parent) \
0035 case SVal::Id##Kind: \
0036 return derived().Visit##Id(V.castAs<Id>());
0037 #define LOC_SVAL(Id, Parent) \
0038 case SVal::Loc##Id##Kind: \
0039 return derived().Visit##Id(V.castAs<loc::Id>());
0040 #define NONLOC_SVAL(Id, Parent) \
0041 case SVal::NonLoc##Id##Kind: \
0042 return derived().Visit##Id(V.castAs<nonloc::Id>());
0043 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
0044 }
0045 llvm_unreachable("Unknown SVal kind!");
0046 }
0047
0048
0049 #define BASIC_SVAL(Id, Parent) \
0050 RetTy Visit##Id(Id V) { return derived().Visit##Parent(V.castAs<Id>()); }
0051 #define ABSTRACT_SVAL(Id, Parent) BASIC_SVAL(Id, Parent)
0052 #define LOC_SVAL(Id, Parent) \
0053 RetTy Visit##Id(loc::Id V) { return derived().VisitLoc(V.castAs<Loc>()); }
0054 #define NONLOC_SVAL(Id, Parent) \
0055 RetTy Visit##Id(nonloc::Id V) { \
0056 return derived().VisitNonLoc(V.castAs<NonLoc>()); \
0057 }
0058 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
0059
0060
0061 RetTy VisitSVal(SVal V) { return RetTy(); }
0062 };
0063
0064
0065
0066 template <typename ImplClass, typename RetTy = void> class SymExprVisitor {
0067 public:
0068
0069 #define DISPATCH(CLASS) \
0070 return static_cast<ImplClass *>(this)->Visit ## CLASS(cast<CLASS>(S))
0071
0072 RetTy Visit(SymbolRef S) {
0073
0074 switch (S->getKind()) {
0075 #define SYMBOL(Id, Parent) \
0076 case SymExpr::Id ## Kind: DISPATCH(Id);
0077 #include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def"
0078 }
0079 llvm_unreachable("Unknown SymExpr kind!");
0080 }
0081
0082
0083
0084 #define SYMBOL(Id, Parent) RetTy Visit ## Id(const Id *S) { DISPATCH(Parent); }
0085 #define ABSTRACT_SYMBOL(Id, Parent) SYMBOL(Id, Parent)
0086 #include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def"
0087
0088
0089 RetTy VisitSymExpr(SymbolRef S) { return RetTy(); }
0090
0091 #undef DISPATCH
0092 };
0093
0094
0095
0096 template <typename ImplClass, typename RetTy = void> class MemRegionVisitor {
0097 public:
0098
0099 #define DISPATCH(CLASS) \
0100 return static_cast<ImplClass *>(this)->Visit ## CLASS(cast<CLASS>(R))
0101
0102 RetTy Visit(const MemRegion *R) {
0103
0104 switch (R->getKind()) {
0105 #define REGION(Id, Parent) case MemRegion::Id ## Kind: DISPATCH(Id);
0106 #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
0107 }
0108 llvm_unreachable("Unknown MemRegion kind!");
0109 }
0110
0111
0112
0113 #define REGION(Id, Parent) \
0114 RetTy Visit ## Id(const Id *R) { DISPATCH(Parent); }
0115 #define ABSTRACT_REGION(Id, Parent) \
0116 REGION(Id, Parent)
0117 #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
0118
0119
0120 RetTy VisitMemRegion(const MemRegion *R) { return RetTy(); }
0121
0122 #undef DISPATCH
0123 };
0124
0125
0126
0127 template <typename ImplClass, typename RetTy = void>
0128 class FullSValVisitor : public SValVisitor<ImplClass, RetTy>,
0129 public SymExprVisitor<ImplClass, RetTy>,
0130 public MemRegionVisitor<ImplClass, RetTy> {
0131 public:
0132 using SValVisitor<ImplClass, RetTy>::Visit;
0133 using SymExprVisitor<ImplClass, RetTy>::Visit;
0134 using MemRegionVisitor<ImplClass, RetTy>::Visit;
0135 };
0136
0137 }
0138
0139 }
0140
0141 #endif