blob: eadc0bcc3edfd147d426f51e09e65013606e382b [file] [log] [blame]
dan sinclairb7edc4c2020-04-07 12:46:30 +00001// Copyright 2020 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
Ben Clayton5f0ea112021-03-09 10:54:37 +000015#include "src/resolver/resolver.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000016
Antonio Maioranobe0fc4e2021-03-16 13:26:03 +000017#include <tuple>
18
Ben Clayton47c4d182021-02-10 21:42:35 +000019#include "gmock/gmock.h"
dan sinclair6c498fc2020-04-07 12:47:23 +000020#include "src/ast/assignment_statement.h"
dan sinclaira7d498e2020-09-22 22:07:13 +000021#include "src/ast/bitcast_expression.h"
Ben Clayton9430cb42021-03-09 15:06:37 +000022#include "src/ast/break_statement.h"
dan sinclair50080b72020-07-21 13:42:13 +000023#include "src/ast/call_statement.h"
dan sinclairaec965e2020-04-07 12:54:29 +000024#include "src/ast/continue_statement.h"
dan sinclair91c44a52020-04-07 12:55:25 +000025#include "src/ast/if_statement.h"
Ben Clayton3ea3c992020-11-18 21:19:22 +000026#include "src/ast/intrinsic_texture_helper_test.h"
dan sinclairbc71eda2020-04-07 12:55:51 +000027#include "src/ast/loop_statement.h"
dan sinclairbf0fff82020-04-07 12:56:24 +000028#include "src/ast/return_statement.h"
dan sinclair05926432020-09-21 17:51:31 +000029#include "src/ast/stage_decoration.h"
dan sinclair18b32852020-04-07 12:56:45 +000030#include "src/ast/switch_statement.h"
dan sinclair327ed1b2020-04-07 19:27:21 +000031#include "src/ast/unary_op_expression.h"
dan sinclairca893e32020-04-07 12:57:12 +000032#include "src/ast/variable_decl_statement.h"
Ben Clayton786cea42021-03-09 15:10:27 +000033#include "src/resolver/resolver_test_helper.h"
Ben Clayton1618f4b2021-02-03 21:02:25 +000034#include "src/semantic/call.h"
Ben Clayton87c78dd2021-02-03 16:43:20 +000035#include "src/semantic/function.h"
Ben Clayton6d612ad2021-02-24 14:15:02 +000036#include "src/semantic/member_accessor_expression.h"
Ben Claytonf97b9c92021-02-16 18:45:45 +000037#include "src/semantic/statement.h"
Ben Claytonb17aea12021-02-03 17:51:09 +000038#include "src/semantic/variable.h"
Ben Claytonfaca02d2021-02-10 21:34:25 +000039#include "src/type/access_control_type.h"
Ben Clayton207b5e22021-01-21 15:42:10 +000040#include "src/type/sampled_texture_type.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000041
Ben Clayton6d612ad2021-02-24 14:15:02 +000042using ::testing::ElementsAre;
Ben Clayton47c4d182021-02-10 21:42:35 +000043using ::testing::HasSubstr;
44
dan sinclairb7edc4c2020-04-07 12:46:30 +000045namespace tint {
Ben Claytonc7dcbae2021-03-09 15:08:48 +000046namespace resolver {
dan sinclairb7edc4c2020-04-07 12:46:30 +000047namespace {
48
Ben Clayton1222c152021-03-16 21:58:23 +000049// Helpers and typedefs
50using i32 = ProgramBuilder::i32;
51using u32 = ProgramBuilder::u32;
52using f32 = ProgramBuilder::f32;
53using Op = ast::BinaryOp;
54
Ben Clayton5f0ea112021-03-09 10:54:37 +000055TEST_F(ResolverTest, Stmt_Assign) {
Ben Clayton6b2fc052021-03-18 21:14:44 +000056 auto* v = Var("v", ty.f32(), ast::StorageClass::kFunction);
57 auto* lhs = Expr("v");
Ben Clayton7eaf4b52020-12-14 22:08:27 +000058 auto* rhs = Expr(2.3f);
dan sinclair6c498fc2020-04-07 12:47:23 +000059
Ben Clayton7eaf4b52020-12-14 22:08:27 +000060 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
Ben Clayton6b2fc052021-03-18 21:14:44 +000061 WrapInFunction(v, assign);
dan sinclair6c498fc2020-04-07 12:47:23 +000062
Ben Clayton5f0ea112021-03-09 10:54:37 +000063 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +000064
Ben Clayton33352542021-01-29 16:43:41 +000065 ASSERT_NE(TypeOf(lhs), nullptr);
66 ASSERT_NE(TypeOf(rhs), nullptr);
dan sinclair6c498fc2020-04-07 12:47:23 +000067
Ben Clayton6b2fc052021-03-18 21:14:44 +000068 EXPECT_TRUE(TypeOf(lhs)->UnwrapAll()->Is<type::F32>());
Ben Clayton33352542021-01-29 16:43:41 +000069 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +000070 EXPECT_EQ(StmtOf(lhs), assign);
71 EXPECT_EQ(StmtOf(rhs), assign);
dan sinclair6c498fc2020-04-07 12:47:23 +000072}
73
Ben Clayton5f0ea112021-03-09 10:54:37 +000074TEST_F(ResolverTest, Stmt_Case) {
Ben Clayton6b2fc052021-03-18 21:14:44 +000075 auto* v = Var("v", ty.f32(), ast::StorageClass::kFunction);
76 auto* lhs = Expr("v");
Ben Clayton7eaf4b52020-12-14 22:08:27 +000077 auto* rhs = Expr(2.3f);
dan sinclair6010b292020-04-07 12:54:20 +000078
Ben Claytonf97b9c92021-02-16 18:45:45 +000079 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
Ben Claytondba65b72021-03-31 20:35:46 +000080 auto* block = Block(assign);
dan sinclair1aadbd42020-06-01 16:56:46 +000081 ast::CaseSelectorList lit;
Ben Clayton8d391f72021-01-26 16:57:10 +000082 lit.push_back(create<ast::SintLiteral>(ty.i32(), 3));
Ben Claytondba65b72021-03-31 20:35:46 +000083 auto* cse = create<ast::CaseStatement>(lit, block);
Ben Clayton6b2fc052021-03-18 21:14:44 +000084 WrapInFunction(v, cse);
dan sinclair6010b292020-04-07 12:54:20 +000085
Ben Clayton5f0ea112021-03-09 10:54:37 +000086 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +000087
Ben Clayton33352542021-01-29 16:43:41 +000088 ASSERT_NE(TypeOf(lhs), nullptr);
89 ASSERT_NE(TypeOf(rhs), nullptr);
Ben Clayton6b2fc052021-03-18 21:14:44 +000090 EXPECT_TRUE(TypeOf(lhs)->UnwrapAll()->Is<type::F32>());
Ben Clayton33352542021-01-29 16:43:41 +000091 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +000092 EXPECT_EQ(StmtOf(lhs), assign);
93 EXPECT_EQ(StmtOf(rhs), assign);
Ben Claytondba65b72021-03-31 20:35:46 +000094 EXPECT_EQ(BlockOf(assign), block);
dan sinclair6010b292020-04-07 12:54:20 +000095}
96
Ben Clayton5f0ea112021-03-09 10:54:37 +000097TEST_F(ResolverTest, Stmt_Block) {
Ben Clayton6b2fc052021-03-18 21:14:44 +000098 auto* v = Var("v", ty.f32(), ast::StorageClass::kFunction);
99 auto* lhs = Expr("v");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000100 auto* rhs = Expr(2.3f);
dan sinclair0975dd52020-07-27 15:25:00 +0000101
Ben Claytonf97b9c92021-02-16 18:45:45 +0000102 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
Ben Clayton6b2fc052021-03-18 21:14:44 +0000103 auto* block = Block(assign);
104 WrapInFunction(v, block);
dan sinclair0975dd52020-07-27 15:25:00 +0000105
Ben Clayton5f0ea112021-03-09 10:54:37 +0000106 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000107
Ben Clayton33352542021-01-29 16:43:41 +0000108 ASSERT_NE(TypeOf(lhs), nullptr);
109 ASSERT_NE(TypeOf(rhs), nullptr);
Ben Clayton6b2fc052021-03-18 21:14:44 +0000110 EXPECT_TRUE(TypeOf(lhs)->UnwrapAll()->Is<type::F32>());
Ben Clayton33352542021-01-29 16:43:41 +0000111 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +0000112 EXPECT_EQ(StmtOf(lhs), assign);
113 EXPECT_EQ(StmtOf(rhs), assign);
Ben Claytondba65b72021-03-31 20:35:46 +0000114 EXPECT_EQ(BlockOf(lhs), block);
115 EXPECT_EQ(BlockOf(rhs), block);
116 EXPECT_EQ(BlockOf(assign), block);
dan sinclair0cf685f2020-04-07 12:54:37 +0000117}
118
Ben Clayton5f0ea112021-03-09 10:54:37 +0000119TEST_F(ResolverTest, Stmt_If) {
Ben Clayton6b2fc052021-03-18 21:14:44 +0000120 auto* v = Var("v", ty.f32(), ast::StorageClass::kFunction);
121 auto* else_lhs = Expr("v");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000122 auto* else_rhs = Expr(2.3f);
dan sinclair91c44a52020-04-07 12:55:25 +0000123
Ben Clayton6b2fc052021-03-18 21:14:44 +0000124 auto* else_body = Block(create<ast::AssignmentStatement>(else_lhs, else_rhs));
dan sinclair91c44a52020-04-07 12:55:25 +0000125
Ben Claytonf97b9c92021-02-16 18:45:45 +0000126 auto* else_cond = Expr(3);
127 auto* else_stmt = create<ast::ElseStatement>(else_cond, else_body);
dan sinclair91c44a52020-04-07 12:55:25 +0000128
Ben Clayton6b2fc052021-03-18 21:14:44 +0000129 auto* lhs = Expr("v");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000130 auto* rhs = Expr(2.3f);
dan sinclair91c44a52020-04-07 12:55:25 +0000131
Ben Claytonf97b9c92021-02-16 18:45:45 +0000132 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
Ben Clayton6b2fc052021-03-18 21:14:44 +0000133 auto* body = Block(assign);
Ben Clayton5fb87dd2021-03-09 15:17:28 +0000134 auto* cond = Expr(true);
Ben Claytonf97b9c92021-02-16 18:45:45 +0000135 auto* stmt =
136 create<ast::IfStatement>(cond, body, ast::ElseStatementList{else_stmt});
Ben Clayton6b2fc052021-03-18 21:14:44 +0000137 WrapInFunction(v, stmt);
dan sinclair91c44a52020-04-07 12:55:25 +0000138
Ben Clayton5f0ea112021-03-09 10:54:37 +0000139 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000140
Ben Clayton33352542021-01-29 16:43:41 +0000141 ASSERT_NE(TypeOf(stmt->condition()), nullptr);
142 ASSERT_NE(TypeOf(else_lhs), nullptr);
143 ASSERT_NE(TypeOf(else_rhs), nullptr);
144 ASSERT_NE(TypeOf(lhs), nullptr);
145 ASSERT_NE(TypeOf(rhs), nullptr);
Ben Clayton5fb87dd2021-03-09 15:17:28 +0000146 EXPECT_TRUE(TypeOf(stmt->condition())->Is<type::Bool>());
Ben Clayton6b2fc052021-03-18 21:14:44 +0000147 EXPECT_TRUE(TypeOf(else_lhs)->UnwrapAll()->Is<type::F32>());
Ben Clayton33352542021-01-29 16:43:41 +0000148 EXPECT_TRUE(TypeOf(else_rhs)->Is<type::F32>());
Ben Clayton6b2fc052021-03-18 21:14:44 +0000149 EXPECT_TRUE(TypeOf(lhs)->UnwrapAll()->Is<type::F32>());
Ben Clayton33352542021-01-29 16:43:41 +0000150 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +0000151 EXPECT_EQ(StmtOf(lhs), assign);
152 EXPECT_EQ(StmtOf(rhs), assign);
153 EXPECT_EQ(StmtOf(cond), stmt);
154 EXPECT_EQ(StmtOf(else_cond), else_stmt);
Ben Claytondba65b72021-03-31 20:35:46 +0000155 EXPECT_EQ(BlockOf(lhs), body);
156 EXPECT_EQ(BlockOf(rhs), body);
157 EXPECT_EQ(BlockOf(else_lhs), else_body);
158 EXPECT_EQ(BlockOf(else_rhs), else_body);
dan sinclair91c44a52020-04-07 12:55:25 +0000159}
160
Ben Clayton5f0ea112021-03-09 10:54:37 +0000161TEST_F(ResolverTest, Stmt_Loop) {
Ben Clayton6b2fc052021-03-18 21:14:44 +0000162 auto* v = Var("v", ty.f32(), ast::StorageClass::kFunction);
163 auto* body_lhs = Expr("v");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000164 auto* body_rhs = Expr(2.3f);
dan sinclairbc71eda2020-04-07 12:55:51 +0000165
Ben Clayton6b2fc052021-03-18 21:14:44 +0000166 auto* body = Block(create<ast::AssignmentStatement>(body_lhs, body_rhs));
167 auto* continuing_lhs = Expr("v");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000168 auto* continuing_rhs = Expr(2.3f);
dan sinclairbc71eda2020-04-07 12:55:51 +0000169
Ben Clayton6b2fc052021-03-18 21:14:44 +0000170 auto* continuing = create<ast::BlockStatement>(ast::StatementList{
171 create<ast::AssignmentStatement>(continuing_lhs, continuing_rhs),
172 });
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000173 auto* stmt = create<ast::LoopStatement>(body, continuing);
Ben Clayton6b2fc052021-03-18 21:14:44 +0000174 WrapInFunction(v, stmt);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000175
Ben Clayton5f0ea112021-03-09 10:54:37 +0000176 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000177
Ben Clayton33352542021-01-29 16:43:41 +0000178 ASSERT_NE(TypeOf(body_lhs), nullptr);
179 ASSERT_NE(TypeOf(body_rhs), nullptr);
180 ASSERT_NE(TypeOf(continuing_lhs), nullptr);
181 ASSERT_NE(TypeOf(continuing_rhs), nullptr);
Ben Clayton6b2fc052021-03-18 21:14:44 +0000182 EXPECT_TRUE(TypeOf(body_lhs)->UnwrapAll()->Is<type::F32>());
Ben Clayton33352542021-01-29 16:43:41 +0000183 EXPECT_TRUE(TypeOf(body_rhs)->Is<type::F32>());
Ben Clayton6b2fc052021-03-18 21:14:44 +0000184 EXPECT_TRUE(TypeOf(continuing_lhs)->UnwrapAll()->Is<type::F32>());
Ben Clayton33352542021-01-29 16:43:41 +0000185 EXPECT_TRUE(TypeOf(continuing_rhs)->Is<type::F32>());
Ben Claytondba65b72021-03-31 20:35:46 +0000186 EXPECT_EQ(BlockOf(body_lhs), body);
187 EXPECT_EQ(BlockOf(body_rhs), body);
188 EXPECT_EQ(BlockOf(continuing_lhs), continuing);
189 EXPECT_EQ(BlockOf(continuing_rhs), continuing);
dan sinclairbc71eda2020-04-07 12:55:51 +0000190}
191
Ben Clayton5f0ea112021-03-09 10:54:37 +0000192TEST_F(ResolverTest, Stmt_Return) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000193 auto* cond = Expr(2);
dan sinclairbf0fff82020-04-07 12:56:24 +0000194
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000195 auto* ret = create<ast::ReturnStatement>(cond);
Antonio Maiorano2e974352021-03-22 23:20:17 +0000196 Func("test", {}, ty.i32(), {ret}, {});
dan sinclairbf0fff82020-04-07 12:56:24 +0000197
Ben Clayton5f0ea112021-03-09 10:54:37 +0000198 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000199
Ben Clayton33352542021-01-29 16:43:41 +0000200 ASSERT_NE(TypeOf(cond), nullptr);
201 EXPECT_TRUE(TypeOf(cond)->Is<type::I32>());
dan sinclairbf0fff82020-04-07 12:56:24 +0000202}
203
Ben Clayton5f0ea112021-03-09 10:54:37 +0000204TEST_F(ResolverTest, Stmt_Return_WithoutValue) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000205 auto* ret = create<ast::ReturnStatement>();
Ben Clayton401b96b2021-02-03 17:19:59 +0000206 WrapInFunction(ret);
207
Ben Clayton5f0ea112021-03-09 10:54:37 +0000208 EXPECT_TRUE(r()->Resolve()) << r()->error();
dan sinclair327ed1b2020-04-07 19:27:21 +0000209}
210
Ben Clayton5f0ea112021-03-09 10:54:37 +0000211TEST_F(ResolverTest, Stmt_Switch) {
Ben Clayton6b2fc052021-03-18 21:14:44 +0000212 auto* v = Var("v", ty.f32(), ast::StorageClass::kFunction);
213 auto* lhs = Expr("v");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000214 auto* rhs = Expr(2.3f);
Ben Claytondba65b72021-03-31 20:35:46 +0000215 auto* case_block = Block(Assign(lhs, rhs));
216 auto* stmt = Switch(Expr(2), Case(Literal(3), case_block), DefaultCase());
Ben Clayton6b2fc052021-03-18 21:14:44 +0000217 WrapInFunction(v, stmt);
dan sinclair18b32852020-04-07 12:56:45 +0000218
Ben Clayton5f0ea112021-03-09 10:54:37 +0000219 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000220
Ben Clayton33352542021-01-29 16:43:41 +0000221 ASSERT_NE(TypeOf(stmt->condition()), nullptr);
222 ASSERT_NE(TypeOf(lhs), nullptr);
223 ASSERT_NE(TypeOf(rhs), nullptr);
dan sinclair18b32852020-04-07 12:56:45 +0000224
Ben Clayton33352542021-01-29 16:43:41 +0000225 EXPECT_TRUE(TypeOf(stmt->condition())->Is<type::I32>());
Ben Clayton6b2fc052021-03-18 21:14:44 +0000226 EXPECT_TRUE(TypeOf(lhs)->UnwrapAll()->Is<type::F32>());
Ben Clayton33352542021-01-29 16:43:41 +0000227 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
Ben Claytondba65b72021-03-31 20:35:46 +0000228 EXPECT_EQ(BlockOf(lhs), case_block);
229 EXPECT_EQ(BlockOf(rhs), case_block);
dan sinclair18b32852020-04-07 12:56:45 +0000230}
231
Ben Clayton5f0ea112021-03-09 10:54:37 +0000232TEST_F(ResolverTest, Stmt_Call) {
dan sinclair50080b72020-07-21 13:42:13 +0000233 ast::VariableList params;
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000234 Func("my_func", params, ty.f32(), ast::StatementList{Return(Expr(0.0f))},
James Price95d40772021-03-11 17:39:32 +0000235 ast::DecorationList{});
dan sinclair50080b72020-07-21 13:42:13 +0000236
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000237 auto* expr = Call("my_func");
dan sinclair50080b72020-07-21 13:42:13 +0000238
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000239 auto* call = create<ast::CallStatement>(expr);
Ben Clayton401b96b2021-02-03 17:19:59 +0000240 WrapInFunction(call);
241
Ben Clayton5f0ea112021-03-09 10:54:37 +0000242 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000243
Ben Clayton33352542021-01-29 16:43:41 +0000244 ASSERT_NE(TypeOf(expr), nullptr);
245 EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +0000246 EXPECT_EQ(StmtOf(expr), call);
dan sinclair50080b72020-07-21 13:42:13 +0000247}
248
Ben Clayton5f0ea112021-03-09 10:54:37 +0000249TEST_F(ResolverTest, Stmt_VariableDecl) {
Ben Clayton81a29fe2021-02-17 00:26:52 +0000250 auto* var = Var("my_var", ty.i32(), ast::StorageClass::kNone, Expr(2));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000251 auto* init = var->constructor();
dan sinclairca893e32020-04-07 12:57:12 +0000252
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000253 auto* decl = create<ast::VariableDeclStatement>(var);
Ben Clayton401b96b2021-02-03 17:19:59 +0000254 WrapInFunction(decl);
dan sinclairca893e32020-04-07 12:57:12 +0000255
Ben Clayton5f0ea112021-03-09 10:54:37 +0000256 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000257
Ben Clayton33352542021-01-29 16:43:41 +0000258 ASSERT_NE(TypeOf(init), nullptr);
259 EXPECT_TRUE(TypeOf(init)->Is<type::I32>());
dan sinclairca893e32020-04-07 12:57:12 +0000260}
261
Ben Clayton5f0ea112021-03-09 10:54:37 +0000262TEST_F(ResolverTest, Stmt_VariableDecl_Alias) {
Antonio Maiorano6ce2edf2021-02-26 18:25:56 +0000263 auto* my_int = ty.alias("MyInt", ty.i32());
264 auto* var = Var("my_var", my_int, ast::StorageClass::kNone, Expr(2));
265 auto* init = var->constructor();
266
267 auto* decl = create<ast::VariableDeclStatement>(var);
268 WrapInFunction(decl);
269
Ben Clayton5f0ea112021-03-09 10:54:37 +0000270 EXPECT_TRUE(r()->Resolve()) << r()->error();
Antonio Maiorano6ce2edf2021-02-26 18:25:56 +0000271
272 ASSERT_NE(TypeOf(init), nullptr);
273 EXPECT_TRUE(TypeOf(init)->Is<type::I32>());
274}
275
Ben Clayton5f0ea112021-03-09 10:54:37 +0000276TEST_F(ResolverTest, Stmt_VariableDecl_ModuleScope) {
Ben Claytonf97b9c92021-02-16 18:45:45 +0000277 auto* init = Expr(2);
Ben Clayton81a29fe2021-02-17 00:26:52 +0000278 Global("my_var", ty.i32(), ast::StorageClass::kNone, init);
dan sinclair7be237a2020-06-15 20:55:09 +0000279
Ben Clayton5f0ea112021-03-09 10:54:37 +0000280 EXPECT_TRUE(r()->Resolve()) << r()->error();
dan sinclair7be237a2020-06-15 20:55:09 +0000281
Ben Clayton33352542021-01-29 16:43:41 +0000282 ASSERT_NE(TypeOf(init), nullptr);
283 EXPECT_TRUE(TypeOf(init)->Is<type::I32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +0000284 EXPECT_EQ(StmtOf(init), nullptr);
dan sinclair7be237a2020-06-15 20:55:09 +0000285}
286
Ben Clayton5f0ea112021-03-09 10:54:37 +0000287TEST_F(ResolverTest, Stmt_VariableDecl_OuterScopeAfterInnerScope) {
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000288 // fn func_i32() -> void {
James Price77f4f022021-02-04 16:33:20 +0000289 // {
290 // var foo : i32 = 2;
291 // var bar : i32 = foo;
292 // }
293 // var foo : f32 = 2.0;
294 // var bar : f32 = foo;
295 // }
296
297 ast::VariableList params;
298
299 // Declare i32 "foo" inside a block
Ben Clayton81a29fe2021-02-17 00:26:52 +0000300 auto* foo_i32 = Var("foo", ty.i32(), ast::StorageClass::kNone, Expr(2));
James Price77f4f022021-02-04 16:33:20 +0000301 auto* foo_i32_init = foo_i32->constructor();
302 auto* foo_i32_decl = create<ast::VariableDeclStatement>(foo_i32);
303
304 // Reference "foo" inside the block
Ben Clayton81a29fe2021-02-17 00:26:52 +0000305 auto* bar_i32 = Var("bar", ty.i32(), ast::StorageClass::kNone, Expr("foo"));
James Price77f4f022021-02-04 16:33:20 +0000306 auto* bar_i32_init = bar_i32->constructor();
307 auto* bar_i32_decl = create<ast::VariableDeclStatement>(bar_i32);
308
309 auto* inner = create<ast::BlockStatement>(
310 ast::StatementList{foo_i32_decl, bar_i32_decl});
311
312 // Declare f32 "foo" at function scope
Ben Clayton81a29fe2021-02-17 00:26:52 +0000313 auto* foo_f32 = Var("foo", ty.f32(), ast::StorageClass::kNone, Expr(2.f));
James Price77f4f022021-02-04 16:33:20 +0000314 auto* foo_f32_init = foo_f32->constructor();
315 auto* foo_f32_decl = create<ast::VariableDeclStatement>(foo_f32);
316
317 // Reference "foo" at function scope
Ben Clayton81a29fe2021-02-17 00:26:52 +0000318 auto* bar_f32 = Var("bar", ty.f32(), ast::StorageClass::kNone, Expr("foo"));
James Price77f4f022021-02-04 16:33:20 +0000319 auto* bar_f32_init = bar_f32->constructor();
320 auto* bar_f32_decl = create<ast::VariableDeclStatement>(bar_f32);
321
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000322 Func("func", params, ty.void_(),
James Price77f4f022021-02-04 16:33:20 +0000323 ast::StatementList{inner, foo_f32_decl, bar_f32_decl},
James Price95d40772021-03-11 17:39:32 +0000324 ast::DecorationList{});
James Price77f4f022021-02-04 16:33:20 +0000325
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000326 EXPECT_TRUE(r()->Resolve()) << r()->error();
James Price77f4f022021-02-04 16:33:20 +0000327 ASSERT_NE(TypeOf(foo_i32_init), nullptr);
328 EXPECT_TRUE(TypeOf(foo_i32_init)->Is<type::I32>());
329 ASSERT_NE(TypeOf(foo_f32_init), nullptr);
330 EXPECT_TRUE(TypeOf(foo_f32_init)->Is<type::F32>());
331 ASSERT_NE(TypeOf(bar_i32_init), nullptr);
332 EXPECT_TRUE(TypeOf(bar_i32_init)->UnwrapAll()->Is<type::I32>());
333 ASSERT_NE(TypeOf(bar_f32_init), nullptr);
334 EXPECT_TRUE(TypeOf(bar_f32_init)->UnwrapAll()->Is<type::F32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +0000335 EXPECT_EQ(StmtOf(foo_i32_init), foo_i32_decl);
336 EXPECT_EQ(StmtOf(bar_i32_init), bar_i32_decl);
337 EXPECT_EQ(StmtOf(foo_f32_init), foo_f32_decl);
338 EXPECT_EQ(StmtOf(bar_f32_init), bar_f32_decl);
James Pricec9af5972021-02-16 21:15:01 +0000339 EXPECT_TRUE(CheckVarUsers(foo_i32, {bar_i32->constructor()}));
340 EXPECT_TRUE(CheckVarUsers(foo_f32, {bar_f32->constructor()}));
James Price77f4f022021-02-04 16:33:20 +0000341}
342
Ben Clayton5f0ea112021-03-09 10:54:37 +0000343TEST_F(ResolverTest, Stmt_VariableDecl_ModuleScopeAfterFunctionScope) {
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000344 // fn func_i32() -> void {
James Price77f4f022021-02-04 16:33:20 +0000345 // var foo : i32 = 2;
346 // }
347 // var foo : f32 = 2.0;
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000348 // fn func_f32() -> void {
James Price77f4f022021-02-04 16:33:20 +0000349 // var bar : f32 = foo;
350 // }
351
352 ast::VariableList params;
353
354 // Declare i32 "foo" inside a function
Ben Clayton81a29fe2021-02-17 00:26:52 +0000355 auto* fn_i32 = Var("foo", ty.i32(), ast::StorageClass::kNone, Expr(2));
James Price77f4f022021-02-04 16:33:20 +0000356 auto* fn_i32_init = fn_i32->constructor();
357 auto* fn_i32_decl = create<ast::VariableDeclStatement>(fn_i32);
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000358 Func("func_i32", params, ty.void_(), ast::StatementList{fn_i32_decl},
James Price95d40772021-03-11 17:39:32 +0000359 ast::DecorationList{});
James Price77f4f022021-02-04 16:33:20 +0000360
361 // Declare f32 "foo" at module scope
Ben Clayton81a29fe2021-02-17 00:26:52 +0000362 auto* mod_f32 = Var("foo", ty.f32(), ast::StorageClass::kNone, Expr(2.f));
James Price77f4f022021-02-04 16:33:20 +0000363 auto* mod_init = mod_f32->constructor();
364 AST().AddGlobalVariable(mod_f32);
365
366 // Reference "foo" in another function
Ben Clayton81a29fe2021-02-17 00:26:52 +0000367 auto* fn_f32 = Var("bar", ty.f32(), ast::StorageClass::kNone, Expr("foo"));
James Price77f4f022021-02-04 16:33:20 +0000368 auto* fn_f32_init = fn_f32->constructor();
369 auto* fn_f32_decl = create<ast::VariableDeclStatement>(fn_f32);
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000370 Func("func_f32", params, ty.void_(), ast::StatementList{fn_f32_decl},
James Price95d40772021-03-11 17:39:32 +0000371 ast::DecorationList{});
James Price77f4f022021-02-04 16:33:20 +0000372
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000373 EXPECT_TRUE(r()->Resolve()) << r()->error();
James Price77f4f022021-02-04 16:33:20 +0000374 ASSERT_NE(TypeOf(mod_init), nullptr);
375 EXPECT_TRUE(TypeOf(mod_init)->Is<type::F32>());
376 ASSERT_NE(TypeOf(fn_i32_init), nullptr);
377 EXPECT_TRUE(TypeOf(fn_i32_init)->Is<type::I32>());
378 ASSERT_NE(TypeOf(fn_f32_init), nullptr);
379 EXPECT_TRUE(TypeOf(fn_f32_init)->UnwrapAll()->Is<type::F32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +0000380 EXPECT_EQ(StmtOf(fn_i32_init), fn_i32_decl);
381 EXPECT_EQ(StmtOf(mod_init), nullptr);
382 EXPECT_EQ(StmtOf(fn_f32_init), fn_f32_decl);
James Pricec9af5972021-02-16 21:15:01 +0000383 EXPECT_TRUE(CheckVarUsers(fn_i32, {}));
384 EXPECT_TRUE(CheckVarUsers(mod_f32, {fn_f32->constructor()}));
James Price77f4f022021-02-04 16:33:20 +0000385}
386
Ben Clayton5f0ea112021-03-09 10:54:37 +0000387TEST_F(ResolverTest, Expr_ArrayAccessor_Array) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000388 auto* idx = Expr(2);
Ben Clayton37571bc2021-02-16 23:57:01 +0000389 Global("my_var", ty.array<f32, 3>(), ast::StorageClass::kFunction);
dan sinclair8eddb782020-04-23 22:26:52 +0000390
dan sinclair8b40a672020-12-16 11:49:10 +0000391 auto* acc = IndexAccessor("my_var", idx);
Ben Clayton401b96b2021-02-03 17:19:59 +0000392 WrapInFunction(acc);
393
Ben Clayton5f0ea112021-03-09 10:54:37 +0000394 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000395
Ben Clayton33352542021-01-29 16:43:41 +0000396 ASSERT_NE(TypeOf(acc), nullptr);
397 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000398
Ben Clayton33352542021-01-29 16:43:41 +0000399 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000400 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000401}
402
Ben Clayton5f0ea112021-03-09 10:54:37 +0000403TEST_F(ResolverTest, Expr_ArrayAccessor_Alias_Array) {
Ben Clayton1637cbb2021-01-05 15:44:39 +0000404 auto* aary = ty.alias("myarrty", ty.array<f32, 3>());
David Neto9c88ea52020-06-22 20:33:12 +0000405
Ben Clayton37571bc2021-02-16 23:57:01 +0000406 Global("my_var", aary, ast::StorageClass::kFunction);
David Neto9c88ea52020-06-22 20:33:12 +0000407
dan sinclair8b40a672020-12-16 11:49:10 +0000408 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton401b96b2021-02-03 17:19:59 +0000409 WrapInFunction(acc);
410
Ben Clayton5f0ea112021-03-09 10:54:37 +0000411 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000412
Ben Clayton33352542021-01-29 16:43:41 +0000413 ASSERT_NE(TypeOf(acc), nullptr);
414 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
David Neto9c88ea52020-06-22 20:33:12 +0000415
Ben Clayton33352542021-01-29 16:43:41 +0000416 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000417 EXPECT_TRUE(ptr->type()->Is<type::F32>());
David Neto9c88ea52020-06-22 20:33:12 +0000418}
419
Ben Clayton5f0ea112021-03-09 10:54:37 +0000420TEST_F(ResolverTest, Expr_ArrayAccessor_Array_Constant) {
Ben Clayton81a29fe2021-02-17 00:26:52 +0000421 GlobalConst("my_var", ty.array<f32, 3>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000422
dan sinclair8b40a672020-12-16 11:49:10 +0000423 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton401b96b2021-02-03 17:19:59 +0000424 WrapInFunction(acc);
425
Ben Clayton5f0ea112021-03-09 10:54:37 +0000426 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000427
Ben Clayton33352542021-01-29 16:43:41 +0000428 ASSERT_NE(TypeOf(acc), nullptr);
429 EXPECT_TRUE(TypeOf(acc)->Is<type::F32>()) << TypeOf(acc)->type_name();
dan sinclair973bd6a2020-04-07 12:57:42 +0000430}
431
Ben Clayton5f0ea112021-03-09 10:54:37 +0000432TEST_F(ResolverTest, Expr_ArrayAccessor_Matrix) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000433 Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kNone);
dan sinclair973bd6a2020-04-07 12:57:42 +0000434
dan sinclair8b40a672020-12-16 11:49:10 +0000435 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton401b96b2021-02-03 17:19:59 +0000436 WrapInFunction(acc);
437
Ben Clayton5f0ea112021-03-09 10:54:37 +0000438 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000439
Ben Clayton33352542021-01-29 16:43:41 +0000440 ASSERT_NE(TypeOf(acc), nullptr);
441 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000442
Ben Clayton33352542021-01-29 16:43:41 +0000443 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000444 ASSERT_TRUE(ptr->type()->Is<type::Vector>());
445 EXPECT_EQ(ptr->type()->As<type::Vector>()->size(), 3u);
dan sinclair973bd6a2020-04-07 12:57:42 +0000446}
447
Ben Clayton5f0ea112021-03-09 10:54:37 +0000448TEST_F(ResolverTest, Expr_ArrayAccessor_Matrix_BothDimensions) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000449 Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kNone);
dan sinclair973bd6a2020-04-07 12:57:42 +0000450
dan sinclair8b40a672020-12-16 11:49:10 +0000451 auto* acc = IndexAccessor(IndexAccessor("my_var", 2), 1);
Ben Clayton401b96b2021-02-03 17:19:59 +0000452 WrapInFunction(acc);
dan sinclair973bd6a2020-04-07 12:57:42 +0000453
Ben Clayton5f0ea112021-03-09 10:54:37 +0000454 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000455
Ben Clayton33352542021-01-29 16:43:41 +0000456 ASSERT_NE(TypeOf(acc), nullptr);
457 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000458
Ben Clayton33352542021-01-29 16:43:41 +0000459 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000460 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000461}
462
Ben Clayton5f0ea112021-03-09 10:54:37 +0000463TEST_F(ResolverTest, Expr_ArrayAccessor_Vector) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000464 Global("my_var", ty.vec3<f32>(), ast::StorageClass::kNone);
dan sinclair973bd6a2020-04-07 12:57:42 +0000465
dan sinclair8b40a672020-12-16 11:49:10 +0000466 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton401b96b2021-02-03 17:19:59 +0000467 WrapInFunction(acc);
468
Ben Clayton5f0ea112021-03-09 10:54:37 +0000469 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000470
Ben Clayton33352542021-01-29 16:43:41 +0000471 ASSERT_NE(TypeOf(acc), nullptr);
472 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000473
Ben Clayton33352542021-01-29 16:43:41 +0000474 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000475 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000476}
477
Ben Clayton5f0ea112021-03-09 10:54:37 +0000478TEST_F(ResolverTest, Expr_Bitcast) {
Antonio Maioranobb5617f2021-03-19 18:45:30 +0000479 Global("name", ty.f32(), ast::StorageClass::kPrivate);
480
Ben Clayton8d391f72021-01-26 16:57:10 +0000481 auto* bitcast = create<ast::BitcastExpression>(ty.f32(), Expr("name"));
Ben Clayton401b96b2021-02-03 17:19:59 +0000482 WrapInFunction(bitcast);
dan sinclaira01777c2020-04-07 12:57:52 +0000483
Ben Clayton5f0ea112021-03-09 10:54:37 +0000484 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000485
Ben Clayton33352542021-01-29 16:43:41 +0000486 ASSERT_NE(TypeOf(bitcast), nullptr);
487 EXPECT_TRUE(TypeOf(bitcast)->Is<type::F32>());
dan sinclaira01777c2020-04-07 12:57:52 +0000488}
489
Ben Clayton5f0ea112021-03-09 10:54:37 +0000490TEST_F(ResolverTest, Expr_Call) {
dan sinclair3ca87462020-04-07 16:41:10 +0000491 ast::VariableList params;
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000492 Func("my_func", params, ty.f32(), ast::StatementList{Return(Expr(0.0f))},
James Price95d40772021-03-11 17:39:32 +0000493 ast::DecorationList{});
dan sinclair3ca87462020-04-07 16:41:10 +0000494
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000495 auto* call = Call("my_func");
Ben Clayton401b96b2021-02-03 17:19:59 +0000496 WrapInFunction(call);
497
Ben Clayton5f0ea112021-03-09 10:54:37 +0000498 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000499
Ben Clayton33352542021-01-29 16:43:41 +0000500 ASSERT_NE(TypeOf(call), nullptr);
501 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclair3ca87462020-04-07 16:41:10 +0000502}
503
Ben Clayton5f0ea112021-03-09 10:54:37 +0000504TEST_F(ResolverTest, Expr_Call_InBinaryOp) {
Ben Clayton7b7d6982021-02-09 17:38:05 +0000505 ast::VariableList params;
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000506 Func("func", params, ty.f32(), ast::StatementList{Return(Expr(0.0f))},
507 ast::DecorationList{});
Ben Clayton7b7d6982021-02-09 17:38:05 +0000508
509 auto* expr = Add(Call("func"), Call("func"));
510 WrapInFunction(expr);
511
Ben Clayton5f0ea112021-03-09 10:54:37 +0000512 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton7b7d6982021-02-09 17:38:05 +0000513
514 ASSERT_NE(TypeOf(expr), nullptr);
515 EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
516}
517
Ben Clayton5f0ea112021-03-09 10:54:37 +0000518TEST_F(ResolverTest, Expr_Call_WithParams) {
dan sinclairccb52dc2020-04-20 14:18:54 +0000519 ast::VariableList params;
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000520 Func("my_func", params, ty.void_(), ast::StatementList{},
James Price95d40772021-03-11 17:39:32 +0000521 ast::DecorationList{});
dan sinclairccb52dc2020-04-20 14:18:54 +0000522
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000523 auto* param = Expr(2.4f);
dan sinclairccb52dc2020-04-20 14:18:54 +0000524
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000525 auto* call = Call("my_func", param);
Ben Clayton401b96b2021-02-03 17:19:59 +0000526 WrapInFunction(call);
527
Ben Clayton5f0ea112021-03-09 10:54:37 +0000528 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000529
Ben Clayton33352542021-01-29 16:43:41 +0000530 ASSERT_NE(TypeOf(param), nullptr);
531 EXPECT_TRUE(TypeOf(param)->Is<type::F32>());
dan sinclairccb52dc2020-04-20 14:18:54 +0000532}
533
Ben Clayton5f0ea112021-03-09 10:54:37 +0000534TEST_F(ResolverTest, Expr_Call_Intrinsic) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000535 auto* call = Call("round", 2.4f);
Ben Clayton401b96b2021-02-03 17:19:59 +0000536 WrapInFunction(call);
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000537
Ben Clayton5f0ea112021-03-09 10:54:37 +0000538 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000539
Ben Clayton33352542021-01-29 16:43:41 +0000540 ASSERT_NE(TypeOf(call), nullptr);
541 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000542}
543
Ben Clayton5f0ea112021-03-09 10:54:37 +0000544TEST_F(ResolverTest, Expr_Cast) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000545 Global("name", ty.f32(), ast::StorageClass::kPrivate);
Ben Clayton401b96b2021-02-03 17:19:59 +0000546
Ben Clayton8d391f72021-01-26 16:57:10 +0000547 auto* cast = Construct(ty.f32(), "name");
Ben Clayton401b96b2021-02-03 17:19:59 +0000548 WrapInFunction(cast);
dan sinclair3c025922020-09-24 14:38:44 +0000549
Ben Clayton5f0ea112021-03-09 10:54:37 +0000550 EXPECT_TRUE(r()->Resolve()) << r()->error();
dan sinclair4e807952020-04-07 16:41:23 +0000551
Ben Clayton33352542021-01-29 16:43:41 +0000552 ASSERT_NE(TypeOf(cast), nullptr);
553 EXPECT_TRUE(TypeOf(cast)->Is<type::F32>());
dan sinclair4e807952020-04-07 16:41:23 +0000554}
555
Ben Clayton5f0ea112021-03-09 10:54:37 +0000556TEST_F(ResolverTest, Expr_Constructor_Scalar) {
Ben Clayton1637cbb2021-01-05 15:44:39 +0000557 auto* s = Expr(1.0f);
Ben Clayton401b96b2021-02-03 17:19:59 +0000558 WrapInFunction(s);
559
Ben Clayton5f0ea112021-03-09 10:54:37 +0000560 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000561
Ben Clayton33352542021-01-29 16:43:41 +0000562 ASSERT_NE(TypeOf(s), nullptr);
563 EXPECT_TRUE(TypeOf(s)->Is<type::F32>());
dan sinclairb7edc4c2020-04-07 12:46:30 +0000564}
565
Arman Uguray3549e2e2021-03-15 21:21:33 +0000566TEST_F(ResolverTest, Expr_Constructor_Type_Vec2) {
567 auto* tc = vec2<f32>(1.0f, 1.0f);
568 WrapInFunction(tc);
569
570 EXPECT_TRUE(r()->Resolve()) << r()->error();
571
572 ASSERT_NE(TypeOf(tc), nullptr);
573 ASSERT_TRUE(TypeOf(tc)->Is<type::Vector>());
574 EXPECT_TRUE(TypeOf(tc)->As<type::Vector>()->type()->Is<type::F32>());
575 EXPECT_EQ(TypeOf(tc)->As<type::Vector>()->size(), 2u);
576}
577
578TEST_F(ResolverTest, Expr_Constructor_Type_Vec3) {
579 auto* tc = vec3<f32>(1.0f, 1.0f, 1.0f);
Ben Clayton401b96b2021-02-03 17:19:59 +0000580 WrapInFunction(tc);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000581
Ben Clayton5f0ea112021-03-09 10:54:37 +0000582 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000583
Ben Clayton33352542021-01-29 16:43:41 +0000584 ASSERT_NE(TypeOf(tc), nullptr);
585 ASSERT_TRUE(TypeOf(tc)->Is<type::Vector>());
586 EXPECT_TRUE(TypeOf(tc)->As<type::Vector>()->type()->Is<type::F32>());
587 EXPECT_EQ(TypeOf(tc)->As<type::Vector>()->size(), 3u);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000588}
589
Arman Uguray3549e2e2021-03-15 21:21:33 +0000590TEST_F(ResolverTest, Expr_Constructor_Type_Vec4) {
591 auto* tc = vec4<f32>(1.0f, 1.0f, 1.0f, 1.0f);
592 WrapInFunction(tc);
593
594 EXPECT_TRUE(r()->Resolve()) << r()->error();
595
596 ASSERT_NE(TypeOf(tc), nullptr);
597 ASSERT_TRUE(TypeOf(tc)->Is<type::Vector>());
598 EXPECT_TRUE(TypeOf(tc)->As<type::Vector>()->type()->Is<type::F32>());
599 EXPECT_EQ(TypeOf(tc)->As<type::Vector>()->size(), 4u);
600}
601
Ben Clayton5f0ea112021-03-09 10:54:37 +0000602TEST_F(ResolverTest, Expr_Identifier_GlobalVariable) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000603 auto* my_var = Global("my_var", ty.f32(), ast::StorageClass::kNone);
dan sinclaircab0e732020-04-07 12:57:27 +0000604
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000605 auto* ident = Expr("my_var");
Ben Clayton401b96b2021-02-03 17:19:59 +0000606 WrapInFunction(ident);
607
Ben Clayton5f0ea112021-03-09 10:54:37 +0000608 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000609
Ben Clayton33352542021-01-29 16:43:41 +0000610 ASSERT_NE(TypeOf(ident), nullptr);
611 EXPECT_TRUE(TypeOf(ident)->Is<type::Pointer>());
612 EXPECT_TRUE(TypeOf(ident)->As<type::Pointer>()->type()->Is<type::F32>());
James Pricec9af5972021-02-16 21:15:01 +0000613 EXPECT_TRUE(CheckVarUsers(my_var, {ident}));
dan sinclair8eddb782020-04-23 22:26:52 +0000614}
615
Ben Clayton5f0ea112021-03-09 10:54:37 +0000616TEST_F(ResolverTest, Expr_Identifier_GlobalConstant) {
Ben Clayton81a29fe2021-02-17 00:26:52 +0000617 auto* my_var = GlobalConst("my_var", ty.f32());
dan sinclair8eddb782020-04-23 22:26:52 +0000618
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000619 auto* ident = Expr("my_var");
Ben Clayton401b96b2021-02-03 17:19:59 +0000620 WrapInFunction(ident);
621
Ben Clayton5f0ea112021-03-09 10:54:37 +0000622 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000623
Ben Clayton33352542021-01-29 16:43:41 +0000624 ASSERT_NE(TypeOf(ident), nullptr);
625 EXPECT_TRUE(TypeOf(ident)->Is<type::F32>());
James Pricec9af5972021-02-16 21:15:01 +0000626 EXPECT_TRUE(CheckVarUsers(my_var, {ident}));
dan sinclaircab0e732020-04-07 12:57:27 +0000627}
628
Ben Clayton5f0ea112021-03-09 10:54:37 +0000629TEST_F(ResolverTest, Expr_Identifier_FunctionVariable_Const) {
Ben Claytonf97b9c92021-02-16 18:45:45 +0000630 auto* my_var_a = Expr("my_var");
Ben Clayton81a29fe2021-02-17 00:26:52 +0000631 auto* var = Const("my_var", ty.f32());
Antonio Maioranoe09989a2021-03-31 13:26:43 +0000632 auto* decl = Decl(Var("b", ty.f32(), ast::StorageClass::kFunction, my_var_a));
dan sinclair8eddb782020-04-23 22:26:52 +0000633
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000634 Func("my_func", ast::VariableList{}, ty.void_(),
Ben Clayton401b96b2021-02-03 17:19:59 +0000635 ast::StatementList{
636 create<ast::VariableDeclStatement>(var),
Antonio Maioranoe09989a2021-03-31 13:26:43 +0000637 decl,
Ben Clayton401b96b2021-02-03 17:19:59 +0000638 },
James Price95d40772021-03-11 17:39:32 +0000639 ast::DecorationList{});
dan sinclair8eddb782020-04-23 22:26:52 +0000640
Ben Clayton5f0ea112021-03-09 10:54:37 +0000641 EXPECT_TRUE(r()->Resolve()) << r()->error();
dan sinclair8eddb782020-04-23 22:26:52 +0000642
Ben Claytonf97b9c92021-02-16 18:45:45 +0000643 ASSERT_NE(TypeOf(my_var_a), nullptr);
644 EXPECT_TRUE(TypeOf(my_var_a)->Is<type::F32>());
Antonio Maioranoe09989a2021-03-31 13:26:43 +0000645 EXPECT_EQ(StmtOf(my_var_a), decl);
646 EXPECT_TRUE(CheckVarUsers(var, {my_var_a}));
dan sinclair8eddb782020-04-23 22:26:52 +0000647}
648
Ben Clayton5f0ea112021-03-09 10:54:37 +0000649TEST_F(ResolverTest, Expr_Identifier_FunctionVariable) {
Ben Claytonf97b9c92021-02-16 18:45:45 +0000650 auto* my_var_a = Expr("my_var");
651 auto* my_var_b = Expr("my_var");
652 auto* assign = create<ast::AssignmentStatement>(my_var_a, my_var_b);
dan sinclaircab0e732020-04-07 12:57:27 +0000653
Ben Clayton37571bc2021-02-16 23:57:01 +0000654 auto* var = Var("my_var", ty.f32(), ast::StorageClass::kNone);
James Pricec9af5972021-02-16 21:15:01 +0000655
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000656 Func("my_func", ast::VariableList{}, ty.void_(),
Ben Clayton401b96b2021-02-03 17:19:59 +0000657 ast::StatementList{
James Pricec9af5972021-02-16 21:15:01 +0000658 create<ast::VariableDeclStatement>(var),
Ben Claytonf97b9c92021-02-16 18:45:45 +0000659 assign,
Ben Clayton401b96b2021-02-03 17:19:59 +0000660 },
James Price95d40772021-03-11 17:39:32 +0000661 ast::DecorationList{});
dan sinclaircab0e732020-04-07 12:57:27 +0000662
Ben Clayton5f0ea112021-03-09 10:54:37 +0000663 EXPECT_TRUE(r()->Resolve()) << r()->error();
dan sinclaircab0e732020-04-07 12:57:27 +0000664
Ben Claytonf97b9c92021-02-16 18:45:45 +0000665 ASSERT_NE(TypeOf(my_var_a), nullptr);
666 EXPECT_TRUE(TypeOf(my_var_a)->Is<type::Pointer>());
667 EXPECT_TRUE(TypeOf(my_var_a)->As<type::Pointer>()->type()->Is<type::F32>());
668 EXPECT_EQ(StmtOf(my_var_a), assign);
669 ASSERT_NE(TypeOf(my_var_b), nullptr);
670 EXPECT_TRUE(TypeOf(my_var_b)->Is<type::Pointer>());
671 EXPECT_TRUE(TypeOf(my_var_b)->As<type::Pointer>()->type()->Is<type::F32>());
672 EXPECT_EQ(StmtOf(my_var_b), assign);
James Pricec9af5972021-02-16 21:15:01 +0000673 EXPECT_TRUE(CheckVarUsers(var, {my_var_a, my_var_b}));
dan sinclaircab0e732020-04-07 12:57:27 +0000674}
675
Ben Clayton5f0ea112021-03-09 10:54:37 +0000676TEST_F(ResolverTest, Expr_Identifier_Function_Ptr) {
Ben Claytonf97b9c92021-02-16 18:45:45 +0000677 auto* my_var_a = Expr("my_var");
678 auto* my_var_b = Expr("my_var");
679 auto* assign = create<ast::AssignmentStatement>(my_var_a, my_var_b);
dan sinclair5e989302020-09-16 21:20:36 +0000680
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000681 Func("my_func", ast::VariableList{}, ty.void_(),
Ben Clayton401b96b2021-02-03 17:19:59 +0000682 ast::StatementList{
683 create<ast::VariableDeclStatement>(
Ben Clayton37571bc2021-02-16 23:57:01 +0000684 Var("my_var", ty.pointer<f32>(ast::StorageClass::kFunction),
685 ast::StorageClass::kNone)),
Ben Claytonf97b9c92021-02-16 18:45:45 +0000686 assign,
Ben Clayton401b96b2021-02-03 17:19:59 +0000687 },
James Price95d40772021-03-11 17:39:32 +0000688 ast::DecorationList{});
dan sinclair5e989302020-09-16 21:20:36 +0000689
Ben Clayton5f0ea112021-03-09 10:54:37 +0000690 EXPECT_TRUE(r()->Resolve()) << r()->error();
dan sinclair5e989302020-09-16 21:20:36 +0000691
Ben Claytonf97b9c92021-02-16 18:45:45 +0000692 ASSERT_NE(TypeOf(my_var_a), nullptr);
693 EXPECT_TRUE(TypeOf(my_var_a)->Is<type::Pointer>());
694 EXPECT_TRUE(TypeOf(my_var_a)->As<type::Pointer>()->type()->Is<type::F32>());
695 EXPECT_EQ(StmtOf(my_var_a), assign);
696 ASSERT_NE(TypeOf(my_var_b), nullptr);
697 EXPECT_TRUE(TypeOf(my_var_b)->Is<type::Pointer>());
698 EXPECT_TRUE(TypeOf(my_var_b)->As<type::Pointer>()->type()->Is<type::F32>());
699 EXPECT_EQ(StmtOf(my_var_b), assign);
dan sinclair5e989302020-09-16 21:20:36 +0000700}
701
Ben Clayton5f0ea112021-03-09 10:54:37 +0000702TEST_F(ResolverTest, Expr_Call_Function) {
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000703 Func("my_func", ast::VariableList{}, ty.f32(),
704 ast::StatementList{Return(Expr(0.0f))}, ast::DecorationList{});
dan sinclaircab0e732020-04-07 12:57:27 +0000705
Ben Clayton1618f4b2021-02-03 21:02:25 +0000706 auto* call = Call("my_func");
707 WrapInFunction(call);
Ben Clayton401b96b2021-02-03 17:19:59 +0000708
Ben Clayton5f0ea112021-03-09 10:54:37 +0000709 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000710
Ben Clayton1618f4b2021-02-03 21:02:25 +0000711 ASSERT_NE(TypeOf(call), nullptr);
712 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000713}
714
Ben Clayton5f0ea112021-03-09 10:54:37 +0000715TEST_F(ResolverTest, Expr_Identifier_Unknown) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000716 auto* a = Expr("a");
Ben Clayton401b96b2021-02-03 17:19:59 +0000717 WrapInFunction(a);
718
Ben Clayton5f0ea112021-03-09 10:54:37 +0000719 EXPECT_FALSE(r()->Resolve());
dan sinclairff267ca2020-10-14 18:26:31 +0000720}
721
Ben Clayton5f0ea112021-03-09 10:54:37 +0000722TEST_F(ResolverTest, Function_RegisterInputOutputVariables) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000723 auto* in_var = Global("in_var", ty.f32(), ast::StorageClass::kInput);
724 auto* out_var = Global("out_var", ty.f32(), ast::StorageClass::kOutput);
725 auto* sb_var = Global("sb_var", ty.f32(), ast::StorageClass::kStorage);
726 auto* wg_var = Global("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
727 auto* priv_var = Global("priv_var", ty.f32(), ast::StorageClass::kPrivate);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000728
dan sinclair181d8ba2020-12-16 15:15:40 +0000729 auto* func = Func(
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000730 "my_func", ast::VariableList{}, ty.void_(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000731 ast::StatementList{
732 create<ast::AssignmentStatement>(Expr("out_var"), Expr("in_var")),
733 create<ast::AssignmentStatement>(Expr("wg_var"), Expr("wg_var")),
734 create<ast::AssignmentStatement>(Expr("sb_var"), Expr("sb_var")),
735 create<ast::AssignmentStatement>(Expr("priv_var"), Expr("priv_var")),
736 },
James Price95d40772021-03-11 17:39:32 +0000737 ast::DecorationList{});
dan sinclair13d2a3b2020-06-22 20:52:24 +0000738
Ben Clayton5f0ea112021-03-09 10:54:37 +0000739 EXPECT_TRUE(r()->Resolve()) << r()->error();
dan sinclair13d2a3b2020-06-22 20:52:24 +0000740
Ben Clayton87c78dd2021-02-03 16:43:20 +0000741 auto* func_sem = Sem().Get(func);
742 ASSERT_NE(func_sem, nullptr);
743
744 const auto& vars = func_sem->ReferencedModuleVariables();
Ryan Harrison9a452c12020-06-23 16:38:47 +0000745 ASSERT_EQ(vars.size(), 5u);
Ben Claytonb17aea12021-02-03 17:51:09 +0000746 EXPECT_EQ(vars[0]->Declaration(), out_var);
747 EXPECT_EQ(vars[1]->Declaration(), in_var);
748 EXPECT_EQ(vars[2]->Declaration(), wg_var);
749 EXPECT_EQ(vars[3]->Declaration(), sb_var);
750 EXPECT_EQ(vars[4]->Declaration(), priv_var);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000751}
752
Ben Clayton5f0ea112021-03-09 10:54:37 +0000753TEST_F(ResolverTest, Function_RegisterInputOutputVariables_SubFunction) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000754 auto* in_var = Global("in_var", ty.f32(), ast::StorageClass::kInput);
755 auto* out_var = Global("out_var", ty.f32(), ast::StorageClass::kOutput);
756 auto* sb_var = Global("sb_var", ty.f32(), ast::StorageClass::kStorage);
757 auto* wg_var = Global("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
758 auto* priv_var = Global("priv_var", ty.f32(), ast::StorageClass::kPrivate);
dan sinclairde2dd682020-07-14 20:37:28 +0000759
Ben Clayton42d1e092021-02-02 14:29:15 +0000760 Func("my_func", ast::VariableList{}, ty.f32(),
761 ast::StatementList{
762 create<ast::AssignmentStatement>(Expr("out_var"), Expr("in_var")),
763 create<ast::AssignmentStatement>(Expr("wg_var"), Expr("wg_var")),
764 create<ast::AssignmentStatement>(Expr("sb_var"), Expr("sb_var")),
765 create<ast::AssignmentStatement>(Expr("priv_var"), Expr("priv_var")),
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000766 Return(Expr(0.0f))},
James Price95d40772021-03-11 17:39:32 +0000767 ast::DecorationList{});
dan sinclairde2dd682020-07-14 20:37:28 +0000768
dan sinclair181d8ba2020-12-16 15:15:40 +0000769 auto* func2 = Func(
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000770 "func", ast::VariableList{}, ty.void_(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000771 ast::StatementList{
772 create<ast::AssignmentStatement>(Expr("out_var"), Call("my_func")),
773 },
James Price95d40772021-03-11 17:39:32 +0000774 ast::DecorationList{});
dan sinclairde2dd682020-07-14 20:37:28 +0000775
Ben Clayton5f0ea112021-03-09 10:54:37 +0000776 EXPECT_TRUE(r()->Resolve()) << r()->error();
dan sinclairde2dd682020-07-14 20:37:28 +0000777
Ben Clayton87c78dd2021-02-03 16:43:20 +0000778 auto* func2_sem = Sem().Get(func2);
779 ASSERT_NE(func2_sem, nullptr);
780
781 const auto& vars = func2_sem->ReferencedModuleVariables();
dan sinclairde2dd682020-07-14 20:37:28 +0000782 ASSERT_EQ(vars.size(), 5u);
Ben Claytonb17aea12021-02-03 17:51:09 +0000783 EXPECT_EQ(vars[0]->Declaration(), out_var);
784 EXPECT_EQ(vars[1]->Declaration(), in_var);
785 EXPECT_EQ(vars[2]->Declaration(), wg_var);
786 EXPECT_EQ(vars[3]->Declaration(), sb_var);
787 EXPECT_EQ(vars[4]->Declaration(), priv_var);
dan sinclairde2dd682020-07-14 20:37:28 +0000788}
789
Ben Clayton5f0ea112021-03-09 10:54:37 +0000790TEST_F(ResolverTest, Function_NotRegisterFunctionVariable) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000791 auto* var = Var("in_var", ty.f32(), ast::StorageClass::kFunction);
Antonio Maioranobb5617f2021-03-19 18:45:30 +0000792 Global("var", ty.f32(), ast::StorageClass::kFunction);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000793
dan sinclair181d8ba2020-12-16 15:15:40 +0000794 auto* func =
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000795 Func("my_func", ast::VariableList{}, ty.void_(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000796 ast::StatementList{
797 create<ast::VariableDeclStatement>(var),
Ben Clayton1637cbb2021-01-05 15:44:39 +0000798 create<ast::AssignmentStatement>(Expr("var"), Expr(1.f)),
dan sinclair181d8ba2020-12-16 15:15:40 +0000799 },
James Price95d40772021-03-11 17:39:32 +0000800 ast::DecorationList{});
dan sinclair13d2a3b2020-06-22 20:52:24 +0000801
Ben Clayton5f0ea112021-03-09 10:54:37 +0000802 EXPECT_TRUE(r()->Resolve()) << r()->error();
dan sinclair13d2a3b2020-06-22 20:52:24 +0000803
Ben Clayton87c78dd2021-02-03 16:43:20 +0000804 auto* func_sem = Sem().Get(func);
805 ASSERT_NE(func_sem, nullptr);
806
807 EXPECT_EQ(func_sem->ReferencedModuleVariables().size(), 0u);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000808}
809
James Price4ffd3e22021-03-17 14:24:04 +0000810TEST_F(ResolverTest, Function_ReturnStatements) {
811 auto* var = Var("foo", ty.f32(), ast::StorageClass::kFunction);
812
813 auto* ret_1 = create<ast::ReturnStatement>(Expr(1.f));
814 auto* ret_foo = create<ast::ReturnStatement>(Expr("foo"));
815
816 auto* func = Func("my_func", ast::VariableList{}, ty.f32(),
817 ast::StatementList{
818 create<ast::VariableDeclStatement>(var),
819 If(Expr(true), Block(ret_1)),
820 ret_foo,
821 },
822 ast::DecorationList{});
823
824 EXPECT_TRUE(r()->Resolve()) << r()->error();
825
826 auto* func_sem = Sem().Get(func);
827 ASSERT_NE(func_sem, nullptr);
828
829 EXPECT_EQ(func_sem->ReturnStatements().size(), 2u);
830 EXPECT_EQ(func_sem->ReturnStatements()[0], ret_1);
831 EXPECT_EQ(func_sem->ReturnStatements()[1], ret_foo);
832}
833
Ben Clayton5f0ea112021-03-09 10:54:37 +0000834TEST_F(ResolverTest, Expr_MemberAccessor_Struct) {
dan sinclair5e5e36e2020-12-16 14:41:00 +0000835 auto* strct = create<ast::Struct>(
Ben Clayton8d391f72021-01-26 16:57:10 +0000836 ast::StructMemberList{Member("first_member", ty.i32()),
837 Member("second_member", ty.f32())},
James Price95d40772021-03-11 17:39:32 +0000838 ast::DecorationList{});
dan sinclair8ee1d222020-04-07 16:41:33 +0000839
dan sinclairb5839932020-12-16 21:38:40 +0000840 auto* st = ty.struct_("S", strct);
Ben Clayton37571bc2021-02-16 23:57:01 +0000841 Global("my_struct", st, ast::StorageClass::kNone);
dan sinclair8ee1d222020-04-07 16:41:33 +0000842
dan sinclair8b40a672020-12-16 11:49:10 +0000843 auto* mem = MemberAccessor("my_struct", "second_member");
Ben Clayton401b96b2021-02-03 17:19:59 +0000844 WrapInFunction(mem);
845
Ben Clayton5f0ea112021-03-09 10:54:37 +0000846 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000847
Ben Clayton33352542021-01-29 16:43:41 +0000848 ASSERT_NE(TypeOf(mem), nullptr);
849 ASSERT_TRUE(TypeOf(mem)->Is<type::Pointer>());
dan sinclair8ee1d222020-04-07 16:41:33 +0000850
Ben Clayton33352542021-01-29 16:43:41 +0000851 auto* ptr = TypeOf(mem)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000852 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair8ee1d222020-04-07 16:41:33 +0000853}
854
Ben Clayton5f0ea112021-03-09 10:54:37 +0000855TEST_F(ResolverTest, Expr_MemberAccessor_Struct_Alias) {
dan sinclair5e5e36e2020-12-16 14:41:00 +0000856 auto* strct = create<ast::Struct>(
Ben Clayton8d391f72021-01-26 16:57:10 +0000857 ast::StructMemberList{Member("first_member", ty.i32()),
858 Member("second_member", ty.f32())},
James Price95d40772021-03-11 17:39:32 +0000859 ast::DecorationList{});
dan sinclairb445a9b2020-04-24 00:40:45 +0000860
dan sinclairb5839932020-12-16 21:38:40 +0000861 auto* st = ty.struct_("alias", strct);
862 auto* alias = ty.alias("alias", st);
Ben Clayton37571bc2021-02-16 23:57:01 +0000863 Global("my_struct", alias, ast::StorageClass::kNone);
dan sinclairb445a9b2020-04-24 00:40:45 +0000864
dan sinclair8b40a672020-12-16 11:49:10 +0000865 auto* mem = MemberAccessor("my_struct", "second_member");
Ben Clayton401b96b2021-02-03 17:19:59 +0000866 WrapInFunction(mem);
867
Ben Clayton5f0ea112021-03-09 10:54:37 +0000868 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000869
Ben Clayton33352542021-01-29 16:43:41 +0000870 ASSERT_NE(TypeOf(mem), nullptr);
871 ASSERT_TRUE(TypeOf(mem)->Is<type::Pointer>());
dan sinclairb445a9b2020-04-24 00:40:45 +0000872
Ben Clayton33352542021-01-29 16:43:41 +0000873 auto* ptr = TypeOf(mem)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000874 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclairb445a9b2020-04-24 00:40:45 +0000875}
876
Ben Clayton5f0ea112021-03-09 10:54:37 +0000877TEST_F(ResolverTest, Expr_MemberAccessor_VectorSwizzle) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000878 Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kNone);
dan sinclair8ee1d222020-04-07 16:41:33 +0000879
Ben Clayton6d612ad2021-02-24 14:15:02 +0000880 auto* mem = MemberAccessor("my_vec", "xzyw");
Ben Clayton401b96b2021-02-03 17:19:59 +0000881 WrapInFunction(mem);
882
Ben Clayton5f0ea112021-03-09 10:54:37 +0000883 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000884
Ben Clayton33352542021-01-29 16:43:41 +0000885 ASSERT_NE(TypeOf(mem), nullptr);
886 ASSERT_TRUE(TypeOf(mem)->Is<type::Vector>());
887 EXPECT_TRUE(TypeOf(mem)->As<type::Vector>()->type()->Is<type::F32>());
Ben Clayton6d612ad2021-02-24 14:15:02 +0000888 EXPECT_EQ(TypeOf(mem)->As<type::Vector>()->size(), 4u);
889 EXPECT_THAT(Sem().Get(mem)->Swizzle(), ElementsAre(0, 2, 1, 3));
dan sinclair8ee1d222020-04-07 16:41:33 +0000890}
891
Ben Clayton5f0ea112021-03-09 10:54:37 +0000892TEST_F(ResolverTest, Expr_MemberAccessor_VectorSwizzle_SingleElement) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000893 Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kNone);
dan sinclairaac58652020-04-21 13:05:34 +0000894
Ben Clayton6d612ad2021-02-24 14:15:02 +0000895 auto* mem = MemberAccessor("my_vec", "b");
Ben Clayton401b96b2021-02-03 17:19:59 +0000896 WrapInFunction(mem);
897
Ben Clayton5f0ea112021-03-09 10:54:37 +0000898 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +0000899
Ben Clayton33352542021-01-29 16:43:41 +0000900 ASSERT_NE(TypeOf(mem), nullptr);
901 ASSERT_TRUE(TypeOf(mem)->Is<type::Pointer>());
dan sinclairaac58652020-04-21 13:05:34 +0000902
Ben Clayton33352542021-01-29 16:43:41 +0000903 auto* ptr = TypeOf(mem)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000904 ASSERT_TRUE(ptr->type()->Is<type::F32>());
Ben Clayton6d612ad2021-02-24 14:15:02 +0000905 EXPECT_THAT(Sem().Get(mem)->Swizzle(), ElementsAre(2));
906}
907
Ben Clayton5f0ea112021-03-09 10:54:37 +0000908TEST_F(ResolverTest, Expr_Accessor_MultiLevel) {
dan sinclair8ee1d222020-04-07 16:41:33 +0000909 // struct b {
910 // vec4<f32> foo
911 // }
912 // struct A {
913 // vec3<struct b> mem
914 // }
915 // var c : A
916 // c.mem[0].foo.yx
917 // -> vec2<f32>
918 //
919 // MemberAccessor{
920 // MemberAccessor{
921 // ArrayAccessor{
922 // MemberAccessor{
923 // Identifier{c}
924 // Identifier{mem}
925 // }
926 // ScalarConstructor{0}
927 // }
928 // Identifier{foo}
929 // }
930 // Identifier{yx}
931 // }
932 //
dan sinclair8ee1d222020-04-07 16:41:33 +0000933
dan sinclair5e5e36e2020-12-16 14:41:00 +0000934 auto* strctB =
935 create<ast::Struct>(ast::StructMemberList{Member("foo", ty.vec4<f32>())},
James Price95d40772021-03-11 17:39:32 +0000936 ast::DecorationList{});
dan sinclairb5839932020-12-16 21:38:40 +0000937 auto* stB = ty.struct_("B", strctB);
dan sinclair8ee1d222020-04-07 16:41:33 +0000938
Ben Clayton207b5e22021-01-21 15:42:10 +0000939 type::Vector vecB(stB, 3);
dan sinclair5e5e36e2020-12-16 14:41:00 +0000940 auto* strctA = create<ast::Struct>(
James Price95d40772021-03-11 17:39:32 +0000941 ast::StructMemberList{Member("mem", &vecB)}, ast::DecorationList{});
dan sinclair8ee1d222020-04-07 16:41:33 +0000942
dan sinclairb5839932020-12-16 21:38:40 +0000943 auto* stA = ty.struct_("A", strctA);
Ben Clayton37571bc2021-02-16 23:57:01 +0000944 Global("c", stA, ast::StorageClass::kNone);
dan sinclair8ee1d222020-04-07 16:41:33 +0000945
dan sinclair8b40a672020-12-16 11:49:10 +0000946 auto* mem = MemberAccessor(
947 MemberAccessor(IndexAccessor(MemberAccessor("c", "mem"), 0), "foo"),
948 "yx");
Ben Clayton401b96b2021-02-03 17:19:59 +0000949 WrapInFunction(mem);
950
Ben Clayton5f0ea112021-03-09 10:54:37 +0000951 EXPECT_TRUE(r()->Resolve()) << r()->error();
dan sinclair8ee1d222020-04-07 16:41:33 +0000952
Ben Clayton33352542021-01-29 16:43:41 +0000953 ASSERT_NE(TypeOf(mem), nullptr);
954 ASSERT_TRUE(TypeOf(mem)->Is<type::Vector>());
955 EXPECT_TRUE(TypeOf(mem)->As<type::Vector>()->type()->Is<type::F32>());
956 EXPECT_EQ(TypeOf(mem)->As<type::Vector>()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +0000957}
958
Ben Clayton5f0ea112021-03-09 10:54:37 +0000959TEST_F(ResolverTest, Expr_MemberAccessor_InBinaryOp) {
Ben Clayton7b7d6982021-02-09 17:38:05 +0000960 auto* strct = create<ast::Struct>(
961 ast::StructMemberList{Member("first_member", ty.f32()),
962 Member("second_member", ty.f32())},
James Price95d40772021-03-11 17:39:32 +0000963 ast::DecorationList{});
Ben Clayton7b7d6982021-02-09 17:38:05 +0000964
965 auto* st = ty.struct_("S", strct);
Ben Clayton37571bc2021-02-16 23:57:01 +0000966 Global("my_struct", st, ast::StorageClass::kNone);
Ben Clayton7b7d6982021-02-09 17:38:05 +0000967
968 auto* expr = Add(MemberAccessor("my_struct", "first_member"),
969 MemberAccessor("my_struct", "second_member"));
970 WrapInFunction(expr);
971
Ben Clayton5f0ea112021-03-09 10:54:37 +0000972 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton7b7d6982021-02-09 17:38:05 +0000973
974 ASSERT_NE(TypeOf(expr), nullptr);
975 EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
976}
977
Antonio Maioranobe0fc4e2021-03-16 13:26:03 +0000978namespace ExprBinaryTest {
dan sinclair9b978022020-04-07 19:26:39 +0000979
Antonio Maioranobe0fc4e2021-03-16 13:26:03 +0000980struct Params {
981 ast::BinaryOp op;
982 create_type_func_ptr create_lhs_type;
983 create_type_func_ptr create_rhs_type;
984 create_type_func_ptr create_result_type;
985};
dan sinclair9b978022020-04-07 19:26:39 +0000986
Antonio Maioranobe0fc4e2021-03-16 13:26:03 +0000987static constexpr create_type_func_ptr all_create_type_funcs[] = {
988 ty_bool_, ty_u32, ty_i32, ty_f32,
989 ty_vec3<bool>, ty_vec3<i32>, ty_vec3<u32>, ty_vec3<f32>,
990 ty_mat3x3<i32>, ty_mat3x3<u32>, ty_mat3x3<f32>};
991
992// A list of all valid test cases for 'lhs op rhs', except that for vecN and
993// matNxN, we only test N=3.
994static constexpr Params all_valid_cases[] = {
995 // Logical expressions
996 // https://gpuweb.github.io/gpuweb/wgsl.html#logical-expr
997
998 // Binary logical expressions
999 Params{Op::kLogicalAnd, ty_bool_, ty_bool_, ty_bool_},
1000 Params{Op::kLogicalOr, ty_bool_, ty_bool_, ty_bool_},
1001
1002 Params{Op::kAnd, ty_bool_, ty_bool_, ty_bool_},
1003 Params{Op::kOr, ty_bool_, ty_bool_, ty_bool_},
1004 Params{Op::kAnd, ty_vec3<bool>, ty_vec3<bool>, ty_vec3<bool>},
1005 Params{Op::kOr, ty_vec3<bool>, ty_vec3<bool>, ty_vec3<bool>},
1006
1007 // Arithmetic expressions
1008 // https://gpuweb.github.io/gpuweb/wgsl.html#arithmetic-expr
1009
1010 // Binary arithmetic expressions over scalars
1011 Params{Op::kAdd, ty_i32, ty_i32, ty_i32},
1012 Params{Op::kSubtract, ty_i32, ty_i32, ty_i32},
1013 Params{Op::kMultiply, ty_i32, ty_i32, ty_i32},
1014 Params{Op::kDivide, ty_i32, ty_i32, ty_i32},
1015 Params{Op::kModulo, ty_i32, ty_i32, ty_i32},
1016
1017 Params{Op::kAdd, ty_u32, ty_u32, ty_u32},
1018 Params{Op::kSubtract, ty_u32, ty_u32, ty_u32},
1019 Params{Op::kMultiply, ty_u32, ty_u32, ty_u32},
1020 Params{Op::kDivide, ty_u32, ty_u32, ty_u32},
1021 Params{Op::kModulo, ty_u32, ty_u32, ty_u32},
1022
1023 Params{Op::kAdd, ty_f32, ty_f32, ty_f32},
1024 Params{Op::kSubtract, ty_f32, ty_f32, ty_f32},
1025 Params{Op::kMultiply, ty_f32, ty_f32, ty_f32},
1026 Params{Op::kDivide, ty_f32, ty_f32, ty_f32},
1027 Params{Op::kModulo, ty_f32, ty_f32, ty_f32},
1028
1029 // Binary arithmetic expressions over vectors
1030 Params{Op::kAdd, ty_vec3<i32>, ty_vec3<i32>, ty_vec3<i32>},
1031 Params{Op::kSubtract, ty_vec3<i32>, ty_vec3<i32>, ty_vec3<i32>},
1032 Params{Op::kMultiply, ty_vec3<i32>, ty_vec3<i32>, ty_vec3<i32>},
1033 Params{Op::kDivide, ty_vec3<i32>, ty_vec3<i32>, ty_vec3<i32>},
1034 Params{Op::kModulo, ty_vec3<i32>, ty_vec3<i32>, ty_vec3<i32>},
1035
1036 Params{Op::kAdd, ty_vec3<u32>, ty_vec3<u32>, ty_vec3<u32>},
1037 Params{Op::kSubtract, ty_vec3<u32>, ty_vec3<u32>, ty_vec3<u32>},
1038 Params{Op::kMultiply, ty_vec3<u32>, ty_vec3<u32>, ty_vec3<u32>},
1039 Params{Op::kDivide, ty_vec3<u32>, ty_vec3<u32>, ty_vec3<u32>},
1040 Params{Op::kModulo, ty_vec3<u32>, ty_vec3<u32>, ty_vec3<u32>},
1041
1042 Params{Op::kAdd, ty_vec3<f32>, ty_vec3<f32>, ty_vec3<f32>},
1043 Params{Op::kSubtract, ty_vec3<f32>, ty_vec3<f32>, ty_vec3<f32>},
1044 Params{Op::kMultiply, ty_vec3<f32>, ty_vec3<f32>, ty_vec3<f32>},
1045 Params{Op::kDivide, ty_vec3<f32>, ty_vec3<f32>, ty_vec3<f32>},
1046 Params{Op::kModulo, ty_vec3<f32>, ty_vec3<f32>, ty_vec3<f32>},
1047
1048 // Binary arithmetic expressions with mixed scalar, vector, and matrix
1049 // operands
1050 Params{Op::kMultiply, ty_vec3<f32>, ty_f32, ty_vec3<f32>},
1051 Params{Op::kMultiply, ty_f32, ty_vec3<f32>, ty_vec3<f32>},
1052
1053 Params{Op::kMultiply, ty_mat3x3<f32>, ty_f32, ty_mat3x3<f32>},
1054 Params{Op::kMultiply, ty_f32, ty_mat3x3<f32>, ty_mat3x3<f32>},
1055
1056 Params{Op::kMultiply, ty_vec3<f32>, ty_mat3x3<f32>, ty_vec3<f32>},
1057 Params{Op::kMultiply, ty_mat3x3<f32>, ty_vec3<f32>, ty_vec3<f32>},
1058 Params{Op::kMultiply, ty_mat3x3<f32>, ty_mat3x3<f32>, ty_mat3x3<f32>},
1059
1060 // Comparison expressions
1061 // https://gpuweb.github.io/gpuweb/wgsl.html#comparison-expr
1062
1063 // Comparisons over scalars
1064 Params{Op::kEqual, ty_bool_, ty_bool_, ty_bool_},
1065 Params{Op::kNotEqual, ty_bool_, ty_bool_, ty_bool_},
1066
1067 Params{Op::kEqual, ty_i32, ty_i32, ty_bool_},
1068 Params{Op::kNotEqual, ty_i32, ty_i32, ty_bool_},
1069 Params{Op::kLessThan, ty_i32, ty_i32, ty_bool_},
1070 Params{Op::kLessThanEqual, ty_i32, ty_i32, ty_bool_},
1071 Params{Op::kGreaterThan, ty_i32, ty_i32, ty_bool_},
1072 Params{Op::kGreaterThanEqual, ty_i32, ty_i32, ty_bool_},
1073
1074 Params{Op::kEqual, ty_u32, ty_u32, ty_bool_},
1075 Params{Op::kNotEqual, ty_u32, ty_u32, ty_bool_},
1076 Params{Op::kLessThan, ty_u32, ty_u32, ty_bool_},
1077 Params{Op::kLessThanEqual, ty_u32, ty_u32, ty_bool_},
1078 Params{Op::kGreaterThan, ty_u32, ty_u32, ty_bool_},
1079 Params{Op::kGreaterThanEqual, ty_u32, ty_u32, ty_bool_},
1080
1081 Params{Op::kEqual, ty_f32, ty_f32, ty_bool_},
1082 Params{Op::kNotEqual, ty_f32, ty_f32, ty_bool_},
1083 Params{Op::kLessThan, ty_f32, ty_f32, ty_bool_},
1084 Params{Op::kLessThanEqual, ty_f32, ty_f32, ty_bool_},
1085 Params{Op::kGreaterThan, ty_f32, ty_f32, ty_bool_},
1086 Params{Op::kGreaterThanEqual, ty_f32, ty_f32, ty_bool_},
1087
1088 // Comparisons over vectors
1089 Params{Op::kEqual, ty_vec3<bool>, ty_vec3<bool>, ty_vec3<bool>},
1090 Params{Op::kNotEqual, ty_vec3<bool>, ty_vec3<bool>, ty_vec3<bool>},
1091
1092 Params{Op::kEqual, ty_vec3<i32>, ty_vec3<i32>, ty_vec3<bool>},
1093 Params{Op::kNotEqual, ty_vec3<i32>, ty_vec3<i32>, ty_vec3<bool>},
1094 Params{Op::kLessThan, ty_vec3<i32>, ty_vec3<i32>, ty_vec3<bool>},
1095 Params{Op::kLessThanEqual, ty_vec3<i32>, ty_vec3<i32>, ty_vec3<bool>},
1096 Params{Op::kGreaterThan, ty_vec3<i32>, ty_vec3<i32>, ty_vec3<bool>},
1097 Params{Op::kGreaterThanEqual, ty_vec3<i32>, ty_vec3<i32>, ty_vec3<bool>},
1098
1099 Params{Op::kEqual, ty_vec3<u32>, ty_vec3<u32>, ty_vec3<bool>},
1100 Params{Op::kNotEqual, ty_vec3<u32>, ty_vec3<u32>, ty_vec3<bool>},
1101 Params{Op::kLessThan, ty_vec3<u32>, ty_vec3<u32>, ty_vec3<bool>},
1102 Params{Op::kLessThanEqual, ty_vec3<u32>, ty_vec3<u32>, ty_vec3<bool>},
1103 Params{Op::kGreaterThan, ty_vec3<u32>, ty_vec3<u32>, ty_vec3<bool>},
1104 Params{Op::kGreaterThanEqual, ty_vec3<u32>, ty_vec3<u32>, ty_vec3<bool>},
1105
1106 Params{Op::kEqual, ty_vec3<f32>, ty_vec3<f32>, ty_vec3<bool>},
1107 Params{Op::kNotEqual, ty_vec3<f32>, ty_vec3<f32>, ty_vec3<bool>},
1108 Params{Op::kLessThan, ty_vec3<f32>, ty_vec3<f32>, ty_vec3<bool>},
1109 Params{Op::kLessThanEqual, ty_vec3<f32>, ty_vec3<f32>, ty_vec3<bool>},
1110 Params{Op::kGreaterThan, ty_vec3<f32>, ty_vec3<f32>, ty_vec3<bool>},
1111 Params{Op::kGreaterThanEqual, ty_vec3<f32>, ty_vec3<f32>, ty_vec3<bool>},
1112
1113 // Bit expressions
1114 // https://gpuweb.github.io/gpuweb/wgsl.html#bit-expr
1115
1116 // Binary bitwise operations
1117 Params{Op::kOr, ty_i32, ty_i32, ty_i32},
1118 Params{Op::kAnd, ty_i32, ty_i32, ty_i32},
1119 Params{Op::kXor, ty_i32, ty_i32, ty_i32},
1120
1121 Params{Op::kOr, ty_u32, ty_u32, ty_u32},
1122 Params{Op::kAnd, ty_u32, ty_u32, ty_u32},
1123 Params{Op::kXor, ty_u32, ty_u32, ty_u32},
1124
1125 // Bit shift expressions
1126 Params{Op::kShiftLeft, ty_i32, ty_u32, ty_i32},
1127 Params{Op::kShiftLeft, ty_vec3<i32>, ty_vec3<u32>, ty_vec3<i32>},
1128
1129 Params{Op::kShiftLeft, ty_u32, ty_u32, ty_u32},
1130 Params{Op::kShiftLeft, ty_vec3<u32>, ty_vec3<u32>, ty_vec3<u32>},
1131
1132 Params{Op::kShiftRight, ty_i32, ty_u32, ty_i32},
1133 Params{Op::kShiftRight, ty_vec3<i32>, ty_vec3<u32>, ty_vec3<i32>},
1134
1135 Params{Op::kShiftRight, ty_u32, ty_u32, ty_u32},
1136 Params{Op::kShiftRight, ty_vec3<u32>, ty_vec3<u32>, ty_vec3<u32>}};
1137
1138using Expr_Binary_Test_Valid = ResolverTestWithParam<Params>;
1139TEST_P(Expr_Binary_Test_Valid, All) {
1140 auto& params = GetParam();
1141
1142 auto* lhs_type = params.create_lhs_type(ty);
1143 auto* rhs_type = params.create_rhs_type(ty);
1144 auto* result_type = params.create_result_type(ty);
1145
Antonio Maioranobe0fc4e2021-03-16 13:26:03 +00001146 Global("lhs", lhs_type, ast::StorageClass::kNone);
1147 Global("rhs", rhs_type, ast::StorageClass::kNone);
1148
1149 auto* expr =
1150 create<ast::BinaryExpression>(params.op, Expr("lhs"), Expr("rhs"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001151 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001152
Ben Clayton5f0ea112021-03-09 10:54:37 +00001153 ASSERT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001154 ASSERT_NE(TypeOf(expr), nullptr);
Antonio Maioranobe0fc4e2021-03-16 13:26:03 +00001155 ASSERT_TRUE(TypeOf(expr) == result_type);
dan sinclair9b978022020-04-07 19:26:39 +00001156}
Ben Clayton5f0ea112021-03-09 10:54:37 +00001157INSTANTIATE_TEST_SUITE_P(ResolverTest,
Antonio Maioranobe0fc4e2021-03-16 13:26:03 +00001158 Expr_Binary_Test_Valid,
1159 testing::ValuesIn(all_valid_cases));
dan sinclair9b978022020-04-07 19:26:39 +00001160
Antonio Maioranobe0fc4e2021-03-16 13:26:03 +00001161using Expr_Binary_Test_Invalid =
1162 ResolverTestWithParam<std::tuple<Params, create_type_func_ptr>>;
1163TEST_P(Expr_Binary_Test_Invalid, All) {
1164 const Params& params = std::get<0>(GetParam());
1165 const create_type_func_ptr& create_type_func = std::get<1>(GetParam());
dan sinclair9b978022020-04-07 19:26:39 +00001166
Antonio Maioranobe0fc4e2021-03-16 13:26:03 +00001167 // Currently, for most operations, for a given lhs type, there is exactly one
1168 // rhs type allowed. The only exception is for multiplication, which allows
1169 // any permutation of f32, vecN<f32>, and matNxN<f32>. We are fed valid inputs
1170 // only via `params`, and all possible types via `create_type_func`, so we
1171 // test invalid combinations by testing every other rhs type, modulo
1172 // exceptions.
dan sinclair9b978022020-04-07 19:26:39 +00001173
Antonio Maioranobe0fc4e2021-03-16 13:26:03 +00001174 // Skip valid rhs type
1175 if (params.create_rhs_type == create_type_func) {
1176 return;
1177 }
1178
1179 auto* lhs_type = params.create_lhs_type(ty);
1180 auto* rhs_type = create_type_func(ty);
1181
1182 // Skip exceptions: multiplication of f32, vecN<f32>, and matNxN<f32>
1183 if (params.op == Op::kMultiply &&
1184 lhs_type->is_float_scalar_or_vector_or_matrix() &&
1185 rhs_type->is_float_scalar_or_vector_or_matrix()) {
1186 return;
1187 }
1188
Antonio Maioranobe0fc4e2021-03-16 13:26:03 +00001189 Global("lhs", lhs_type, ast::StorageClass::kNone);
1190 Global("rhs", rhs_type, ast::StorageClass::kNone);
1191
1192 auto* expr = create<ast::BinaryExpression>(
1193 Source{Source::Location{12, 34}}, params.op, Expr("lhs"), Expr("rhs"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001194 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001195
Antonio Maioranobe0fc4e2021-03-16 13:26:03 +00001196 ASSERT_FALSE(r()->Resolve()) << r()->error();
1197 ASSERT_EQ(r()->error(),
1198 "12:34 error: Binary expression operand types are invalid for "
1199 "this operation");
dan sinclair9b978022020-04-07 19:26:39 +00001200}
Antonio Maioranobe0fc4e2021-03-16 13:26:03 +00001201INSTANTIATE_TEST_SUITE_P(
1202 ResolverTest,
1203 Expr_Binary_Test_Invalid,
1204 testing::Combine(testing::ValuesIn(all_valid_cases),
1205 testing::ValuesIn(all_create_type_funcs)));
1206} // namespace ExprBinaryTest
dan sinclair9b978022020-04-07 19:26:39 +00001207
Ben Clayton5f0ea112021-03-09 10:54:37 +00001208using UnaryOpExpressionTest = ResolverTestWithParam<ast::UnaryOp>;
dan sinclair0e257622020-04-07 19:27:11 +00001209TEST_P(UnaryOpExpressionTest, Expr_UnaryOp) {
1210 auto op = GetParam();
1211
Ben Clayton37571bc2021-02-16 23:57:01 +00001212 Global("ident", ty.vec4<f32>(), ast::StorageClass::kNone);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001213 auto* der = create<ast::UnaryOpExpression>(op, Expr("ident"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001214 WrapInFunction(der);
1215
Ben Clayton5f0ea112021-03-09 10:54:37 +00001216 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +00001217
Ben Clayton33352542021-01-29 16:43:41 +00001218 ASSERT_NE(TypeOf(der), nullptr);
1219 ASSERT_TRUE(TypeOf(der)->Is<type::Vector>());
1220 EXPECT_TRUE(TypeOf(der)->As<type::Vector>()->type()->Is<type::F32>());
1221 EXPECT_EQ(TypeOf(der)->As<type::Vector>()->size(), 4u);
dan sinclair0e257622020-04-07 19:27:11 +00001222}
Ben Clayton5f0ea112021-03-09 10:54:37 +00001223INSTANTIATE_TEST_SUITE_P(ResolverTest,
dan sinclair0e257622020-04-07 19:27:11 +00001224 UnaryOpExpressionTest,
1225 testing::Values(ast::UnaryOp::kNegation,
1226 ast::UnaryOp::kNot));
1227
Ben Clayton5f0ea112021-03-09 10:54:37 +00001228TEST_F(ResolverTest, StorageClass_SetsIfMissing) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001229 auto* var = Var("var", ty.i32(), ast::StorageClass::kNone);
dan sinclairee8ae042020-04-08 19:58:20 +00001230
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001231 auto* stmt = create<ast::VariableDeclStatement>(var);
Antonio Maiorano03c01b52021-03-19 14:04:51 +00001232 Func("func", ast::VariableList{}, ty.void_(), ast::StatementList{stmt},
James Price95d40772021-03-11 17:39:32 +00001233 ast::DecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001234
Ben Clayton5f0ea112021-03-09 10:54:37 +00001235 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +00001236
Ben Claytonb17aea12021-02-03 17:51:09 +00001237 EXPECT_EQ(Sem().Get(var)->StorageClass(), ast::StorageClass::kFunction);
dan sinclairee8ae042020-04-08 19:58:20 +00001238}
1239
Ben Clayton5f0ea112021-03-09 10:54:37 +00001240TEST_F(ResolverTest, StorageClass_DoesNotSetOnConst) {
Ben Clayton81a29fe2021-02-17 00:26:52 +00001241 auto* var = Const("var", ty.i32());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001242 auto* stmt = create<ast::VariableDeclStatement>(var);
Antonio Maiorano03c01b52021-03-19 14:04:51 +00001243 Func("func", ast::VariableList{}, ty.void_(), ast::StatementList{stmt},
James Price95d40772021-03-11 17:39:32 +00001244 ast::DecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001245
Ben Clayton5f0ea112021-03-09 10:54:37 +00001246 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +00001247
Ben Claytonb17aea12021-02-03 17:51:09 +00001248 EXPECT_EQ(Sem().Get(var)->StorageClass(), ast::StorageClass::kNone);
dan sinclairee8ae042020-04-08 19:58:20 +00001249}
1250
Ben Clayton5f0ea112021-03-09 10:54:37 +00001251TEST_F(ResolverTest, Function_EntryPoints_StageDecoration) {
dan sinclair05926432020-09-21 17:51:31 +00001252 // fn b() {}
1253 // fn c() { b(); }
1254 // fn a() { c(); }
1255 // fn ep_1() { a(); b(); }
1256 // fn ep_2() { c();}
1257 //
1258 // c -> {ep_1, ep_2}
1259 // a -> {ep_1}
1260 // b -> {ep_1, ep_2}
1261 // ep_1 -> {}
1262 // ep_2 -> {}
1263
Antonio Maioranobb5617f2021-03-19 18:45:30 +00001264 Global("first", ty.f32(), ast::StorageClass::kPrivate);
1265 Global("second", ty.f32(), ast::StorageClass::kPrivate);
1266 Global("call_a", ty.f32(), ast::StorageClass::kPrivate);
1267 Global("call_b", ty.f32(), ast::StorageClass::kPrivate);
1268 Global("call_c", ty.f32(), ast::StorageClass::kPrivate);
1269
dan sinclair05926432020-09-21 17:51:31 +00001270 ast::VariableList params;
James Price95d40772021-03-11 17:39:32 +00001271 auto* func_b =
Antonio Maiorano03c01b52021-03-19 14:04:51 +00001272 Func("b", params, ty.f32(), ast::StatementList{Return(Expr(0.0f))},
James Price95d40772021-03-11 17:39:32 +00001273 ast::DecorationList{});
Antonio Maiorano03c01b52021-03-19 14:04:51 +00001274 auto* func_c = Func("c", params, ty.f32(),
1275 ast::StatementList{create<ast::AssignmentStatement>(
1276 Expr("second"), Call("b")),
1277 Return(Expr(0.0f))},
1278 ast::DecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00001279
Antonio Maiorano03c01b52021-03-19 14:04:51 +00001280 auto* func_a = Func("a", params, ty.f32(),
1281 ast::StatementList{create<ast::AssignmentStatement>(
1282 Expr("first"), Call("c")),
1283 Return(Expr(0.0f))},
1284 ast::DecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00001285
dan sinclair181d8ba2020-12-16 15:15:40 +00001286 auto* ep_1 =
Antonio Maiorano03c01b52021-03-19 14:04:51 +00001287 Func("ep_1", params, ty.void_(),
dan sinclair181d8ba2020-12-16 15:15:40 +00001288 ast::StatementList{
1289 create<ast::AssignmentStatement>(Expr("call_a"), Call("a")),
1290 create<ast::AssignmentStatement>(Expr("call_b"), Call("b")),
1291 },
James Price95d40772021-03-11 17:39:32 +00001292 ast::DecorationList{
dan sinclair181d8ba2020-12-16 15:15:40 +00001293 create<ast::StageDecoration>(ast::PipelineStage::kVertex),
1294 });
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001295
dan sinclair181d8ba2020-12-16 15:15:40 +00001296 auto* ep_2 =
Antonio Maiorano03c01b52021-03-19 14:04:51 +00001297 Func("ep_2", params, ty.void_(),
dan sinclair181d8ba2020-12-16 15:15:40 +00001298 ast::StatementList{
1299 create<ast::AssignmentStatement>(Expr("call_c"), Call("c")),
1300 },
James Price95d40772021-03-11 17:39:32 +00001301 ast::DecorationList{
dan sinclair181d8ba2020-12-16 15:15:40 +00001302 create<ast::StageDecoration>(ast::PipelineStage::kVertex),
1303 });
dan sinclair05926432020-09-21 17:51:31 +00001304
Ben Clayton5f0ea112021-03-09 10:54:37 +00001305 ASSERT_TRUE(r()->Resolve()) << r()->error();
dan sinclair05926432020-09-21 17:51:31 +00001306
Ben Clayton87c78dd2021-02-03 16:43:20 +00001307 auto* func_b_sem = Sem().Get(func_b);
1308 auto* func_a_sem = Sem().Get(func_a);
1309 auto* func_c_sem = Sem().Get(func_c);
1310 auto* ep_1_sem = Sem().Get(ep_1);
1311 auto* ep_2_sem = Sem().Get(ep_2);
1312 ASSERT_NE(func_b_sem, nullptr);
1313 ASSERT_NE(func_a_sem, nullptr);
1314 ASSERT_NE(func_c_sem, nullptr);
1315 ASSERT_NE(ep_1_sem, nullptr);
1316 ASSERT_NE(ep_2_sem, nullptr);
1317
1318 const auto& b_eps = func_b_sem->AncestorEntryPoints();
dan sinclair05926432020-09-21 17:51:31 +00001319 ASSERT_EQ(2u, b_eps.size());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001320 EXPECT_EQ(Symbols().Register("ep_1"), b_eps[0]);
1321 EXPECT_EQ(Symbols().Register("ep_2"), b_eps[1]);
dan sinclair05926432020-09-21 17:51:31 +00001322
Ben Clayton87c78dd2021-02-03 16:43:20 +00001323 const auto& a_eps = func_a_sem->AncestorEntryPoints();
dan sinclair05926432020-09-21 17:51:31 +00001324 ASSERT_EQ(1u, a_eps.size());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001325 EXPECT_EQ(Symbols().Register("ep_1"), a_eps[0]);
dan sinclair05926432020-09-21 17:51:31 +00001326
Ben Clayton87c78dd2021-02-03 16:43:20 +00001327 const auto& c_eps = func_c_sem->AncestorEntryPoints();
dan sinclair05926432020-09-21 17:51:31 +00001328 ASSERT_EQ(2u, c_eps.size());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001329 EXPECT_EQ(Symbols().Register("ep_1"), c_eps[0]);
1330 EXPECT_EQ(Symbols().Register("ep_2"), c_eps[1]);
dan sinclair05926432020-09-21 17:51:31 +00001331
Ben Clayton87c78dd2021-02-03 16:43:20 +00001332 EXPECT_TRUE(ep_1_sem->AncestorEntryPoints().empty());
1333 EXPECT_TRUE(ep_2_sem->AncestorEntryPoints().empty());
dan sinclair05926432020-09-21 17:51:31 +00001334}
1335
Ben Clayton5a132582021-03-03 19:54:44 +00001336// Check for linear-time traversal of functions reachable from entry points.
1337// See: crbug.com/tint/245
Ben Clayton5f0ea112021-03-09 10:54:37 +00001338TEST_F(ResolverTest, Function_EntryPoints_LinearTime) {
Ben Clayton5a132582021-03-03 19:54:44 +00001339 // fn lNa() { }
1340 // fn lNb() { }
1341 // ...
1342 // fn l2a() { l3a(); l3b(); }
1343 // fn l2b() { l3a(); l3b(); }
1344 // fn l1a() { l2a(); l2b(); }
1345 // fn l1b() { l2a(); l2b(); }
1346 // fn main() { l1a(); l1b(); }
1347
1348 static constexpr int levels = 64;
1349
1350 auto fn_a = [](int level) { return "l" + std::to_string(level + 1) + "a"; };
1351 auto fn_b = [](int level) { return "l" + std::to_string(level + 1) + "b"; };
1352
1353 Func(fn_a(levels), {}, ty.void_(), {}, {});
1354 Func(fn_b(levels), {}, ty.void_(), {}, {});
1355
1356 for (int i = levels - 1; i >= 0; i--) {
1357 Func(fn_a(i), {}, ty.void_(),
1358 {
1359 create<ast::CallStatement>(Call(fn_a(i + 1))),
1360 create<ast::CallStatement>(Call(fn_b(i + 1))),
1361 },
1362 {});
1363 Func(fn_b(i), {}, ty.void_(),
1364 {
1365 create<ast::CallStatement>(Call(fn_a(i + 1))),
1366 create<ast::CallStatement>(Call(fn_b(i + 1))),
1367 },
1368 {});
1369 }
1370
1371 Func("main", {}, ty.void_(),
1372 {
1373 create<ast::CallStatement>(Call(fn_a(0))),
1374 create<ast::CallStatement>(Call(fn_b(0))),
1375 },
1376 {
1377 create<ast::StageDecoration>(ast::PipelineStage::kVertex),
1378 });
1379
Ben Clayton5f0ea112021-03-09 10:54:37 +00001380 ASSERT_TRUE(r()->Resolve()) << r()->error();
Ben Clayton5a132582021-03-03 19:54:44 +00001381}
1382
dan sinclairb7edc4c2020-04-07 12:46:30 +00001383} // namespace
Ben Claytonc7dcbae2021-03-09 15:08:48 +00001384} // namespace resolver
dan sinclairb7edc4c2020-04-07 12:46:30 +00001385} // namespace tint