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