Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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
 
17
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
18
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
19
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
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:
141
  using SValVisitor<ImplClass, RetTy>::Visit;
142
  using SymExprVisitor<ImplClass, RetTy>::Visit;
143
  using MemRegionVisitor<ImplClass, RetTy>::Visit;
144
};
145
 
146
} // end namespace ento
147
 
148
} // end namespace clang
149
 
150
#endif