ROSE  0.11.145.0
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 
8 namespace Rose {
9 namespace Traits {
10 
11 #if 0
12 auto 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 
25 namespace traversal_details {
27  struct empty_field_t {
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 
130 template < typename NodeT, typename PreFuncT, typename PostFuncT>
131 void traverse( NodeT * node_, PreFuncT & pre = traversal_details::nop_noargs_f, PostFuncT & post = traversal_details::nop_noargs_f) {
133 }
134 
135 } }
136 
137 #endif
Main namespace for the ROSE library.
Used for the call to pre/post functor at the root of the traversal.
Definition: Traversal.h:27
std::remove_const< typename std::remove_reference< RoseVisitor >::type >::type dispatch(RoseVisitor &&rv, SgNode *n)
uncovers the type of SgNode and passes it to an function "handle" in RoseVisitor. ...
Definition: sageGeneric.h:1249