GCC Code Coverage Report


Directory: ./
File: openvdb_ax/openvdb_ax/ast/Scanners.h
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 12 12 100.0%
Functions: 3 3 100.0%
Branches: 29 55 52.7%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 /// @file ast/Scanners.h
5 ///
6 /// @authors Nick Avramoussis, Richard Jones
7 ///
8 /// @brief Retrieve intrinsic information from AX AST by performing
9 /// various traversal algorithms.
10 ///
11
12 #ifndef OPENVDB_AX_COMPILER_AST_SCANNERS_HAS_BEEN_INCLUDED
13 #define OPENVDB_AX_COMPILER_AST_SCANNERS_HAS_BEEN_INCLUDED
14
15 #include "AST.h"
16 #include "Visitor.h"
17
18 #include <openvdb/version.h>
19
20 #include <string>
21
22 namespace openvdb {
23 OPENVDB_USE_VERSION_NAMESPACE
24 namespace OPENVDB_VERSION_NAME {
25
26 namespace ax {
27 namespace ast {
28
29 /// @brief Returns whether or not a given branch of an AST reads from or writes
30 /// to a given attribute.
31 ///
32 /// @param node The AST to analyze
33 /// @param name the name of the attribute to search for
34 /// @param type the type of the attribute to search for. If UNKNOWN, any
35 /// attribute with the given name is checked.
36 ///
37 OPENVDB_AX_API bool usesAttribute(const ast::Node& node,
38 const std::string& name,
39 const tokens::CoreType type = tokens::UNKNOWN);
40
41 /// @brief Returns whether or not a given branch of an AST writes to a given
42 /// attribute.
43 ///
44 /// @param node The AST to analyze
45 /// @param name the name of the attribute to search for
46 /// @param type the type of the attribute to search for. If UNKNOWN, the first
47 /// attribute encountered with the given name is checked.
48 ///
49 OPENVDB_AX_API bool writesToAttribute(const ast::Node& node,
50 const std::string& name,
51 const tokens::CoreType type = tokens::UNKNOWN);
52
53 /// @brief Returns whether or not a given branch of an AST calls a function
54 ///
55 /// @param node The AST to analyze
56 /// @param name the name of the function to search for
57 ///
58 OPENVDB_AX_API bool callsFunction(const ast::Node& node, const std::string& name);
59
60 /// @brief todo
61 OPENVDB_AX_API void catalogueVariables(const ast::Node& node,
62 std::vector<const ast::Variable*>* readOnly,
63 std::vector<const ast::Variable*>* writeOnly,
64 std::vector<const ast::Variable*>* readWrite,
65 const bool locals = true,
66 const bool attributes = true);
67
68 /// @brief Parse all attributes into three unique vectors which represent how they
69 /// are accessed within the syntax tree. Read only attributes are stored
70 /// within the 'readOnly' container (for example @code int a=@a; @endcode),
71 /// write only attributes in the 'writeOnly' container @code @a=1; @endcode
72 /// and readWrite attributes in the 'readWrite' container @code @a+=1; @endcode
73 /// @note Note that the code generator is able to do this far more efficiently, however
74 /// this provides simple front-end support for detecting these types of operations
75 ///
76 /// @param node The AST to analyze
77 /// @param readOnly The unique list of attributes which are only read from
78 /// @param writeOnly The unique list of attributes which are only written too
79 /// @param readWrite The unique list of attributes which both read from and written too
80 ///
81 OPENVDB_AX_API void catalogueAttributeTokens(const ast::Node& node,
82 std::vector<std::string>* readOnly,
83 std::vector<std::string>* writeOnly,
84 std::vector<std::string>* readWrite);
85
86 /// @brief Populate a list of attribute names which the given attribute depends on
87 OPENVDB_AX_API void attributeDependencyTokens(const ast::Tree& tree,
88 const std::string& name,
89 const tokens::CoreType type,
90 std::vector<std::string>& dependencies);
91
92 /// @brief For an AST node of a given type, search for and call a custom
93 /// const operator() which takes a const reference to every occurrence
94 /// of the specified node type.
95 ///
96 /// @param node The AST to run over
97 /// @param op The operator to call on every found AST node of type NodeT
98 ///
99 template <typename NodeT, typename OpT>
100 inline void visitNodeType(const ast::Node& node, const OpT& op);
101
102 /// @brief Visit all nodes of a given type and store pointers to them in a
103 /// provided compatible container
104 template<typename NodeT, typename ContainerType = std::vector<const NodeT*>>
105 inline void collectNodeType(const ast::Node& node, ContainerType& array);
106
107 /// @brief Visit all nodes of the given types and store pointers to them in a
108 /// container of base ast::Node pointers
109 /// @note NodeTypeList is expected to be a an openvdb::TypeList object with a
110 /// list of node types. For example, to collect all Attribute and
111 /// External Variable ast Nodes:
112 ///
113 /// using ListT = openvdb::TypeList<ast::Attribute, ast::ExternalVariable>;
114 /// std::vector<const ast::Node*> nodes;
115 /// ast::collectNodeTypes<ListT>(tree, nodes);
116 ///
117 template <typename NodeTypeList, typename ContainerType = std::vector<const Node*>>
118 inline void collectNodeTypes(const ast::Node& node, ContainerType& array);
119
120 /// @brief Flatten the provided AST branch into a linear list using post order traversal
121 ///
122 OPENVDB_AX_API void linearize(const ast::Node& node, std::vector<const ast::Node*>& list);
123
124 OPENVDB_AX_API const ast::Variable* firstUse(const ast::Node& node, const std::string& token);
125 OPENVDB_AX_API const ast::Variable* lastUse(const ast::Node& node, const std::string& token);
126
127
128 //////////////////////////////////////////////////////////////////////
129 //////////////////////////////////////////////////////////////////////
130
131 /// @cond OPENVDB_DOCS_INTERNAL
132
133 namespace internal {
134 template<typename ContainerType, typename T, typename ...Ts>
135 struct CollectForEach {
136 static void exec(const ast::Node&, ContainerType&) {}
137 };
138
139 template<typename ContainerType, typename T, typename ...Ts>
140 struct CollectForEach<ContainerType, TypeList<T, Ts...>> {
141 179932 static void exec(const ast::Node& node, ContainerType& C) {
142 collectNodeType<T, ContainerType>(node, C);
143 89966 CollectForEach<ContainerType, TypeList<Ts...>>::exec(node, C);
144 179932 }
145 };
146 }
147
148 // @endcond
149
150 template<typename NodeT, typename ContainerType>
151 inline void collectNodeType(const ast::Node& node, ContainerType& array)
152 {
153 44983 visitNodeType<NodeT>(node, [&](const NodeT& node) -> bool {
154 44577 array.push_back(&node);
155 return true;
156 });
157 1537 }
158
159 template <typename NodeTypeList, typename ContainerType>
160 inline void collectNodeTypes(const ast::Node& node, ContainerType& array)
161 {
162
7/14
✓ Branch 1 taken 225 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 108 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 116 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 11793 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 17344 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 8783 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 6614 times.
✗ Branch 20 not taken.
44983 internal::CollectForEach<ContainerType, NodeTypeList>::exec(node, array);
163 44983 }
164
165 template <typename NodeT, typename OpT, typename Derived = void>
166 struct VisitNodeType :
167 public ast::Visitor<typename std::conditional<
168 std::is_same<Derived, void>::value,
169 VisitNodeType<NodeT, OpT>,
170 Derived>::type>
171 {
172 using VisitorT = typename std::conditional<
173 std::is_same<Derived, void>::value,
174 VisitNodeType<NodeT, OpT>,
175 Derived>::type;
176
177 using ast::Visitor<VisitorT>::traverse;
178 using ast::Visitor<VisitorT>::visit;
179
180 inline bool visitNodeHierarchies() const {
181 return std::is_abstract<NodeT>::value;
182 }
183
184
1/2
✓ Branch 1 taken 19232 times.
✗ Branch 2 not taken.
22327 VisitNodeType(const OpT& op) : mOp(op) {}
185 ~VisitNodeType() = default;
186 17121 inline bool visit(const NodeT* node) {
187
3/4
✓ Branch 21 taken 17121 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 23 times.
✓ Branch 24 taken 17098 times.
412047 if (node) return mOp(*node);
188 return true;
189 }
190 private:
191 const OpT& mOp;
192 };
193
194 template <typename NodeT, typename OpT>
195 inline void visitNodeType(const ast::Node& node, const OpT& op)
196 {
197 VisitNodeType<NodeT, OpT> visitOp(op);
198
18/35
✓ Branch 1 taken 1540 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1540 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1537 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 1 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 1 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 1 times.
✗ Branch 50 not taken.
100760 visitOp.traverse(&node);
199 }
200
201 } // namespace ast
202 } // namespace ax
203 } // namespace OPENVDB_VERSION_NAME
204 } // namespace openvdb
205
206 #endif // OPENVDB_AX_COMPILER_AST_SCANNERS_HAS_BEEN_INCLUDED
207
208
209