blob: b67eea477c7fc3afbbcf627e175500eaa09e94d9 [file] [log] [blame]
Ben Clayton2c41f4f2021-03-09 15:12:57 +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#include "src/resolver/resolver.h"
16
17#include "gmock/gmock.h"
18#include "src/ast/assignment_statement.h"
19#include "src/ast/bitcast_expression.h"
20#include "src/ast/break_statement.h"
21#include "src/ast/call_statement.h"
22#include "src/ast/continue_statement.h"
23#include "src/ast/if_statement.h"
24#include "src/ast/intrinsic_texture_helper_test.h"
25#include "src/ast/loop_statement.h"
26#include "src/ast/return_statement.h"
27#include "src/ast/stage_decoration.h"
28#include "src/ast/switch_statement.h"
29#include "src/ast/unary_op_expression.h"
30#include "src/ast/variable_decl_statement.h"
31#include "src/resolver/resolver_test_helper.h"
Antonio Maioranoaea9c682021-04-19 22:54:43 +000032#include "src/sem/access_control_type.h"
Antonio Maiorano5cd71b82021-04-16 19:07:51 +000033#include "src/sem/call.h"
34#include "src/sem/function.h"
35#include "src/sem/member_accessor_expression.h"
Antonio Maioranoaea9c682021-04-19 22:54:43 +000036#include "src/sem/sampled_texture_type.h"
Antonio Maiorano5cd71b82021-04-16 19:07:51 +000037#include "src/sem/statement.h"
38#include "src/sem/variable.h"
Ben Clayton2c41f4f2021-03-09 15:12:57 +000039
40using ::testing::ElementsAre;
41using ::testing::HasSubstr;
42
43namespace tint {
44namespace resolver {
45namespace {
46
47using ResolverValidationTest = ResolverTest;
48
49class FakeStmt : public ast::Statement {
50 public:
Ben Claytone6995de2021-04-13 23:27:27 +000051 FakeStmt(ProgramID program_id, Source source)
52 : ast::Statement(program_id, source) {}
Ben Clayton2c41f4f2021-03-09 15:12:57 +000053 FakeStmt* Clone(CloneContext*) const override { return nullptr; }
Antonio Maiorano5cd71b82021-04-16 19:07:51 +000054 void to_str(const sem::Info&, std::ostream& out, size_t) const override {
Ben Clayton2c41f4f2021-03-09 15:12:57 +000055 out << "Fake";
56 }
57};
58
59class FakeExpr : public ast::Expression {
60 public:
Ben Claytone6995de2021-04-13 23:27:27 +000061 FakeExpr(ProgramID program_id, Source source)
62 : ast::Expression(program_id, source) {}
Ben Clayton2c41f4f2021-03-09 15:12:57 +000063 FakeExpr* Clone(CloneContext*) const override { return nullptr; }
Antonio Maiorano5cd71b82021-04-16 19:07:51 +000064 void to_str(const sem::Info&, std::ostream&, size_t) const override {}
Ben Clayton2c41f4f2021-03-09 15:12:57 +000065};
66
67TEST_F(ResolverValidationTest, Error_WithEmptySource) {
68 auto* s = create<FakeStmt>();
69 WrapInFunction(s);
70
71 EXPECT_FALSE(r()->Resolve());
72
73 EXPECT_EQ(r()->error(),
74 "error: unknown statement type for type determination: Fake");
75}
76
77TEST_F(ResolverValidationTest, Stmt_Error_Unknown) {
78 auto* s = create<FakeStmt>(Source{Source::Location{2, 30}});
79 WrapInFunction(s);
80
81 EXPECT_FALSE(r()->Resolve());
82
83 EXPECT_EQ(r()->error(),
84 "2:30 error: unknown statement type for type determination: Fake");
85}
86
87TEST_F(ResolverValidationTest, Stmt_Call_undeclared) {
Ben Clayton9328d942021-04-08 14:39:47 +000088 // fn main() {func(); return; }
89 // fn func() { return; }
Ben Clayton2c41f4f2021-03-09 15:12:57 +000090
91 SetSource(Source::Location{12, 34});
92 auto* call_expr = Call("func");
93 ast::VariableList params0;
94
95 Func("main", params0, ty.f32(),
96 ast::StatementList{
97 create<ast::CallStatement>(call_expr),
98 create<ast::ReturnStatement>(),
99 },
James Price95d40772021-03-11 17:39:32 +0000100 ast::DecorationList{});
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000101
102 Func("func", params0, ty.f32(),
103 ast::StatementList{
104 create<ast::ReturnStatement>(),
105 },
James Price95d40772021-03-11 17:39:32 +0000106 ast::DecorationList{});
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000107
108 EXPECT_FALSE(r()->Resolve());
109
110 EXPECT_EQ(r()->error(),
111 "12:34 error: v-0006: unable to find called function: func");
112}
113
114TEST_F(ResolverValidationTest, Stmt_Call_recursive) {
Ben Clayton9328d942021-04-08 14:39:47 +0000115 // fn main() {main(); }
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000116
117 SetSource(Source::Location{12, 34});
118 auto* call_expr = Call("main");
119 ast::VariableList params0;
120
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000121 Func("main", params0, ty.void_(),
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000122 ast::StatementList{
123 create<ast::CallStatement>(call_expr),
124 },
James Price95d40772021-03-11 17:39:32 +0000125 ast::DecorationList{
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000126 create<ast::StageDecoration>(ast::PipelineStage::kVertex),
127 });
128
129 EXPECT_FALSE(r()->Resolve());
130
131 EXPECT_EQ(r()->error(),
Antonio Maiorano06feb3f2021-03-22 17:42:06 +0000132 "12:34 error v-0004: recursion is not permitted. 'main' attempted "
133 "to call "
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000134 "itself.");
135}
136
Ben Clayton5fb87dd2021-03-09 15:17:28 +0000137TEST_F(ResolverValidationTest, Stmt_If_NonBool) {
138 // if (1.23f) {}
139
140 WrapInFunction(If(create<ast::ScalarConstructorExpression>(Source{{12, 34}},
141 Literal(1.23f)),
142 Block()));
143
144 EXPECT_FALSE(r()->Resolve());
145
146 EXPECT_EQ(r()->error(),
147 "12:34 error: if statement condition must be bool, got f32");
148}
149
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000150TEST_F(ResolverValidationTest,
151 Stmt_VariableDecl_MismatchedTypeScalarConstructor) {
152 u32 unsigned_value = 2u; // Type does not match variable type
153 auto* var =
154 Var("my_var", ty.i32(), ast::StorageClass::kNone, Expr(unsigned_value));
155
156 auto* decl =
157 create<ast::VariableDeclStatement>(Source{{{3, 3}, {3, 22}}}, var);
158 WrapInFunction(decl);
159
160 EXPECT_FALSE(r()->Resolve());
161 EXPECT_EQ(
162 r()->error(),
Ben Clayton6b2fc052021-03-18 21:14:44 +0000163 R"(3:3 error: variable of type 'i32' cannot be initialized with a value of type 'u32')");
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000164}
165
166TEST_F(ResolverValidationTest,
167 Stmt_VariableDecl_MismatchedTypeScalarConstructor_Alias) {
168 auto* my_int = ty.alias("MyInt", ty.i32());
169 u32 unsigned_value = 2u; // Type does not match variable type
170 auto* var =
171 Var("my_var", my_int, ast::StorageClass::kNone, Expr(unsigned_value));
172
173 auto* decl =
174 create<ast::VariableDeclStatement>(Source{{{3, 3}, {3, 22}}}, var);
175 WrapInFunction(decl);
176
177 EXPECT_FALSE(r()->Resolve());
178 EXPECT_EQ(
179 r()->error(),
Ben Clayton6b2fc052021-03-18 21:14:44 +0000180 R"(3:3 error: variable of type 'MyInt' cannot be initialized with a value of type 'u32')");
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000181}
182
183TEST_F(ResolverValidationTest, Expr_Error_Unknown) {
Ben Claytone6995de2021-04-13 23:27:27 +0000184 auto* e = create<FakeExpr>(Source{Source::Location{2, 30}});
185 WrapInFunction(e);
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000186
187 EXPECT_FALSE(r()->Resolve());
188
189 EXPECT_EQ(r()->error(),
190 "2:30 error: unknown expression for type determination");
191}
192
193TEST_F(ResolverValidationTest, Expr_DontCall_Function) {
194 Func("func", {}, ty.void_(), {}, {});
195 auto* ident = create<ast::IdentifierExpression>(
196 Source{{Source::Location{3, 3}, Source::Location{3, 8}}},
197 Symbols().Register("func"));
198 WrapInFunction(ident);
199
200 EXPECT_FALSE(r()->Resolve());
201 EXPECT_EQ(r()->error(), "3:8 error: missing '(' for function call");
202}
203
204TEST_F(ResolverValidationTest, Expr_DontCall_Intrinsic) {
205 auto* ident = create<ast::IdentifierExpression>(
206 Source{{Source::Location{3, 3}, Source::Location{3, 8}}},
207 Symbols().Register("round"));
208 WrapInFunction(ident);
209
210 EXPECT_FALSE(r()->Resolve());
211 EXPECT_EQ(r()->error(), "3:8 error: missing '(' for intrinsic call");
212}
213
214TEST_F(ResolverValidationTest, UsingUndefinedVariable_Fail) {
215 // b = 2;
216
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000217 auto* lhs = Expr(Source{{12, 34}}, "b");
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000218 auto* rhs = Expr(2);
219 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
220 WrapInFunction(assign);
221
222 EXPECT_FALSE(r()->Resolve());
223 EXPECT_EQ(r()->error(),
224 "12:34 error: v-0006: identifier must be declared before use: b");
225}
226
227TEST_F(ResolverValidationTest, UsingUndefinedVariableInBlockStatement_Fail) {
228 // {
229 // b = 2;
230 // }
231
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000232 auto* lhs = Expr(Source{{12, 34}}, "b");
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000233 auto* rhs = Expr(2);
234
235 auto* body = create<ast::BlockStatement>(ast::StatementList{
236 create<ast::AssignmentStatement>(lhs, rhs),
237 });
238 WrapInFunction(body);
239
240 EXPECT_FALSE(r()->Resolve());
241 EXPECT_EQ(r()->error(),
242 "12:34 error: v-0006: identifier must be declared before use: b");
243}
244
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000245TEST_F(ResolverValidationTest, UsingUndefinedVariableGlobalVariableAfter_Fail) {
Ben Clayton9328d942021-04-08 14:39:47 +0000246 // fn my_func() {
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000247 // global_var = 3.14f;
248 // }
249 // var global_var: f32 = 2.1;
250
251 auto* lhs = Expr(Source{{12, 34}}, "global_var");
252 auto* rhs = Expr(3.14f);
253
254 Func("my_func", ast::VariableList{}, ty.void_(),
255 ast::StatementList{
256 create<ast::AssignmentStatement>(lhs, rhs),
257 },
258 ast::DecorationList{
259 create<ast::StageDecoration>(ast::PipelineStage::kVertex)});
260
261 Global("global_var", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1f));
262
263 EXPECT_FALSE(r()->Resolve());
264 EXPECT_EQ(r()->error(),
265 "12:34 error: v-0006: identifier must be declared before use: "
266 "global_var");
267}
268
269TEST_F(ResolverValidationTest, UsingUndefinedVariableGlobalVariable_Pass) {
270 // var global_var: f32 = 2.1;
Ben Clayton9328d942021-04-08 14:39:47 +0000271 // fn my_func() {
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000272 // global_var = 3.14;
273 // return;
274 // }
275
276 Global("global_var", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1f));
277
278 Func("my_func", ast::VariableList{}, ty.void_(),
279 ast::StatementList{
280 create<ast::AssignmentStatement>(Source{Source::Location{12, 34}},
281 Expr("global_var"), Expr(3.14f)),
282 create<ast::ReturnStatement>(),
283 },
284 ast::DecorationList{
285 create<ast::StageDecoration>(ast::PipelineStage::kVertex),
286 });
287
288 EXPECT_TRUE(r()->Resolve()) << r()->error();
289}
290
291TEST_F(ResolverValidationTest, UsingUndefinedVariableInnerScope_Fail) {
292 // {
293 // if (true) { var a : f32 = 2.0; }
294 // a = 3.14;
295 // }
296 auto* var = Var("a", ty.f32(), ast::StorageClass::kNone, Expr(2.0f));
297
298 auto* cond = Expr(true);
299 auto* body = create<ast::BlockStatement>(ast::StatementList{
300 create<ast::VariableDeclStatement>(var),
301 });
302
303 SetSource(Source{Source::Location{12, 34}});
304 auto* lhs = Expr(Source{{12, 34}}, "a");
305 auto* rhs = Expr(3.14f);
306
307 auto* outer_body = create<ast::BlockStatement>(ast::StatementList{
308 create<ast::IfStatement>(cond, body, ast::ElseStatementList{}),
309 create<ast::AssignmentStatement>(lhs, rhs),
310 });
311
312 WrapInFunction(outer_body);
313
314 EXPECT_FALSE(r()->Resolve());
315 EXPECT_EQ(r()->error(),
316 "12:34 error: v-0006: identifier must be declared before use: a");
317}
318
319TEST_F(ResolverValidationTest, UsingUndefinedVariableOuterScope_Pass) {
320 // {
321 // var a : f32 = 2.0;
322 // if (true) { a = 3.14; }
323 // }
324 auto* var = Var("a", ty.f32(), ast::StorageClass::kNone, Expr(2.0f));
325
326 auto* lhs = Expr(Source{{12, 34}}, "a");
327 auto* rhs = Expr(3.14f);
328
329 auto* cond = Expr(true);
330 auto* body = create<ast::BlockStatement>(ast::StatementList{
331 create<ast::AssignmentStatement>(lhs, rhs),
332 });
333
334 auto* outer_body = create<ast::BlockStatement>(ast::StatementList{
335 create<ast::VariableDeclStatement>(var),
336 create<ast::IfStatement>(cond, body, ast::ElseStatementList{}),
337 });
338
339 WrapInFunction(outer_body);
340
341 EXPECT_TRUE(r()->Resolve()) << r()->error();
342}
343
344TEST_F(ResolverValidationTest, UsingUndefinedVariableDifferentScope_Fail) {
345 // {
346 // { var a : f32 = 2.0; }
347 // { a = 3.14; }
348 // }
349 auto* var = Var("a", ty.f32(), ast::StorageClass::kNone, Expr(2.0f));
350 auto* first_body = create<ast::BlockStatement>(ast::StatementList{
351 create<ast::VariableDeclStatement>(var),
352 });
353
354 auto* lhs = Expr(Source{{12, 34}}, "a");
355 auto* rhs = Expr(3.14f);
356 auto* second_body = create<ast::BlockStatement>(ast::StatementList{
357 create<ast::AssignmentStatement>(lhs, rhs),
358 });
359
360 auto* outer_body = create<ast::BlockStatement>(ast::StatementList{
361 first_body,
362 second_body,
363 });
364
365 WrapInFunction(outer_body);
366
367 EXPECT_FALSE(r()->Resolve());
368 EXPECT_EQ(r()->error(),
369 "12:34 error: v-0006: identifier must be declared before use: a");
370}
371
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000372TEST_F(ResolverValidationTest, StorageClass_NonFunctionClassError) {
373 auto* var = Var("var", ty.i32(), ast::StorageClass::kWorkgroup);
374
375 auto* stmt = create<ast::VariableDeclStatement>(var);
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000376 Func("func", ast::VariableList{}, ty.void_(), ast::StatementList{stmt},
James Price95d40772021-03-11 17:39:32 +0000377 ast::DecorationList{});
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000378
379 EXPECT_FALSE(r()->Resolve());
380
381 EXPECT_EQ(r()->error(),
382 "error: function variable has a non-function storage class");
383}
384
385TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadChar) {
Antonio Maioranobbbb0ed2021-04-06 20:18:57 +0000386 Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kInput);
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000387
388 auto* ident = create<ast::IdentifierExpression>(
389 Source{{Source::Location{3, 3}, Source::Location{3, 7}}},
390 Symbols().Register("xyqz"));
391
392 auto* mem = MemberAccessor("my_vec", ident);
393 WrapInFunction(mem);
394
395 EXPECT_FALSE(r()->Resolve());
396 EXPECT_EQ(r()->error(), "3:5 error: invalid vector swizzle character");
397}
398
399TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_MixedChars) {
Antonio Maioranobbbb0ed2021-04-06 20:18:57 +0000400 Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kInput);
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000401
402 auto* ident = create<ast::IdentifierExpression>(
403 Source{{Source::Location{3, 3}, Source::Location{3, 7}}},
404 Symbols().Register("rgyw"));
405
406 auto* mem = MemberAccessor("my_vec", ident);
407 WrapInFunction(mem);
408
409 EXPECT_FALSE(r()->Resolve());
410 EXPECT_EQ(
411 r()->error(),
412 "3:3 error: invalid mixing of vector swizzle characters rgba with xyzw");
413}
414
415TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadLength) {
Antonio Maioranobbbb0ed2021-04-06 20:18:57 +0000416 Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kInput);
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000417
418 auto* ident = create<ast::IdentifierExpression>(
419 Source{{Source::Location{3, 3}, Source::Location{3, 8}}},
420 Symbols().Register("zzzzz"));
421 auto* mem = MemberAccessor("my_vec", ident);
422 WrapInFunction(mem);
423
424 EXPECT_FALSE(r()->Resolve());
425 EXPECT_EQ(r()->error(), "3:3 error: invalid vector swizzle size");
426}
427
428TEST_F(ResolverValidationTest,
429 Stmt_Loop_ContinueInLoopBodyBeforeDecl_UsageInContinuing) {
430 // loop {
431 // continue; // Bypasses z decl
432 // var z : i32;
433 //
434 // continuing {
435 // z = 2;
436 // }
437 // }
438
439 auto error_loc = Source{Source::Location{12, 34}};
440 auto* body = Block(create<ast::ContinueStatement>(),
441 Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
442 auto* continuing = Block(Assign(Expr(error_loc, "z"), Expr(2)));
443 auto* loop_stmt = Loop(body, continuing);
444 WrapInFunction(loop_stmt);
445
446 EXPECT_FALSE(r()->Resolve()) << r()->error();
447 EXPECT_EQ(r()->error(),
448 "12:34 error: continue statement bypasses declaration of 'z' in "
449 "continuing block");
450}
451
452TEST_F(ResolverValidationTest,
453 Stmt_Loop_ContinueInLoopBodyBeforeDeclAndAfterDecl_UsageInContinuing) {
454 // loop {
455 // continue; // Bypasses z decl
456 // var z : i32;
457 // continue; // Ok
458 //
459 // continuing {
460 // z = 2;
461 // }
462 // }
463
464 auto error_loc = Source{Source::Location{12, 34}};
465 auto* body = Block(create<ast::ContinueStatement>(),
466 Decl(Var("z", ty.i32(), ast::StorageClass::kNone)),
467 create<ast::ContinueStatement>());
468 auto* continuing = Block(Assign(Expr(error_loc, "z"), Expr(2)));
469 auto* loop_stmt = Loop(body, continuing);
470 WrapInFunction(loop_stmt);
471
472 EXPECT_FALSE(r()->Resolve()) << r()->error();
473 EXPECT_EQ(r()->error(),
474 "12:34 error: continue statement bypasses declaration of 'z' in "
475 "continuing block");
476}
477
478TEST_F(ResolverValidationTest,
479 Stmt_Loop_ContinueInLoopBodySubscopeBeforeDecl_UsageInContinuing) {
480 // loop {
481 // if (true) {
482 // continue; // Still bypasses z decl (if we reach here)
483 // }
484 // var z : i32;
485 // continuing {
486 // z = 2;
487 // }
488 // }
489
490 auto error_loc = Source{Source::Location{12, 34}};
491 auto* body = Block(If(Expr(true), Block(create<ast::ContinueStatement>())),
492 Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
493 auto* continuing = Block(Assign(Expr(error_loc, "z"), Expr(2)));
494 auto* loop_stmt = Loop(body, continuing);
495 WrapInFunction(loop_stmt);
496
497 EXPECT_FALSE(r()->Resolve()) << r()->error();
498 EXPECT_EQ(r()->error(),
499 "12:34 error: continue statement bypasses declaration of 'z' in "
500 "continuing block");
501}
502
503TEST_F(
Arman Uguray3549e2e2021-03-15 21:21:33 +0000504 ResolverValidationTest,
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000505 Stmt_Loop_ContinueInLoopBodySubscopeBeforeDecl_UsageInContinuingSubscope) {
506 // loop {
507 // if (true) {
508 // continue; // Still bypasses z decl (if we reach here)
509 // }
510 // var z : i32;
511 // continuing {
512 // if (true) {
513 // z = 2; // Must fail even if z is in a sub-scope
514 // }
515 // }
516 // }
517
518 auto error_loc = Source{Source::Location{12, 34}};
519 auto* body = Block(If(Expr(true), Block(create<ast::ContinueStatement>())),
520 Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
521
522 auto* continuing =
523 Block(If(Expr(true), Block(Assign(Expr(error_loc, "z"), Expr(2)))));
524 auto* loop_stmt = Loop(body, continuing);
525 WrapInFunction(loop_stmt);
526
527 EXPECT_FALSE(r()->Resolve()) << r()->error();
528 EXPECT_EQ(r()->error(),
529 "12:34 error: continue statement bypasses declaration of 'z' in "
530 "continuing block");
531}
532
533TEST_F(ResolverValidationTest,
534 Stmt_Loop_ContinueInLoopBodySubscopeBeforeDecl_UsageInContinuingLoop) {
535 // loop {
536 // if (true) {
537 // continue; // Still bypasses z decl (if we reach here)
538 // }
539 // var z : i32;
540 // continuing {
541 // loop {
542 // z = 2; // Must fail even if z is in a sub-scope
543 // }
544 // }
545 // }
546
547 auto error_loc = Source{Source::Location{12, 34}};
548 auto* body = Block(If(Expr(true), Block(create<ast::ContinueStatement>())),
549 Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
550
551 auto* continuing = Block(Loop(Block(Assign(Expr(error_loc, "z"), Expr(2)))));
552 auto* loop_stmt = Loop(body, continuing);
553 WrapInFunction(loop_stmt);
554
555 EXPECT_FALSE(r()->Resolve()) << r()->error();
556 EXPECT_EQ(r()->error(),
557 "12:34 error: continue statement bypasses declaration of 'z' in "
558 "continuing block");
559}
560
561TEST_F(ResolverValidationTest,
562 Stmt_Loop_ContinueInNestedLoopBodyBeforeDecl_UsageInContinuing) {
563 // loop {
564 // loop {
565 // continue; // OK: not part of the outer loop
566 // }
567 // var z : i32;
568 //
569 // continuing {
570 // z = 2;
571 // }
572 // }
573
574 auto* inner_loop = Loop(Block(create<ast::ContinueStatement>()));
575 auto* body =
576 Block(inner_loop, Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
577 auto* continuing = Block(Assign(Expr("z"), Expr(2)));
578 auto* loop_stmt = Loop(body, continuing);
579 WrapInFunction(loop_stmt);
580
581 EXPECT_TRUE(r()->Resolve()) << r()->error();
582}
583
584TEST_F(ResolverValidationTest,
585 Stmt_Loop_ContinueInNestedLoopBodyBeforeDecl_UsageInContinuingSubscope) {
586 // loop {
587 // loop {
588 // continue; // OK: not part of the outer loop
589 // }
590 // var z : i32;
591 //
592 // continuing {
593 // if (true) {
594 // z = 2;
595 // }
596 // }
597 // }
598
599 auto* inner_loop = Loop(Block(create<ast::ContinueStatement>()));
600 auto* body =
601 Block(inner_loop, Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
602 auto* continuing = Block(If(Expr(true), Block(Assign(Expr("z"), Expr(2)))));
603 auto* loop_stmt = Loop(body, continuing);
604 WrapInFunction(loop_stmt);
605
606 EXPECT_TRUE(r()->Resolve()) << r()->error();
607}
608
609TEST_F(ResolverValidationTest,
610 Stmt_Loop_ContinueInNestedLoopBodyBeforeDecl_UsageInContinuingLoop) {
611 // loop {
612 // loop {
613 // continue; // OK: not part of the outer loop
614 // }
615 // var z : i32;
616 //
617 // continuing {
618 // loop {
619 // z = 2;
620 // }
621 // }
622 // }
623
624 auto* inner_loop = Loop(Block(create<ast::ContinueStatement>()));
625 auto* body =
626 Block(inner_loop, Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
627 auto* continuing = Block(Loop(Block(Assign(Expr("z"), Expr(2)))));
628 auto* loop_stmt = Loop(body, continuing);
629 WrapInFunction(loop_stmt);
630
631 EXPECT_TRUE(r()->Resolve()) << r()->error();
632}
633
Ben Claytonf4c0d542021-03-10 23:15:09 +0000634TEST_F(ResolverTest, Stmt_Loop_ContinueInLoopBodyAfterDecl_UsageInContinuing) {
635 // loop {
636 // var z : i32;
637 // continue;
638 //
639 // continuing {
640 // z = 2;
641 // }
642 // }
643
644 auto error_loc = Source{Source::Location{12, 34}};
645 auto* body = Block(Decl(Var("z", ty.i32(), ast::StorageClass::kNone)),
646 create<ast::ContinueStatement>());
647 auto* continuing = Block(Assign(Expr(error_loc, "z"), Expr(2)));
648 auto* loop_stmt = Loop(body, continuing);
649 WrapInFunction(loop_stmt);
650
651 EXPECT_TRUE(r()->Resolve());
652}
653
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000654TEST_F(ResolverValidationTest, Stmt_ContinueInLoop) {
655 WrapInFunction(Loop(Block(create<ast::ContinueStatement>(Source{{12, 34}}))));
656 EXPECT_TRUE(r()->Resolve()) << r()->error();
657}
658
659TEST_F(ResolverValidationTest, Stmt_ContinueNotInLoop) {
660 WrapInFunction(create<ast::ContinueStatement>(Source{{12, 34}}));
661 EXPECT_FALSE(r()->Resolve());
662 EXPECT_EQ(r()->error(), "12:34 error: continue statement must be in a loop");
663}
664
665TEST_F(ResolverValidationTest, Stmt_BreakInLoop) {
666 WrapInFunction(Loop(Block(create<ast::BreakStatement>(Source{{12, 34}}))));
667 EXPECT_TRUE(r()->Resolve()) << r()->error();
668}
669
670TEST_F(ResolverValidationTest, Stmt_BreakInSwitch) {
Antonio Maioranocea744d2021-03-25 12:55:27 +0000671 WrapInFunction(Loop(Block(Switch(
672 Expr(1),
673 Case(Literal(1), Block(create<ast::BreakStatement>(Source{{12, 34}}))),
674 DefaultCase()))));
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000675 EXPECT_TRUE(r()->Resolve()) << r()->error();
676}
677
678TEST_F(ResolverValidationTest, Stmt_BreakNotInLoopOrSwitch) {
679 WrapInFunction(create<ast::BreakStatement>(Source{{12, 34}}));
680 EXPECT_FALSE(r()->Resolve());
681 EXPECT_EQ(r()->error(),
682 "12:34 error: break statement must be in a loop or switch case");
683}
684
Ben Claytond614dd52021-03-15 10:43:11 +0000685TEST_F(ResolverValidationTest, NonPOTStructMemberAlignDecoration) {
686 Structure("S", {
687 Member("a", ty.f32(), {MemberAlign(Source{{12, 34}}, 3)}),
688 });
689
690 EXPECT_FALSE(r()->Resolve());
691 EXPECT_EQ(
692 r()->error(),
693 "12:34 error: align value must be a positive, power-of-two integer");
694}
695
696TEST_F(ResolverValidationTest, ZeroStructMemberAlignDecoration) {
697 Structure("S", {
698 Member("a", ty.f32(), {MemberAlign(Source{{12, 34}}, 0)}),
699 });
700
701 EXPECT_FALSE(r()->Resolve());
702 EXPECT_EQ(
703 r()->error(),
704 "12:34 error: align value must be a positive, power-of-two integer");
705}
706
707TEST_F(ResolverValidationTest, ZeroStructMemberSizeDecoration) {
708 Structure("S", {
709 Member("a", ty.f32(), {MemberSize(Source{{12, 34}}, 0)}),
710 });
711
712 EXPECT_FALSE(r()->Resolve());
713 EXPECT_EQ(r()->error(),
714 "12:34 error: size must be at least as big as the type's size (4)");
715}
716
Ben Clayton2f9ced02021-03-15 20:34:22 +0000717TEST_F(ResolverValidationTest, OffsetAndSizeDecoration) {
718 Structure("S", {
719 Member(Source{{12, 34}}, "a", ty.f32(),
720 {MemberOffset(0), MemberSize(4)}),
721 });
722
723 EXPECT_FALSE(r()->Resolve());
724 EXPECT_EQ(r()->error(),
725 "12:34 error: offset decorations cannot be used with align or size "
726 "decorations");
727}
728
729TEST_F(ResolverValidationTest, OffsetAndAlignDecoration) {
730 Structure("S", {
731 Member(Source{{12, 34}}, "a", ty.f32(),
732 {MemberOffset(0), MemberAlign(4)}),
733 });
734
735 EXPECT_FALSE(r()->Resolve());
736 EXPECT_EQ(r()->error(),
737 "12:34 error: offset decorations cannot be used with align or size "
738 "decorations");
739}
740
741TEST_F(ResolverValidationTest, OffsetAndAlignAndSizeDecoration) {
742 Structure("S", {
743 Member(Source{{12, 34}}, "a", ty.f32(),
744 {MemberOffset(0), MemberAlign(4), MemberSize(4)}),
745 });
746
747 EXPECT_FALSE(r()->Resolve());
748 EXPECT_EQ(r()->error(),
749 "12:34 error: offset decorations cannot be used with align or size "
750 "decorations");
751}
752
Arman Uguray3549e2e2021-03-15 21:21:33 +0000753TEST_F(ResolverValidationTest,
754 Expr_Constructor_Vec2F32_Error_ScalarArgumentTypeMismatch) {
755 auto* tc = vec2<f32>(
756 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1)),
757 1.0f);
758 WrapInFunction(tc);
759
760 EXPECT_FALSE(r()->Resolve());
761 EXPECT_EQ(r()->error(),
762 "12:34 error: type in vector constructor does not match vector "
763 "type: expected 'f32', found 'i32'");
764}
765
766TEST_F(ResolverValidationTest,
767 Expr_Constructor_Vec2U32_Error_ScalarArgumentTypeMismatch) {
768 auto* tc = vec2<u32>(1u, create<ast::ScalarConstructorExpression>(
769 Source{{12, 34}}, Literal(1)));
770 WrapInFunction(tc);
771
772 EXPECT_FALSE(r()->Resolve());
773 EXPECT_EQ(r()->error(),
774 "12:34 error: type in vector constructor does not match vector "
775 "type: expected 'u32', found 'i32'");
776}
777
778TEST_F(ResolverValidationTest,
779 Expr_Constructor_Vec2I32_Error_ScalarArgumentTypeMismatch) {
780 auto* tc = vec2<i32>(
781 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1u)),
782 1);
783 WrapInFunction(tc);
784
785 EXPECT_FALSE(r()->Resolve());
786 EXPECT_EQ(r()->error(),
787 "12:34 error: type in vector constructor does not match vector "
788 "type: expected 'i32', found 'u32'");
789}
790
791TEST_F(ResolverValidationTest,
792 Expr_Constructor_Vec2Bool_Error_ScalarArgumentTypeMismatch) {
793 auto* tc = vec2<bool>(true, create<ast::ScalarConstructorExpression>(
794 Source{{12, 34}}, Literal(1)));
795 WrapInFunction(tc);
796
797 EXPECT_FALSE(r()->Resolve());
798 EXPECT_EQ(r()->error(),
799 "12:34 error: type in vector constructor does not match vector "
800 "type: expected 'bool', found 'i32'");
801}
802
803TEST_F(ResolverValidationTest,
804 Expr_Constructor_Vec2_Error_Vec3ArgumentCardinalityTooLarge) {
805 auto* tc = vec2<f32>(create<ast::TypeConstructorExpression>(
806 Source{{12, 34}}, ty.vec3<f32>(), ExprList()));
807 WrapInFunction(tc);
808
809 EXPECT_FALSE(r()->Resolve());
810 EXPECT_EQ(
811 r()->error(),
812 "12:34 error: attempted to construct 'vec2<f32>' with 3 component(s)");
813}
814
815TEST_F(ResolverValidationTest,
816 Expr_Constructor_Vec2_Error_Vec4ArgumentCardinalityTooLarge) {
817 auto* tc = vec2<f32>(create<ast::TypeConstructorExpression>(
818 Source{{12, 34}}, ty.vec4<f32>(), ExprList()));
819 WrapInFunction(tc);
820
821 EXPECT_FALSE(r()->Resolve());
822 EXPECT_EQ(
823 r()->error(),
824 "12:34 error: attempted to construct 'vec2<f32>' with 4 component(s)");
825}
826
827TEST_F(ResolverValidationTest,
828 Expr_Constructor_Vec2_Error_TooFewArgumentsScalar) {
829 auto* tc = vec2<f32>(create<ast::ScalarConstructorExpression>(
830 Source{{12, 34}}, Literal(1.0f)));
831 WrapInFunction(tc);
832
833 EXPECT_FALSE(r()->Resolve());
834 EXPECT_EQ(
835 r()->error(),
836 "12:34 error: attempted to construct 'vec2<f32>' with 1 component(s)");
837}
838
839TEST_F(ResolverValidationTest,
840 Expr_Constructor_Vec2_Error_TooManyArgumentsScalar) {
841 auto* tc = vec2<f32>(
842 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1.0f)),
843 create<ast::ScalarConstructorExpression>(Source{{12, 40}}, Literal(1.0f)),
844 create<ast::ScalarConstructorExpression>(Source{{12, 46}},
845 Literal(1.0f)));
846 WrapInFunction(tc);
847
848 EXPECT_FALSE(r()->Resolve());
849 EXPECT_EQ(
850 r()->error(),
851 "12:34 error: attempted to construct 'vec2<f32>' with 3 component(s)");
852}
853
854TEST_F(ResolverValidationTest,
855 Expr_Constructor_Vec2_Error_TooManyArgumentsVector) {
856 auto* tc = vec2<f32>(create<ast::TypeConstructorExpression>(
857 Source{{12, 34}}, ty.vec2<f32>(), ExprList()),
858 create<ast::TypeConstructorExpression>(
859 Source{{12, 40}}, ty.vec2<f32>(), ExprList()));
860 WrapInFunction(tc);
861
862 EXPECT_FALSE(r()->Resolve());
863 EXPECT_EQ(
864 r()->error(),
865 "12:34 error: attempted to construct 'vec2<f32>' with 4 component(s)");
866}
867
868TEST_F(ResolverValidationTest,
869 Expr_Constructor_Vec2_Error_TooManyArgumentsVectorAndScalar) {
870 auto* tc = vec2<f32>(create<ast::TypeConstructorExpression>(
871 Source{{12, 34}}, ty.vec2<f32>(), ExprList()),
872 create<ast::ScalarConstructorExpression>(
873 Source{{12, 40}}, Literal(1.0f)));
874 WrapInFunction(tc);
875
876 EXPECT_FALSE(r()->Resolve());
877 EXPECT_EQ(
878 r()->error(),
879 "12:34 error: attempted to construct 'vec2<f32>' with 3 component(s)");
880}
881
882TEST_F(ResolverValidationTest,
883 Expr_Constructor_Vec2_Error_InvalidConversionFromVec2Bool) {
884 SetSource(Source::Location({12, 34}));
885
886 auto* tc = vec2<f32>(create<ast::TypeConstructorExpression>(
887 Source{{12, 34}}, ty.vec2<bool>(), ExprList()));
888 WrapInFunction(tc);
889
890 EXPECT_FALSE(r()->Resolve());
891 EXPECT_EQ(r()->error(),
892 "12:34 error: type in vector constructor does not match vector "
893 "type: expected 'f32', found 'bool'");
894}
895
896TEST_F(ResolverValidationTest,
897 Expr_Constructor_Vec2_Error_InvalidArgumentType) {
898 auto* tc = vec2<f32>(create<ast::TypeConstructorExpression>(
899 Source{{12, 34}}, ty.mat2x2<f32>(), ExprList()));
900 WrapInFunction(tc);
901
902 EXPECT_FALSE(r()->Resolve());
903 EXPECT_EQ(r()->error(),
904 "12:34 error: expected vector or scalar type in vector "
905 "constructor; found: mat2x2<f32>");
906}
907
908TEST_F(ResolverValidationTest, Expr_Constructor_Vec2_Success_ZeroValue) {
909 auto* tc = vec2<f32>();
910 WrapInFunction(tc);
911
912 EXPECT_TRUE(r()->Resolve()) << r()->error();
913
914 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +0000915 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
916 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
917 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 2u);
Arman Uguray3549e2e2021-03-15 21:21:33 +0000918}
919
920TEST_F(ResolverValidationTest, Expr_Constructor_Vec2F32_Success_Scalar) {
921 auto* tc = vec2<f32>(1.0f, 1.0f);
922 WrapInFunction(tc);
923
924 EXPECT_TRUE(r()->Resolve()) << r()->error();
925
926 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +0000927 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
928 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
929 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 2u);
Arman Uguray3549e2e2021-03-15 21:21:33 +0000930}
931
932TEST_F(ResolverValidationTest, Expr_Constructor_Vec2U32_Success_Scalar) {
933 auto* tc = vec2<u32>(1u, 1u);
934 WrapInFunction(tc);
935
936 EXPECT_TRUE(r()->Resolve()) << r()->error();
937
938 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +0000939 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
940 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::U32>());
941 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 2u);
Arman Uguray3549e2e2021-03-15 21:21:33 +0000942}
943
944TEST_F(ResolverValidationTest, Expr_Constructor_Vec2I32_Success_Scalar) {
945 auto* tc = vec2<i32>(1, 1);
946 WrapInFunction(tc);
947
948 EXPECT_TRUE(r()->Resolve()) << r()->error();
949
950 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +0000951 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
952 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::I32>());
953 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 2u);
Arman Uguray3549e2e2021-03-15 21:21:33 +0000954}
955
956TEST_F(ResolverValidationTest, Expr_Constructor_Vec2Bool_Success_Scalar) {
957 auto* tc = vec2<bool>(true, false);
958 WrapInFunction(tc);
959
960 EXPECT_TRUE(r()->Resolve()) << r()->error();
961
962 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +0000963 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
964 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::Bool>());
965 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 2u);
Arman Uguray3549e2e2021-03-15 21:21:33 +0000966}
967
968TEST_F(ResolverValidationTest, Expr_Constructor_Vec2_Success_Identity) {
969 auto* tc = vec2<f32>(vec2<f32>());
970 WrapInFunction(tc);
971
972 EXPECT_TRUE(r()->Resolve()) << r()->error();
973
974 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +0000975 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
976 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
977 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 2u);
Arman Uguray3549e2e2021-03-15 21:21:33 +0000978}
979
980TEST_F(ResolverValidationTest,
981 Expr_Constructor_Vec2_Success_Vec2TypeConversion) {
982 auto* tc = vec2<f32>(vec2<i32>());
983 WrapInFunction(tc);
984
985 EXPECT_TRUE(r()->Resolve()) << r()->error();
986
987 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +0000988 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
989 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
990 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 2u);
Arman Uguray3549e2e2021-03-15 21:21:33 +0000991}
992
993TEST_F(ResolverValidationTest,
994 Expr_Constructor_Vec3F32_Error_ScalarArgumentTypeMismatch) {
995 auto* tc = vec3<f32>(
996 1.0f, 1.0f,
997 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1)));
998 WrapInFunction(tc);
999
1000 EXPECT_FALSE(r()->Resolve());
1001 EXPECT_EQ(r()->error(),
1002 "12:34 error: type in vector constructor does not match vector "
1003 "type: expected 'f32', found 'i32'");
1004}
1005
1006TEST_F(ResolverValidationTest,
1007 Expr_Constructor_Vec3U32_Error_ScalarArgumentTypeMismatch) {
1008 auto* tc = vec3<u32>(
1009 1u,
1010 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1)),
1011 1u);
1012 WrapInFunction(tc);
1013
1014 EXPECT_FALSE(r()->Resolve());
1015 EXPECT_EQ(r()->error(),
1016 "12:34 error: type in vector constructor does not match vector "
1017 "type: expected 'u32', found 'i32'");
1018}
1019
1020TEST_F(ResolverValidationTest,
1021 Expr_Constructor_Vec3I32_Error_ScalarArgumentTypeMismatch) {
1022 auto* tc = vec3<i32>(
1023 1,
1024 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1u)),
1025 1);
1026 WrapInFunction(tc);
1027
1028 EXPECT_FALSE(r()->Resolve());
1029 EXPECT_EQ(r()->error(),
1030 "12:34 error: type in vector constructor does not match vector "
1031 "type: expected 'i32', found 'u32'");
1032}
1033
1034TEST_F(ResolverValidationTest,
1035 Expr_Constructor_Vec3Bool_Error_ScalarArgumentTypeMismatch) {
1036 auto* tc = vec3<bool>(
1037 true,
1038 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1)),
1039 false);
1040 WrapInFunction(tc);
1041
1042 EXPECT_FALSE(r()->Resolve());
1043 EXPECT_EQ(r()->error(),
1044 "12:34 error: type in vector constructor does not match vector "
1045 "type: expected 'bool', found 'i32'");
1046}
1047
1048TEST_F(ResolverValidationTest,
1049 Expr_Constructor_Vec3_Error_Vec4ArgumentCardinalityTooLarge) {
1050 auto* tc = vec3<f32>(create<ast::TypeConstructorExpression>(
1051 Source{{12, 34}}, ty.vec4<f32>(), ExprList()));
1052 WrapInFunction(tc);
1053
1054 EXPECT_FALSE(r()->Resolve());
1055 EXPECT_EQ(
1056 r()->error(),
1057 "12:34 error: attempted to construct 'vec3<f32>' with 4 component(s)");
1058}
1059
1060TEST_F(ResolverValidationTest,
1061 Expr_Constructor_Vec3_Error_TooFewArgumentsScalar) {
1062 auto* tc = vec3<f32>(
1063 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1.0f)),
1064 create<ast::ScalarConstructorExpression>(Source{{12, 40}},
1065 Literal(1.0f)));
1066 WrapInFunction(tc);
1067
1068 EXPECT_FALSE(r()->Resolve());
1069 EXPECT_EQ(
1070 r()->error(),
1071 "12:34 error: attempted to construct 'vec3<f32>' with 2 component(s)");
1072}
1073
1074TEST_F(ResolverValidationTest,
1075 Expr_Constructor_Vec3_Error_TooManyArgumentsScalar) {
1076 auto* tc = vec3<f32>(
1077 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1.0f)),
1078 create<ast::ScalarConstructorExpression>(Source{{12, 40}}, Literal(1.0f)),
1079 create<ast::ScalarConstructorExpression>(Source{{12, 46}}, Literal(1.0f)),
1080 create<ast::ScalarConstructorExpression>(Source{{12, 52}},
1081 Literal(1.0f)));
1082 WrapInFunction(tc);
1083
1084 EXPECT_FALSE(r()->Resolve());
1085 EXPECT_EQ(
1086 r()->error(),
1087 "12:34 error: attempted to construct 'vec3<f32>' with 4 component(s)");
1088}
1089
1090TEST_F(ResolverValidationTest,
1091 Expr_Constructor_Vec3_Error_TooFewArgumentsVec2) {
1092 auto* tc = vec3<f32>(create<ast::TypeConstructorExpression>(
1093 Source{{12, 34}}, ty.vec2<f32>(), ExprList()));
1094 WrapInFunction(tc);
1095
1096 EXPECT_FALSE(r()->Resolve());
1097 EXPECT_EQ(
1098 r()->error(),
1099 "12:34 error: attempted to construct 'vec3<f32>' with 2 component(s)");
1100}
1101
1102TEST_F(ResolverValidationTest,
1103 Expr_Constructor_Vec3_Error_TooManyArgumentsVec2) {
1104 auto* tc = vec3<f32>(create<ast::TypeConstructorExpression>(
1105 Source{{12, 34}}, ty.vec2<f32>(), ExprList()),
1106 create<ast::TypeConstructorExpression>(
1107 Source{{12, 40}}, ty.vec2<f32>(), ExprList()));
1108 WrapInFunction(tc);
1109
1110 EXPECT_FALSE(r()->Resolve());
1111 EXPECT_EQ(
1112 r()->error(),
1113 "12:34 error: attempted to construct 'vec3<f32>' with 4 component(s)");
1114}
1115
1116TEST_F(ResolverValidationTest,
1117 Expr_Constructor_Vec3_Error_TooManyArgumentsVec2AndScalar) {
1118 auto* tc = vec3<f32>(
1119 create<ast::TypeConstructorExpression>(Source{{12, 34}}, ty.vec2<f32>(),
1120 ExprList()),
1121 create<ast::ScalarConstructorExpression>(Source{{12, 40}}, Literal(1.0f)),
1122 create<ast::ScalarConstructorExpression>(Source{{12, 46}},
1123 Literal(1.0f)));
1124 WrapInFunction(tc);
1125
1126 EXPECT_FALSE(r()->Resolve());
1127 EXPECT_EQ(
1128 r()->error(),
1129 "12:34 error: attempted to construct 'vec3<f32>' with 4 component(s)");
1130}
1131
1132TEST_F(ResolverValidationTest,
1133 Expr_Constructor_Vec3_Error_TooManyArgumentsVec3) {
1134 auto* tc = vec3<f32>(create<ast::TypeConstructorExpression>(
1135 Source{{12, 34}}, ty.vec3<f32>(), ExprList()),
1136 create<ast::ScalarConstructorExpression>(
1137 Source{{12, 40}}, Literal(1.0f)));
1138 WrapInFunction(tc);
1139
1140 EXPECT_FALSE(r()->Resolve());
1141 EXPECT_EQ(
1142 r()->error(),
1143 "12:34 error: attempted to construct 'vec3<f32>' with 4 component(s)");
1144}
1145
1146TEST_F(ResolverValidationTest,
1147 Expr_Constructor_Vec3_Error_InvalidConversionFromVec3Bool) {
1148 auto* tc = vec3<f32>(create<ast::TypeConstructorExpression>(
1149 Source{{12, 34}}, ty.vec3<bool>(), ExprList()));
1150 WrapInFunction(tc);
1151
1152 EXPECT_FALSE(r()->Resolve());
1153 EXPECT_EQ(r()->error(),
1154 "12:34 error: type in vector constructor does not match vector "
1155 "type: expected 'f32', found 'bool'");
1156}
1157
1158TEST_F(ResolverValidationTest,
1159 Expr_Constructor_Vec3_Error_InvalidArgumentType) {
1160 auto* tc = vec3<f32>(create<ast::TypeConstructorExpression>(
1161 Source{{12, 34}}, ty.mat2x2<f32>(), ExprList()));
1162 WrapInFunction(tc);
1163
1164 EXPECT_FALSE(r()->Resolve());
1165 EXPECT_EQ(r()->error(),
1166 "12:34 error: expected vector or scalar type in vector "
1167 "constructor; found: mat2x2<f32>");
1168}
1169
1170TEST_F(ResolverValidationTest, Expr_Constructor_Vec3_Success_ZeroValue) {
1171 auto* tc = vec3<f32>();
1172 WrapInFunction(tc);
1173
1174 EXPECT_TRUE(r()->Resolve()) << r()->error();
1175
1176 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001177 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1178 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1179 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001180}
1181
1182TEST_F(ResolverValidationTest, Expr_Constructor_Vec3F32_Success_Scalar) {
1183 auto* tc = vec3<f32>(1.0f, 1.0f, 1.0f);
1184 WrapInFunction(tc);
1185
1186 EXPECT_TRUE(r()->Resolve()) << r()->error();
1187
1188 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001189 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1190 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1191 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001192}
1193
1194TEST_F(ResolverValidationTest, Expr_Constructor_Vec3U32_Success_Scalar) {
1195 auto* tc = vec3<u32>(1u, 1u, 1u);
1196 WrapInFunction(tc);
1197
1198 EXPECT_TRUE(r()->Resolve()) << r()->error();
1199
1200 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001201 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1202 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::U32>());
1203 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001204}
1205
1206TEST_F(ResolverValidationTest, Expr_Constructor_Vec3I32_Success_Scalar) {
1207 auto* tc = vec3<i32>(1, 1, 1);
1208 WrapInFunction(tc);
1209
1210 EXPECT_TRUE(r()->Resolve()) << r()->error();
1211
1212 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001213 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1214 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::I32>());
1215 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001216}
1217
1218TEST_F(ResolverValidationTest, Expr_Constructor_Vec3Bool_Success_Scalar) {
1219 auto* tc = vec3<bool>(true, false, true);
1220 WrapInFunction(tc);
1221
1222 EXPECT_TRUE(r()->Resolve()) << r()->error();
1223
1224 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001225 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1226 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::Bool>());
1227 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001228}
1229
1230TEST_F(ResolverValidationTest, Expr_Constructor_Vec3_Success_Vec2AndScalar) {
1231 auto* tc = vec3<f32>(vec2<f32>(), 1.0f);
1232 WrapInFunction(tc);
1233
1234 EXPECT_TRUE(r()->Resolve()) << r()->error();
1235
1236 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001237 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1238 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1239 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001240}
1241
1242TEST_F(ResolverValidationTest, Expr_Constructor_Vec3_Success_ScalarAndVec2) {
1243 auto* tc = vec3<f32>(1.0f, vec2<f32>());
1244 WrapInFunction(tc);
1245
1246 EXPECT_TRUE(r()->Resolve()) << r()->error();
1247
1248 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001249 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1250 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1251 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001252}
1253
1254TEST_F(ResolverValidationTest, Expr_Constructor_Vec3_Success_Identity) {
1255 auto* tc = vec3<f32>(vec3<f32>());
1256 WrapInFunction(tc);
1257
1258 EXPECT_TRUE(r()->Resolve()) << r()->error();
1259
1260 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001261 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1262 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1263 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001264}
1265
1266TEST_F(ResolverValidationTest,
1267 Expr_Constructor_Vec3_Success_Vec3TypeConversion) {
1268 auto* tc = vec3<f32>(vec3<i32>());
1269 WrapInFunction(tc);
1270
1271 EXPECT_TRUE(r()->Resolve()) << r()->error();
1272
1273 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001274 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1275 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1276 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001277}
1278
1279TEST_F(ResolverValidationTest,
1280 Expr_Constructor_Vec4F32_Error_ScalarArgumentTypeMismatch) {
1281 auto* tc = vec4<f32>(
1282 1.0f, 1.0f,
1283 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1)),
1284 1.0f);
1285 WrapInFunction(tc);
1286
1287 EXPECT_FALSE(r()->Resolve());
1288 EXPECT_EQ(r()->error(),
1289 "12:34 error: type in vector constructor does not match vector "
1290 "type: expected 'f32', found 'i32'");
1291}
1292
1293TEST_F(ResolverValidationTest,
1294 Expr_Constructor_Vec4U32_Error_ScalarArgumentTypeMismatch) {
1295 auto* tc = vec4<u32>(
1296 1u, 1u,
1297 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1)),
1298 1u);
1299 WrapInFunction(tc);
1300
1301 EXPECT_FALSE(r()->Resolve());
1302 EXPECT_EQ(r()->error(),
1303 "12:34 error: type in vector constructor does not match vector "
1304 "type: expected 'u32', found 'i32'");
1305}
1306
1307TEST_F(ResolverValidationTest,
1308 Expr_Constructor_Vec4I32_Error_ScalarArgumentTypeMismatch) {
1309 auto* tc = vec4<i32>(
1310 1, 1,
1311 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1u)),
1312 1);
1313 WrapInFunction(tc);
1314
1315 EXPECT_FALSE(r()->Resolve());
1316 EXPECT_EQ(r()->error(),
1317 "12:34 error: type in vector constructor does not match vector "
1318 "type: expected 'i32', found 'u32'");
1319}
1320
1321TEST_F(ResolverValidationTest,
1322 Expr_Constructor_Vec4Bool_Error_ScalarArgumentTypeMismatch) {
1323 auto* tc = vec4<bool>(
1324 true, false,
1325 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1)),
1326 true);
1327 WrapInFunction(tc);
1328
1329 EXPECT_FALSE(r()->Resolve());
1330 EXPECT_EQ(r()->error(),
1331 "12:34 error: type in vector constructor does not match vector "
1332 "type: expected 'bool', found 'i32'");
1333}
1334
1335TEST_F(ResolverValidationTest,
1336 Expr_Constructor_Vec4_Error_TooFewArgumentsScalar) {
1337 auto* tc = vec4<f32>(
1338 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1.0f)),
1339 create<ast::ScalarConstructorExpression>(Source{{12, 40}}, Literal(1.0f)),
1340 create<ast::ScalarConstructorExpression>(Source{{12, 46}},
1341 Literal(1.0f)));
1342 WrapInFunction(tc);
1343
1344 EXPECT_FALSE(r()->Resolve());
1345 EXPECT_EQ(
1346 r()->error(),
1347 "12:34 error: attempted to construct 'vec4<f32>' with 3 component(s)");
1348}
1349
1350TEST_F(ResolverValidationTest,
1351 Expr_Constructor_Vec4_Error_TooManyArgumentsScalar) {
1352 auto* tc = vec4<f32>(
1353 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1.0f)),
1354 create<ast::ScalarConstructorExpression>(Source{{12, 40}}, Literal(1.0f)),
1355 create<ast::ScalarConstructorExpression>(Source{{12, 46}}, Literal(1.0f)),
1356 create<ast::ScalarConstructorExpression>(Source{{12, 52}}, Literal(1.0f)),
1357 create<ast::ScalarConstructorExpression>(Source{{12, 58}},
1358 Literal(1.0f)));
1359 WrapInFunction(tc);
1360
1361 EXPECT_FALSE(r()->Resolve());
1362 EXPECT_EQ(
1363 r()->error(),
1364 "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
1365}
1366
1367TEST_F(ResolverValidationTest,
1368 Expr_Constructor_Vec4_Error_TooFewArgumentsVec2AndScalar) {
1369 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1370 Source{{12, 34}}, ty.vec2<f32>(), ExprList()),
1371 create<ast::ScalarConstructorExpression>(
1372 Source{{12, 40}}, Literal(1.0f)));
1373 WrapInFunction(tc);
1374
1375 EXPECT_FALSE(r()->Resolve());
1376 EXPECT_EQ(
1377 r()->error(),
1378 "12:34 error: attempted to construct 'vec4<f32>' with 3 component(s)");
1379}
1380
1381TEST_F(ResolverValidationTest,
1382 Expr_Constructor_Vec4_Error_TooManyArgumentsVec2AndScalars) {
1383 auto* tc = vec4<f32>(
1384 create<ast::TypeConstructorExpression>(Source{{12, 34}}, ty.vec2<f32>(),
1385 ExprList()),
1386 create<ast::ScalarConstructorExpression>(Source{{12, 40}}, Literal(1.0f)),
1387 create<ast::ScalarConstructorExpression>(Source{{12, 46}}, Literal(1.0f)),
1388 create<ast::ScalarConstructorExpression>(Source{{12, 52}},
1389 Literal(1.0f)));
1390 WrapInFunction(tc);
1391
1392 EXPECT_FALSE(r()->Resolve());
1393 EXPECT_EQ(
1394 r()->error(),
1395 "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
1396}
1397
1398TEST_F(ResolverValidationTest,
1399 Expr_Constructor_Vec4_Error_TooManyArgumentsVec2Vec2Scalar) {
1400 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1401 Source{{12, 34}}, ty.vec2<f32>(), ExprList()),
1402 create<ast::TypeConstructorExpression>(
1403 Source{{12, 40}}, ty.vec2<f32>(), ExprList()),
1404 create<ast::ScalarConstructorExpression>(
1405 Source{{12, 46}}, Literal(1.0f)));
1406 WrapInFunction(tc);
1407
1408 EXPECT_FALSE(r()->Resolve());
1409 EXPECT_EQ(
1410 r()->error(),
1411 "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
1412}
1413
1414TEST_F(ResolverValidationTest,
1415 Expr_Constructor_Vec4_Error_TooManyArgumentsVec2Vec2Vec2) {
1416 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1417 Source{{12, 34}}, ty.vec2<f32>(), ExprList()),
1418 create<ast::TypeConstructorExpression>(
1419 Source{{12, 40}}, ty.vec2<f32>(), ExprList()),
1420 create<ast::TypeConstructorExpression>(
1421 Source{{12, 40}}, ty.vec2<f32>(), ExprList()));
1422 WrapInFunction(tc);
1423
1424 EXPECT_FALSE(r()->Resolve());
1425 EXPECT_EQ(
1426 r()->error(),
1427 "12:34 error: attempted to construct 'vec4<f32>' with 6 component(s)");
1428}
1429
1430TEST_F(ResolverValidationTest,
1431 Expr_Constructor_Vec4_Error_TooFewArgumentsVec3) {
1432 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1433 Source{{12, 34}}, ty.vec3<f32>(), ExprList()));
1434 WrapInFunction(tc);
1435
1436 EXPECT_FALSE(r()->Resolve());
1437 EXPECT_EQ(
1438 r()->error(),
1439 "12:34 error: attempted to construct 'vec4<f32>' with 3 component(s)");
1440}
1441
1442TEST_F(ResolverValidationTest,
1443 Expr_Constructor_Vec4_Error_TooManyArgumentsVec3AndScalars) {
1444 auto* tc = vec4<f32>(
1445 create<ast::TypeConstructorExpression>(Source{{12, 34}}, ty.vec3<f32>(),
1446 ExprList()),
1447 create<ast::ScalarConstructorExpression>(Source{{12, 40}}, Literal(1.0f)),
1448 create<ast::ScalarConstructorExpression>(Source{{12, 46}},
1449 Literal(1.0f)));
1450 WrapInFunction(tc);
1451
1452 EXPECT_FALSE(r()->Resolve());
1453 EXPECT_EQ(
1454 r()->error(),
1455 "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
1456}
1457
1458TEST_F(ResolverValidationTest,
1459 Expr_Constructor_Vec4_Error_TooManyArgumentsVec3AndVec2) {
1460 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1461 Source{{12, 34}}, ty.vec3<f32>(), ExprList()),
1462 create<ast::TypeConstructorExpression>(
1463 Source{{12, 40}}, ty.vec2<f32>(), ExprList()));
1464 WrapInFunction(tc);
1465
1466 EXPECT_FALSE(r()->Resolve());
1467 EXPECT_EQ(
1468 r()->error(),
1469 "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
1470}
1471
1472TEST_F(ResolverValidationTest,
1473 Expr_Constructor_Vec4_Error_TooManyArgumentsVec2AndVec3) {
1474 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1475 Source{{12, 34}}, ty.vec2<f32>(), ExprList()),
1476 create<ast::TypeConstructorExpression>(
1477 Source{{12, 40}}, ty.vec3<f32>(), ExprList()));
1478 WrapInFunction(tc);
1479
1480 EXPECT_FALSE(r()->Resolve());
1481 EXPECT_EQ(
1482 r()->error(),
1483 "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
1484}
1485
1486TEST_F(ResolverValidationTest,
1487 Expr_Constructor_Vec4_Error_TooManyArgumentsVec3AndVec3) {
1488 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1489 Source{{12, 34}}, ty.vec3<f32>(), ExprList()),
1490 create<ast::TypeConstructorExpression>(
1491 Source{{12, 40}}, ty.vec3<f32>(), ExprList()));
1492 WrapInFunction(tc);
1493
1494 EXPECT_FALSE(r()->Resolve());
1495 EXPECT_EQ(
1496 r()->error(),
1497 "12:34 error: attempted to construct 'vec4<f32>' with 6 component(s)");
1498}
1499
1500TEST_F(ResolverValidationTest,
1501 Expr_Constructor_Vec4_Error_InvalidConversionFromVec4Bool) {
1502 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1503 Source{{12, 34}}, ty.vec4<bool>(), ExprList()));
1504 WrapInFunction(tc);
1505
1506 EXPECT_FALSE(r()->Resolve());
1507 EXPECT_EQ(r()->error(),
1508 "12:34 error: type in vector constructor does not match vector "
1509 "type: expected 'f32', found 'bool'");
1510}
1511
1512TEST_F(ResolverValidationTest,
1513 Expr_Constructor_Vec4_Error_InvalidArgumentType) {
1514 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1515 Source{{12, 34}}, ty.mat2x2<f32>(), ExprList()));
1516 WrapInFunction(tc);
1517
1518 EXPECT_FALSE(r()->Resolve());
1519 EXPECT_EQ(r()->error(),
1520 "12:34 error: expected vector or scalar type in vector "
1521 "constructor; found: mat2x2<f32>");
1522}
1523
1524TEST_F(ResolverValidationTest, Expr_Constructor_Vec4_Success_ZeroValue) {
1525 auto* tc = vec4<f32>();
1526 WrapInFunction(tc);
1527
1528 EXPECT_TRUE(r()->Resolve()) << r()->error();
1529
1530 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001531 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1532 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1533 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001534}
1535
1536TEST_F(ResolverValidationTest, Expr_Constructor_Vec4F32_Success_Scalar) {
1537 auto* tc = vec4<f32>(1.0f, 1.0f, 1.0f, 1.0f);
1538 WrapInFunction(tc);
1539
1540 EXPECT_TRUE(r()->Resolve()) << r()->error();
1541
1542 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001543 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1544 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1545 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001546}
1547
1548TEST_F(ResolverValidationTest, Expr_Constructor_Vec4U32_Success_Scalar) {
1549 auto* tc = vec4<u32>(1u, 1u, 1u, 1u);
1550 WrapInFunction(tc);
1551
1552 EXPECT_TRUE(r()->Resolve()) << r()->error();
1553
1554 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001555 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1556 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::U32>());
1557 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001558}
1559
1560TEST_F(ResolverValidationTest, Expr_Constructor_Vec4I32_Success_Scalar) {
1561 auto* tc = vec4<i32>(1, 1, 1, 1);
1562 WrapInFunction(tc);
1563
1564 EXPECT_TRUE(r()->Resolve()) << r()->error();
1565
1566 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001567 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1568 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::I32>());
1569 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001570}
1571
1572TEST_F(ResolverValidationTest, Expr_Constructor_Vec4Bool_Success_Scalar) {
1573 auto* tc = vec4<bool>(true, false, true, false);
1574 WrapInFunction(tc);
1575
1576 EXPECT_TRUE(r()->Resolve()) << r()->error();
1577
1578 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001579 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1580 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::Bool>());
1581 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001582}
1583
1584TEST_F(ResolverValidationTest, Expr_Constructor_Vec4_Success_Vec2ScalarScalar) {
1585 auto* tc = vec4<f32>(vec2<f32>(), 1.0f, 1.0f);
1586 WrapInFunction(tc);
1587
1588 EXPECT_TRUE(r()->Resolve()) << r()->error();
1589
1590 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001591 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1592 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1593 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001594}
1595
1596TEST_F(ResolverValidationTest, Expr_Constructor_Vec4_Success_ScalarVec2Scalar) {
1597 auto* tc = vec4<f32>(1.0f, vec2<f32>(), 1.0f);
1598 WrapInFunction(tc);
1599
1600 EXPECT_TRUE(r()->Resolve()) << r()->error();
1601
1602 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001603 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1604 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1605 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001606}
1607
1608TEST_F(ResolverValidationTest, Expr_Constructor_Vec4_Success_ScalarScalarVec2) {
1609 auto* tc = vec4<f32>(1.0f, 1.0f, vec2<f32>());
1610 WrapInFunction(tc);
1611
1612 EXPECT_TRUE(r()->Resolve()) << r()->error();
1613
1614 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001615 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1616 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1617 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001618}
1619
1620TEST_F(ResolverValidationTest, Expr_Constructor_Vec4_Success_Vec2AndVec2) {
1621 auto* tc = vec4<f32>(vec2<f32>(), vec2<f32>());
1622 WrapInFunction(tc);
1623
1624 EXPECT_TRUE(r()->Resolve()) << r()->error();
1625
1626 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001627 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1628 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1629 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001630}
1631
1632TEST_F(ResolverValidationTest, Expr_Constructor_Vec4_Success_Vec3AndScalar) {
1633 auto* tc = vec4<f32>(vec3<f32>(), 1.0f);
1634 WrapInFunction(tc);
1635
1636 EXPECT_TRUE(r()->Resolve()) << r()->error();
1637
1638 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001639 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1640 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1641 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001642}
1643
1644TEST_F(ResolverValidationTest, Expr_Constructor_Vec4_Success_ScalarAndVec3) {
1645 auto* tc = vec4<f32>(1.0f, vec3<f32>());
1646 WrapInFunction(tc);
1647
1648 EXPECT_TRUE(r()->Resolve()) << r()->error();
1649
1650 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001651 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1652 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1653 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001654}
1655
1656TEST_F(ResolverValidationTest, Expr_Constructor_Vec4_Success_Identity) {
1657 auto* tc = vec4<f32>(vec4<f32>());
1658 WrapInFunction(tc);
1659
1660 EXPECT_TRUE(r()->Resolve()) << r()->error();
1661
1662 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001663 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1664 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1665 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001666}
1667
1668TEST_F(ResolverValidationTest,
1669 Expr_Constructor_Vec4_Success_Vec4TypeConversion) {
1670 auto* tc = vec4<f32>(vec4<i32>());
1671 WrapInFunction(tc);
1672
1673 EXPECT_TRUE(r()->Resolve()) << r()->error();
1674
1675 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001676 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1677 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1678 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001679}
1680
1681TEST_F(ResolverValidationTest,
1682 Expr_Constructor_NestedVectorConstructors_InnerError) {
1683 auto* tc = vec4<f32>(
1684 vec3<f32>(1.0f, vec2<f32>(create<ast::ScalarConstructorExpression>(
1685 Source{{12, 34}}, Literal(1.0f)))),
1686 1.0f);
1687 WrapInFunction(tc);
1688
1689 EXPECT_FALSE(r()->Resolve());
1690 EXPECT_EQ(
1691 r()->error(),
1692 "12:34 error: attempted to construct 'vec2<f32>' with 1 component(s)");
1693}
1694
1695TEST_F(ResolverValidationTest,
1696 Expr_Constructor_NestedVectorConstructors_Success) {
1697 auto* tc = vec4<f32>(vec3<f32>(vec2<f32>(1.0f, 1.0f), 1.0f), 1.0f);
1698 WrapInFunction(tc);
1699
1700 EXPECT_TRUE(r()->Resolve()) << r()->error();
1701
1702 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001703 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1704 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1705 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001706}
1707
1708TEST_F(ResolverValidationTest, Expr_Constructor_Vector_Alias_Argument_Error) {
1709 auto* alias = ty.alias("UnsignedInt", ty.u32());
Antonio Maioranobbbb0ed2021-04-06 20:18:57 +00001710 Global("uint_var", alias, ast::StorageClass::kInput);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001711
1712 auto* tc = vec2<f32>(Expr(Source{{12, 34}}, "uint_var"));
1713 WrapInFunction(tc);
1714
1715 EXPECT_FALSE(r()->Resolve());
1716 EXPECT_EQ(r()->error(),
1717 "12:34 error: type in vector constructor does not match vector "
1718 "type: expected 'f32', found 'u32'");
1719}
1720
1721TEST_F(ResolverValidationTest, Expr_Constructor_Vector_Alias_Argument_Success) {
1722 auto* f32_alias = ty.alias("Float32", ty.f32());
1723 auto* vec2_alias = ty.alias("VectorFloat2", ty.vec2<f32>());
Antonio Maioranobbbb0ed2021-04-06 20:18:57 +00001724 Global("my_f32", f32_alias, ast::StorageClass::kInput);
1725 Global("my_vec2", vec2_alias, ast::StorageClass::kInput);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001726
1727 auto* tc = vec3<f32>("my_vec2", "my_f32");
1728 WrapInFunction(tc);
1729 EXPECT_TRUE(r()->Resolve()) << r()->error();
1730}
1731
1732TEST_F(ResolverValidationTest, Expr_Constructor_Vector_ElementTypeAlias_Error) {
1733 auto* f32_alias = ty.alias("Float32", ty.f32());
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001734 auto* vec_type = create<sem::Vector>(f32_alias, 2);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001735
1736 // vec2<Float32>(1.0f, 1u)
1737 auto* tc = create<ast::TypeConstructorExpression>(
1738 Source{{12, 34}}, vec_type,
1739 ExprList(1.0f, create<ast::ScalarConstructorExpression>(Source{{12, 40}},
1740 Literal(1u))));
1741 WrapInFunction(tc);
1742
1743 EXPECT_FALSE(r()->Resolve());
1744 EXPECT_EQ(r()->error(),
1745 "12:40 error: type in vector constructor does not match vector "
1746 "type: expected 'f32', found 'u32'");
1747}
1748
1749TEST_F(ResolverValidationTest,
1750 Expr_Constructor_Vector_ElementTypeAlias_Success) {
1751 auto* f32_alias = ty.alias("Float32", ty.f32());
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001752 auto* vec_type = create<sem::Vector>(f32_alias, 2);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001753
1754 // vec2<Float32>(1.0f, 1.0f)
1755 auto* tc = create<ast::TypeConstructorExpression>(Source{{12, 34}}, vec_type,
1756 ExprList(1.0f, 1.0f));
1757 WrapInFunction(tc);
1758
1759 EXPECT_TRUE(r()->Resolve()) << r()->error();
1760}
1761
1762TEST_F(ResolverValidationTest,
1763 Expr_Constructor_Vector_ArgumentElementTypeAlias_Error) {
1764 auto* f32_alias = ty.alias("Float32", ty.f32());
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001765 auto* vec_type = create<sem::Vector>(f32_alias, 2);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001766
1767 // vec3<u32>(vec<Float32>(), 1.0f)
1768 auto* tc = vec3<u32>(create<ast::TypeConstructorExpression>(
1769 Source{{12, 34}}, vec_type, ExprList()),
1770 1.0f);
1771 WrapInFunction(tc);
1772
1773 EXPECT_FALSE(r()->Resolve());
1774 EXPECT_EQ(r()->error(),
1775 "12:34 error: type in vector constructor does not match vector "
1776 "type: expected 'u32', found 'f32'");
1777}
1778
1779TEST_F(ResolverValidationTest,
1780 Expr_Constructor_Vector_ArgumentElementTypeAlias_Success) {
1781 auto* f32_alias = ty.alias("Float32", ty.f32());
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001782 auto* vec_type = create<sem::Vector>(f32_alias, 2);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001783
1784 // vec3<f32>(vec<Float32>(), 1.0f)
1785 auto* tc = vec3<f32>(create<ast::TypeConstructorExpression>(
1786 Source{{12, 34}}, vec_type, ExprList()),
1787 1.0f);
1788 WrapInFunction(tc);
1789
1790 EXPECT_TRUE(r()->Resolve()) << r()->error();
1791}
1792
Arman Uguray097c75a2021-03-18 15:43:14 +00001793struct MatrixDimensions {
1794 uint32_t rows;
1795 uint32_t columns;
1796};
1797
1798std::string MatrixStr(const MatrixDimensions& dimensions,
1799 std::string subtype = "f32") {
1800 return "mat" + std::to_string(dimensions.columns) + "x" +
1801 std::to_string(dimensions.rows) + "<" + subtype + ">";
1802}
1803
1804std::string VecStr(uint32_t dimensions, std::string subtype = "f32") {
1805 return "vec" + std::to_string(dimensions) + "<" + subtype + ">";
1806}
1807
1808using MatrixConstructorTest = ResolverTestWithParam<MatrixDimensions>;
1809
1810TEST_P(MatrixConstructorTest, Expr_Constructor_Error_TooFewArguments) {
1811 // matNxM<f32>(vecM<f32>(), ...); with N - 1 arguments
1812
1813 const auto param = GetParam();
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001814 auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns);
1815 auto* vec_type = create<sem::Vector>(ty.f32(), param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00001816
1817 ast::ExpressionList args;
1818 for (uint32_t i = 1; i <= param.columns - 1; i++) {
1819 args.push_back(create<ast::TypeConstructorExpression>(
1820 Source{{12, i}}, vec_type, ExprList()));
1821 }
1822
1823 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
1824 std::move(args));
1825 WrapInFunction(tc);
1826
1827 EXPECT_FALSE(r()->Resolve());
1828 EXPECT_EQ(r()->error(),
1829 "12:1 error: expected " + std::to_string(param.columns) + " '" +
1830 VecStr(param.rows) + "' arguments in '" + MatrixStr(param) +
1831 "' constructor, found " + std::to_string(param.columns - 1));
1832}
1833
1834TEST_P(MatrixConstructorTest, Expr_Constructor_Error_TooManyArguments) {
1835 // matNxM<f32>(vecM<f32>(), ...); with N + 1 arguments
1836
1837 const auto param = GetParam();
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001838 auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns);
1839 auto* vec_type = create<sem::Vector>(ty.f32(), param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00001840
1841 ast::ExpressionList args;
1842 for (uint32_t i = 1; i <= param.columns + 1; i++) {
1843 args.push_back(create<ast::TypeConstructorExpression>(
1844 Source{{12, i}}, vec_type, ExprList()));
1845 }
1846
1847 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
1848 std::move(args));
1849 WrapInFunction(tc);
1850
1851 EXPECT_FALSE(r()->Resolve());
1852 EXPECT_EQ(r()->error(),
1853 "12:1 error: expected " + std::to_string(param.columns) + " '" +
1854 VecStr(param.rows) + "' arguments in '" + MatrixStr(param) +
1855 "' constructor, found " + std::to_string(param.columns + 1));
1856}
1857
1858TEST_P(MatrixConstructorTest, Expr_Constructor_Error_InvalidArgumentType) {
1859 // matNxM<f32>(1.0, 1.0, ...); N arguments
1860
1861 const auto param = GetParam();
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001862 auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns);
Arman Uguray097c75a2021-03-18 15:43:14 +00001863
1864 ast::ExpressionList args;
1865 for (uint32_t i = 1; i <= param.columns; i++) {
1866 args.push_back(create<ast::ScalarConstructorExpression>(Source{{12, i}},
1867 Literal(1.0f)));
1868 }
1869
1870 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
1871 std::move(args));
1872 WrapInFunction(tc);
1873
1874 EXPECT_FALSE(r()->Resolve());
1875 EXPECT_EQ(r()->error(), "12:1 error: expected argument type '" +
1876 VecStr(param.rows) + "' in '" + MatrixStr(param) +
1877 "' constructor, found 'f32'");
1878}
1879
1880TEST_P(MatrixConstructorTest,
1881 Expr_Constructor_Error_TooFewRowsInVectorArgument) {
1882 // matNxM<f32>(vecM<f32>(),...,vecM-1<f32>());
1883
1884 const auto param = GetParam();
1885
1886 // Skip the test if parameters would have resuled in an invalid vec1 type.
1887 if (param.rows == 2) {
1888 return;
1889 }
1890
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001891 auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns);
1892 auto* valid_vec_type = create<sem::Vector>(ty.f32(), param.rows);
1893 auto* invalid_vec_type = create<sem::Vector>(ty.f32(), param.rows - 1);
Arman Uguray097c75a2021-03-18 15:43:14 +00001894
1895 ast::ExpressionList args;
1896 for (uint32_t i = 1; i <= param.columns - 1; i++) {
1897 args.push_back(create<ast::TypeConstructorExpression>(
1898 Source{{12, i}}, valid_vec_type, ExprList()));
1899 }
1900 const size_t kInvalidLoc = 2 * (param.columns - 1);
1901 args.push_back(create<ast::TypeConstructorExpression>(
1902 Source{{12, kInvalidLoc}}, invalid_vec_type, ExprList()));
1903
1904 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
1905 std::move(args));
1906 WrapInFunction(tc);
1907
1908 EXPECT_FALSE(r()->Resolve());
1909 EXPECT_EQ(r()->error(), "12:" + std::to_string(kInvalidLoc) +
1910 " error: expected argument type '" +
1911 VecStr(param.rows) + "' in '" + MatrixStr(param) +
1912 "' constructor, found '" +
1913 VecStr(param.rows - 1) + "'");
1914}
1915
1916TEST_P(MatrixConstructorTest,
1917 Expr_Constructor_Error_TooManyRowsInVectorArgument) {
1918 // matNxM<f32>(vecM<f32>(),...,vecM+1<f32>());
1919
1920 const auto param = GetParam();
1921
1922 // Skip the test if parameters would have resuled in an invalid vec5 type.
1923 if (param.rows == 4) {
1924 return;
1925 }
1926
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001927 auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns);
1928 auto* valid_vec_type = create<sem::Vector>(ty.f32(), param.rows);
1929 auto* invalid_vec_type = create<sem::Vector>(ty.f32(), param.rows + 1);
Arman Uguray097c75a2021-03-18 15:43:14 +00001930
1931 ast::ExpressionList args;
1932 for (uint32_t i = 1; i <= param.columns - 1; i++) {
1933 args.push_back(create<ast::TypeConstructorExpression>(
1934 Source{{12, i}}, valid_vec_type, ExprList()));
1935 }
1936 const size_t kInvalidLoc = 2 * (param.columns - 1);
1937 args.push_back(create<ast::TypeConstructorExpression>(
1938 Source{{12, kInvalidLoc}}, invalid_vec_type, ExprList()));
1939
1940 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
1941 std::move(args));
1942 WrapInFunction(tc);
1943
1944 EXPECT_FALSE(r()->Resolve());
1945 EXPECT_EQ(r()->error(), "12:" + std::to_string(kInvalidLoc) +
1946 " error: expected argument type '" +
1947 VecStr(param.rows) + "' in '" + MatrixStr(param) +
1948 "' constructor, found '" +
1949 VecStr(param.rows + 1) + "'");
1950}
1951
1952TEST_P(MatrixConstructorTest,
1953 Expr_Constructor_Error_ArgumentVectorElementTypeMismatch) {
1954 // matNxM<f32>(vecM<u32>(), ...); with N arguments
1955
1956 const auto param = GetParam();
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001957 auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns);
1958 auto* vec_type = create<sem::Vector>(ty.u32(), param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00001959
1960 ast::ExpressionList args;
1961 for (uint32_t i = 1; i <= param.columns; i++) {
1962 args.push_back(create<ast::TypeConstructorExpression>(
1963 Source{{12, i}}, vec_type, ExprList()));
1964 }
1965
1966 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
1967 std::move(args));
1968 WrapInFunction(tc);
1969
1970 EXPECT_FALSE(r()->Resolve());
1971 EXPECT_EQ(r()->error(), "12:1 error: expected argument type '" +
1972 VecStr(param.rows) + "' in '" + MatrixStr(param) +
1973 "' constructor, found '" +
1974 VecStr(param.rows, "u32") + "'");
1975}
1976
1977TEST_P(MatrixConstructorTest, Expr_Constructor_ZeroValue_Success) {
1978 // matNxM<f32>();
1979
1980 const auto param = GetParam();
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001981 auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns);
Arman Uguray097c75a2021-03-18 15:43:14 +00001982 auto* tc = create<ast::TypeConstructorExpression>(Source{{12, 40}},
1983 matrix_type, ExprList());
1984 WrapInFunction(tc);
1985
1986 EXPECT_TRUE(r()->Resolve()) << r()->error();
1987}
1988
1989TEST_P(MatrixConstructorTest, Expr_Constructor_WithArguments_Success) {
1990 // matNxM<f32>(vecM<f32>(), ...); with N arguments
1991
1992 const auto param = GetParam();
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001993 auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns);
1994 auto* vec_type = create<sem::Vector>(ty.f32(), param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00001995
1996 ast::ExpressionList args;
1997 for (uint32_t i = 1; i <= param.columns; i++) {
1998 args.push_back(create<ast::TypeConstructorExpression>(
1999 Source{{12, i}}, vec_type, ExprList()));
2000 }
2001
2002 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
2003 std::move(args));
2004 WrapInFunction(tc);
2005
2006 EXPECT_TRUE(r()->Resolve()) << r()->error();
2007}
2008
2009TEST_P(MatrixConstructorTest, Expr_Constructor_ElementTypeAlias_Error) {
2010 // matNxM<Float32>(vecM<u32>(), ...); with N arguments
2011
2012 const auto param = GetParam();
2013 auto* f32_alias = ty.alias("Float32", ty.f32());
Antonio Maiorano3751fd22021-04-19 22:51:23 +00002014 auto* matrix_type = create<sem::Matrix>(f32_alias, param.rows, param.columns);
2015 auto* vec_type = create<sem::Vector>(ty.u32(), param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00002016
2017 ast::ExpressionList args;
2018 for (uint32_t i = 1; i <= param.columns; i++) {
2019 args.push_back(create<ast::TypeConstructorExpression>(
2020 Source{{12, i}}, vec_type, ExprList()));
2021 }
2022
2023 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
2024 std::move(args));
2025 WrapInFunction(tc);
2026
2027 EXPECT_FALSE(r()->Resolve());
2028 EXPECT_EQ(r()->error(),
2029 "12:1 error: expected argument type '" + VecStr(param.rows) +
2030 "' in '" + MatrixStr(param, "Float32") +
2031 "' constructor, found '" + VecStr(param.rows, "u32") + "'");
2032}
2033
2034TEST_P(MatrixConstructorTest, Expr_Constructor_ElementTypeAlias_Success) {
2035 // matNxM<Float32>(vecM<f32>(), ...); with N arguments
2036
2037 const auto param = GetParam();
2038 auto* f32_alias = ty.alias("Float32", ty.f32());
Antonio Maiorano3751fd22021-04-19 22:51:23 +00002039 auto* matrix_type = create<sem::Matrix>(f32_alias, param.rows, param.columns);
2040 auto* vec_type = create<sem::Vector>(ty.f32(), param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00002041
2042 ast::ExpressionList args;
2043 for (uint32_t i = 1; i <= param.columns; i++) {
2044 args.push_back(create<ast::TypeConstructorExpression>(
2045 Source{{12, i}}, vec_type, ExprList()));
2046 }
2047
2048 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
2049 std::move(args));
2050 WrapInFunction(tc);
2051
2052 EXPECT_TRUE(r()->Resolve()) << r()->error();
2053}
2054
2055TEST_F(ResolverValidationTest, Expr_MatrixConstructor_ArgumentTypeAlias_Error) {
2056 auto* vec2_alias = ty.alias("VectorUnsigned2", ty.vec2<u32>());
2057 auto* tc = mat2x2<f32>(create<ast::TypeConstructorExpression>(
2058 Source{{12, 34}}, vec2_alias, ExprList()),
2059 vec2<f32>());
2060 WrapInFunction(tc);
2061
2062 EXPECT_FALSE(r()->Resolve());
2063 EXPECT_EQ(r()->error(),
2064 "12:34 error: expected argument type 'vec2<f32>' in 'mat2x2<f32>' "
2065 "constructor, found 'vec2<u32>'");
2066}
2067
2068TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentTypeAlias_Success) {
2069 const auto param = GetParam();
Antonio Maiorano3751fd22021-04-19 22:51:23 +00002070 auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns);
2071 auto* vec_type = create<sem::Vector>(ty.f32(), param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00002072 auto* vec_alias = ty.alias("VectorFloat2", vec_type);
2073
2074 ast::ExpressionList args;
2075 for (uint32_t i = 1; i <= param.columns; i++) {
2076 args.push_back(create<ast::TypeConstructorExpression>(
2077 Source{{12, i}}, vec_alias, ExprList()));
2078 }
2079
2080 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
2081 std::move(args));
2082 WrapInFunction(tc);
2083
2084 EXPECT_TRUE(r()->Resolve()) << r()->error();
2085}
2086
2087TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentElementTypeAlias_Error) {
2088 const auto param = GetParam();
Antonio Maiorano3751fd22021-04-19 22:51:23 +00002089 auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns);
Arman Uguray097c75a2021-03-18 15:43:14 +00002090 auto* f32_alias = ty.alias("UnsignedInt", ty.u32());
Antonio Maiorano3751fd22021-04-19 22:51:23 +00002091 auto* vec_type = create<sem::Vector>(f32_alias, param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00002092
2093 ast::ExpressionList args;
2094 for (uint32_t i = 1; i <= param.columns; i++) {
2095 args.push_back(create<ast::TypeConstructorExpression>(
2096 Source{{12, i}}, vec_type, ExprList()));
2097 }
2098
2099 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
2100 std::move(args));
2101 WrapInFunction(tc);
2102
2103 EXPECT_FALSE(r()->Resolve());
2104 EXPECT_EQ(r()->error(), "12:1 error: expected argument type '" +
2105 VecStr(param.rows) + "' in '" + MatrixStr(param) +
2106 "' constructor, found '" +
2107 VecStr(param.rows, "UnsignedInt") + "'");
2108}
2109
2110TEST_P(MatrixConstructorTest,
2111 Expr_Constructor_ArgumentElementTypeAlias_Success) {
2112 const auto param = GetParam();
Antonio Maiorano3751fd22021-04-19 22:51:23 +00002113 auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns);
Arman Uguray097c75a2021-03-18 15:43:14 +00002114 auto* f32_alias = ty.alias("Float32", ty.f32());
Antonio Maiorano3751fd22021-04-19 22:51:23 +00002115 auto* vec_type = create<sem::Vector>(f32_alias, param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00002116
2117 ast::ExpressionList args;
2118 for (uint32_t i = 1; i <= param.columns; i++) {
2119 args.push_back(create<ast::TypeConstructorExpression>(
2120 Source{{12, i}}, vec_type, ExprList()));
2121 }
2122
2123 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
2124 std::move(args));
2125 WrapInFunction(tc);
2126
2127 EXPECT_TRUE(r()->Resolve()) << r()->error();
2128}
2129
2130INSTANTIATE_TEST_SUITE_P(ResolverValidationTest,
2131 MatrixConstructorTest,
2132 testing::Values(MatrixDimensions{2, 2},
2133 MatrixDimensions{3, 2},
2134 MatrixDimensions{4, 2},
2135 MatrixDimensions{2, 3},
2136 MatrixDimensions{3, 3},
2137 MatrixDimensions{4, 3},
2138 MatrixDimensions{2, 4},
2139 MatrixDimensions{3, 4},
2140 MatrixDimensions{4, 4}));
2141
Ben Clayton2c41f4f2021-03-09 15:12:57 +00002142} // namespace
2143} // namespace resolver
2144} // namespace tint