OpenVDB  12.0.0
Scanners.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: Apache-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 {
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  static void exec(const ast::Node& node, ContainerType& C) {
142  collectNodeType<T, ContainerType>(node, C);
143  CollectForEach<ContainerType, TypeList<Ts...>>::exec(node, C);
144  }
145 };
146 }
147 
148 // @endcond
149 
150 template<typename NodeT, typename ContainerType>
151 inline void collectNodeType(const ast::Node& node, ContainerType& array)
152 {
153  visitNodeType<NodeT>(node, [&](const NodeT& node) -> bool {
154  array.push_back(&node);
155  return true;
156  });
157 }
158 
159 template <typename NodeTypeList, typename ContainerType>
160 inline void collectNodeTypes(const ast::Node& node, ContainerType& array)
161 {
162  internal::CollectForEach<ContainerType, NodeTypeList>::exec(node, array);
163 }
164 
165 template <typename NodeT, typename OpT, typename Derived = void>
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,
175  Derived>::type;
176 
179 
180  inline bool visitNodeHierarchies() const {
181  return std::is_abstract<NodeT>::value;
182  }
183 
184  VisitNodeType(const OpT& op) : mOp(op) {}
185  ~VisitNodeType() = default;
186  inline bool visit(const NodeT* node) {
187  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  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 
void collectNodeType(const ast::Node &node, ContainerType &array)
Visit all nodes of a given type and store pointers to them in a provided compatible container...
Definition: Scanners.h:151
Provides the definition for every abstract and concrete derived class which represent a particular ab...
The Visitor class uses the Curiously Recursive Template Pattern (CRTP) to provide a customizable inte...
Definition: Visitor.h:95
OPENVDB_AX_API const ast::Variable * lastUse(const ast::Node &node, const std::string &token)
bool visitNodeHierarchies() const
Definition: Scanners.h:180
OPENVDB_AX_API bool writesToAttribute(const ast::Node &node, const std::string &name, const tokens::CoreType type=tokens::UNKNOWN)
Returns whether or not a given branch of an AST writes to a given attribute.
#define OPENVDB_AX_API
Definition: Platform.h:289
OPENVDB_AX_API void linearize(const ast::Node &node, std::vector< const ast::Node * > &list)
Flatten the provided AST branch into a linear list using post order traversal.
void collectNodeTypes(const ast::Node &node, ContainerType &array)
Visit all nodes of the given types and store pointers to them in a container of base ast::Node pointe...
Definition: Scanners.h:160
OutGridT XformOp & op
Definition: ValueTransformer.h:139
VisitNodeType(const OpT &op)
Definition: Scanners.h:184
typename std::conditional< std::is_same< Derived, void >::value, VisitNodeType< NodeT, OpT >, Derived >::type VisitorT
Definition: Scanners.h:175
void visitNodeType(const ast::Node &node, const OpT &op)
For an AST node of a given type, search for and call a custom const operator() which takes a const re...
Definition: Scanners.h:195
CoreType
Definition: Tokens.h:31
OPENVDB_AX_API void catalogueVariables(const ast::Node &node, std::vector< const ast::Variable * > *readOnly, std::vector< const ast::Variable * > *writeOnly, std::vector< const ast::Variable * > *readWrite, const bool locals=true, const bool attributes=true)
todo
Definition: Exceptions.h:13
OPENVDB_AX_API const ast::Variable * firstUse(const ast::Node &node, const std::string &token)
OPENVDB_AX_API void catalogueAttributeTokens(const ast::Node &node, std::vector< std::string > *readOnly, std::vector< std::string > *writeOnly, std::vector< std::string > *readWrite)
Parse all attributes into three unique vectors which represent how they are accessed within the synta...
bool traverse(NodeType< ast::Tree > *tree)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:161
OPENVDB_AX_API bool callsFunction(const ast::Node &node, const std::string &name)
Returns whether or not a given branch of an AST calls a function.
OPENVDB_AX_API void attributeDependencyTokens(const ast::Tree &tree, const std::string &name, const tokens::CoreType type, std::vector< std::string > &dependencies)
Populate a list of attribute names which the given attribute depends on.
Contains the AX AST Node Visitor, providing default and customizable traversal and visitation methods...
bool visit(const NodeT *node)
Definition: Scanners.h:186
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
The base abstract node which determines the interface and required methods for all derived concrete n...
Definition: AST.h:102
OPENVDB_AX_API bool usesAttribute(const ast::Node &node, const std::string &name, const tokens::CoreType type=tokens::UNKNOWN)
Returns whether or not a given branch of an AST reads from or writes to a given attribute.
Definition: Scanners.h:166
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218