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