blob: 420db00396e765a566283283e936ec153183ff76 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
/**
** \file ast/visitor.hh
** \brief Definition of ast::Visitor.
*/
#pragma once
#include <functional>
#include <ast/fwd.hh>
#include <misc/select-const.hh>
namespace ast
{
/** \brief Root class of all Ast visitors.
**
** GenVisitor<CONSTIFY> is the root class of all Ast visitors. */
template <template <typename> class Const> class GenVisitor
{
/** \name Ctor & dtor.
** \{ */
public:
/// Convenient abbreviation.
template <typename Type> using const_t = typename Const<Type>::type;
/// Destroy a GenVisitor.
virtual ~GenVisitor();
/** \} */
/// The entry point: visit \a e.
virtual void operator()(const_t<Ast>& e);
virtual void operator()(const_t<ArrayExp>&) = 0;
virtual void operator()(const_t<ArrayTy>&) = 0;
virtual void operator()(const_t<AssignExp>&) = 0;
virtual void operator()(const_t<BreakExp>&) = 0;
virtual void operator()(const_t<CallExp>&) = 0;
virtual void operator()(const_t<CastExp>&) = 0;
virtual void operator()(const_t<ChunkList>&) = 0;
virtual void operator()(const_t<ClassTy>&) = 0;
virtual void operator()(const_t<Field>&) = 0;
virtual void operator()(const_t<FieldInit>&) = 0;
virtual void operator()(const_t<FieldVar>&) = 0;
virtual void operator()(const_t<ForExp>&) = 0;
virtual void operator()(const_t<FunctionDec>&) = 0;
virtual void operator()(const_t<IfExp>&) = 0;
virtual void operator()(const_t<IntExp>&) = 0;
virtual void operator()(const_t<LetExp>&) = 0;
virtual void operator()(const_t<MethodCallExp>&) = 0;
virtual void operator()(const_t<MethodDec>&) = 0;
virtual void operator()(const_t<NameTy>&) = 0;
virtual void operator()(const_t<NilExp>&) = 0;
virtual void operator()(const_t<ObjectExp>&) = 0;
virtual void operator()(const_t<OpExp>&) = 0;
virtual void operator()(const_t<RecordExp>&) = 0;
virtual void operator()(const_t<RecordTy>&) = 0;
virtual void operator()(const_t<SeqExp>&) = 0;
virtual void operator()(const_t<SimpleVar>&) = 0;
virtual void operator()(const_t<StringExp>&) = 0;
virtual void operator()(const_t<SubscriptVar>&) = 0;
virtual void operator()(const_t<TypeDec>&) = 0;
virtual void operator()(const_t<VarDec>&) = 0;
virtual void operator()(const_t<WhileExp>&) = 0;
virtual void operator()(const_t<FunctionChunk>&) = 0;
virtual void operator()(const_t<MethodChunk>&) = 0;
virtual void operator()(const_t<TypeChunk>&) = 0;
virtual void operator()(const_t<VarChunk>&) = 0;
virtual void operator()(const_t<AssertExp>&) = 0;
/// Helper to visit nodes manipulated via a pointer.
template <class E> void operator()(E* e);
protected:
/** A convenient shortcut for recurring code like this:
\code
if (e)
e->accept(*this);
\endcode
However, the drawback of this approach is that it doesn't take
care of the constness, and any \a const violation will be
reported \em within the body of this method, not at its
corresponding call site.
We cannot use the misc/select_const.hh approach here, since
the compiler cannot resolve a function overloaded or
specialized on an associated type of a template. E.g., writing
\a accept like this:
\code
template <typename E>
void accept(const_t<E>* e);
\endcode
won't work directly. Of course, one can help the compiler,
providing it with \a E
\code
accept<ast::NameTy>(e.result_get());
\endcode
but this is painful. */
template <typename E> void accept(E* e);
};
/// Shorthand for a const visitor.
using ConstVisitor = GenVisitor<misc::constify_traits>;
/// Shorthand for a non const visitor.
using Visitor = GenVisitor<misc::id_traits>;
} // namespace ast
#include <ast/visitor.hxx>
|