source: src/Common/PassVisitor.proto.h@ fa4805f

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since fa4805f was b73bd70, checked in by Thierry Delisle <tdelisle@…>, 8 years ago

PassVisitor now properly copes skip-children

  • Property mode set to 100644
File size: 6.1 KB
Line 
1#pragma once
2
3template<typename pass_type>
4class PassVisitor;
5
6typedef std::function<void( void * )> cleanup_func_t;
7
8class guard_value_impl {
9public:
10 guard_value_impl() = default;
11
12 ~guard_value_impl() {
13 while( !cleanups.empty() ) {
14 auto& cleanup = cleanups.top();
15 cleanup.func( cleanup.val );
16 cleanups.pop();
17 }
18 }
19
20 void push( cleanup_func_t && func, void* val ) {
21 cleanups.emplace( std::move(func), val );
22 }
23
24private:
25 struct cleanup_t {
26 cleanup_func_t func;
27 void * val;
28
29 cleanup_t( cleanup_func_t&& func, void * val ) : func(func), val(val) {}
30 };
31
32 std::stack< cleanup_t > cleanups;
33};
34
35typedef std::function< void( cleanup_func_t, void * ) > at_cleanup_t;
36
37class bool_ref {
38public:
39 bool_ref() = default;
40 ~bool_ref() = default;
41
42 operator bool() { return *m_ref; }
43 bool operator=( bool val ) { return *m_ref = val; }
44
45private:
46
47 template<typename pass>
48 friend class PassVisitor;
49
50 void set( bool & val ) { m_ref = &val; };
51
52 bool * m_ref;
53};
54
55//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
56// Deep magic (a.k.a template meta programming) to make the templated visitor work
57// Basically the goal is to make 2 previsit_impl
58// 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of
59// 'pass.previsit( node )' that compiles will be used for that node for that type
60// This requires that this option only compile for passes that actually define an appropriate visit.
61// SFINAE will make sure the compilation errors in this function don't halt the build.
62// See http://en.cppreference.com/w/cpp/language/sfinae for details on SFINAE
63// 2 - Since the first implementation might not be specilizable, the second implementation exists and does nothing.
64// This is needed only to eliminate the need for passes to specify any kind of handlers.
65// The second implementation only works because it has a lower priority. This is due to the bogus last parameter.
66// The second implementation takes a long while the first takes an int. Since the caller always passes an literal 0
67// the first implementation takes priority in regards to overloading.
68// Mutator functions work along the same principal
69//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
70// Visit
71template<typename pass_type, typename node_type>
72static inline auto previsit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.previsit( node ), void() ) {
73 pass.previsit( node );
74}
75
76template<typename pass_type, typename node_type>
77static inline void previsit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) node_type * node, __attribute__((unused)) long unused ) {}
78
79
80template<typename pass_type, typename node_type>
81static inline auto postvisit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.postvisit( node ), void() ) {
82 pass.postvisit( node );
83}
84
85template<typename pass_type, typename node_type>
86static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) node_type * node, __attribute__((unused)) long unused ) {}
87
88// Mutate
89template<typename pass_type, typename node_type>
90static inline auto premutate_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.premutate( node ), void() ) {
91 return pass.premutate( node );
92}
93
94template<typename pass_type, typename node_type>
95static inline void premutate_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) node_type * node, __attribute__((unused)) long unused ) {}
96
97
98template<typename return_type, typename pass_type, typename node_type>
99static inline auto postmutate_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.postmutate( node ) ) {
100 return pass.postmutate( node );
101}
102
103template<typename return_type, typename pass_type, typename node_type>
104static inline return_type postmutate_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) { return node; }
105
106// Begin/End scope
107template<typename pass_type>
108static inline auto begin_scope_impl( pass_type& pass, __attribute__((unused)) int unused ) -> decltype( pass.beginScope(), void() ) {
109 pass.beginScope();
110}
111
112template<typename pass_type>
113static inline void begin_scope_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) {}
114
115
116template<typename pass_type>
117static inline auto end_scope_impl( pass_type& pass, __attribute__((unused)) int unused ) -> decltype( pass.endScope(), void() ) {
118 pass.endScope();
119}
120
121template<typename pass_type>
122static inline void end_scope_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) {}
123
124// Fields
125#define FIELD_PTR( type, name ) \
126template<typename pass_type> \
127static inline auto name##_impl( pass_type& pass, __attribute__((unused)) int unused ) -> decltype( &pass.name ) { return &pass.name; } \
128 \
129template<typename pass_type> \
130static inline type * name##_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) { return nullptr;} \
131
132FIELD_PTR( TypeSubstitution *, env )
133FIELD_PTR( std::list< Statement* >, stmtsToAddBefore )
134FIELD_PTR( std::list< Statement* >, stmtsToAddAfter )
135FIELD_PTR( std::list< Declaration* >, declsToAddBefore )
136FIELD_PTR( std::list< Declaration* >, declsToAddAfter )
137FIELD_PTR( bool_ref, visit_children )
138FIELD_PTR( at_cleanup_t, at_cleanup )
139FIELD_PTR( PassVisitor<pass_type> * const, visitor )
Note: See TracBrowser for help on using the repository browser.