GCC Code Coverage Report


Directory: ./
File: openvdb_ax/openvdb_ax/ast/Visitor.h
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 100 105 95.2%
Functions: 368 674 54.6%
Branches: 117 409 28.6%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 /// @file ast/Visitor.h
5 ///
6 /// @authors Nick Avramoussis
7 ///
8 /// @brief Contains the AX AST Node Visitor, providing default and
9 /// customizable traversal and visitation methods on a AST hierarchy.
10 /// Using the visitor pattern is the recommended way to implement
11 /// custom operations on AST nodes.
12 ///
13
14 #ifndef OPENVDB_AX_AST_VISITOR_HAS_BEEN_INCLUDED
15 #define OPENVDB_AX_AST_VISITOR_HAS_BEEN_INCLUDED
16
17 #include "AST.h"
18 #include "Tokens.h"
19
20 #include <openvdb/version.h>
21
22 #include <type_traits>
23
24 namespace openvdb {
25 OPENVDB_USE_VERSION_NAMESPACE
26 namespace OPENVDB_VERSION_NAME {
27
28 namespace ax {
29 namespace ast {
30
31 /// @brief The Visitor class uses the Curiously Recursive Template Pattern
32 /// (CRTP) to provide a customizable interface intended to be used by
33 /// clients wishing to perform custom operations over an AX Abstract
34 /// Syntax Tree (AST). By default the Visitor implements simple
35 /// traversal of all nodes, ensuring that each node on a well formed
36 /// AST is visited at least once. By deriving from the Visitor, users
37 /// are able to customize this default behavior and further manually
38 /// override specific node behavior to their needs. The function
39 /// options at the top of visitor can be overridden using CRTP to
40 /// control the prior default behavior, with the ability to override
41 /// the traverse() and visit() methods for the latter more granular
42 /// control.
43 ///
44 /// @details To commence a full visit of an AST, begin by calling traverse() on
45 /// a Node pointer. A visit is defined as one of the visit() methods
46 /// being called and accepting a Node type. Each node is is guaranteed
47 /// to be visited exactly once at its lowest concrete derived type.
48 /// Node inheritance hierarchies can also be visited (disable by
49 /// default, see Visitor::visitNodeHierarchies) The traverse() methods
50 /// define how each AST node accesses its children. The default
51 /// implementation is for each node to traverses its child pointers in
52 /// the order returned by the derived Node::child() method
53 /// (see Visitor::reverseChildVisits). You'll typically only require
54 /// overriding of the visit() methods for achieving most goals, however
55 /// you can utilize the traverse methods if you find that you require
56 /// more control over how the node hierarchy is accessed. The default
57 /// visit order is post order, where by nodes traverse and visit their
58 /// children first (see Visitor::postOrderNodes). Each visit method
59 /// returns a boolean value which, if false, allows for early
60 /// termination of the traversal. In the below example, we show a
61 /// Visitor capable of visiting every Local node type exactly once,
62 /// terminating if the Local variable is called "var".
63 ///
64 /// @par Example:
65 /// @code
66 /// struct LocalVisitor : public Visitor<LocalVisitor>
67 /// {
68 /// // Bring in all base methods to avoid hiding
69 /// using ast::Visitor<LocalVisitor>::traverse;
70 /// using ast::Visitor<LocalVisitor>::visit;
71 ///
72 /// // override the visit for Local AST nodes
73 /// inline bool visit(const Local* node) {
74 /// if (!node) return true;
75 /// if (node->name() == "var") return false;
76 /// return true;
77 /// }
78 /// };
79 ///
80 /// LocalVisitor visitor;
81 /// visitor.traverse(&tree);
82 /// @endcode
83 ///
84 /// @note The second template argument, ConstVisit, allows you to perform
85 /// non-const traversals over the AST. In this case, the visit and
86 /// traversal function signatures change to non-const pointers.
87 /// @note This design is heavily influenced by Clang's RecursiveVisitor.
88 ///
89 /// @tparam Derived The derived visitor to template on the base visitor,
90 /// using CRTP
91 /// @tparam ConstVisit Whether to visit const or non-const versions of the AST
92 /// nodes. Note that this value changes the class function
93 /// signatures.
94 template <typename Derived, bool ConstVisit=true>
95 struct Visitor
96 {
97 /// @brief Templated conditional which resolves to a const NodeT if
98 /// ConstVisit is true, or a non-const NodeT if ConstVisit is false
99 template <typename NodeT>
100 using NodeType = typename std::conditional<ConstVisit, const NodeT, NodeT>::type;
101
102 /// @brief Accesses the derived class by static casting the current object.
103 /// Assumes use of the Curiously Recursive Template Pattern (CRTP).
104 inline Derived& derived() {
105 return *static_cast<Derived*>(this);
106 }
107
108 /// @name Options
109 /// @{
110
111 /// @brief Default behavior option. If true, this results in post-order
112 /// traversal, where node children are traversed and visited before
113 /// their parent node. If false, this results in pre-order
114 /// traversal, where by the current node is visited before the
115 /// node's children.
116 /// @details Post-order traversal (for each node):
117 /// 1. Traverse all children.
118 /// 2. Visit the current node.
119 /// Pre-order traversal (for each node):
120 /// 1. Visit the current node.
121 /// 2. Traverse all children.
122 inline bool postOrderNodes() const { return true; }
123
124 /// @brief Default behavior option. Reverses the traversal order of child
125 /// nodes. If true, child nodes are accessed from last to first
126 /// index .i.e. Node::children() -> 0. If false, child nodes are
127 /// accessed from first to last .i.e. 0 -> Node::children()
128 inline bool reverseChildVisits() const { return false; }
129
130 /// @brief Default behavior option. Controls whether nodes visit themselves
131 /// at each stage of their class hierarchy. If true, nodes perform
132 /// multiple visits on their potentially abstract base classes. If
133 /// false, only the concrete derived types are visited.
134 /// @details When disabled, abstract node visitor methods are never accessed
135 /// directly through the default Visitor implementation. These
136 /// types include Node, Statement, Expression, etc AST nodes.
137 /// If true, for each linearly inherited AST node, a visit is
138 /// performed on the entire hierarchy. For example, for a Local AST
139 /// node which derives from Variable -> Expression -> Statement ->
140 /// Node, 5 visits will be performed at each level.
141 inline bool visitNodeHierarchies() const { return false; }
142
143 /// @brief Default behavior option. Reverses the traversal order of node
144 /// hierarchies. If true, hierarchical visits start at the very top
145 /// of their inheritance structure (always a Node AST node) and
146 /// visit downwards until the lowest derived concrete node is
147 /// reached. If false, hierarchical visits start at the lowest
148 /// derived concrete node and visit upwards until the very top of
149 /// their inheritance structure (always a Node AST node) is reached.
150 /// @note Has no effect if visitNodeHierarchies() is false
151 inline bool reverseHierarchyVisits() const { return false; }
152
153 /// @}
154
155 /// @name Traversals
156 /// @{
157
158 /// @brief Default traversals for a given concrete AST node type
159 /// @return True if traversal should continue, false to terminate
160
161 78776 bool traverse(NodeType<ast::Tree>* tree) {
162
2/3
✓ Branch 1 taken 2302 times.
✓ Branch 2 taken 290 times.
✗ Branch 3 not taken.
81368 return this->defaultTraversal<ast::Tree>(tree);
163 }
164
165 9260 bool traverse(NodeType<ast::StatementList>* cond) {
166 9260 return this->defaultTraversal<ast::StatementList>(cond);
167 }
168
169 24986 bool traverse(NodeType<ast::Block>* block) {
170 70517 return this->defaultTraversal<ast::Block>(block);
171 }
172
173 7900 bool traverse(NodeType<ast::CommaOperator>* comma) {
174 7900 return this->defaultTraversal<ast::CommaOperator>(comma);
175 }
176
177 2440 bool traverse(NodeType<ast::Loop>* loop) {
178 2440 return this->defaultTraversal<ast::Loop>(loop);
179 }
180
181 5995 bool traverse(NodeType<ast::Keyword>* keyw) {
182 5995 return this->defaultTraversal<ast::Keyword>(keyw);
183 }
184
185 7730 bool traverse(NodeType<ast::ConditionalStatement>* cond) {
186 7730 return this->defaultTraversal<ast::ConditionalStatement>(cond);
187 }
188
189 627820 bool traverse(NodeType<ast::AssignExpression>* asgn) {
190 627820 return this->defaultTraversal<ast::AssignExpression>(asgn);
191 }
192
193 53458 bool traverse(NodeType<ast::Crement>* crmt) {
194 53458 return this->defaultTraversal<ast::Crement>(crmt);
195 }
196
197 215070 bool traverse(NodeType<ast::UnaryOperator>* unry) {
198 215070 return this->defaultTraversal<ast::UnaryOperator>(unry);
199 }
200
201 195706 bool traverse(NodeType<ast::BinaryOperator>* bin) {
202 195706 return this->defaultTraversal<ast::BinaryOperator>(bin);
203 }
204
205 15502 bool traverse(NodeType<ast::TernaryOperator>* tern) {
206 15502 return this->defaultTraversal<ast::TernaryOperator>(tern);
207 }
208
209 3708 bool traverse(NodeType<ast::Cast>* cast) {
210 3708 return this->defaultTraversal<ast::Cast>(cast);
211 }
212
213 300955 bool traverse(NodeType<ast::FunctionCall>* call) {
214 300955 return this->defaultTraversal<ast::FunctionCall>(call);
215 }
216
217 653056 bool traverse(NodeType<ast::Attribute>* attr) {
218 671237 return this->defaultTraversal<ast::Attribute>(attr);
219 }
220
221 1715 bool traverse(NodeType<ast::ExternalVariable>* ext) {
222 1796 return this->defaultTraversal<ast::ExternalVariable>(ext);
223 }
224
225 189760 bool traverse(NodeType<ast::DeclareLocal>* decl) {
226 189760 return this->defaultTraversal<ast::DeclareLocal>(decl);
227 }
228
229 364757 bool traverse(NodeType<ast::Local>* loc) {
230 539062 return this->defaultTraversal<ast::Local>(loc);
231 }
232
233 247239 bool traverse(NodeType<ast::ArrayPack>* pack) {
234 247239 return this->defaultTraversal<ast::ArrayPack>(pack);
235 }
236
237 249276 bool traverse(NodeType<ast::ArrayUnpack>* pack) {
238 249276 return this->defaultTraversal<ast::ArrayUnpack>(pack);
239 }
240
241 51811 bool traverse(NodeType<ast::Value<bool>>* val) {
242 51811 return this->defaultTraversal<ast::Value<bool>>(val);
243 }
244
245 bool traverse(NodeType<ast::Value<int16_t>>* val) {
246 return this->defaultTraversal<ast::Value<int16_t>>(val);
247 }
248
249 696881 bool traverse(NodeType<ast::Value<int32_t>>* val) {
250 696881 return this->defaultTraversal<ast::Value<int32_t>>(val);
251 }
252
253 21756 bool traverse(NodeType<ast::Value<int64_t>>* val) {
254 21756 return this->defaultTraversal<ast::Value<int64_t>>(val);
255 }
256
257 709648 bool traverse(NodeType<ast::Value<float>>* val) {
258 709648 return this->defaultTraversal<ast::Value<float>>(val);
259 }
260
261 635285 bool traverse(NodeType<ast::Value<double>>* val) {
262 676674 return this->defaultTraversal<ast::Value<double>>(val);
263 }
264
265 13870 bool traverse(NodeType<ast::Value<std::string>>* val) {
266 20388 return this->defaultTraversal<ast::Value<std::string>>(val);
267 }
268
269 /// @brief The default traversal method which is hit for all child
270 /// traversals. The correct derived traversal scheme is selected by
271 /// using the node enumerated type.
272 /// @note Only handles traversal on concrete node types.
273 6113120 bool traverse(NodeType<ast::Node>* node) {
274
2/2
✓ Branch 0 taken 2987012 times.
✓ Branch 1 taken 113602 times.
6113120 if (!node) return true;
275
26/28
✓ Branch 1 taken 39388 times.
✓ Branch 2 taken 4799 times.
✓ Branch 3 taken 12662 times.
✓ Branch 4 taken 4137 times.
✓ Branch 5 taken 7349 times.
✓ Branch 6 taken 3042 times.
✓ Branch 7 taken 4042 times.
✓ Branch 8 taken 319650 times.
✓ Branch 9 taken 27122 times.
✓ Branch 10 taken 109376 times.
✓ Branch 11 taken 99725 times.
✓ Branch 12 taken 7939 times.
✓ Branch 13 taken 1895 times.
✓ Branch 14 taken 356802 times.
✓ Branch 15 taken 152949 times.
✓ Branch 16 taken 977 times.
✓ Branch 17 taken 98475 times.
✓ Branch 18 taken 125592 times.
✓ Branch 19 taken 125902 times.
✓ Branch 20 taken 356381 times.
✓ Branch 21 taken 26239 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 352531 times.
✓ Branch 24 taken 11076 times.
✓ Branch 25 taken 360560 times.
✓ Branch 26 taken 364949 times.
✓ Branch 27 taken 13453 times.
✗ Branch 28 not taken.
5888007 switch (node->nodetype()) {
276 78776 case Node::TreeNode : return this->derived().traverse(static_cast<NodeType<ast::Tree>*>(node));
277 9270 case Node::StatementListNode : return this->derived().traverse(static_cast<NodeType<ast::StatementList>*>(node));
278 24986 case Node::BlockNode : return this->derived().traverse(static_cast<NodeType<ast::Block>*>(node));
279 7918 case Node::CommaOperatorNode : return this->derived().traverse(static_cast<NodeType<ast::CommaOperator>*>(node));
280 14298 case Node::LoopNode : return this->derived().traverse(static_cast<NodeType<ast::Loop>*>(node));
281 5995 case Node::KeywordNode : return this->derived().traverse(static_cast<NodeType<ast::Keyword>*>(node));
282 7738 case Node::ConditionalStatementNode : return this->derived().traverse(static_cast<NodeType<ast::ConditionalStatement>*>(node));
283 627852 case Node::AssignExpressionNode : return this->derived().traverse(static_cast<NodeType<ast::AssignExpression>*>(node));
284 53470 case Node::CrementNode : return this->derived().traverse(static_cast<NodeType<ast::Crement>*>(node));
285 215070 case Node::UnaryOperatorNode : return this->derived().traverse(static_cast<NodeType<ast::UnaryOperator>*>(node));
286 195762 case Node::BinaryOperatorNode : return this->derived().traverse(static_cast<NodeType<ast::BinaryOperator>*>(node));
287 15510 case Node::TernaryOperatorNode : return this->derived().traverse(static_cast<NodeType<ast::TernaryOperator>*>(node));
288 3708 case Node::CastNode : return this->derived().traverse(static_cast<NodeType<ast::Cast>*>(node));
289 701513 case Node::AttributeNode : return this->derived().traverse(static_cast<NodeType<ast::Attribute>*>(node));
290 300955 case Node::FunctionCallNode : return this->derived().traverse(static_cast<NodeType<ast::FunctionCall>*>(node));
291 1877 case Node::ExternalVariableNode : return this->derived().traverse(static_cast<NodeType<ast::ExternalVariable>*>(node));
292 189776 case Node::DeclareLocalNode : return this->derived().traverse(static_cast<NodeType<ast::DeclareLocal>*>(node));
293 247245 case Node::ArrayPackNode : return this->derived().traverse(static_cast<NodeType<ast::ArrayPack>*>(node));
294 249294 case Node::ArrayUnpackNode : return this->derived().traverse(static_cast<NodeType<ast::ArrayUnpack>*>(node));
295 706199 case Node::LocalNode : return this->derived().traverse(static_cast<NodeType<ast::Local>*>(node));
296 51811 case Node::ValueBoolNode : return this->derived().traverse(static_cast<NodeType<ast::Value<bool>>*>(node));
297 case Node::ValueInt16Node : return this->derived().traverse(static_cast<NodeType<ast::Value<int16_t>>*>(node));
298 696881 case Node::ValueInt32Node : return this->derived().traverse(static_cast<NodeType<ast::Value<int32_t>>*>(node));
299 21756 case Node::ValueInt64Node : return this->derived().traverse(static_cast<NodeType<ast::Value<int64_t>>*>(node));
300 709648 case Node::ValueFloatNode : return this->derived().traverse(static_cast<NodeType<ast::Value<float>>*>(node));
301 718063 case Node::ValueDoubleNode : return this->derived().traverse(static_cast<NodeType<ast::Value<double>>*>(node));
302 26301 case Node::ValueStrNode : return this->derived().traverse(static_cast<NodeType<ast::Value<std::string>>*>(node));
303 default : return true;
304 }
305 }
306
307 /// @}
308
309 /// @name Visits
310 /// @{
311
312 /// @brief Visits for abstract (pure-virtual) Node types.
313 /// @note These are only hit through the default behavior if
314 /// Visitor::visitNodeHierarchies is enabled.
315 /// @return True if traversal should continue, false to terminate
316 inline bool visit(NodeType<ast::Node>*) { return true; }
317 inline bool visit(NodeType<ast::Statement>*) { return true; }
318 inline bool visit(NodeType<ast::Expression>*) { return true; }
319 inline bool visit(NodeType<ast::Variable>*) { return true; }
320 inline bool visit(NodeType<ast::ValueBase>*) { return true; }
321
322 /// @brief Visits for concrete Node types.
323 /// @return True if traversal should continue, false to terminate
324 inline bool visit(NodeType<ast::Tree>*) { return true; }
325 inline bool visit(NodeType<ast::StatementList>*) { return true; }
326 inline bool visit(NodeType<ast::Block>*) { return true; }
327 inline bool visit(NodeType<ast::CommaOperator>*) { return true; }
328 inline bool visit(NodeType<ast::Loop>*) { return true; }
329 inline bool visit(NodeType<ast::Keyword>*) { return true; }
330 inline bool visit(NodeType<ast::ConditionalStatement>*) { return true; }
331 inline bool visit(NodeType<ast::AssignExpression>*) { return true; }
332 inline bool visit(NodeType<ast::Crement>*) { return true; }
333 inline bool visit(NodeType<ast::UnaryOperator>*) { return true; }
334 inline bool visit(NodeType<ast::BinaryOperator>*) { return true; }
335 inline bool visit(NodeType<ast::TernaryOperator>*) { return true; }
336 inline bool visit(NodeType<ast::Cast>*) { return true; }
337 inline bool visit(NodeType<ast::FunctionCall>*) { return true; }
338 inline bool visit(NodeType<ast::Attribute>*) { return true; }
339 inline bool visit(NodeType<ast::ExternalVariable>*) { return true; }
340 inline bool visit(NodeType<ast::DeclareLocal>*) { return true; }
341 inline bool visit(NodeType<ast::Local>*) { return true; }
342 inline bool visit(NodeType<ast::ArrayPack>*) { return true; }
343 inline bool visit(NodeType<ast::ArrayUnpack>*) { return true; }
344 inline bool visit(NodeType<ast::Value<bool>>*) { return true; }
345 inline bool visit(NodeType<ast::Value<int16_t>>*) { return true; }
346 inline bool visit(NodeType<ast::Value<int32_t>>*) { return true; }
347 inline bool visit(NodeType<ast::Value<int64_t>>*) { return true; }
348 inline bool visit(NodeType<ast::Value<float>>*) { return true; }
349 inline bool visit(NodeType<ast::Value<double>>*) { return true; }
350 inline bool visit(NodeType<ast::Value<std::string>>*) { return true; }
351
352 /// @}
353
354 private:
355 /// @brief Enabled for const traversals, where by the node pointer is
356 /// returned
357 /// @param Const reference to an AST node
358 /// @return Const pointer to the node
359 template <bool V, typename NodeT>
360 inline typename std::enable_if<V, const NodeT*>::type
361 strip(const NodeT* node) {
362 return node;
363 }
364
365 /// @brief Enabled for non-const traversals, where by a const stripped node
366 /// pointer is returned
367 /// @param Const reference to an AST node
368 /// @return Non-const pointer to the node
369 template <bool V, typename NodeT>
370 inline typename std::enable_if<!V, typename std::remove_const<NodeT>::type*>::type
371 strip(const NodeT* node) {
372 return const_cast<NodeT*>(node);
373 }
374
375 /// @brief Implements recursive hierarchical visits to a given AST node
376 /// @tparam NodeT The node type
377 /// @param node The node to perform class hierarchy visits on
378 /// @return True if traversal should continue, false to terminate
379 template <typename NodeT>
380
1/2
✓ Branch 0 taken 3048 times.
✗ Branch 1 not taken.
6096 bool hierarchyVisits(NodeT& node)
381 {
382 if (this->derived().reverseHierarchyVisits()) {
383 if (auto base = node.NodeT::basetype()) {
384 if (!hierarchyVisits(*base)) return false;
385 }
386 if (!this->derived().visit(this->strip<ConstVisit>(&node))) return false;
387 }
388 else {
389
4/6
✓ Branch 0 taken 164070 times.
✓ Branch 1 taken 6651 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 154825 times.
✓ Branch 5 taken 12581 times.
338127 if (!this->derived().visit(this->strip<ConstVisit>(&node))) return false;
390
78/358
✓ Branch 0 taken 3092 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3102 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3096 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 19 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 585 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 129 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 913 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 117 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 117 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 35 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 243 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 96 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 96 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 6 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 6 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 84 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 84 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 224 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 224 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 14 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 14 times.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✓ Branch 46 taken 170721 times.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✓ Branch 50 taken 167406 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 1 times.
✗ Branch 53 not taken.
✓ Branch 54 taken 1 times.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✓ Branch 114 taken 1 times.
✗ Branch 115 not taken.
✓ Branch 116 taken 1 times.
✗ Branch 117 not taken.
✓ Branch 118 taken 1 times.
✗ Branch 119 not taken.
✓ Branch 120 taken 1 times.
✗ Branch 121 not taken.
✓ Branch 122 taken 1 times.
✗ Branch 123 not taken.
✓ Branch 124 taken 1 times.
✗ Branch 125 not taken.
✓ Branch 126 taken 2 times.
✗ Branch 127 not taken.
✓ Branch 128 taken 2 times.
✗ Branch 129 not taken.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✗ Branch 135 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✓ Branch 138 taken 1 times.
✗ Branch 139 not taken.
✓ Branch 140 taken 1 times.
✗ Branch 141 not taken.
✓ Branch 142 taken 1 times.
✗ Branch 143 not taken.
✓ Branch 144 taken 1 times.
✗ Branch 145 not taken.
✗ Branch 146 not taken.
✗ Branch 147 not taken.
✗ Branch 148 not taken.
✗ Branch 149 not taken.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✓ Branch 152 taken 2 times.
✗ Branch 153 not taken.
✓ Branch 154 taken 2 times.
✗ Branch 155 not taken.
✗ Branch 156 not taken.
✗ Branch 157 not taken.
✗ Branch 158 not taken.
✗ Branch 159 not taken.
✗ Branch 160 not taken.
✗ Branch 161 not taken.
✗ Branch 162 not taken.
✗ Branch 163 not taken.
✗ Branch 164 not taken.
✗ Branch 165 not taken.
✓ Branch 166 taken 3 times.
✗ Branch 167 not taken.
✗ Branch 168 not taken.
✗ Branch 169 not taken.
✗ Branch 170 not taken.
✗ Branch 171 not taken.
✓ Branch 172 taken 1 times.
✗ Branch 173 not taken.
✓ Branch 174 taken 1 times.
✗ Branch 175 not taken.
✓ Branch 176 taken 1 times.
✗ Branch 177 not taken.
✗ Branch 178 not taken.
✗ Branch 179 not taken.
✗ Branch 180 not taken.
✗ Branch 181 not taken.
✗ Branch 182 not taken.
✗ Branch 183 not taken.
✗ Branch 184 not taken.
✗ Branch 185 not taken.
✗ Branch 186 not taken.
✗ Branch 187 not taken.
✓ Branch 188 taken 1 times.
✗ Branch 189 not taken.
✗ Branch 190 not taken.
✗ Branch 191 not taken.
✗ Branch 192 not taken.
✗ Branch 193 not taken.
✗ Branch 194 not taken.
✗ Branch 195 not taken.
✗ Branch 196 not taken.
✗ Branch 197 not taken.
✓ Branch 198 taken 1 times.
✗ Branch 199 not taken.
✓ Branch 200 taken 1 times.
✗ Branch 201 not taken.
✓ Branch 202 taken 1 times.
✗ Branch 203 not taken.
✓ Branch 204 taken 1 times.
✗ Branch 205 not taken.
✓ Branch 206 taken 1 times.
✗ Branch 207 not taken.
✓ Branch 208 taken 1 times.
✗ Branch 209 not taken.
✓ Branch 210 taken 1 times.
✗ Branch 211 not taken.
✓ Branch 212 taken 1 times.
✗ Branch 213 not taken.
✓ Branch 214 taken 1 times.
✗ Branch 215 not taken.
✓ Branch 216 taken 1 times.
✗ Branch 217 not taken.
✓ Branch 218 taken 1 times.
✗ Branch 219 not taken.
✓ Branch 220 taken 1 times.
✗ Branch 221 not taken.
✓ Branch 222 taken 2 times.
✗ Branch 223 not taken.
✓ Branch 224 taken 2 times.
✗ Branch 225 not taken.
✓ Branch 226 taken 2 times.
✗ Branch 227 not taken.
✓ Branch 228 taken 2 times.
✗ Branch 229 not taken.
✗ Branch 230 not taken.
✗ Branch 231 not taken.
✗ Branch 232 not taken.
✗ Branch 233 not taken.
✗ Branch 234 not taken.
✗ Branch 235 not taken.
✗ Branch 236 not taken.
✗ Branch 237 not taken.
✗ Branch 238 not taken.
✗ Branch 239 not taken.
✗ Branch 240 not taken.
✗ Branch 241 not taken.
✗ Branch 242 not taken.
✗ Branch 243 not taken.
✗ Branch 244 not taken.
✗ Branch 245 not taken.
✓ Branch 246 taken 1 times.
✗ Branch 247 not taken.
✓ Branch 248 taken 1 times.
✗ Branch 249 not taken.
✓ Branch 250 taken 1 times.
✗ Branch 251 not taken.
✓ Branch 252 taken 1 times.
✗ Branch 253 not taken.
✓ Branch 254 taken 1 times.
✗ Branch 255 not taken.
✓ Branch 256 taken 1 times.
✗ Branch 257 not taken.
✓ Branch 258 taken 1 times.
✗ Branch 259 not taken.
✓ Branch 260 taken 1 times.
✗ Branch 261 not taken.
✓ Branch 262 taken 1 times.
✗ Branch 263 not taken.
✓ Branch 264 taken 1 times.
✗ Branch 265 not taken.
✗ Branch 266 not taken.
✗ Branch 267 not taken.
✗ Branch 268 not taken.
✗ Branch 269 not taken.
✗ Branch 270 not taken.
✗ Branch 271 not taken.
✗ Branch 272 not taken.
✗ Branch 273 not taken.
✗ Branch 274 not taken.
✗ Branch 275 not taken.
✗ Branch 276 not taken.
✗ Branch 277 not taken.
✗ Branch 278 not taken.
✗ Branch 279 not taken.
✗ Branch 280 not taken.
✗ Branch 281 not taken.
✗ Branch 282 not taken.
✗ Branch 283 not taken.
✓ Branch 284 taken 3 times.
✗ Branch 285 not taken.
✓ Branch 286 taken 3 times.
✗ Branch 287 not taken.
✓ Branch 288 taken 3 times.
✗ Branch 289 not taken.
✓ Branch 290 taken 3 times.
✗ Branch 291 not taken.
✗ Branch 292 not taken.
✗ Branch 293 not taken.
✗ Branch 294 not taken.
✗ Branch 295 not taken.
✗ Branch 296 not taken.
✗ Branch 297 not taken.
✗ Branch 298 not taken.
✗ Branch 299 not taken.
✗ Branch 300 not taken.
✗ Branch 301 not taken.
✗ Branch 302 not taken.
✗ Branch 303 not taken.
✗ Branch 304 not taken.
✗ Branch 305 not taken.
✗ Branch 306 not taken.
✗ Branch 307 not taken.
✗ Branch 308 not taken.
✗ Branch 309 not taken.
✗ Branch 310 not taken.
✗ Branch 311 not taken.
✗ Branch 312 not taken.
✗ Branch 313 not taken.
✗ Branch 314 not taken.
✗ Branch 315 not taken.
✗ Branch 316 not taken.
✗ Branch 317 not taken.
✗ Branch 318 not taken.
✗ Branch 319 not taken.
✗ Branch 320 not taken.
✗ Branch 321 not taken.
✓ Branch 322 taken 3 times.
✗ Branch 323 not taken.
✓ Branch 324 taken 3 times.
✗ Branch 325 not taken.
✓ Branch 326 taken 3 times.
✗ Branch 327 not taken.
✗ Branch 328 not taken.
✗ Branch 329 not taken.
✗ Branch 330 not taken.
✗ Branch 331 not taken.
✗ Branch 332 not taken.
✗ Branch 333 not taken.
✗ Branch 334 not taken.
✗ Branch 335 not taken.
✗ Branch 336 not taken.
✗ Branch 337 not taken.
✗ Branch 338 not taken.
✗ Branch 339 not taken.
✗ Branch 340 not taken.
✗ Branch 341 not taken.
✗ Branch 342 not taken.
✗ Branch 343 not taken.
✗ Branch 344 not taken.
✗ Branch 345 not taken.
✗ Branch 346 not taken.
✗ Branch 347 not taken.
✗ Branch 348 not taken.
✗ Branch 349 not taken.
✗ Branch 350 not taken.
✗ Branch 351 not taken.
✗ Branch 352 not taken.
✗ Branch 353 not taken.
✗ Branch 354 not taken.
✗ Branch 355 not taken.
✗ Branch 356 not taken.
✗ Branch 357 not taken.
346862 if (auto base = node.NodeT::basetype()) {
391 8735 return hierarchyVisits(*base);
392 }
393 }
394 return true;
395 }
396
397 /// @brief Implements the default behavior for a traversal to a given AST
398 /// node
399 /// @tparam NodeT The node type
400 /// @param node The node to traverse
401 /// @return True if traversal should continue, false to terminate
402 template <typename NodeT>
403 3023327 inline bool defaultTraversal(NodeType<NodeT>* node)
404 {
405
1/4
✓ Branch 0 taken 1627 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3023419 if (!node) return true;
406 1846552 const size_t children = node->children();
407
408 if (this->derived().postOrderNodes()) {
409 if (this->derived().reverseChildVisits()) {
410 420012 if (children != 0) {
411 788142 for (int64_t i = static_cast<int64_t>(children - 1); i >= 0; --i) {
412 539609 auto child = this->strip<ConstVisit>(node->child(i));
413 586334 if (!this->derived().traverse(child)) {
414 return false;
415 }
416 }
417 }
418 }
419 else {
420
2/2
✓ Branch 0 taken 1535 times.
✓ Branch 1 taken 1526 times.
4711502 for (size_t i = 0; i < children; ++i) {
421 auto child = this->strip<ConstVisit>(node->child(i));
422 2338269 if (!this->derived().traverse(child)) {
423 return false;
424 }
425 }
426 }
427 if (this->derived().visitNodeHierarchies()) {
428 984 return this->hierarchyVisits(*node);
429 }
430 else {
431 238186 return this->derived().visit(node);
432 }
433 }
434 else {
435 if (this->derived().visitNodeHierarchies()) {
436 if (!this->hierarchyVisits(*node)) return false;
437 }
438 else {
439
1/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
153 if (!this->derived().visit(node)) return false;
440 }
441 if (this->derived().reverseChildVisits()) {
442 if (children != 0) {
443 for (int64_t i = static_cast<int64_t>(children - 1); i >= 0; --i) {
444 auto child = this->strip<ConstVisit>(node->child(i));
445 if (!this->derived().traverse(child)) {
446 return false;
447 }
448 }
449 }
450 }
451 else {
452 180 for (size_t i = 0; i < children; ++i) {
453 auto child = this->strip<ConstVisit>(node->child(i));
454 15 if (!this->derived().traverse(child)) {
455 return false;
456 }
457 }
458 }
459 3 return true;
460 }
461 }
462 };
463
464 } // namespace ast
465 } // namespace ax
466
467 } // namespace OPENVDB_VERSION_NAME
468 } // namespace openvdb
469
470 #endif // OPENVDB_AX_AST_VISITOR_HAS_BEEN_INCLUDED
471
472