OpenVDB 12.1.0

Loading...
Searching...
No Matches
Compiler.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 compiler/Compiler.h
5///
6/// @authors Nick Avramoussis, Francisco Gochez, Richard Jones
7///
8/// @brief The OpenVDB AX Compiler class provides methods to generate
9/// AX executables from a provided AX AST (or directly from a given
10/// string). The class object exists to cache various structures,
11/// primarily LLVM constructs, which benefit from existing across
12/// additional compilation runs.
13///
14
15#ifndef OPENVDB_AX_COMPILER_HAS_BEEN_INCLUDED
16#define OPENVDB_AX_COMPILER_HAS_BEEN_INCLUDED
17
18#include "CompilerOptions.h"
19#include "CustomData.h"
20#include "Logger.h"
21
22#include "openvdb_ax/ax.h" // backward compat support for initialize()
23#include "openvdb_ax/ast/Parse.h"
24
25#include <openvdb/version.h>
26#include <openvdb/util/Assert.h>
27
28#include <memory>
29#include <sstream>
30
31
32 namespace openvdb {
33 OPENVDB_USE_VERSION_NAMESPACE
34 namespace OPENVDB_VERSION_NAME {
35
36 namespace ax {
37
38 namespace codegen {
39// forward
40 class FunctionRegistry;
41}
42
43/// @brief The compiler class. This holds a set of compiler options and
44/// constructs executable objects (e.g. PointExecutable or VolumeExecutable)
45/// from a syntax tree or snippet of code.
46/// @note Compilers cannot be copied and it is _unsafe_ to call compile()
47/// methods concurrently on instances of the same compiler (due to access
48/// into the function registry currently not being thread safe). It is safe
49/// to create new instances of a Compiler to compile programs concurrently.
50 class OPENVDB_AX_API Compiler
51{
52 public:
53 using Ptr = std::shared_ptr<Compiler>;
54 using UniquePtr = std::unique_ptr<Compiler>;
55
56 /// @brief Construct a compiler object with given settings
57 /// @param options CompilerOptions object with various settings
58 Compiler(const CompilerOptions& options = CompilerOptions());
59 ~Compiler();
60
61 Compiler(const Compiler&) = delete;
62 Compiler& operator=(const Compiler&) = delete;
63 Compiler(Compiler&&);
64 Compiler& operator=(Compiler&&);
65
66 /// @brief Static method for creating Compiler objects
67 static UniquePtr create(const CompilerOptions& options = CompilerOptions());
68
69 /// @brief Compile a given AST into an executable object of the given type.
70 /// @param syntaxTree An abstract syntax tree to compile
71 /// @param logger Logger for errors and warnings during compilation, this
72 /// should be linked to an ast::Tree and populated with AST node + line
73 /// number mappings for this Tree, e.g. during ast::parse(). This Tree can
74 /// be different from the syntaxTree argument.
75 /// @param data Optional external/custom data which is to be referenced by
76 /// the executable object. It allows one to reference data held elsewhere,
77 /// such as inside of a DCC, from inside the AX code
78 /// @note If the logger has not been populated with AST node and line
79 /// mappings, all messages will appear without valid line and column
80 /// numbers.
81 template <typename ExecutableT>
82 typename ExecutableT::Ptr
83 compile(const ast::Tree& syntaxTree,
84 Logger& logger,
85 const CustomData::Ptr data = CustomData::Ptr());
86
87 /// @brief Compile a given snippet of AX code into an executable object of
88 /// the given type.
89 /// @param code A string of AX code
90 /// @param logger Logger for errors and warnings during compilation, will be
91 /// cleared of existing data
92 /// @param data Optional external/custom data which is to be referenced by
93 /// the executable object. It allows one to reference data held elsewhere,
94 /// such as inside of a DCC, from inside the AX code
95 /// @note If compilation is unsuccessful, will return nullptr. Logger can
96 /// then be queried for errors.
97 template <typename ExecutableT>
98 typename ExecutableT::Ptr
99 compile(const std::string& code,
100 Logger& logger,
101 const CustomData::Ptr data = CustomData::Ptr())
102 {
103 logger.clear();
104 const ast::Tree::ConstPtr syntaxTree = ast::parse(code.c_str(), logger);
105 if (syntaxTree) return compile<ExecutableT>(*syntaxTree, logger, data);
106 else return nullptr;
107 }
108
109 /// @brief Compile a given snippet of AX code into an executable object of
110 /// the given type.
111 /// @param code A string of AX code
112 /// @param data Optional external/custom data which is to be referenced by
113 /// the executable object. It allows one to reference data held elsewhere,
114 /// such as inside of a DCC, from inside the AX code
115 /// @note Parser errors are handled separately from compiler errors.
116 /// Each are collected and produce runtime errors.
117 template <typename ExecutableT>
118 typename ExecutableT::Ptr
119 compile(const std::string& code,
120 const CustomData::Ptr data = CustomData::Ptr())
121 {
122 std::vector<std::string> errors;
123 openvdb::ax::Logger logger(
124 [&errors] (const std::string& error) {
125 errors.emplace_back(error + "\n");
126 },
127 [] (const std::string&) {} // ignore warnings
128 );
129 const ast::Tree::ConstPtr syntaxTree = ast::parse(code.c_str(), logger);
130 if (!errors.empty()) {
131 std::ostringstream os;
132 for (const auto& e : errors) os << e << "\n";
133 OPENVDB_THROW(AXSyntaxError, os.str());
134 }
135 OPENVDB_ASSERT(syntaxTree);
136 typename ExecutableT::Ptr exe = this->compile<ExecutableT>(*syntaxTree, logger, data);
137 if (!errors.empty()) {
138 std::ostringstream os;
139 for (const auto& e : errors) os << e << "\n";
140 OPENVDB_THROW(AXCompilerError, os.str());
141 }
142 OPENVDB_ASSERT(exe);
143 return exe;
144 }
145
146 /// @brief Compile a given AST into an executable object of the given type.
147 /// @param syntaxTree An abstract syntax tree to compile
148 /// @param data Optional external/custom data which is to be referenced by
149 /// the executable object. It allows one to reference data held elsewhere,
150 /// such as inside of a DCC, from inside the AX code
151 /// @note Any errors encountered are collected into a single runtime error
152 template <typename ExecutableT>
153 typename ExecutableT::Ptr
154 compile(const ast::Tree& syntaxTree,
155 const CustomData::Ptr data = CustomData::Ptr())
156 {
157 std::vector<std::string> errors;
158 openvdb::ax::Logger logger(
159 [&errors] (const std::string& error) {
160 errors.emplace_back(error + "\n");
161 },
162 [] (const std::string&) {} // ignore warnings
163 );
164 auto exe = compile<ExecutableT>(syntaxTree, logger, data);
165 if (!errors.empty()) {
166 std::ostringstream os;
167 for (const auto& e : errors) os << e << "\n";
168 OPENVDB_THROW(AXCompilerError, os.str());
169 }
170 OPENVDB_ASSERT(exe);
171 return exe;
172 }
173
174 /// @brief Sets the compiler's function registry object.
175 /// @param functionRegistry A unique pointer to a FunctionRegistry object.
176 /// The compiler will take ownership of the registry that was passed in.
177 /// @todo Perhaps allow one to register individual functions into this
178 /// class rather than the entire registry at once, and/or allow one to
179 /// extract a pointer to the registry and update it manually.
180 void setFunctionRegistry(std::unique_ptr<codegen::FunctionRegistry>&& functionRegistry);
181
182 ///////////////////////////////////////////////////////////////////////////
183
184 private:
185 template <typename ExeT, typename GenT>
186 typename ExeT::Ptr
187 compile(const ast::Tree& tree,
188 const std::string& moduleName,
189 const std::vector<std::string>& functions,
190 CustomData::Ptr data,
191 Logger& logger);
192
193 private:
194 CompilerOptions mCompilerOptions;
195 std::unique_ptr<codegen::FunctionRegistry> mFunctionRegistry;
196};
197
198
199} // namespace ax
200} // namespace OPENVDB_VERSION_NAME
201} // namespace openvdb
202
203#endif // OPENVDB_AX_COMPILER_HAS_BEEN_INCLUDED
204
Assert.h
OPENVDB_ASSERT
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
CompilerOptions.h
OpenVDB AX Compiler Options.
CustomData.h
Access to the CustomData class which can provide custom user user data to the OpenVDB AX Compiler.
Logger.h
Logging system to collect errors and warnings throughout the different stages of parsing and compilat...
Parse.h
Parsing methods for creating abstract syntax trees out of AX code.
OPENVDB_AX_API
#define OPENVDB_AX_API
Definition Platform.h:312
ax.h
Single header include which provides methods for initializing AX and running a full AX pipeline (pars...
openvdb::v12_1::AXCompilerError
Definition Exceptions.h:39
openvdb::v12_1::AXSyntaxError
Definition Exceptions.h:37
openvdb::v12_1::ax::Compiler::Ptr
std::shared_ptr< Compiler > Ptr
Definition Compiler.h:53
openvdb::v12_1::ax::Compiler::compile
ExecutableT::Ptr compile(const std::string &code, Logger &logger, const CustomData::Ptr data=CustomData::Ptr())
Compile a given snippet of AX code into an executable object of the given type.
Definition Compiler.h:99
openvdb::v12_1::ax::Compiler::Compiler
Compiler(const Compiler &)=delete
openvdb::v12_1::ax::Compiler::UniquePtr
std::unique_ptr< Compiler > UniquePtr
Definition Compiler.h:54
openvdb::v12_1::ax::Compiler::Compiler
Compiler(Compiler &&)
openvdb::v12_1::ax::Compiler::setFunctionRegistry
void setFunctionRegistry(std::unique_ptr< codegen::FunctionRegistry > &&functionRegistry)
Sets the compiler's function registry object.
openvdb::v12_1::ax::Compiler::compile
ExecutableT::Ptr compile(const std::string &code, const CustomData::Ptr data=CustomData::Ptr())
Compile a given snippet of AX code into an executable object of the given type.
Definition Compiler.h:119
openvdb::v12_1::ax::Compiler::operator=
Compiler & operator=(const Compiler &)=delete
openvdb::v12_1::ax::Compiler::compile
ExecutableT::Ptr compile(const ast::Tree &syntaxTree, const CustomData::Ptr data=CustomData::Ptr())
Compile a given AST into an executable object of the given type.
Definition Compiler.h:154
openvdb::v12_1::ax::Compiler::operator=
Compiler & operator=(Compiler &&)
openvdb::v12_1::ax::Compiler::compile
ExecutableT::Ptr compile(const ast::Tree &syntaxTree, Logger &logger, const CustomData::Ptr data=CustomData::Ptr())
Compile a given AST into an executable object of the given type.
openvdb::v12_1::ax::Compiler::~Compiler
~Compiler()
openvdb::v12_1::ax::Compiler::Compiler
Compiler(const CompilerOptions &options=CompilerOptions())
Construct a compiler object with given settings.
openvdb::v12_1::ax::Compiler::create
static UniquePtr create(const CompilerOptions &options=CompilerOptions())
Static method for creating Compiler objects.
openvdb::v12_1::ax::CustomData::Ptr
std::shared_ptr< CustomData > Ptr
Definition CustomData.h:37
openvdb::v12_1::ax::Logger
Logger for collecting errors and warnings that occur during AX compilation.
Definition Logger.h:58
openvdb::v12_1::ax::Logger::clear
void clear()
Clear the tree-code mapping and reset the number of errors/warnings.
openvdb::v12_1::ax::ast::parse
OPENVDB_AX_API openvdb::ax::ast::Tree::ConstPtr parse(const char *code, ax::Logger &logger)
Construct an abstract syntax tree from a code snippet.
openvdb::v12_1::tree
Definition PointDataGrid.h:170
openvdb
Definition Exceptions.h:13
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
openvdb::v12_1::ax::CompilerOptions
Settings which control how a Compiler class object behaves.
Definition CompilerOptions.h:48
openvdb::v12_1::ax::ast::Tree
A Tree is the highest concrete (non-abstract) node in the entire AX AST hierarchy....
Definition AST.h:563
openvdb::v12_1::ax::ast::Tree::ConstPtr
std::shared_ptr< const Tree > ConstPtr
Definition AST.h:565
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218