blob: 9d712364c14793c4f2dbc215f4e252bb8698e2fa [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"
22#include "src/ast/binary_expression.h"
23#include "src/ast/bool_literal.h"
24#include "src/ast/call_expression.h"
25#include "src/ast/expression.h"
26#include "src/ast/float_literal.h"
27#include "src/ast/identifier_expression.h"
28#include "src/ast/member_accessor_expression.h"
29#include "src/ast/module.h"
30#include "src/ast/scalar_constructor_expression.h"
31#include "src/ast/sint_literal.h"
32#include "src/ast/struct.h"
33#include "src/ast/struct_member.h"
34#include "src/ast/struct_member_offset_decoration.h"
35#include "src/ast/type_constructor_expression.h"
36#include "src/ast/uint_literal.h"
37#include "src/ast/variable.h"
Ben Clayton844217f2021-01-27 18:49:05 +000038#include "src/diagnostic/diagnostic.h"
Ben Claytona6b9a8e2021-01-26 16:57:10 +000039#include "src/program.h"
40#include "src/symbol_table.h"
41#include "src/type/alias_type.h"
42#include "src/type/array_type.h"
43#include "src/type/bool_type.h"
44#include "src/type/f32_type.h"
45#include "src/type/i32_type.h"
46#include "src/type/matrix_type.h"
47#include "src/type/pointer_type.h"
48#include "src/type/struct_type.h"
49#include "src/type/type_manager.h"
50#include "src/type/u32_type.h"
51#include "src/type/vector_type.h"
52#include "src/type/void_type.h"
53
54namespace tint {
55
56class CloneContext;
57
58/// ProgramBuilder is a mutable builder for a Program.
59/// To construct a Program, populate the builder and then `std::move` it to a
60/// Program.
61class ProgramBuilder {
62 public:
63 /// ASTNodes is an alias to BlockAllocator<ast::Node>
64 using ASTNodes = BlockAllocator<ast::Node>;
65
66 /// `i32` is a type alias to `int`.
67 /// Useful for passing to template methods such as `vec2<i32>()` to imitate
68 /// WGSL syntax.
69 /// Note: this is intentionally not aliased to uint32_t as we want integer
70 /// literals passed to the builder to match WGSL's integer literal types.
71 using i32 = decltype(1);
72 /// `u32` is a type alias to `unsigned int`.
73 /// Useful for passing to template methods such as `vec2<u32>()` to imitate
74 /// WGSL syntax.
75 /// Note: this is intentionally not aliased to uint32_t as we want integer
76 /// literals passed to the builder to match WGSL's integer literal types.
77 using u32 = decltype(1u);
78 /// `f32` is a type alias to `float`
79 /// Useful for passing to template methods such as `vec2<f32>()` to imitate
80 /// WGSL syntax.
81 using f32 = float;
82
83 /// Constructor
84 ProgramBuilder();
85
86 /// Move constructor
87 /// @param rhs the builder to move
88 ProgramBuilder(ProgramBuilder&& rhs);
89
90 /// Destructor
91 virtual ~ProgramBuilder();
92
93 /// Move assignment operator
94 /// @param rhs the builder to move
95 /// @return this builder
96 ProgramBuilder& operator=(ProgramBuilder&& rhs);
97
98 /// @returns a reference to the program's types
99 type::Manager& Types() {
100 AssertNotMoved();
101 return types_;
102 }
103
104 /// @returns a reference to the program's AST nodes storage
105 ASTNodes& Nodes() {
106 AssertNotMoved();
107 return nodes_;
108 }
109
110 /// @returns a reference to the program's AST root Module
111 ast::Module& AST() {
112 AssertNotMoved();
113 return *ast_;
114 }
115
116 /// @returns a reference to the program's SymbolTable
117 SymbolTable& Symbols() {
118 AssertNotMoved();
119 return symbols_;
120 }
121
Ben Clayton844217f2021-01-27 18:49:05 +0000122 /// @returns a reference to the program's diagnostics
123 diag::List& Diagnostics() {
124 AssertNotMoved();
125 return diagnostics_;
126 }
127
128 /// @returns true if the program has no error diagnostics and is not missing
129 /// information
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000130 bool IsValid() const;
131
132 /// creates a new ast::Node owned by the Module. When the Module is
133 /// destructed, the ast::Node will also be destructed.
134 /// @param source the Source of the node
135 /// @param args the arguments to pass to the type constructor
136 /// @returns the node pointer
137 template <typename T, typename... ARGS>
138 traits::EnableIfIsType<T, ast::Node>* create(const Source& source,
139 ARGS&&... args) {
140 AssertNotMoved();
141 return nodes_.Create<T>(source, std::forward<ARGS>(args)...);
142 }
143
144 /// creates a new ast::Node owned by the Module, injecting the current Source
145 /// as set by the last call to SetSource() as the only argument to the
146 /// constructor.
147 /// When the Module is destructed, the ast::Node will also be destructed.
148 /// @returns the node pointer
149 template <typename T>
150 traits::EnableIfIsType<T, ast::Node>* create() {
151 AssertNotMoved();
152 return nodes_.Create<T>(source_);
153 }
154
155 /// creates a new ast::Node owned by the Module, injecting the current Source
156 /// as set by the last call to SetSource() as the first argument to the
157 /// constructor.
158 /// When the Module is destructed, the ast::Node will also be destructed.
159 /// @param arg0 the first arguments to pass to the type constructor
160 /// @param args the remaining arguments to pass to the type constructor
161 /// @returns the node pointer
162 template <typename T, typename ARG0, typename... ARGS>
163 traits::EnableIf</* T is ast::Node and ARG0 is not Source */
164 traits::IsTypeOrDerived<T, ast::Node>::value &&
165 !traits::IsTypeOrDerived<ARG0, Source>::value,
166 T>*
167 create(ARG0&& arg0, ARGS&&... args) {
168 AssertNotMoved();
169 return nodes_.Create<T>(source_, std::forward<ARG0>(arg0),
170 std::forward<ARGS>(args)...);
171 }
172
173 /// creates a new type::Type owned by the Module.
174 /// When the Module is destructed, owned Module and the returned
175 /// `Type` will also be destructed.
176 /// Types are unique (de-aliased), and so calling create() for the same `T`
177 /// and arguments will return the same pointer.
178 /// @warning Use this method to acquire a type only if all of its type
179 /// information is provided in the constructor arguments `args`.<br>
180 /// If the type requires additional configuration after construction that
181 /// affect its fundamental type, build the type with `std::make_unique`, make
182 /// any necessary alterations and then call unique_type() instead.
183 /// @param args the arguments to pass to the type constructor
184 /// @returns the de-aliased type pointer
185 template <typename T, typename... ARGS>
186 traits::EnableIfIsType<T, type::Type>* create(ARGS&&... args) {
187 static_assert(std::is_base_of<type::Type, T>::value,
188 "T does not derive from type::Type");
189 AssertNotMoved();
190 return types_.Get<T>(std::forward<ARGS>(args)...);
191 }
192
193 /// Marks this builder as moved, preventing any further use of the builder.
194 void MarkAsMoved();
195
196 //////////////////////////////////////////////////////////////////////////////
197 // TypesBuilder
198 //////////////////////////////////////////////////////////////////////////////
199
200 /// TypesBuilder holds basic `tint` types and methods for constructing
201 /// complex types.
202 class TypesBuilder {
203 public:
204 /// Constructor
205 /// @param builder the program builder
206 explicit TypesBuilder(ProgramBuilder* builder);
207
208 /// @return the tint AST type for the C type `T`.
209 template <typename T>
210 type::Type* Of() const {
211 return CToAST<T>::get(this);
212 }
213
214 /// @returns a boolean type
215 type::Bool* bool_() const { return builder->create<type::Bool>(); }
216
217 /// @returns a f32 type
218 type::F32* f32() const { return builder->create<type::F32>(); }
219
220 /// @returns a i32 type
221 type::I32* i32() const { return builder->create<type::I32>(); }
222
223 /// @returns a u32 type
224 type::U32* u32() const { return builder->create<type::U32>(); }
225
226 /// @returns a void type
227 type::Void* void_() const { return builder->create<type::Void>(); }
228
229 /// @return the tint AST type for a 2-element vector of the C type `T`.
230 template <typename T>
231 type::Vector* vec2() const {
232 return builder->create<type::Vector>(Of<T>(), 2);
233 }
234
235 /// @return the tint AST type for a 3-element vector of the C type `T`.
236 template <typename T>
237 type::Vector* vec3() const {
238 return builder->create<type::Vector>(Of<T>(), 3);
239 }
240
241 /// @return the tint AST type for a 4-element vector of the C type `T`.
242 template <typename T>
243 type::Type* vec4() const {
244 return builder->create<type::Vector>(Of<T>(), 4);
245 }
246
247 /// @return the tint AST type for a 2x3 matrix of the C type `T`.
248 template <typename T>
249 type::Matrix* mat2x2() const {
250 return builder->create<type::Matrix>(Of<T>(), 2, 2);
251 }
252
253 /// @return the tint AST type for a 2x3 matrix of the C type `T`.
254 template <typename T>
255 type::Matrix* mat2x3() const {
256 return builder->create<type::Matrix>(Of<T>(), 3, 2);
257 }
258
259 /// @return the tint AST type for a 2x4 matrix of the C type `T`.
260 template <typename T>
261 type::Matrix* mat2x4() const {
262 return builder->create<type::Matrix>(Of<T>(), 4, 2);
263 }
264
265 /// @return the tint AST type for a 3x2 matrix of the C type `T`.
266 template <typename T>
267 type::Matrix* mat3x2() const {
268 return builder->create<type::Matrix>(Of<T>(), 2, 3);
269 }
270
271 /// @return the tint AST type for a 3x3 matrix of the C type `T`.
272 template <typename T>
273 type::Matrix* mat3x3() const {
274 return builder->create<type::Matrix>(Of<T>(), 3, 3);
275 }
276
277 /// @return the tint AST type for a 3x4 matrix of the C type `T`.
278 template <typename T>
279 type::Matrix* mat3x4() const {
280 return builder->create<type::Matrix>(Of<T>(), 4, 3);
281 }
282
283 /// @return the tint AST type for a 4x2 matrix of the C type `T`.
284 template <typename T>
285 type::Matrix* mat4x2() const {
286 return builder->create<type::Matrix>(Of<T>(), 2, 4);
287 }
288
289 /// @return the tint AST type for a 4x3 matrix of the C type `T`.
290 template <typename T>
291 type::Matrix* mat4x3() const {
292 return builder->create<type::Matrix>(Of<T>(), 3, 4);
293 }
294
295 /// @return the tint AST type for a 4x4 matrix of the C type `T`.
296 template <typename T>
297 type::Matrix* mat4x4() const {
298 return builder->create<type::Matrix>(Of<T>(), 4, 4);
299 }
300
301 /// @param subtype the array element type
302 /// @param n the array size. 0 represents a runtime-array.
303 /// @return the tint AST type for a array of size `n` of type `T`
304 type::Array* array(type::Type* subtype, uint32_t n) const {
305 return builder->create<type::Array>(subtype, n,
306 ast::ArrayDecorationList{});
307 }
308
309 /// @return the tint AST type for an array of size `N` of type `T`
310 template <typename T, int N = 0>
311 type::Array* array() const {
312 return array(Of<T>(), N);
313 }
314
315 /// creates an alias type
316 /// @param name the alias name
317 /// @param type the alias type
318 /// @returns the alias pointer
319 type::Alias* alias(const std::string& name, type::Type* type) const {
320 return builder->create<type::Alias>(builder->Symbols().Register(name),
321 type);
322 }
323
324 /// @return the tint AST pointer to type `T` with the given
325 /// ast::StorageClass.
326 /// @param storage_class the storage class of the pointer
327 template <typename T>
328 type::Pointer* pointer(ast::StorageClass storage_class) const {
329 return builder->create<type::Pointer>(Of<T>(), storage_class);
330 }
331
332 /// @param name the struct name
333 /// @param impl the struct implementation
334 /// @returns a struct pointer
335 type::Struct* struct_(const std::string& name, ast::Struct* impl) const {
336 return builder->create<type::Struct>(builder->Symbols().Register(name),
337 impl);
338 }
339
340 private:
341 /// CToAST<T> is specialized for various `T` types and each specialization
342 /// contains a single static `get()` method for obtaining the corresponding
343 /// AST type for the C type `T`.
344 /// `get()` has the signature:
345 /// `static type::Type* get(Types* t)`
346 template <typename T>
347 struct CToAST {};
348
349 ProgramBuilder* builder;
350 };
351
352 //////////////////////////////////////////////////////////////////////////////
353 // AST helper methods
354 //////////////////////////////////////////////////////////////////////////////
355
356 /// @param expr the expression
357 /// @return expr
358 ast::Expression* Expr(ast::Expression* expr) { return expr; }
359
360 /// @param name the identifier name
361 /// @return an ast::IdentifierExpression with the given name
362 ast::IdentifierExpression* Expr(const std::string& name) {
363 return create<ast::IdentifierExpression>(Symbols().Register(name));
364 }
365
366 /// @param source the source information
367 /// @param name the identifier name
368 /// @return an ast::IdentifierExpression with the given name
369 ast::IdentifierExpression* Expr(const Source& source,
370 const std::string& name) {
371 return create<ast::IdentifierExpression>(source, Symbols().Register(name));
372 }
373
374 /// @param name the identifier name
375 /// @return an ast::IdentifierExpression with the given name
376 ast::IdentifierExpression* Expr(const char* name) {
377 return create<ast::IdentifierExpression>(Symbols().Register(name));
378 }
379
380 /// @param value the boolean value
381 /// @return a Scalar constructor for the given value
382 ast::ScalarConstructorExpression* Expr(bool value) {
383 return create<ast::ScalarConstructorExpression>(Literal(value));
384 }
385
386 /// @param value the float value
387 /// @return a Scalar constructor for the given value
388 ast::ScalarConstructorExpression* Expr(f32 value) {
389 return create<ast::ScalarConstructorExpression>(Literal(value));
390 }
391
392 /// @param value the integer value
393 /// @return a Scalar constructor for the given value
394 ast::ScalarConstructorExpression* Expr(i32 value) {
395 return create<ast::ScalarConstructorExpression>(Literal(value));
396 }
397
398 /// @param value the unsigned int value
399 /// @return a Scalar constructor for the given value
400 ast::ScalarConstructorExpression* Expr(u32 value) {
401 return create<ast::ScalarConstructorExpression>(Literal(value));
402 }
403
404 /// Converts `arg` to an `ast::Expression` using `Expr()`, then appends it to
405 /// `list`.
406 /// @param list the list to append too
407 /// @param arg the arg to create
408 template <typename ARG>
409 void Append(ast::ExpressionList& list, ARG&& arg) {
410 list.emplace_back(Expr(std::forward<ARG>(arg)));
411 }
412
413 /// Converts `arg0` and `args` to `ast::Expression`s using `Expr()`,
414 /// then appends them to `list`.
415 /// @param list the list to append too
416 /// @param arg0 the first argument
417 /// @param args the rest of the arguments
418 template <typename ARG0, typename... ARGS>
419 void Append(ast::ExpressionList& list, ARG0&& arg0, ARGS&&... args) {
420 Append(list, std::forward<ARG0>(arg0));
421 Append(list, std::forward<ARGS>(args)...);
422 }
423
424 /// @return an empty list of expressions
425 ast::ExpressionList ExprList() { return {}; }
426
427 /// @param args the list of expressions
428 /// @return the list of expressions converted to `ast::Expression`s using
429 /// `Expr()`,
430 template <typename... ARGS>
431 ast::ExpressionList ExprList(ARGS&&... args) {
432 ast::ExpressionList list;
433 list.reserve(sizeof...(args));
434 Append(list, std::forward<ARGS>(args)...);
435 return list;
436 }
437
438 /// @param list the list of expressions
439 /// @return `list`
440 ast::ExpressionList ExprList(ast::ExpressionList list) { return list; }
441
442 /// @param val the boolan value
443 /// @return a boolean literal with the given value
444 ast::BoolLiteral* Literal(bool val) {
445 return create<ast::BoolLiteral>(ty.bool_(), val);
446 }
447
448 /// @param val the float value
449 /// @return a float literal with the given value
450 ast::FloatLiteral* Literal(f32 val) {
451 return create<ast::FloatLiteral>(ty.f32(), val);
452 }
453
454 /// @param val the unsigned int value
455 /// @return a ast::UintLiteral with the given value
456 ast::UintLiteral* Literal(u32 val) {
457 return create<ast::UintLiteral>(ty.u32(), val);
458 }
459
460 /// @param val the integer value
461 /// @return the ast::SintLiteral with the given value
462 ast::SintLiteral* Literal(i32 val) {
463 return create<ast::SintLiteral>(ty.i32(), val);
464 }
465
466 /// @param args the arguments for the type constructor
467 /// @return an `ast::TypeConstructorExpression` of type `ty`, with the values
468 /// of `args` converted to `ast::Expression`s using `Expr()`
469 template <typename T, typename... ARGS>
470 ast::TypeConstructorExpression* Construct(ARGS&&... args) {
471 return create<ast::TypeConstructorExpression>(
472 ty.Of<T>(), ExprList(std::forward<ARGS>(args)...));
473 }
474
475 /// @param type the type to construct
476 /// @param args the arguments for the constructor
477 /// @return an `ast::TypeConstructorExpression` of `type` constructed with the
478 /// values `args`.
479 template <typename... ARGS>
480 ast::TypeConstructorExpression* Construct(type::Type* type, ARGS&&... args) {
481 return create<ast::TypeConstructorExpression>(
482 type, ExprList(std::forward<ARGS>(args)...));
483 }
484
485 /// @param args the arguments for the vector constructor
486 /// @return an `ast::TypeConstructorExpression` of a 2-element vector of type
487 /// `T`, constructed with the values `args`.
488 template <typename T, typename... ARGS>
489 ast::TypeConstructorExpression* vec2(ARGS&&... args) {
490 return create<ast::TypeConstructorExpression>(
491 ty.vec2<T>(), ExprList(std::forward<ARGS>(args)...));
492 }
493
494 /// @param args the arguments for the vector constructor
495 /// @return an `ast::TypeConstructorExpression` of a 3-element vector of type
496 /// `T`, constructed with the values `args`.
497 template <typename T, typename... ARGS>
498 ast::TypeConstructorExpression* vec3(ARGS&&... args) {
499 return create<ast::TypeConstructorExpression>(
500 ty.vec3<T>(), ExprList(std::forward<ARGS>(args)...));
501 }
502
503 /// @param args the arguments for the vector constructor
504 /// @return an `ast::TypeConstructorExpression` of a 4-element vector of type
505 /// `T`, constructed with the values `args`.
506 template <typename T, typename... ARGS>
507 ast::TypeConstructorExpression* vec4(ARGS&&... args) {
508 return create<ast::TypeConstructorExpression>(
509 ty.vec4<T>(), ExprList(std::forward<ARGS>(args)...));
510 }
511
512 /// @param args the arguments for the matrix constructor
513 /// @return an `ast::TypeConstructorExpression` of a 2x2 matrix of type
514 /// `T`, constructed with the values `args`.
515 template <typename T, typename... ARGS>
516 ast::TypeConstructorExpression* mat2x2(ARGS&&... args) {
517 return create<ast::TypeConstructorExpression>(
518 ty.mat2x2<T>(), ExprList(std::forward<ARGS>(args)...));
519 }
520
521 /// @param args the arguments for the matrix constructor
522 /// @return an `ast::TypeConstructorExpression` of a 2x3 matrix of type
523 /// `T`, constructed with the values `args`.
524 template <typename T, typename... ARGS>
525 ast::TypeConstructorExpression* mat2x3(ARGS&&... args) {
526 return create<ast::TypeConstructorExpression>(
527 ty.mat2x3<T>(), ExprList(std::forward<ARGS>(args)...));
528 }
529
530 /// @param args the arguments for the matrix constructor
531 /// @return an `ast::TypeConstructorExpression` of a 2x4 matrix of type
532 /// `T`, constructed with the values `args`.
533 template <typename T, typename... ARGS>
534 ast::TypeConstructorExpression* mat2x4(ARGS&&... args) {
535 return create<ast::TypeConstructorExpression>(
536 ty.mat2x4<T>(), ExprList(std::forward<ARGS>(args)...));
537 }
538
539 /// @param args the arguments for the matrix constructor
540 /// @return an `ast::TypeConstructorExpression` of a 3x2 matrix of type
541 /// `T`, constructed with the values `args`.
542 template <typename T, typename... ARGS>
543 ast::TypeConstructorExpression* mat3x2(ARGS&&... args) {
544 return create<ast::TypeConstructorExpression>(
545 ty.mat3x2<T>(), ExprList(std::forward<ARGS>(args)...));
546 }
547
548 /// @param args the arguments for the matrix constructor
549 /// @return an `ast::TypeConstructorExpression` of a 3x3 matrix of type
550 /// `T`, constructed with the values `args`.
551 template <typename T, typename... ARGS>
552 ast::TypeConstructorExpression* mat3x3(ARGS&&... args) {
553 return create<ast::TypeConstructorExpression>(
554 ty.mat3x3<T>(), ExprList(std::forward<ARGS>(args)...));
555 }
556
557 /// @param args the arguments for the matrix constructor
558 /// @return an `ast::TypeConstructorExpression` of a 3x4 matrix of type
559 /// `T`, constructed with the values `args`.
560 template <typename T, typename... ARGS>
561 ast::TypeConstructorExpression* mat3x4(ARGS&&... args) {
562 return create<ast::TypeConstructorExpression>(
563 ty.mat3x4<T>(), ExprList(std::forward<ARGS>(args)...));
564 }
565
566 /// @param args the arguments for the matrix constructor
567 /// @return an `ast::TypeConstructorExpression` of a 4x2 matrix of type
568 /// `T`, constructed with the values `args`.
569 template <typename T, typename... ARGS>
570 ast::TypeConstructorExpression* mat4x2(ARGS&&... args) {
571 return create<ast::TypeConstructorExpression>(
572 ty.mat4x2<T>(), ExprList(std::forward<ARGS>(args)...));
573 }
574
575 /// @param args the arguments for the matrix constructor
576 /// @return an `ast::TypeConstructorExpression` of a 4x3 matrix of type
577 /// `T`, constructed with the values `args`.
578 template <typename T, typename... ARGS>
579 ast::TypeConstructorExpression* mat4x3(ARGS&&... args) {
580 return create<ast::TypeConstructorExpression>(
581 ty.mat4x3<T>(), ExprList(std::forward<ARGS>(args)...));
582 }
583
584 /// @param args the arguments for the matrix constructor
585 /// @return an `ast::TypeConstructorExpression` of a 4x4 matrix of type
586 /// `T`, constructed with the values `args`.
587 template <typename T, typename... ARGS>
588 ast::TypeConstructorExpression* mat4x4(ARGS&&... args) {
589 return create<ast::TypeConstructorExpression>(
590 ty.mat4x4<T>(), ExprList(std::forward<ARGS>(args)...));
591 }
592
593 /// @param args the arguments for the array constructor
594 /// @return an `ast::TypeConstructorExpression` of an array with element type
595 /// `T`, constructed with the values `args`.
596 template <typename T, int N = 0, typename... ARGS>
597 ast::TypeConstructorExpression* array(ARGS&&... args) {
598 return create<ast::TypeConstructorExpression>(
599 ty.array<T, N>(), ExprList(std::forward<ARGS>(args)...));
600 }
601
602 /// @param subtype the array element type
603 /// @param n the array size. 0 represents a runtime-array.
604 /// @param args the arguments for the array constructor
605 /// @return an `ast::TypeConstructorExpression` of an array with element type
606 /// `subtype`, constructed with the values `args`.
607 template <typename... ARGS>
608 ast::TypeConstructorExpression* array(type::Type* subtype,
609 uint32_t n,
610 ARGS&&... args) {
611 return create<ast::TypeConstructorExpression>(
612 ty.array(subtype, n), ExprList(std::forward<ARGS>(args)...));
613 }
614
615 /// @param name the variable name
616 /// @param storage the variable storage class
617 /// @param type the variable type
618 /// @returns a `ast::Variable` with the given name, storage and type. The
619 /// variable will be built with a nullptr constructor and no decorations.
620 ast::Variable* Var(const std::string& name,
621 ast::StorageClass storage,
622 type::Type* type);
623
624 /// @param name the variable name
625 /// @param storage the variable storage class
626 /// @param type the variable type
627 /// @param constructor constructor expression
628 /// @param decorations variable decorations
629 /// @returns a `ast::Variable` with the given name, storage and type
630 ast::Variable* Var(const std::string& name,
631 ast::StorageClass storage,
632 type::Type* type,
633 ast::Expression* constructor,
634 ast::VariableDecorationList decorations);
635
636 /// @param source the variable source
637 /// @param name the variable name
638 /// @param storage the variable storage class
639 /// @param type the variable type
640 /// @param constructor constructor expression
641 /// @param decorations variable decorations
642 /// @returns a `ast::Variable` with the given name, storage and type
643 ast::Variable* Var(const Source& source,
644 const std::string& name,
645 ast::StorageClass storage,
646 type::Type* type,
647 ast::Expression* constructor,
648 ast::VariableDecorationList decorations);
649
650 /// @param name the variable name
651 /// @param storage the variable storage class
652 /// @param type the variable type
653 /// @returns a constant `ast::Variable` with the given name, storage and type.
654 /// The variable will be built with a nullptr constructor and no decorations.
655 ast::Variable* Const(const std::string& name,
656 ast::StorageClass storage,
657 type::Type* type);
658
659 /// @param name the variable name
660 /// @param storage the variable storage class
661 /// @param type the variable type
662 /// @param constructor optional constructor expression
663 /// @param decorations optional variable decorations
664 /// @returns a constant `ast::Variable` with the given name, storage and type
665 ast::Variable* Const(const std::string& name,
666 ast::StorageClass storage,
667 type::Type* type,
668 ast::Expression* constructor,
669 ast::VariableDecorationList decorations);
670
671 /// @param source the variable source
672 /// @param name the variable name
673 /// @param storage the variable storage class
674 /// @param type the variable type
675 /// @param constructor optional constructor expression
676 /// @param decorations optional variable decorations
677 /// @returns a constant `ast::Variable` with the given name, storage and type
678 ast::Variable* Const(const Source& source,
679 const std::string& name,
680 ast::StorageClass storage,
681 type::Type* type,
682 ast::Expression* constructor,
683 ast::VariableDecorationList decorations);
684
685 /// @param func the function name
686 /// @param args the function call arguments
687 /// @returns a `ast::CallExpression` to the function `func`, with the
688 /// arguments of `args` converted to `ast::Expression`s using `Expr()`.
689 template <typename NAME, typename... ARGS>
690 ast::CallExpression* Call(NAME&& func, ARGS&&... args) {
691 return create<ast::CallExpression>(Expr(func),
692 ExprList(std::forward<ARGS>(args)...));
693 }
694
695 /// @param lhs the left hand argument to the addition operation
696 /// @param rhs the right hand argument to the addition operation
697 /// @returns a `ast::BinaryExpression` summing the arguments `lhs` and `rhs`
698 template <typename LHS, typename RHS>
699 ast::Expression* Add(LHS&& lhs, RHS&& rhs) {
700 return create<ast::BinaryExpression>(ast::BinaryOp::kAdd,
701 Expr(std::forward<LHS>(lhs)),
702 Expr(std::forward<RHS>(rhs)));
703 }
704
705 /// @param lhs the left hand argument to the subtraction operation
706 /// @param rhs the right hand argument to the subtraction operation
707 /// @returns a `ast::BinaryExpression` subtracting `rhs` from `lhs`
708 template <typename LHS, typename RHS>
709 ast::Expression* Sub(LHS&& lhs, RHS&& rhs) {
710 return create<ast::BinaryExpression>(ast::BinaryOp::kSubtract,
711 Expr(std::forward<LHS>(lhs)),
712 Expr(std::forward<RHS>(rhs)));
713 }
714
715 /// @param lhs the left hand argument to the multiplication operation
716 /// @param rhs the right hand argument to the multiplication operation
717 /// @returns a `ast::BinaryExpression` multiplying `rhs` from `lhs`
718 template <typename LHS, typename RHS>
719 ast::Expression* Mul(LHS&& lhs, RHS&& rhs) {
720 return create<ast::BinaryExpression>(ast::BinaryOp::kMultiply,
721 Expr(std::forward<LHS>(lhs)),
722 Expr(std::forward<RHS>(rhs)));
723 }
724
725 /// @param arr the array argument for the array accessor expression
726 /// @param idx the index argument for the array accessor expression
727 /// @returns a `ast::ArrayAccessorExpression` that indexes `arr` with `idx`
728 template <typename ARR, typename IDX>
729 ast::Expression* IndexAccessor(ARR&& arr, IDX&& idx) {
730 return create<ast::ArrayAccessorExpression>(Expr(std::forward<ARR>(arr)),
731 Expr(std::forward<IDX>(idx)));
732 }
733
734 /// @param obj the object for the member accessor expression
735 /// @param idx the index argument for the array accessor expression
736 /// @returns a `ast::MemberAccessorExpression` that indexes `obj` with `idx`
737 template <typename OBJ, typename IDX>
738 ast::Expression* MemberAccessor(OBJ&& obj, IDX&& idx) {
739 return create<ast::MemberAccessorExpression>(Expr(std::forward<OBJ>(obj)),
740 Expr(std::forward<IDX>(idx)));
741 }
742
743 /// creates a ast::StructMemberOffsetDecoration
744 /// @param val the offset value
745 /// @returns the offset decoration pointer
746 ast::StructMemberOffsetDecoration* MemberOffset(uint32_t val) {
747 return create<ast::StructMemberOffsetDecoration>(source_, val);
748 }
749
750 /// creates a ast::Function
751 /// @param source the source information
752 /// @param name the function name
753 /// @param params the function parameters
754 /// @param type the function return type
755 /// @param body the function body
756 /// @param decorations the function decorations
757 /// @returns the function pointer
758 ast::Function* Func(Source source,
759 std::string name,
760 ast::VariableList params,
761 type::Type* type,
762 ast::StatementList body,
763 ast::FunctionDecorationList decorations) {
764 return create<ast::Function>(source, Symbols().Register(name), params, type,
765 create<ast::BlockStatement>(body),
766 decorations);
767 }
768
769 /// creates a ast::Function
770 /// @param name the function name
771 /// @param params the function parameters
772 /// @param type the function return type
773 /// @param body the function body
774 /// @param decorations the function decorations
775 /// @returns the function pointer
776 ast::Function* Func(std::string name,
777 ast::VariableList params,
778 type::Type* type,
779 ast::StatementList body,
780 ast::FunctionDecorationList decorations) {
781 return create<ast::Function>(Symbols().Register(name), params, type,
782 create<ast::BlockStatement>(body),
783 decorations);
784 }
785
786 /// creates a ast::StructMember
787 /// @param source the source information
788 /// @param name the struct member name
789 /// @param type the struct member type
790 /// @returns the struct member pointer
791 ast::StructMember* Member(const Source& source,
792 const std::string& name,
793 type::Type* type) {
794 return create<ast::StructMember>(source, Symbols().Register(name), type,
795 ast::StructMemberDecorationList{});
796 }
797
798 /// creates a ast::StructMember
799 /// @param name the struct member name
800 /// @param type the struct member type
801 /// @returns the struct member pointer
802 ast::StructMember* Member(const std::string& name, type::Type* type) {
803 return create<ast::StructMember>(source_, Symbols().Register(name), type,
804 ast::StructMemberDecorationList{});
805 }
806
807 /// creates a ast::StructMember
808 /// @param name the struct member name
809 /// @param type the struct member type
810 /// @param decorations the struct member decorations
811 /// @returns the struct member pointer
812 ast::StructMember* Member(const std::string& name,
813 type::Type* type,
814 ast::StructMemberDecorationList decorations) {
815 return create<ast::StructMember>(source_, Symbols().Register(name), type,
816 decorations);
817 }
818
819 /// Sets the current builder source to `src`
820 /// @param src the Source used for future create() calls
821 void SetSource(const Source& src) {
822 AssertNotMoved();
823 source_ = src;
824 }
825
826 /// Sets the current builder source to `loc`
827 /// @param loc the Source used for future create() calls
828 void SetSource(const Source::Location& loc) {
829 AssertNotMoved();
830 source_ = Source(loc);
831 }
832
833 /// The builder types
834 TypesBuilder ty;
835
836 protected:
837 /// Asserts that the builder has not been moved.
838 void AssertNotMoved() const;
839
840 /// Called whenever a new variable is built with `Var()`.
841 virtual void OnVariableBuilt(ast::Variable*) {}
842
843 private:
844 type::Manager types_;
845 ASTNodes nodes_;
846 ast::Module* ast_;
847 SymbolTable symbols_;
Ben Clayton844217f2021-01-27 18:49:05 +0000848 diag::List diagnostics_;
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000849
850 /// The source to use when creating AST nodes without providing a Source as
851 /// the first argument.
852 Source source_;
853
854 /// Set by MarkAsMoved(). Once set, no methods may be called on this builder.
855 bool moved_ = false;
856};
857
858//! @cond Doxygen_Suppress
859// Various template specializations for ProgramBuilder::TypesBuilder::CToAST.
860template <>
861struct ProgramBuilder::TypesBuilder::CToAST<ProgramBuilder::i32> {
862 static type::Type* get(const ProgramBuilder::TypesBuilder* t) {
863 return t->i32();
864 }
865};
866template <>
867struct ProgramBuilder::TypesBuilder::CToAST<ProgramBuilder::u32> {
868 static type::Type* get(const ProgramBuilder::TypesBuilder* t) {
869 return t->u32();
870 }
871};
872template <>
873struct ProgramBuilder::TypesBuilder::CToAST<ProgramBuilder::f32> {
874 static type::Type* get(const ProgramBuilder::TypesBuilder* t) {
875 return t->f32();
876 }
877};
878template <>
879struct ProgramBuilder::TypesBuilder::CToAST<bool> {
880 static type::Type* get(const ProgramBuilder::TypesBuilder* t) {
881 return t->bool_();
882 }
883};
884template <>
885struct ProgramBuilder::TypesBuilder::CToAST<void> {
886 static type::Type* get(const ProgramBuilder::TypesBuilder* t) {
887 return t->void_();
888 }
889};
890//! @endcond
891
892} // namespace tint
893
894#endif // SRC_PROGRAM_BUILDER_H_