ROSE 0.11.145.147
Traits/Traversal.h
1#ifndef ROSE_Traits_Traversal_H
2#define ROSE_Traits_Traversal_H
3
4#include <Rose/Traits/describe/fields.h>
5#include <Rose/Traits/grammar/lists.h>
6#include <Rose/Traits/grammar/predicates.h>
7
8namespace Rose {
9namespace Traits {
10
11#if 0
12auto dispatch = []<typename OrigNodeT>(OrigNodeT * node, auto & F = details::nop_f) {
13 using nl = Nodes; // mp::List<SgExpression>; // TODO list_concrete_subclasses<OrigNodeT>
14 if (node) {
15 auto const v = node->variantT(); // TODO better? variantFromMempool is slow but maybe a version using `nl` above
16 nl::apply([&]<typename ConcreteNodeT>() {
17 if (v == Describe<ConcreteNodeT>::variant) {
18 F((ConcreteNodeT*)node);
19 }
20 });
21 }
22};
23#endif
24
25namespace traversal_details {
28 using parent = void;
29 static constexpr size_t position{0};
30 size_t index{0};
31 };
32
36 auto nop_noargs_f = []<typename NodeT, typename FieldT>(NodeT * node, FieldT pfld) {};
37
38// auto nop_pre_f = []<typename SynthT, typename NodeT, typename FieldT, typename InhT>(NodeT * node, FieldT pfld, InhT & inh) { return InhT{}; };
39// auto nop_post_f = []<typename SynthT, typename NodeT, typename FieldT, typename InhT>(NodeT * node, FieldT pfld, InhT const & inh, SynthContT const & synths) { return SynthT{}; };
40
41 template <typename OrigNodeT, typename PreFuncT, typename PostFuncT, typename FieldT>
42 struct Dispatcher;
43
44 template <typename ParentNodeT, typename PreFuncT, typename PostFuncT>
46 template <typename ChildNodeT>
47 static constexpr bool is_match = std::is_same<ParentNodeT, ChildNodeT>::value;
48
49 template <typename F, typename N>
50 static constexpr bool do_nothing = !is_match<N> || !F::traverse;
51
52 template <typename F, typename N>
53 using enable_nop = std::enable_if_t<do_nothing<F, N>>;
54
55 template <typename F, typename N>
56 using enable_call = std::enable_if_t<!do_nothing<F, N> && !F::iterable>;
57
58 template <typename F, typename N>
59 using enable_iterate = std::enable_if_t<!do_nothing<F, N> && F::iterable>;
60
61 template <typename FieldT, typename ChildNodeT, enable_nop<FieldT, ChildNodeT> * = nullptr>
62 inline void operator() (ChildNodeT * node, PreFuncT & pre, PostFuncT & post) const { /* NOP */ }
63
64 template <typename FieldT, typename ChildNodeT, enable_call<FieldT, ChildNodeT> * = nullptr>
65 inline void operator() (ChildNodeT * node, PreFuncT & pre, PostFuncT & post) const {
66 using node_type = std::remove_pointer_t<typename FieldT::type>;
68 if (node->*(FieldT::mbr_ptr)) {
69 FieldDispatcher::dispatch(node->*(FieldT::mbr_ptr), pre, post, FieldT{FieldT::position});
70 }
71 }
72
73 template <typename FieldT, typename ChildNodeT, enable_iterate<FieldT, ChildNodeT> * = nullptr>
74 inline void operator() (ChildNodeT * node, PreFuncT & pre, PostFuncT & post) const {
75 using node_type = std::remove_pointer_t<typename FieldT::type>;
77
78 size_t i = 0;
79 for (auto ptr: node->*(FieldT::mbr_ptr)) {
80 if (ptr) {
81 FieldDispatcher::dispatch(ptr, pre, post, FieldT{i});
82 }
83 i++;
84 }
85 }
86 };
87
88 template <typename FieldT>
90 static constexpr bool value = FieldT::traverse;
91 };
92
93 template <typename NodeT>
95 using fields = typename generated::describe_node_t<NodeT>::fields_t;
96 using trav_fields = typename fields::template filter<is_traversable_t>;
97 using list = typename trav_fields::template map_t<details::transcribe_field_desc_t>;
98 };
99
100 template <typename NodeT>
102 using parents = list_base_classes<NodeT>;
103 using list = typename parents::template map_ravel_t<get_traversable_list_t>;
104 };
105
106 template <typename OrigNodeT, typename PreFuncT, typename PostFuncT, typename FieldT>
107 struct Dispatcher {
108 using subclasses = list_concrete_subclasses<OrigNodeT>;
109
110 static void dispatch(OrigNodeT * node, PreFuncT & pre, PostFuncT & post, FieldT field) {
111 if (!node) return;
112 auto const v = node->variantT(); // TODO better? variantFromMempool is slow but maybe a version using `subclasses` above
113 subclasses::apply([&]<typename ConcreteNodeT>() {
115 using fields = typename get_inherited_traversable_list_t<ConcreteNodeT>::list;
116
117 ConcreteNodeT * cnode = (ConcreteNodeT*)node;
119
120 pre.PreFuncT::template operator()(cnode, field);
121 fields::apply(ftt, cnode, pre, post);
122 post.PostFuncT::template operator()(cnode, field);
123 }
124 });
125 }
126 };
127
128}
129
130template < typename NodeT, typename PreFuncT, typename PostFuncT>
131void traverse( NodeT * node_, PreFuncT & pre = traversal_details::nop_noargs_f, PostFuncT & post = traversal_details::nop_noargs_f) {
133}
134
135} }
136
137#endif
The ROSE library.
std::remove_const< typenamestd::remove_reference< RoseVisitor >::type >::type dispatch(RoseVisitor &&rv, SgNode *n)
uncovers the type of SgNode and passes it to an function "handle" in RoseVisitor.
Used for the call to pre/post functor at the root of the traversal.