blob: 716c9f9d3ca3a2256091fc65e95e352db0ab8e14 [file] [log] [blame]
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001// Copyright 2021 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef SRC_PROGRAM_BUILDER_H_
16#define SRC_PROGRAM_BUILDER_H_
17
18#include <string>
19#include <utility>
20
21#include "src/ast/array_accessor_expression.h"
Antonio Maioranofd31bbd2021-03-09 10:26:57 +000022#include "src/ast/assignment_statement.h"
Ben Claytona6b9a8e2021-01-26 16:57:10 +000023#include "src/ast/binary_expression.h"
24#include "src/ast/bool_literal.h"
25#include "src/ast/call_expression.h"
Antonio Maioranocea744d2021-03-25 12:55:27 +000026#include "src/ast/case_statement.h"
Ben Claytona6b9a8e2021-01-26 16:57:10 +000027#include "src/ast/float_literal.h"
Antonio Maioranofd31bbd2021-03-09 10:26:57 +000028#include "src/ast/if_statement.h"
29#include "src/ast/loop_statement.h"
Ben Claytona6b9a8e2021-01-26 16:57:10 +000030#include "src/ast/member_accessor_expression.h"
31#include "src/ast/module.h"
Antonio Maiorano03c01b52021-03-19 14:04:51 +000032#include "src/ast/return_statement.h"
Ben Claytona6b9a8e2021-01-26 16:57:10 +000033#include "src/ast/scalar_constructor_expression.h"
34#include "src/ast/sint_literal.h"
James Price68f558f2021-04-06 15:51:47 +000035#include "src/ast/stage_decoration.h"
Ben Claytonbab31972021-02-08 21:16:21 +000036#include "src/ast/stride_decoration.h"
Ben Claytond614dd52021-03-15 10:43:11 +000037#include "src/ast/struct_member_align_decoration.h"
Ben Claytona6b9a8e2021-01-26 16:57:10 +000038#include "src/ast/struct_member_offset_decoration.h"
Ben Claytond614dd52021-03-15 10:43:11 +000039#include "src/ast/struct_member_size_decoration.h"
Antonio Maioranocea744d2021-03-25 12:55:27 +000040#include "src/ast/switch_statement.h"
Ben Claytona6b9a8e2021-01-26 16:57:10 +000041#include "src/ast/type_constructor_expression.h"
42#include "src/ast/uint_literal.h"
Antonio Maioranofd31bbd2021-03-09 10:26:57 +000043#include "src/ast/variable_decl_statement.h"
Ben Claytona6b9a8e2021-01-26 16:57:10 +000044#include "src/program.h"
Ben Claytone6995de2021-04-13 23:27:27 +000045#include "src/program_id.h"
Ben Claytona6b9a8e2021-01-26 16:57:10 +000046#include "src/type/alias_type.h"
47#include "src/type/array_type.h"
48#include "src/type/bool_type.h"
49#include "src/type/f32_type.h"
50#include "src/type/i32_type.h"
51#include "src/type/matrix_type.h"
52#include "src/type/pointer_type.h"
53#include "src/type/struct_type.h"
Ben Claytona6b9a8e2021-01-26 16:57:10 +000054#include "src/type/u32_type.h"
55#include "src/type/vector_type.h"
56#include "src/type/void_type.h"
57
58namespace tint {
59
Ben Clayton401b96b2021-02-03 17:19:59 +000060// Forward declarations
61namespace ast {
62class VariableDeclStatement;
63} // namespace ast
64
Ben Claytona6b9a8e2021-01-26 16:57:10 +000065class CloneContext;
66
67/// ProgramBuilder is a mutable builder for a Program.
68/// To construct a Program, populate the builder and then `std::move` it to a
69/// Program.
70class ProgramBuilder {
71 public:
Ben Clayton7fdfff12021-01-29 15:17:30 +000072 /// ASTNodeAllocator is an alias to BlockAllocator<ast::Node>
73 using ASTNodeAllocator = BlockAllocator<ast::Node>;
74
75 /// SemNodeAllocator is an alias to BlockAllocator<semantic::Node>
76 using SemNodeAllocator = BlockAllocator<semantic::Node>;
Ben Claytona6b9a8e2021-01-26 16:57:10 +000077
78 /// `i32` is a type alias to `int`.
79 /// Useful for passing to template methods such as `vec2<i32>()` to imitate
80 /// WGSL syntax.
81 /// Note: this is intentionally not aliased to uint32_t as we want integer
82 /// literals passed to the builder to match WGSL's integer literal types.
83 using i32 = decltype(1);
84 /// `u32` is a type alias to `unsigned int`.
85 /// Useful for passing to template methods such as `vec2<u32>()` to imitate
86 /// WGSL syntax.
87 /// Note: this is intentionally not aliased to uint32_t as we want integer
88 /// literals passed to the builder to match WGSL's integer literal types.
89 using u32 = decltype(1u);
90 /// `f32` is a type alias to `float`
91 /// Useful for passing to template methods such as `vec2<f32>()` to imitate
92 /// WGSL syntax.
93 using f32 = float;
94
95 /// Constructor
96 ProgramBuilder();
97
98 /// Move constructor
99 /// @param rhs the builder to move
100 ProgramBuilder(ProgramBuilder&& rhs);
101
102 /// Destructor
103 virtual ~ProgramBuilder();
104
105 /// Move assignment operator
106 /// @param rhs the builder to move
107 /// @return this builder
108 ProgramBuilder& operator=(ProgramBuilder&& rhs);
109
Ben Claytone43c8302021-01-29 11:59:32 +0000110 /// Wrap returns a new ProgramBuilder wrapping the Program `program` without
111 /// making a deep clone of the Program contents.
112 /// ProgramBuilder returned by Wrap() is intended to temporarily extend an
113 /// existing immutable program.
114 /// As the returned ProgramBuilder wraps `program`, `program` must not be
115 /// destructed or assigned while using the returned ProgramBuilder.
116 /// TODO(bclayton) - Evaluate whether there are safer alternatives to this
117 /// function. See crbug.com/tint/460.
118 /// @param program the immutable Program to wrap
119 /// @return the ProgramBuilder that wraps `program`
120 static ProgramBuilder Wrap(const Program* program);
121
Ben Claytone6995de2021-04-13 23:27:27 +0000122 /// @returns the unique identifier for this program
123 ProgramID ID() const { return id_; }
124
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000125 /// @returns a reference to the program's types
126 type::Manager& Types() {
127 AssertNotMoved();
128 return types_;
129 }
130
Ben Claytondd1b6fc2021-01-29 10:55:40 +0000131 /// @returns a reference to the program's types
132 const type::Manager& Types() const {
133 AssertNotMoved();
134 return types_;
135 }
136
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000137 /// @returns a reference to the program's AST nodes storage
Ben Clayton7fdfff12021-01-29 15:17:30 +0000138 ASTNodeAllocator& ASTNodes() {
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000139 AssertNotMoved();
Ben Clayton7fdfff12021-01-29 15:17:30 +0000140 return ast_nodes_;
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000141 }
142
Ben Claytondd1b6fc2021-01-29 10:55:40 +0000143 /// @returns a reference to the program's AST nodes storage
Ben Clayton7fdfff12021-01-29 15:17:30 +0000144 const ASTNodeAllocator& ASTNodes() const {
Ben Claytondd1b6fc2021-01-29 10:55:40 +0000145 AssertNotMoved();
Ben Clayton7fdfff12021-01-29 15:17:30 +0000146 return ast_nodes_;
147 }
148
149 /// @returns a reference to the program's semantic nodes storage
150 SemNodeAllocator& SemNodes() {
151 AssertNotMoved();
152 return sem_nodes_;
153 }
154
155 /// @returns a reference to the program's semantic nodes storage
156 const SemNodeAllocator& SemNodes() const {
157 AssertNotMoved();
158 return sem_nodes_;
Ben Claytondd1b6fc2021-01-29 10:55:40 +0000159 }
160
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000161 /// @returns a reference to the program's AST root Module
162 ast::Module& AST() {
163 AssertNotMoved();
164 return *ast_;
165 }
166
Ben Claytondd1b6fc2021-01-29 10:55:40 +0000167 /// @returns a reference to the program's AST root Module
168 const ast::Module& AST() const {
169 AssertNotMoved();
170 return *ast_;
171 }
172
173 /// @returns a reference to the program's semantic info
174 semantic::Info& Sem() {
175 AssertNotMoved();
176 return sem_;
177 }
178
179 /// @returns a reference to the program's semantic info
180 const semantic::Info& Sem() const {
181 AssertNotMoved();
182 return sem_;
183 }
184
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000185 /// @returns a reference to the program's SymbolTable
186 SymbolTable& Symbols() {
187 AssertNotMoved();
188 return symbols_;
189 }
190
Ben Clayton708dc2d2021-01-29 11:22:40 +0000191 /// @returns a reference to the program's SymbolTable
192 const SymbolTable& Symbols() const {
193 AssertNotMoved();
194 return symbols_;
195 }
196
Ben Clayton844217f2021-01-27 18:49:05 +0000197 /// @returns a reference to the program's diagnostics
198 diag::List& Diagnostics() {
199 AssertNotMoved();
200 return diagnostics_;
201 }
202
Ben Claytondd1b6fc2021-01-29 10:55:40 +0000203 /// @returns a reference to the program's diagnostics
204 const diag::List& Diagnostics() const {
205 AssertNotMoved();
206 return diagnostics_;
207 }
208
Ben Clayton5f0ea112021-03-09 10:54:37 +0000209 /// Controls whether the Resolver will be run on the program when it is built.
Ben Claytondd69ac32021-01-27 19:23:55 +0000210 /// @param enable the new flag value (defaults to true)
211 void SetResolveOnBuild(bool enable) { resolve_on_build_ = enable; }
212
Ben Clayton5f0ea112021-03-09 10:54:37 +0000213 /// @return true if the Resolver will be run on the program when it is
Ben Claytondd69ac32021-01-27 19:23:55 +0000214 /// built.
215 bool ResolveOnBuild() const { return resolve_on_build_; }
216
Ben Clayton844217f2021-01-27 18:49:05 +0000217 /// @returns true if the program has no error diagnostics and is not missing
218 /// information
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000219 bool IsValid() const;
220
Ben Clayton708dc2d2021-01-29 11:22:40 +0000221 /// Writes a representation of the node to the output stream
222 /// @note unlike str(), to_str() does not automatically demangle the string.
223 /// @param node the AST node
224 /// @param out the stream to write to
225 /// @param indent number of spaces to indent the node when writing
226 void to_str(const ast::Node* node, std::ostream& out, size_t indent) const {
227 node->to_str(Sem(), out, indent);
228 }
229
230 /// Returns a demangled, string representation of `node`.
231 /// @param node the AST node
232 /// @returns a string representation of the node
233 std::string str(const ast::Node* node) const;
234
Ben Clayton7fdfff12021-01-29 15:17:30 +0000235 /// Creates a new ast::Node owned by the ProgramBuilder. When the
236 /// ProgramBuilder is destructed, the ast::Node will also be destructed.
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000237 /// @param source the Source of the node
238 /// @param args the arguments to pass to the type constructor
239 /// @returns the node pointer
240 template <typename T, typename... ARGS>
241 traits::EnableIfIsType<T, ast::Node>* create(const Source& source,
242 ARGS&&... args) {
243 AssertNotMoved();
Ben Claytone6995de2021-04-13 23:27:27 +0000244 return ast_nodes_.Create<T>(id_, source, std::forward<ARGS>(args)...);
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000245 }
246
Ben Clayton7fdfff12021-01-29 15:17:30 +0000247 /// Creates a new ast::Node owned by the ProgramBuilder, injecting the current
248 /// Source as set by the last call to SetSource() as the only argument to the
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000249 /// constructor.
Ben Clayton7fdfff12021-01-29 15:17:30 +0000250 /// When the ProgramBuilder is destructed, the ast::Node will also be
251 /// destructed.
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000252 /// @returns the node pointer
253 template <typename T>
254 traits::EnableIfIsType<T, ast::Node>* create() {
255 AssertNotMoved();
Ben Claytone6995de2021-04-13 23:27:27 +0000256 return ast_nodes_.Create<T>(id_, source_);
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000257 }
258
Ben Clayton7fdfff12021-01-29 15:17:30 +0000259 /// Creates a new ast::Node owned by the ProgramBuilder, injecting the current
260 /// Source as set by the last call to SetSource() as the first argument to the
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000261 /// constructor.
Ben Clayton7fdfff12021-01-29 15:17:30 +0000262 /// When the ProgramBuilder is destructed, the ast::Node will also be
263 /// destructed.
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000264 /// @param arg0 the first arguments to pass to the type constructor
265 /// @param args the remaining arguments to pass to the type constructor
266 /// @returns the node pointer
267 template <typename T, typename ARG0, typename... ARGS>
268 traits::EnableIf</* T is ast::Node and ARG0 is not Source */
269 traits::IsTypeOrDerived<T, ast::Node>::value &&
270 !traits::IsTypeOrDerived<ARG0, Source>::value,
271 T>*
272 create(ARG0&& arg0, ARGS&&... args) {
273 AssertNotMoved();
Ben Claytone6995de2021-04-13 23:27:27 +0000274 return ast_nodes_.Create<T>(id_, source_, std::forward<ARG0>(arg0),
Ben Clayton7fdfff12021-01-29 15:17:30 +0000275 std::forward<ARGS>(args)...);
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000276 }
277
Ben Clayton7fdfff12021-01-29 15:17:30 +0000278 /// Creates a new semantic::Node owned by the ProgramBuilder.
279 /// When the ProgramBuilder is destructed, the semantic::Node will also be
280 /// destructed.
281 /// @param args the arguments to pass to the type constructor
282 /// @returns the node pointer
283 template <typename T, typename... ARGS>
284 traits::EnableIfIsType<T, semantic::Node>* create(ARGS&&... args) {
285 AssertNotMoved();
286 return sem_nodes_.Create<T>(std::forward<ARGS>(args)...);
287 }
288
289 /// Creates a new type::Type owned by the ProgramBuilder.
290 /// When the ProgramBuilder is destructed, owned ProgramBuilder and the
291 /// returned`Type` will also be destructed.
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000292 /// Types are unique (de-aliased), and so calling create() for the same `T`
293 /// and arguments will return the same pointer.
294 /// @warning Use this method to acquire a type only if all of its type
295 /// information is provided in the constructor arguments `args`.<br>
296 /// If the type requires additional configuration after construction that
297 /// affect its fundamental type, build the type with `std::make_unique`, make
298 /// any necessary alterations and then call unique_type() instead.
299 /// @param args the arguments to pass to the type constructor
300 /// @returns the de-aliased type pointer
301 template <typename T, typename... ARGS>
302 traits::EnableIfIsType<T, type::Type>* create(ARGS&&... args) {
303 static_assert(std::is_base_of<type::Type, T>::value,
304 "T does not derive from type::Type");
305 AssertNotMoved();
306 return types_.Get<T>(std::forward<ARGS>(args)...);
307 }
308
309 /// Marks this builder as moved, preventing any further use of the builder.
310 void MarkAsMoved();
311
312 //////////////////////////////////////////////////////////////////////////////
313 // TypesBuilder
314 //////////////////////////////////////////////////////////////////////////////
315
316 /// TypesBuilder holds basic `tint` types and methods for constructing
317 /// complex types.
318 class TypesBuilder {
319 public:
320 /// Constructor
321 /// @param builder the program builder
322 explicit TypesBuilder(ProgramBuilder* builder);
323
324 /// @return the tint AST type for the C type `T`.
325 template <typename T>
326 type::Type* Of() const {
327 return CToAST<T>::get(this);
328 }
329
330 /// @returns a boolean type
331 type::Bool* bool_() const { return builder->create<type::Bool>(); }
332
333 /// @returns a f32 type
334 type::F32* f32() const { return builder->create<type::F32>(); }
335
336 /// @returns a i32 type
337 type::I32* i32() const { return builder->create<type::I32>(); }
338
339 /// @returns a u32 type
340 type::U32* u32() const { return builder->create<type::U32>(); }
341
342 /// @returns a void type
343 type::Void* void_() const { return builder->create<type::Void>(); }
344
Antonio Maiorano25436862021-04-13 13:32:33 +0000345 /// @param type vector subtype
346 /// @return the tint AST type for a 2-element vector of `type`.
347 type::Vector* vec2(type::Type* type) const {
348 return builder->create<type::Vector>(type, 2u);
349 }
350
351 /// @param type vector subtype
352 /// @return the tint AST type for a 3-element vector of `type`.
353 type::Vector* vec3(type::Type* type) const {
354 return builder->create<type::Vector>(type, 3u);
355 }
356
357 /// @param type vector subtype
358 /// @return the tint AST type for a 4-element vector of `type`.
359 type::Type* vec4(type::Type* type) const {
360 return builder->create<type::Vector>(type, 4u);
361 }
362
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000363 /// @return the tint AST type for a 2-element vector of the C type `T`.
364 template <typename T>
365 type::Vector* vec2() const {
Antonio Maiorano25436862021-04-13 13:32:33 +0000366 return vec2(Of<T>());
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000367 }
368
369 /// @return the tint AST type for a 3-element vector of the C type `T`.
370 template <typename T>
371 type::Vector* vec3() const {
Antonio Maiorano25436862021-04-13 13:32:33 +0000372 return vec3(Of<T>());
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000373 }
374
375 /// @return the tint AST type for a 4-element vector of the C type `T`.
376 template <typename T>
377 type::Type* vec4() const {
Antonio Maiorano25436862021-04-13 13:32:33 +0000378 return vec4(Of<T>());
379 }
380
381 /// @param type matrix subtype
382 /// @return the tint AST type for a 2x3 matrix of `type`.
383 type::Matrix* mat2x2(type::Type* type) const {
384 return builder->create<type::Matrix>(type, 2u, 2u);
385 }
386
387 /// @param type matrix subtype
388 /// @return the tint AST type for a 2x3 matrix of `type`.
389 type::Matrix* mat2x3(type::Type* type) const {
390 return builder->create<type::Matrix>(type, 3u, 2u);
391 }
392
393 /// @param type matrix subtype
394 /// @return the tint AST type for a 2x4 matrix of `type`.
395 type::Matrix* mat2x4(type::Type* type) const {
396 return builder->create<type::Matrix>(type, 4u, 2u);
397 }
398
399 /// @param type matrix subtype
400 /// @return the tint AST type for a 3x2 matrix of `type`.
401 type::Matrix* mat3x2(type::Type* type) const {
402 return builder->create<type::Matrix>(type, 2u, 3u);
403 }
404
405 /// @param type matrix subtype
406 /// @return the tint AST type for a 3x3 matrix of `type`.
407 type::Matrix* mat3x3(type::Type* type) const {
408 return builder->create<type::Matrix>(type, 3u, 3u);
409 }
410
411 /// @param type matrix subtype
412 /// @return the tint AST type for a 3x4 matrix of `type`.
413 type::Matrix* mat3x4(type::Type* type) const {
414 return builder->create<type::Matrix>(type, 4u, 3u);
415 }
416
417 /// @param type matrix subtype
418 /// @return the tint AST type for a 4x2 matrix of `type`.
419 type::Matrix* mat4x2(type::Type* type) const {
420 return builder->create<type::Matrix>(type, 2u, 4u);
421 }
422
423 /// @param type matrix subtype
424 /// @return the tint AST type for a 4x3 matrix of `type`.
425 type::Matrix* mat4x3(type::Type* type) const {
426 return builder->create<type::Matrix>(type, 3u, 4u);
427 }
428
429 /// @param type matrix subtype
430 /// @return the tint AST type for a 4x4 matrix of `type`.
431 type::Matrix* mat4x4(type::Type* type) const {
432 return builder->create<type::Matrix>(type, 4u, 4u);
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000433 }
434
435 /// @return the tint AST type for a 2x3 matrix of the C type `T`.
436 template <typename T>
437 type::Matrix* mat2x2() const {
Antonio Maiorano25436862021-04-13 13:32:33 +0000438 return mat2x2(Of<T>());
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000439 }
440
441 /// @return the tint AST type for a 2x3 matrix of the C type `T`.
442 template <typename T>
443 type::Matrix* mat2x3() const {
Antonio Maiorano25436862021-04-13 13:32:33 +0000444 return mat2x3(Of<T>());
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000445 }
446
447 /// @return the tint AST type for a 2x4 matrix of the C type `T`.
448 template <typename T>
449 type::Matrix* mat2x4() const {
Antonio Maiorano25436862021-04-13 13:32:33 +0000450 return mat2x4(Of<T>());
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000451 }
452
453 /// @return the tint AST type for a 3x2 matrix of the C type `T`.
454 template <typename T>
455 type::Matrix* mat3x2() const {
Antonio Maiorano25436862021-04-13 13:32:33 +0000456 return mat3x2(Of<T>());
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000457 }
458
459 /// @return the tint AST type for a 3x3 matrix of the C type `T`.
460 template <typename T>
461 type::Matrix* mat3x3() const {
Antonio Maiorano25436862021-04-13 13:32:33 +0000462 return mat3x3(Of<T>());
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000463 }
464
465 /// @return the tint AST type for a 3x4 matrix of the C type `T`.
466 template <typename T>
467 type::Matrix* mat3x4() const {
Antonio Maiorano25436862021-04-13 13:32:33 +0000468 return mat3x4(Of<T>());
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000469 }
470
471 /// @return the tint AST type for a 4x2 matrix of the C type `T`.
472 template <typename T>
473 type::Matrix* mat4x2() const {
Antonio Maiorano25436862021-04-13 13:32:33 +0000474 return mat4x2(Of<T>());
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000475 }
476
477 /// @return the tint AST type for a 4x3 matrix of the C type `T`.
478 template <typename T>
479 type::Matrix* mat4x3() const {
Antonio Maiorano25436862021-04-13 13:32:33 +0000480 return mat4x3(Of<T>());
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000481 }
482
483 /// @return the tint AST type for a 4x4 matrix of the C type `T`.
484 template <typename T>
485 type::Matrix* mat4x4() const {
Antonio Maiorano25436862021-04-13 13:32:33 +0000486 return mat4x4(Of<T>());
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000487 }
488
489 /// @param subtype the array element type
490 /// @param n the array size. 0 represents a runtime-array.
491 /// @return the tint AST type for a array of size `n` of type `T`
Ben Clayton1b8d9f22021-04-07 11:16:01 +0000492 type::Array* array(type::Type* subtype, uint32_t n = 0) const {
James Price95d40772021-03-11 17:39:32 +0000493 return builder->create<type::Array>(subtype, n, ast::DecorationList{});
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000494 }
495
Ben Claytonbab31972021-02-08 21:16:21 +0000496 /// @param subtype the array element type
497 /// @param n the array size. 0 represents a runtime-array.
498 /// @param stride the array stride.
499 /// @return the tint AST type for a array of size `n` of type `T`
500 type::Array* array(type::Type* subtype, uint32_t n, uint32_t stride) const {
501 return builder->create<type::Array>(
502 subtype, n,
James Price95d40772021-03-11 17:39:32 +0000503 ast::DecorationList{
Ben Claytonbab31972021-02-08 21:16:21 +0000504 builder->create<ast::StrideDecoration>(stride),
505 });
506 }
507
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000508 /// @return the tint AST type for an array of size `N` of type `T`
509 template <typename T, int N = 0>
510 type::Array* array() const {
511 return array(Of<T>(), N);
512 }
513
Ben Claytonbab31972021-02-08 21:16:21 +0000514 /// @param stride the array stride
515 /// @return the tint AST type for an array of size `N` of type `T`
516 template <typename T, int N = 0>
517 type::Array* array(uint32_t stride) const {
518 return array(Of<T>(), N, stride);
519 }
Ben Clayton42d1e092021-02-02 14:29:15 +0000520 /// Creates an alias type
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000521 /// @param name the alias name
522 /// @param type the alias type
523 /// @returns the alias pointer
Ben Clayton1d618b12021-04-09 16:19:48 +0000524 template <typename NAME>
525 type::Alias* alias(NAME&& name, type::Type* type) const {
526 return builder->create<type::Alias>(
527 builder->Sym(std::forward<NAME>(name)), type);
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000528 }
529
Antonio Maiorano39a65a12021-03-31 12:46:52 +0000530 /// @return the tint AST pointer to `type` with the given ast::StorageClass
531 /// @param type the type of the pointer
532 /// @param storage_class the storage class of the pointer
533 type::Pointer* pointer(type::Type* type,
534 ast::StorageClass storage_class) const {
535 return builder->create<type::Pointer>(type, storage_class);
536 }
537
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000538 /// @return the tint AST pointer to type `T` with the given
539 /// ast::StorageClass.
540 /// @param storage_class the storage class of the pointer
541 template <typename T>
542 type::Pointer* pointer(ast::StorageClass storage_class) const {
Antonio Maiorano39a65a12021-03-31 12:46:52 +0000543 return pointer(Of<T>(), storage_class);
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000544 }
545
546 /// @param name the struct name
547 /// @param impl the struct implementation
548 /// @returns a struct pointer
Ben Clayton1d618b12021-04-09 16:19:48 +0000549 template <typename NAME>
550 type::Struct* struct_(NAME&& name, ast::Struct* impl) const {
551 return builder->create<type::Struct>(
552 builder->Sym(std::forward<NAME>(name)), impl);
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000553 }
554
555 private:
556 /// CToAST<T> is specialized for various `T` types and each specialization
557 /// contains a single static `get()` method for obtaining the corresponding
558 /// AST type for the C type `T`.
559 /// `get()` has the signature:
560 /// `static type::Type* get(Types* t)`
561 template <typename T>
562 struct CToAST {};
563
Ben Claytonc7ca7662021-02-17 16:23:52 +0000564 ProgramBuilder* const builder;
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000565 };
566
567 //////////////////////////////////////////////////////////////////////////////
568 // AST helper methods
569 //////////////////////////////////////////////////////////////////////////////
570
Ben Clayton1b8d9f22021-04-07 11:16:01 +0000571 /// @param name the symbol string
572 /// @return a Symbol with the given name
573 Symbol Sym(const std::string& name) { return Symbols().Register(name); }
574
575 /// @param sym the symbol
576 /// @return `sym`
577 Symbol Sym(Symbol sym) { return sym; }
578
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000579 /// @param expr the expression
580 /// @return expr
Ben Clayton6d612ad2021-02-24 14:15:02 +0000581 template <typename T>
582 traits::EnableIfIsType<T, ast::Expression>* Expr(T* expr) {
583 return expr;
584 }
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000585
586 /// @param name the identifier name
587 /// @return an ast::IdentifierExpression with the given name
588 ast::IdentifierExpression* Expr(const std::string& name) {
589 return create<ast::IdentifierExpression>(Symbols().Register(name));
590 }
591
Ben Clayton46d78d72021-02-10 21:34:26 +0000592 /// @param symbol the identifier symbol
593 /// @return an ast::IdentifierExpression with the given symbol
594 ast::IdentifierExpression* Expr(Symbol symbol) {
595 return create<ast::IdentifierExpression>(symbol);
596 }
597
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000598 /// @param source the source information
599 /// @param name the identifier name
600 /// @return an ast::IdentifierExpression with the given name
601 ast::IdentifierExpression* Expr(const Source& source,
602 const std::string& name) {
603 return create<ast::IdentifierExpression>(source, Symbols().Register(name));
604 }
605
606 /// @param name the identifier name
607 /// @return an ast::IdentifierExpression with the given name
608 ast::IdentifierExpression* Expr(const char* name) {
609 return create<ast::IdentifierExpression>(Symbols().Register(name));
610 }
611
612 /// @param value the boolean value
613 /// @return a Scalar constructor for the given value
614 ast::ScalarConstructorExpression* Expr(bool value) {
615 return create<ast::ScalarConstructorExpression>(Literal(value));
616 }
617
618 /// @param value the float value
619 /// @return a Scalar constructor for the given value
620 ast::ScalarConstructorExpression* Expr(f32 value) {
621 return create<ast::ScalarConstructorExpression>(Literal(value));
622 }
623
624 /// @param value the integer value
625 /// @return a Scalar constructor for the given value
626 ast::ScalarConstructorExpression* Expr(i32 value) {
627 return create<ast::ScalarConstructorExpression>(Literal(value));
628 }
629
630 /// @param value the unsigned int value
631 /// @return a Scalar constructor for the given value
632 ast::ScalarConstructorExpression* Expr(u32 value) {
633 return create<ast::ScalarConstructorExpression>(Literal(value));
634 }
635
636 /// Converts `arg` to an `ast::Expression` using `Expr()`, then appends it to
637 /// `list`.
638 /// @param list the list to append too
639 /// @param arg the arg to create
640 template <typename ARG>
641 void Append(ast::ExpressionList& list, ARG&& arg) {
642 list.emplace_back(Expr(std::forward<ARG>(arg)));
643 }
644
645 /// Converts `arg0` and `args` to `ast::Expression`s using `Expr()`,
646 /// then appends them to `list`.
647 /// @param list the list to append too
648 /// @param arg0 the first argument
649 /// @param args the rest of the arguments
650 template <typename ARG0, typename... ARGS>
651 void Append(ast::ExpressionList& list, ARG0&& arg0, ARGS&&... args) {
652 Append(list, std::forward<ARG0>(arg0));
653 Append(list, std::forward<ARGS>(args)...);
654 }
655
656 /// @return an empty list of expressions
657 ast::ExpressionList ExprList() { return {}; }
658
659 /// @param args the list of expressions
660 /// @return the list of expressions converted to `ast::Expression`s using
661 /// `Expr()`,
662 template <typename... ARGS>
663 ast::ExpressionList ExprList(ARGS&&... args) {
664 ast::ExpressionList list;
665 list.reserve(sizeof...(args));
666 Append(list, std::forward<ARGS>(args)...);
667 return list;
668 }
669
670 /// @param list the list of expressions
671 /// @return `list`
672 ast::ExpressionList ExprList(ast::ExpressionList list) { return list; }
673
674 /// @param val the boolan value
675 /// @return a boolean literal with the given value
676 ast::BoolLiteral* Literal(bool val) {
677 return create<ast::BoolLiteral>(ty.bool_(), val);
678 }
679
680 /// @param val the float value
681 /// @return a float literal with the given value
682 ast::FloatLiteral* Literal(f32 val) {
683 return create<ast::FloatLiteral>(ty.f32(), val);
684 }
685
686 /// @param val the unsigned int value
687 /// @return a ast::UintLiteral with the given value
688 ast::UintLiteral* Literal(u32 val) {
689 return create<ast::UintLiteral>(ty.u32(), val);
690 }
691
692 /// @param val the integer value
693 /// @return the ast::SintLiteral with the given value
694 ast::SintLiteral* Literal(i32 val) {
695 return create<ast::SintLiteral>(ty.i32(), val);
696 }
697
698 /// @param args the arguments for the type constructor
699 /// @return an `ast::TypeConstructorExpression` of type `ty`, with the values
700 /// of `args` converted to `ast::Expression`s using `Expr()`
701 template <typename T, typename... ARGS>
702 ast::TypeConstructorExpression* Construct(ARGS&&... args) {
703 return create<ast::TypeConstructorExpression>(
704 ty.Of<T>(), ExprList(std::forward<ARGS>(args)...));
705 }
706
707 /// @param type the type to construct
708 /// @param args the arguments for the constructor
709 /// @return an `ast::TypeConstructorExpression` of `type` constructed with the
710 /// values `args`.
711 template <typename... ARGS>
712 ast::TypeConstructorExpression* Construct(type::Type* type, ARGS&&... args) {
713 return create<ast::TypeConstructorExpression>(
714 type, ExprList(std::forward<ARGS>(args)...));
715 }
716
Antonio Maiorano39a65a12021-03-31 12:46:52 +0000717 /// Creates a constructor expression that constructs an object of
718 /// `type` filled with `elem_value`. For example,
719 /// ConstructValueFilledWith(ty.mat3x4<float>(), 5) returns a
720 /// TypeConstructorExpression for a Mat3x4 filled with 5.0f values.
721 /// @param type the type to construct
722 /// @param elem_value the initial or element value (for vec and mat) to
723 /// construct with
724 /// @return the constructor expression
725 ast::ConstructorExpression* ConstructValueFilledWith(type::Type* type,
726 int elem_value = 0);
727
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000728 /// @param args the arguments for the vector constructor
729 /// @return an `ast::TypeConstructorExpression` of a 2-element vector of type
730 /// `T`, constructed with the values `args`.
731 template <typename T, typename... ARGS>
732 ast::TypeConstructorExpression* vec2(ARGS&&... args) {
733 return create<ast::TypeConstructorExpression>(
734 ty.vec2<T>(), ExprList(std::forward<ARGS>(args)...));
735 }
736
737 /// @param args the arguments for the vector constructor
738 /// @return an `ast::TypeConstructorExpression` of a 3-element vector of type
739 /// `T`, constructed with the values `args`.
740 template <typename T, typename... ARGS>
741 ast::TypeConstructorExpression* vec3(ARGS&&... args) {
742 return create<ast::TypeConstructorExpression>(
743 ty.vec3<T>(), ExprList(std::forward<ARGS>(args)...));
744 }
745
746 /// @param args the arguments for the vector constructor
747 /// @return an `ast::TypeConstructorExpression` of a 4-element vector of type
748 /// `T`, constructed with the values `args`.
749 template <typename T, typename... ARGS>
750 ast::TypeConstructorExpression* vec4(ARGS&&... args) {
751 return create<ast::TypeConstructorExpression>(
752 ty.vec4<T>(), ExprList(std::forward<ARGS>(args)...));
753 }
754
755 /// @param args the arguments for the matrix constructor
756 /// @return an `ast::TypeConstructorExpression` of a 2x2 matrix of type
757 /// `T`, constructed with the values `args`.
758 template <typename T, typename... ARGS>
759 ast::TypeConstructorExpression* mat2x2(ARGS&&... args) {
760 return create<ast::TypeConstructorExpression>(
761 ty.mat2x2<T>(), ExprList(std::forward<ARGS>(args)...));
762 }
763
764 /// @param args the arguments for the matrix constructor
765 /// @return an `ast::TypeConstructorExpression` of a 2x3 matrix of type
766 /// `T`, constructed with the values `args`.
767 template <typename T, typename... ARGS>
768 ast::TypeConstructorExpression* mat2x3(ARGS&&... args) {
769 return create<ast::TypeConstructorExpression>(
770 ty.mat2x3<T>(), ExprList(std::forward<ARGS>(args)...));
771 }
772
773 /// @param args the arguments for the matrix constructor
774 /// @return an `ast::TypeConstructorExpression` of a 2x4 matrix of type
775 /// `T`, constructed with the values `args`.
776 template <typename T, typename... ARGS>
777 ast::TypeConstructorExpression* mat2x4(ARGS&&... args) {
778 return create<ast::TypeConstructorExpression>(
779 ty.mat2x4<T>(), ExprList(std::forward<ARGS>(args)...));
780 }
781
782 /// @param args the arguments for the matrix constructor
783 /// @return an `ast::TypeConstructorExpression` of a 3x2 matrix of type
784 /// `T`, constructed with the values `args`.
785 template <typename T, typename... ARGS>
786 ast::TypeConstructorExpression* mat3x2(ARGS&&... args) {
787 return create<ast::TypeConstructorExpression>(
788 ty.mat3x2<T>(), ExprList(std::forward<ARGS>(args)...));
789 }
790
791 /// @param args the arguments for the matrix constructor
792 /// @return an `ast::TypeConstructorExpression` of a 3x3 matrix of type
793 /// `T`, constructed with the values `args`.
794 template <typename T, typename... ARGS>
795 ast::TypeConstructorExpression* mat3x3(ARGS&&... args) {
796 return create<ast::TypeConstructorExpression>(
797 ty.mat3x3<T>(), ExprList(std::forward<ARGS>(args)...));
798 }
799
800 /// @param args the arguments for the matrix constructor
801 /// @return an `ast::TypeConstructorExpression` of a 3x4 matrix of type
802 /// `T`, constructed with the values `args`.
803 template <typename T, typename... ARGS>
804 ast::TypeConstructorExpression* mat3x4(ARGS&&... args) {
805 return create<ast::TypeConstructorExpression>(
806 ty.mat3x4<T>(), ExprList(std::forward<ARGS>(args)...));
807 }
808
809 /// @param args the arguments for the matrix constructor
810 /// @return an `ast::TypeConstructorExpression` of a 4x2 matrix of type
811 /// `T`, constructed with the values `args`.
812 template <typename T, typename... ARGS>
813 ast::TypeConstructorExpression* mat4x2(ARGS&&... args) {
814 return create<ast::TypeConstructorExpression>(
815 ty.mat4x2<T>(), ExprList(std::forward<ARGS>(args)...));
816 }
817
818 /// @param args the arguments for the matrix constructor
819 /// @return an `ast::TypeConstructorExpression` of a 4x3 matrix of type
820 /// `T`, constructed with the values `args`.
821 template <typename T, typename... ARGS>
822 ast::TypeConstructorExpression* mat4x3(ARGS&&... args) {
823 return create<ast::TypeConstructorExpression>(
824 ty.mat4x3<T>(), ExprList(std::forward<ARGS>(args)...));
825 }
826
827 /// @param args the arguments for the matrix constructor
828 /// @return an `ast::TypeConstructorExpression` of a 4x4 matrix of type
829 /// `T`, constructed with the values `args`.
830 template <typename T, typename... ARGS>
831 ast::TypeConstructorExpression* mat4x4(ARGS&&... args) {
832 return create<ast::TypeConstructorExpression>(
833 ty.mat4x4<T>(), ExprList(std::forward<ARGS>(args)...));
834 }
835
836 /// @param args the arguments for the array constructor
837 /// @return an `ast::TypeConstructorExpression` of an array with element type
838 /// `T`, constructed with the values `args`.
839 template <typename T, int N = 0, typename... ARGS>
840 ast::TypeConstructorExpression* array(ARGS&&... args) {
841 return create<ast::TypeConstructorExpression>(
842 ty.array<T, N>(), ExprList(std::forward<ARGS>(args)...));
843 }
844
845 /// @param subtype the array element type
846 /// @param n the array size. 0 represents a runtime-array.
847 /// @param args the arguments for the array constructor
848 /// @return an `ast::TypeConstructorExpression` of an array with element type
849 /// `subtype`, constructed with the values `args`.
850 template <typename... ARGS>
851 ast::TypeConstructorExpression* array(type::Type* subtype,
852 uint32_t n,
853 ARGS&&... args) {
854 return create<ast::TypeConstructorExpression>(
855 ty.array(subtype, n), ExprList(std::forward<ARGS>(args)...));
856 }
857
858 /// @param name the variable name
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000859 /// @param type the variable type
Ben Clayton37571bc2021-02-16 23:57:01 +0000860 /// @param storage the variable storage class
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000861 /// @param constructor constructor expression
862 /// @param decorations variable decorations
863 /// @returns a `ast::Variable` with the given name, storage and type
Ben Clayton1b8d9f22021-04-07 11:16:01 +0000864 template <typename NAME>
865 ast::Variable* Var(NAME&& name,
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000866 type::Type* type,
Ben Clayton37571bc2021-02-16 23:57:01 +0000867 ast::StorageClass storage,
Ben Clayton46d78d72021-02-10 21:34:26 +0000868 ast::Expression* constructor = nullptr,
James Price95d40772021-03-11 17:39:32 +0000869 ast::DecorationList decorations = {}) {
Ben Clayton1b8d9f22021-04-07 11:16:01 +0000870 return create<ast::Variable>(Sym(std::forward<NAME>(name)), storage, type,
871 false, constructor, decorations);
Ben Clayton46d78d72021-02-10 21:34:26 +0000872 }
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000873
874 /// @param source the variable source
875 /// @param name the variable name
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000876 /// @param type the variable type
Ben Clayton37571bc2021-02-16 23:57:01 +0000877 /// @param storage the variable storage class
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000878 /// @param constructor constructor expression
879 /// @param decorations variable decorations
880 /// @returns a `ast::Variable` with the given name, storage and type
Ben Clayton1b8d9f22021-04-07 11:16:01 +0000881 template <typename NAME>
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000882 ast::Variable* Var(const Source& source,
Ben Clayton1b8d9f22021-04-07 11:16:01 +0000883 NAME&& name,
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000884 type::Type* type,
Ben Clayton37571bc2021-02-16 23:57:01 +0000885 ast::StorageClass storage,
Ben Clayton46d78d72021-02-10 21:34:26 +0000886 ast::Expression* constructor = nullptr,
James Price95d40772021-03-11 17:39:32 +0000887 ast::DecorationList decorations = {}) {
Ben Clayton1b8d9f22021-04-07 11:16:01 +0000888 return create<ast::Variable>(source, Sym(std::forward<NAME>(name)), storage,
Ben Clayton46d78d72021-02-10 21:34:26 +0000889 type, false, constructor, decorations);
890 }
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000891
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000892 /// @param name the variable name
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000893 /// @param type the variable type
894 /// @param constructor optional constructor expression
895 /// @param decorations optional variable decorations
James Pricedaf1f1c2021-04-08 22:15:48 +0000896 /// @returns a constant `ast::Variable` with the given name and type
Ben Clayton1b8d9f22021-04-07 11:16:01 +0000897 template <typename NAME>
898 ast::Variable* Const(NAME&& name,
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000899 type::Type* type,
Ben Clayton46d78d72021-02-10 21:34:26 +0000900 ast::Expression* constructor = nullptr,
James Price95d40772021-03-11 17:39:32 +0000901 ast::DecorationList decorations = {}) {
Ben Clayton1b8d9f22021-04-07 11:16:01 +0000902 return create<ast::Variable>(Sym(std::forward<NAME>(name)),
Ben Clayton81a29fe2021-02-17 00:26:52 +0000903 ast::StorageClass::kNone, type, true,
Ben Clayton46d78d72021-02-10 21:34:26 +0000904 constructor, decorations);
905 }
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000906
907 /// @param source the variable source
908 /// @param name the variable name
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000909 /// @param type the variable type
910 /// @param constructor optional constructor expression
911 /// @param decorations optional variable decorations
James Pricedaf1f1c2021-04-08 22:15:48 +0000912 /// @returns a constant `ast::Variable` with the given name and type
Ben Clayton1b8d9f22021-04-07 11:16:01 +0000913 template <typename NAME>
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000914 ast::Variable* Const(const Source& source,
Ben Clayton1b8d9f22021-04-07 11:16:01 +0000915 NAME&& name,
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000916 type::Type* type,
Ben Clayton46d78d72021-02-10 21:34:26 +0000917 ast::Expression* constructor = nullptr,
James Price95d40772021-03-11 17:39:32 +0000918 ast::DecorationList decorations = {}) {
Ben Clayton1b8d9f22021-04-07 11:16:01 +0000919 return create<ast::Variable>(source, Sym(std::forward<NAME>(name)),
Ben Clayton81a29fe2021-02-17 00:26:52 +0000920 ast::StorageClass::kNone, type, true,
921 constructor, decorations);
Ben Clayton46d78d72021-02-10 21:34:26 +0000922 }
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000923
James Pricedaf1f1c2021-04-08 22:15:48 +0000924 /// @param name the parameter name
925 /// @param type the parameter type
926 /// @param decorations optional parameter decorations
927 /// @returns a constant `ast::Variable` with the given name and type
928 template <typename NAME>
929 ast::Variable* Param(NAME&& name,
930 type::Type* type,
931 ast::DecorationList decorations = {}) {
932 return create<ast::Variable>(Sym(std::forward<NAME>(name)),
933 ast::StorageClass::kNone, type, true, nullptr,
934 decorations);
935 }
936
937 /// @param source the parameter source
938 /// @param name the parameter name
939 /// @param type the parameter type
940 /// @param decorations optional parameter decorations
941 /// @returns a constant `ast::Variable` with the given name and type
942 template <typename NAME>
943 ast::Variable* Param(const Source& source,
944 NAME&& name,
945 type::Type* type,
946 ast::DecorationList decorations = {}) {
947 return create<ast::Variable>(source, Sym(std::forward<NAME>(name)),
948 ast::StorageClass::kNone, type, true, nullptr,
949 decorations);
950 }
951
Ben Clayton401b96b2021-02-03 17:19:59 +0000952 /// @param args the arguments to pass to Var()
953 /// @returns a `ast::Variable` constructed by calling Var() with the arguments
954 /// of `args`, which is automatically registered as a global variable with the
955 /// ast::Module.
956 template <typename... ARGS>
957 ast::Variable* Global(ARGS&&... args) {
958 auto* var = Var(std::forward<ARGS>(args)...);
959 AST().AddGlobalVariable(var);
960 return var;
961 }
962
963 /// @param args the arguments to pass to Const()
964 /// @returns a const `ast::Variable` constructed by calling Var() with the
965 /// arguments of `args`, which is automatically registered as a global
966 /// variable with the ast::Module.
967 template <typename... ARGS>
968 ast::Variable* GlobalConst(ARGS&&... args) {
969 auto* var = Const(std::forward<ARGS>(args)...);
970 AST().AddGlobalVariable(var);
971 return var;
972 }
973
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000974 /// @param func the function name
975 /// @param args the function call arguments
976 /// @returns a `ast::CallExpression` to the function `func`, with the
977 /// arguments of `args` converted to `ast::Expression`s using `Expr()`.
978 template <typename NAME, typename... ARGS>
979 ast::CallExpression* Call(NAME&& func, ARGS&&... args) {
980 return create<ast::CallExpression>(Expr(func),
981 ExprList(std::forward<ARGS>(args)...));
982 }
983
984 /// @param lhs the left hand argument to the addition operation
985 /// @param rhs the right hand argument to the addition operation
986 /// @returns a `ast::BinaryExpression` summing the arguments `lhs` and `rhs`
987 template <typename LHS, typename RHS>
Antonio Maiorano61dabab2021-04-01 19:58:37 +0000988 ast::BinaryExpression* Add(LHS&& lhs, RHS&& rhs) {
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000989 return create<ast::BinaryExpression>(ast::BinaryOp::kAdd,
990 Expr(std::forward<LHS>(lhs)),
991 Expr(std::forward<RHS>(rhs)));
992 }
993
994 /// @param lhs the left hand argument to the subtraction operation
995 /// @param rhs the right hand argument to the subtraction operation
996 /// @returns a `ast::BinaryExpression` subtracting `rhs` from `lhs`
997 template <typename LHS, typename RHS>
Antonio Maiorano61dabab2021-04-01 19:58:37 +0000998 ast::BinaryExpression* Sub(LHS&& lhs, RHS&& rhs) {
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000999 return create<ast::BinaryExpression>(ast::BinaryOp::kSubtract,
1000 Expr(std::forward<LHS>(lhs)),
1001 Expr(std::forward<RHS>(rhs)));
1002 }
1003
1004 /// @param lhs the left hand argument to the multiplication operation
1005 /// @param rhs the right hand argument to the multiplication operation
1006 /// @returns a `ast::BinaryExpression` multiplying `rhs` from `lhs`
1007 template <typename LHS, typename RHS>
Antonio Maiorano61dabab2021-04-01 19:58:37 +00001008 ast::BinaryExpression* Mul(LHS&& lhs, RHS&& rhs) {
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001009 return create<ast::BinaryExpression>(ast::BinaryOp::kMultiply,
1010 Expr(std::forward<LHS>(lhs)),
1011 Expr(std::forward<RHS>(rhs)));
1012 }
1013
Antonio Maiorano61dabab2021-04-01 19:58:37 +00001014 /// @param source the source information
1015 /// @param lhs the left hand argument to the multiplication operation
1016 /// @param rhs the right hand argument to the multiplication operation
1017 /// @returns a `ast::BinaryExpression` multiplying `rhs` from `lhs`
1018 template <typename LHS, typename RHS>
1019 ast::BinaryExpression* Mul(const Source& source, LHS&& lhs, RHS&& rhs) {
1020 return create<ast::BinaryExpression>(source, ast::BinaryOp::kMultiply,
1021 Expr(std::forward<LHS>(lhs)),
1022 Expr(std::forward<RHS>(rhs)));
1023 }
1024
Ben Clayton1b8d9f22021-04-07 11:16:01 +00001025 /// @param lhs the left hand argument to the division operation
1026 /// @param rhs the right hand argument to the division operation
1027 /// @returns a `ast::BinaryExpression` dividing `lhs` by `rhs`
1028 template <typename LHS, typename RHS>
1029 ast::Expression* Div(LHS&& lhs, RHS&& rhs) {
1030 return create<ast::BinaryExpression>(ast::BinaryOp::kDivide,
1031 Expr(std::forward<LHS>(lhs)),
1032 Expr(std::forward<RHS>(rhs)));
1033 }
1034
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001035 /// @param arr the array argument for the array accessor expression
1036 /// @param idx the index argument for the array accessor expression
1037 /// @returns a `ast::ArrayAccessorExpression` that indexes `arr` with `idx`
1038 template <typename ARR, typename IDX>
Antonio Maiorano61dabab2021-04-01 19:58:37 +00001039 ast::ArrayAccessorExpression* IndexAccessor(ARR&& arr, IDX&& idx) {
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001040 return create<ast::ArrayAccessorExpression>(Expr(std::forward<ARR>(arr)),
1041 Expr(std::forward<IDX>(idx)));
1042 }
1043
1044 /// @param obj the object for the member accessor expression
1045 /// @param idx the index argument for the array accessor expression
1046 /// @returns a `ast::MemberAccessorExpression` that indexes `obj` with `idx`
1047 template <typename OBJ, typename IDX>
Ben Clayton6d612ad2021-02-24 14:15:02 +00001048 ast::MemberAccessorExpression* MemberAccessor(OBJ&& obj, IDX&& idx) {
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001049 return create<ast::MemberAccessorExpression>(Expr(std::forward<OBJ>(obj)),
1050 Expr(std::forward<IDX>(idx)));
1051 }
1052
Ben Clayton42d1e092021-02-02 14:29:15 +00001053 /// Creates a ast::StructMemberOffsetDecoration
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001054 /// @param val the offset value
1055 /// @returns the offset decoration pointer
1056 ast::StructMemberOffsetDecoration* MemberOffset(uint32_t val) {
1057 return create<ast::StructMemberOffsetDecoration>(source_, val);
1058 }
1059
Ben Claytond614dd52021-03-15 10:43:11 +00001060 /// Creates a ast::StructMemberSizeDecoration
1061 /// @param source the source information
1062 /// @param val the size value
1063 /// @returns the size decoration pointer
Antonio Maiorano101f4632021-04-07 20:35:11 +00001064 ast::StructMemberSizeDecoration* MemberSize(const Source& source,
1065 uint32_t val) {
Ben Claytond614dd52021-03-15 10:43:11 +00001066 return create<ast::StructMemberSizeDecoration>(source, val);
1067 }
1068
1069 /// Creates a ast::StructMemberSizeDecoration
1070 /// @param val the size value
1071 /// @returns the size decoration pointer
1072 ast::StructMemberSizeDecoration* MemberSize(uint32_t val) {
1073 return create<ast::StructMemberSizeDecoration>(source_, val);
1074 }
1075
1076 /// Creates a ast::StructMemberAlignDecoration
1077 /// @param source the source information
1078 /// @param val the align value
1079 /// @returns the align decoration pointer
Antonio Maiorano101f4632021-04-07 20:35:11 +00001080 ast::StructMemberAlignDecoration* MemberAlign(const Source& source,
1081 uint32_t val) {
Ben Claytond614dd52021-03-15 10:43:11 +00001082 return create<ast::StructMemberAlignDecoration>(source, val);
1083 }
1084
1085 /// Creates a ast::StructMemberAlignDecoration
1086 /// @param val the align value
1087 /// @returns the align decoration pointer
1088 ast::StructMemberAlignDecoration* MemberAlign(uint32_t val) {
1089 return create<ast::StructMemberAlignDecoration>(source_, val);
1090 }
1091
Ben Clayton42d1e092021-02-02 14:29:15 +00001092 /// Creates an ast::Function and registers it with the ast::Module.
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001093 /// @param source the source information
1094 /// @param name the function name
1095 /// @param params the function parameters
1096 /// @param type the function return type
1097 /// @param body the function body
Ben Clayton1b8d9f22021-04-07 11:16:01 +00001098 /// @param decorations the optional function decorations
1099 /// @param return_type_decorations the optional function return type
1100 /// decorations
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001101 /// @returns the function pointer
Ben Clayton1b8d9f22021-04-07 11:16:01 +00001102 template <typename NAME>
Antonio Maiorano101f4632021-04-07 20:35:11 +00001103 ast::Function* Func(const Source& source,
Ben Clayton1b8d9f22021-04-07 11:16:01 +00001104 NAME&& name,
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001105 ast::VariableList params,
1106 type::Type* type,
1107 ast::StatementList body,
Ben Clayton4f154a82021-04-06 18:15:17 +00001108 ast::DecorationList decorations = {},
James Pricefeecbe02021-03-15 17:01:34 +00001109 ast::DecorationList return_type_decorations = {}) {
Ben Clayton1b8d9f22021-04-07 11:16:01 +00001110 auto* func =
1111 create<ast::Function>(source, Sym(std::forward<NAME>(name)), params,
1112 type, create<ast::BlockStatement>(body),
1113 decorations, return_type_decorations);
James Price3eaa4502021-02-09 21:26:21 +00001114 AST().AddFunction(func);
Ben Clayton42d1e092021-02-02 14:29:15 +00001115 return func;
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001116 }
1117
Ben Clayton42d1e092021-02-02 14:29:15 +00001118 /// Creates an ast::Function and registers it with the ast::Module.
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001119 /// @param name the function name
1120 /// @param params the function parameters
1121 /// @param type the function return type
1122 /// @param body the function body
Ben Clayton1b8d9f22021-04-07 11:16:01 +00001123 /// @param decorations the optional function decorations
1124 /// @param return_type_decorations the optional function return type
1125 /// decorations
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001126 /// @returns the function pointer
Ben Clayton1b8d9f22021-04-07 11:16:01 +00001127 template <typename NAME>
1128 ast::Function* Func(NAME&& name,
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001129 ast::VariableList params,
1130 type::Type* type,
1131 ast::StatementList body,
Ben Clayton4f154a82021-04-06 18:15:17 +00001132 ast::DecorationList decorations = {},
James Pricefeecbe02021-03-15 17:01:34 +00001133 ast::DecorationList return_type_decorations = {}) {
Ben Clayton1b8d9f22021-04-07 11:16:01 +00001134 auto* func = create<ast::Function>(Sym(std::forward<NAME>(name)), params,
1135 type, create<ast::BlockStatement>(body),
James Pricefeecbe02021-03-15 17:01:34 +00001136 decorations, return_type_decorations);
James Price3eaa4502021-02-09 21:26:21 +00001137 AST().AddFunction(func);
Ben Clayton42d1e092021-02-02 14:29:15 +00001138 return func;
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001139 }
1140
Antonio Maiorano03c01b52021-03-19 14:04:51 +00001141 /// Creates an ast::ReturnStatement with the input args
1142 /// @param args arguments to construct a return statement with
1143 /// @returns the return statement pointer
1144 template <typename... Args>
1145 ast::ReturnStatement* Return(Args&&... args) {
1146 return create<ast::ReturnStatement>(std::forward<Args>(args)...);
1147 }
1148
Ben Claytond614dd52021-03-15 10:43:11 +00001149 /// Creates a ast::Struct and type::Struct, registering the type::Struct with
1150 /// the AST().ConstructedTypes().
1151 /// @param source the source information
1152 /// @param name the struct name
1153 /// @param members the struct members
1154 /// @param decorations the optional struct decorations
1155 /// @returns the struct type
Ben Clayton1d618b12021-04-09 16:19:48 +00001156 template <typename NAME>
Ben Claytond614dd52021-03-15 10:43:11 +00001157 type::Struct* Structure(const Source& source,
Ben Clayton1d618b12021-04-09 16:19:48 +00001158 NAME&& name,
Ben Claytond614dd52021-03-15 10:43:11 +00001159 ast::StructMemberList members,
1160 ast::DecorationList decorations = {}) {
1161 auto* impl =
1162 create<ast::Struct>(source, std::move(members), std::move(decorations));
Ben Clayton1d618b12021-04-09 16:19:48 +00001163 auto* type = ty.struct_(Sym(std::forward<NAME>(name)), impl);
Ben Claytond614dd52021-03-15 10:43:11 +00001164 AST().AddConstructedType(type);
1165 return type;
1166 }
1167
1168 /// Creates a ast::Struct and type::Struct, registering the type::Struct with
1169 /// the AST().ConstructedTypes().
1170 /// @param name the struct name
1171 /// @param members the struct members
1172 /// @param decorations the optional struct decorations
1173 /// @returns the struct type
Ben Clayton1d618b12021-04-09 16:19:48 +00001174 template <typename NAME>
1175 type::Struct* Structure(NAME&& name,
Ben Claytond614dd52021-03-15 10:43:11 +00001176 ast::StructMemberList members,
1177 ast::DecorationList decorations = {}) {
1178 auto* impl =
1179 create<ast::Struct>(std::move(members), std::move(decorations));
Ben Clayton1d618b12021-04-09 16:19:48 +00001180 auto* type = ty.struct_(Sym(std::forward<NAME>(name)), impl);
Ben Claytond614dd52021-03-15 10:43:11 +00001181 AST().AddConstructedType(type);
1182 return type;
1183 }
1184
Ben Clayton42d1e092021-02-02 14:29:15 +00001185 /// Creates a ast::StructMember
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001186 /// @param source the source information
1187 /// @param name the struct member name
1188 /// @param type the struct member type
Ben Claytond614dd52021-03-15 10:43:11 +00001189 /// @param decorations the optional struct member decorations
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001190 /// @returns the struct member pointer
Ben Clayton1b8d9f22021-04-07 11:16:01 +00001191 template <typename NAME>
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001192 ast::StructMember* Member(const Source& source,
Ben Clayton1b8d9f22021-04-07 11:16:01 +00001193 NAME&& name,
Ben Claytond614dd52021-03-15 10:43:11 +00001194 type::Type* type,
1195 ast::DecorationList decorations = {}) {
Ben Clayton1b8d9f22021-04-07 11:16:01 +00001196 return create<ast::StructMember>(source, Sym(std::forward<NAME>(name)),
1197 type, std::move(decorations));
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001198 }
1199
Ben Clayton42d1e092021-02-02 14:29:15 +00001200 /// Creates a ast::StructMember
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001201 /// @param name the struct member name
1202 /// @param type the struct member type
Ben Claytond614dd52021-03-15 10:43:11 +00001203 /// @param decorations the optional struct member decorations
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001204 /// @returns the struct member pointer
Ben Clayton1b8d9f22021-04-07 11:16:01 +00001205 template <typename NAME>
1206 ast::StructMember* Member(NAME&& name,
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001207 type::Type* type,
Ben Claytond614dd52021-03-15 10:43:11 +00001208 ast::DecorationList decorations = {}) {
Ben Clayton1b8d9f22021-04-07 11:16:01 +00001209 return create<ast::StructMember>(source_, Sym(std::forward<NAME>(name)),
1210 type, std::move(decorations));
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001211 }
1212
Ben Claytonbab31972021-02-08 21:16:21 +00001213 /// Creates a ast::StructMember with the given byte offset
1214 /// @param offset the offset to use in the StructMemberOffsetDecoration
1215 /// @param name the struct member name
1216 /// @param type the struct member type
1217 /// @returns the struct member pointer
Ben Clayton1b8d9f22021-04-07 11:16:01 +00001218 template <typename NAME>
1219 ast::StructMember* Member(uint32_t offset, NAME&& name, type::Type* type) {
Ben Claytonbab31972021-02-08 21:16:21 +00001220 return create<ast::StructMember>(
Ben Clayton1b8d9f22021-04-07 11:16:01 +00001221 source_, Sym(std::forward<NAME>(name)), type,
James Price95d40772021-03-11 17:39:32 +00001222 ast::DecorationList{
Ben Claytonbab31972021-02-08 21:16:21 +00001223 create<ast::StructMemberOffsetDecoration>(offset),
1224 });
1225 }
1226
Antonio Maioranofd31bbd2021-03-09 10:26:57 +00001227 /// Creates a ast::BlockStatement with input statements
1228 /// @param statements statements of block
1229 /// @returns the block statement pointer
1230 template <typename... Statements>
1231 ast::BlockStatement* Block(Statements&&... statements) {
1232 return create<ast::BlockStatement>(
1233 ast::StatementList{std::forward<Statements>(statements)...});
1234 }
1235
1236 /// Creates a ast::ElseStatement with input condition and body
1237 /// @param condition the else condition expression
1238 /// @param body the else body
1239 /// @returns the else statement pointer
1240 ast::ElseStatement* Else(ast::Expression* condition,
1241 ast::BlockStatement* body) {
1242 return create<ast::ElseStatement>(condition, body);
1243 }
1244
1245 /// Creates a ast::IfStatement with input condition, body, and optional
1246 /// variadic else statements
1247 /// @param condition the if statement condition expression
1248 /// @param body the if statement body
1249 /// @param elseStatements optional variadic else statements
1250 /// @returns the if statement pointer
1251 template <typename... ElseStatements>
1252 ast::IfStatement* If(ast::Expression* condition,
1253 ast::BlockStatement* body,
1254 ElseStatements&&... elseStatements) {
1255 return create<ast::IfStatement>(
1256 condition, body,
1257 ast::ElseStatementList{
1258 std::forward<ElseStatements>(elseStatements)...});
1259 }
1260
1261 /// Creates a ast::AssignmentStatement with input lhs and rhs expressions
Antonio Maioranocea744d2021-03-25 12:55:27 +00001262 /// @param lhs the left hand side expression initializer
1263 /// @param rhs the right hand side expression initializer
Antonio Maioranofd31bbd2021-03-09 10:26:57 +00001264 /// @returns the assignment statement pointer
Antonio Maioranocea744d2021-03-25 12:55:27 +00001265 template <typename LhsExpressionInit, typename RhsExpressionInit>
1266 ast::AssignmentStatement* Assign(LhsExpressionInit&& lhs,
1267 RhsExpressionInit&& rhs) {
1268 return create<ast::AssignmentStatement>(
1269 Expr(std::forward<LhsExpressionInit>(lhs)),
1270 Expr(std::forward<RhsExpressionInit>(rhs)));
Antonio Maioranofd31bbd2021-03-09 10:26:57 +00001271 }
1272
1273 /// Creates a ast::LoopStatement with input body and optional continuing
1274 /// @param body the loop body
1275 /// @param continuing the optional continuing block
1276 /// @returns the loop statement pointer
1277 ast::LoopStatement* Loop(ast::BlockStatement* body,
1278 ast::BlockStatement* continuing = nullptr) {
1279 return create<ast::LoopStatement>(body, continuing);
1280 }
1281
1282 /// Creates a ast::VariableDeclStatement for the input variable
1283 /// @param var the variable to wrap in a decl statement
1284 /// @returns the variable decl statement pointer
1285 ast::VariableDeclStatement* Decl(ast::Variable* var) {
1286 return create<ast::VariableDeclStatement>(var);
1287 }
1288
Antonio Maioranocea744d2021-03-25 12:55:27 +00001289 /// Creates a ast::SwitchStatement with input expression and cases
1290 /// @param condition the condition expression initializer
1291 /// @param cases case statements
1292 /// @returns the switch statement pointer
1293 template <typename ExpressionInit, typename... Cases>
1294 ast::SwitchStatement* Switch(ExpressionInit&& condition, Cases&&... cases) {
1295 return create<ast::SwitchStatement>(
1296 Expr(std::forward<ExpressionInit>(condition)),
1297 ast::CaseStatementList{std::forward<Cases>(cases)...});
1298 }
1299
1300 /// Creates a ast::CaseStatement with input list of selectors, and body
1301 /// @param selectors list of selectors
1302 /// @param body the case body
1303 /// @returns the case statement pointer
1304 ast::CaseStatement* Case(ast::CaseSelectorList selectors,
1305 ast::BlockStatement* body = nullptr) {
1306 return create<ast::CaseStatement>(std::move(selectors),
1307 body ? body : Block());
1308 }
1309
1310 /// Convenient overload that takes a single selector
1311 /// @param selector a single case selector
1312 /// @param body the case body
1313 /// @returns the case statement pointer
1314 ast::CaseStatement* Case(ast::IntLiteral* selector,
1315 ast::BlockStatement* body = nullptr) {
1316 return Case(ast::CaseSelectorList{selector}, body);
1317 }
1318
1319 /// Convenience function that creates a 'default' ast::CaseStatement
1320 /// @param body the case body
1321 /// @returns the case statement pointer
1322 ast::CaseStatement* DefaultCase(ast::BlockStatement* body = nullptr) {
1323 return Case(ast::CaseSelectorList{}, body);
1324 }
1325
James Price68f558f2021-04-06 15:51:47 +00001326 /// Creates an ast::BuiltinDecoration
1327 /// @param source the source information
1328 /// @param builtin the builtin value
1329 /// @returns the builtin decoration pointer
Antonio Maiorano101f4632021-04-07 20:35:11 +00001330 ast::BuiltinDecoration* Builtin(const Source& source, ast::Builtin builtin) {
James Price68f558f2021-04-06 15:51:47 +00001331 return create<ast::BuiltinDecoration>(source, builtin);
1332 }
1333
1334 /// Creates an ast::BuiltinDecoration
1335 /// @param builtin the builtin value
1336 /// @returns the builtin decoration pointer
1337 ast::BuiltinDecoration* Builtin(ast::Builtin builtin) {
1338 return create<ast::BuiltinDecoration>(source_, builtin);
1339 }
1340
1341 /// Creates an ast::LocationDecoration
1342 /// @param source the source information
1343 /// @param location the location value
1344 /// @returns the location decoration pointer
Antonio Maiorano101f4632021-04-07 20:35:11 +00001345 ast::LocationDecoration* Location(const Source& source, uint32_t location) {
James Price68f558f2021-04-06 15:51:47 +00001346 return create<ast::LocationDecoration>(source, location);
1347 }
1348
1349 /// Creates an ast::LocationDecoration
1350 /// @param location the location value
1351 /// @returns the location decoration pointer
1352 ast::LocationDecoration* Location(uint32_t location) {
1353 return create<ast::LocationDecoration>(source_, location);
1354 }
1355
1356 /// Creates an ast::StageDecoration
1357 /// @param source the source information
1358 /// @param stage the pipeline stage
1359 /// @returns the stage decoration pointer
Antonio Maiorano101f4632021-04-07 20:35:11 +00001360 ast::StageDecoration* Stage(const Source& source, ast::PipelineStage stage) {
James Price68f558f2021-04-06 15:51:47 +00001361 return create<ast::StageDecoration>(source, stage);
1362 }
1363
1364 /// Creates an ast::StageDecoration
1365 /// @param stage the pipeline stage
1366 /// @returns the stage decoration pointer
1367 ast::StageDecoration* Stage(ast::PipelineStage stage) {
1368 return create<ast::StageDecoration>(source_, stage);
1369 }
1370
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001371 /// Sets the current builder source to `src`
1372 /// @param src the Source used for future create() calls
1373 void SetSource(const Source& src) {
1374 AssertNotMoved();
1375 source_ = src;
1376 }
1377
1378 /// Sets the current builder source to `loc`
1379 /// @param loc the Source used for future create() calls
1380 void SetSource(const Source::Location& loc) {
1381 AssertNotMoved();
1382 source_ = Source(loc);
1383 }
1384
Ben Clayton33352542021-01-29 16:43:41 +00001385 /// Helper for returning the resolved semantic type of the expression `expr`.
Ben Clayton5f0ea112021-03-09 10:54:37 +00001386 /// @note As the Resolver is run when the Program is built, this will only be
1387 /// useful for the Resolver itself and tests that use their own Resolver.
Ben Clayton33352542021-01-29 16:43:41 +00001388 /// @param expr the AST expression
1389 /// @return the resolved semantic type for the expression, or nullptr if the
1390 /// expression has no resolved type.
1391 type::Type* TypeOf(ast::Expression* expr) const;
1392
Ben Clayton401b96b2021-02-03 17:19:59 +00001393 /// Wraps the ast::Expression in a statement. This is used by tests that
Ben Clayton5f0ea112021-03-09 10:54:37 +00001394 /// construct a partial AST and require the Resolver to reach these
Ben Clayton401b96b2021-02-03 17:19:59 +00001395 /// nodes.
1396 /// @param expr the ast::Expression to be wrapped by an ast::Statement
1397 /// @return the ast::Statement that wraps the ast::Expression
1398 ast::Statement* WrapInStatement(ast::Expression* expr);
1399 /// Wraps the ast::Variable in a ast::VariableDeclStatement. This is used by
Ben Clayton5f0ea112021-03-09 10:54:37 +00001400 /// tests that construct a partial AST and require the Resolver to reach
Ben Clayton401b96b2021-02-03 17:19:59 +00001401 /// these nodes.
1402 /// @param v the ast::Variable to be wrapped by an ast::VariableDeclStatement
1403 /// @return the ast::VariableDeclStatement that wraps the ast::Variable
1404 ast::VariableDeclStatement* WrapInStatement(ast::Variable* v);
1405 /// Returns the statement argument. Used as a passthrough-overload by
1406 /// WrapInFunction().
1407 /// @param stmt the ast::Statement
1408 /// @return `stmt`
1409 ast::Statement* WrapInStatement(ast::Statement* stmt);
1410 /// Wraps the list of arguments in a simple function so that each is reachable
Ben Clayton5f0ea112021-03-09 10:54:37 +00001411 /// by the Resolver.
Ben Clayton401b96b2021-02-03 17:19:59 +00001412 /// @param args a mix of ast::Expression, ast::Statement, ast::Variables.
Antonio Maiorano03c01b52021-03-19 14:04:51 +00001413 /// @returns the function
Ben Clayton401b96b2021-02-03 17:19:59 +00001414 template <typename... ARGS>
Antonio Maiorano03c01b52021-03-19 14:04:51 +00001415 ast::Function* WrapInFunction(ARGS&&... args) {
Ben Clayton401b96b2021-02-03 17:19:59 +00001416 ast::StatementList stmts{WrapInStatement(std::forward<ARGS>(args))...};
Antonio Maiorano03c01b52021-03-19 14:04:51 +00001417 return WrapInFunction(std::move(stmts));
Ben Clayton401b96b2021-02-03 17:19:59 +00001418 }
1419 /// @param stmts a list of ast::Statement that will be wrapped by a function,
Ben Clayton5f0ea112021-03-09 10:54:37 +00001420 /// so that each statement is reachable by the Resolver.
Antonio Maiorano03c01b52021-03-19 14:04:51 +00001421 /// @returns the function
1422 ast::Function* WrapInFunction(ast::StatementList stmts);
Ben Clayton401b96b2021-02-03 17:19:59 +00001423
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001424 /// The builder types
Ben Claytonc7ca7662021-02-17 16:23:52 +00001425 TypesBuilder const ty{this};
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001426
1427 protected:
1428 /// Asserts that the builder has not been moved.
1429 void AssertNotMoved() const;
1430
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001431 private:
Ben Claytone6995de2021-04-13 23:27:27 +00001432 ProgramID id_;
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001433 type::Manager types_;
Ben Clayton7fdfff12021-01-29 15:17:30 +00001434 ASTNodeAllocator ast_nodes_;
1435 SemNodeAllocator sem_nodes_;
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001436 ast::Module* ast_;
Ben Claytondd1b6fc2021-01-29 10:55:40 +00001437 semantic::Info sem_;
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001438 SymbolTable symbols_;
Ben Clayton844217f2021-01-27 18:49:05 +00001439 diag::List diagnostics_;
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001440
1441 /// The source to use when creating AST nodes without providing a Source as
1442 /// the first argument.
1443 Source source_;
1444
Ben Clayton5f0ea112021-03-09 10:54:37 +00001445 /// Set by SetResolveOnBuild(). If set, the Resolver will be run on the
Ben Claytondd69ac32021-01-27 19:23:55 +00001446 /// program when built.
1447 bool resolve_on_build_ = true;
1448
Ben Claytona6b9a8e2021-01-26 16:57:10 +00001449 /// Set by MarkAsMoved(). Once set, no methods may be called on this builder.
1450 bool moved_ = false;
1451};
1452
1453//! @cond Doxygen_Suppress
1454// Various template specializations for ProgramBuilder::TypesBuilder::CToAST.
1455template <>
1456struct ProgramBuilder::TypesBuilder::CToAST<ProgramBuilder::i32> {
1457 static type::Type* get(const ProgramBuilder::TypesBuilder* t) {
1458 return t->i32();
1459 }
1460};
1461template <>
1462struct ProgramBuilder::TypesBuilder::CToAST<ProgramBuilder::u32> {
1463 static type::Type* get(const ProgramBuilder::TypesBuilder* t) {
1464 return t->u32();
1465 }
1466};
1467template <>
1468struct ProgramBuilder::TypesBuilder::CToAST<ProgramBuilder::f32> {
1469 static type::Type* get(const ProgramBuilder::TypesBuilder* t) {
1470 return t->f32();
1471 }
1472};
1473template <>
1474struct ProgramBuilder::TypesBuilder::CToAST<bool> {
1475 static type::Type* get(const ProgramBuilder::TypesBuilder* t) {
1476 return t->bool_();
1477 }
1478};
1479template <>
1480struct ProgramBuilder::TypesBuilder::CToAST<void> {
1481 static type::Type* get(const ProgramBuilder::TypesBuilder* t) {
1482 return t->void_();
1483 }
1484};
1485//! @endcond
1486
1487} // namespace tint
1488
1489#endif // SRC_PROGRAM_BUILDER_H_