blob: edb95cf99aaafa17d2cc38c8043ca37292e5eeb7 [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
15#include "src/type_determiner.h"
16
Ben Clayton3ea3c992020-11-18 21:19:22 +000017#include <algorithm>
dan sinclairb7edc4c2020-04-07 12:46:30 +000018#include <memory>
19#include <utility>
dan sinclairfd5d4ca2020-04-20 15:46:18 +000020#include <vector>
dan sinclairb7edc4c2020-04-07 12:46:30 +000021
Ben Clayton47c4d182021-02-10 21:42:35 +000022#include "gmock/gmock.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000023#include "gtest/gtest.h"
dan sinclair973bd6a2020-04-07 12:57:42 +000024#include "src/ast/array_accessor_expression.h"
dan sinclair6c498fc2020-04-07 12:47:23 +000025#include "src/ast/assignment_statement.h"
dan sinclair1c9b4862020-04-07 19:27:41 +000026#include "src/ast/binary_expression.h"
dan sinclaira7d498e2020-09-22 22:07:13 +000027#include "src/ast/bitcast_expression.h"
dan sinclair0975dd52020-07-27 15:25:00 +000028#include "src/ast/block_statement.h"
dan sinclairb4fee2f2020-09-22 19:42:13 +000029#include "src/ast/bool_literal.h"
dan sinclairb7ea6e22020-04-07 12:54:10 +000030#include "src/ast/break_statement.h"
dan sinclair3ca87462020-04-07 16:41:10 +000031#include "src/ast/call_expression.h"
dan sinclair50080b72020-07-21 13:42:13 +000032#include "src/ast/call_statement.h"
dan sinclair6010b292020-04-07 12:54:20 +000033#include "src/ast/case_statement.h"
dan sinclairaec965e2020-04-07 12:54:29 +000034#include "src/ast/continue_statement.h"
dan sinclair0cf685f2020-04-07 12:54:37 +000035#include "src/ast/else_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000036#include "src/ast/float_literal.h"
dan sinclaircab0e732020-04-07 12:57:27 +000037#include "src/ast/identifier_expression.h"
dan sinclair91c44a52020-04-07 12:55:25 +000038#include "src/ast/if_statement.h"
Ben Clayton3ea3c992020-11-18 21:19:22 +000039#include "src/ast/intrinsic_texture_helper_test.h"
dan sinclairbc71eda2020-04-07 12:55:51 +000040#include "src/ast/loop_statement.h"
dan sinclair8ee1d222020-04-07 16:41:33 +000041#include "src/ast/member_accessor_expression.h"
dan sinclair05926432020-09-21 17:51:31 +000042#include "src/ast/pipeline_stage.h"
dan sinclairbf0fff82020-04-07 12:56:24 +000043#include "src/ast/return_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000044#include "src/ast/scalar_constructor_expression.h"
dan sinclairc6f29472020-06-02 20:11:44 +000045#include "src/ast/sint_literal.h"
dan sinclair05926432020-09-21 17:51:31 +000046#include "src/ast/stage_decoration.h"
dan sinclair8ee1d222020-04-07 16:41:33 +000047#include "src/ast/struct.h"
48#include "src/ast/struct_member.h"
dan sinclair18b32852020-04-07 12:56:45 +000049#include "src/ast/switch_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000050#include "src/ast/type_constructor_expression.h"
dan sinclair92bb5572020-06-08 23:48:07 +000051#include "src/ast/uint_literal.h"
dan sinclair327ed1b2020-04-07 19:27:21 +000052#include "src/ast/unary_op_expression.h"
dan sinclairca893e32020-04-07 12:57:12 +000053#include "src/ast/variable_decl_statement.h"
Ben Claytona6b9a8e2021-01-26 16:57:10 +000054#include "src/program_builder.h"
Ben Clayton1618f4b2021-02-03 21:02:25 +000055#include "src/semantic/call.h"
Ben Clayton33352542021-01-29 16:43:41 +000056#include "src/semantic/expression.h"
Ben Clayton87c78dd2021-02-03 16:43:20 +000057#include "src/semantic/function.h"
Ben Clayton6d612ad2021-02-24 14:15:02 +000058#include "src/semantic/member_accessor_expression.h"
Ben Claytonf97b9c92021-02-16 18:45:45 +000059#include "src/semantic/statement.h"
Ben Claytonb17aea12021-02-03 17:51:09 +000060#include "src/semantic/variable.h"
Ben Claytonfaca02d2021-02-10 21:34:25 +000061#include "src/type/access_control_type.h"
Ben Clayton207b5e22021-01-21 15:42:10 +000062#include "src/type/alias_type.h"
63#include "src/type/array_type.h"
64#include "src/type/bool_type.h"
65#include "src/type/depth_texture_type.h"
66#include "src/type/f32_type.h"
67#include "src/type/i32_type.h"
68#include "src/type/matrix_type.h"
69#include "src/type/multisampled_texture_type.h"
70#include "src/type/pointer_type.h"
71#include "src/type/sampled_texture_type.h"
72#include "src/type/sampler_type.h"
73#include "src/type/storage_texture_type.h"
74#include "src/type/struct_type.h"
75#include "src/type/texture_type.h"
76#include "src/type/u32_type.h"
77#include "src/type/vector_type.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000078
Ben Clayton6d612ad2021-02-24 14:15:02 +000079using ::testing::ElementsAre;
Ben Clayton47c4d182021-02-10 21:42:35 +000080using ::testing::HasSubstr;
81
dan sinclairb7edc4c2020-04-07 12:46:30 +000082namespace tint {
83namespace {
84
Ben Clayton052ab892021-02-08 19:53:42 +000085using IntrinsicType = semantic::IntrinsicType;
86
dan sinclair7456f422020-04-08 19:58:35 +000087class FakeStmt : public ast::Statement {
88 public:
Ben Clayton604bc722020-12-12 01:24:53 +000089 explicit FakeStmt(Source source) : ast::Statement(source) {}
Ben Clayton1e29f4b2021-01-21 16:20:40 +000090 FakeStmt* Clone(CloneContext*) const override { return nullptr; }
dan sinclair7456f422020-04-08 19:58:35 +000091 bool IsValid() const override { return true; }
Ben Claytondd1b6fc2021-01-29 10:55:40 +000092 void to_str(const semantic::Info&, std::ostream& out, size_t) const override {
93 out << "Fake";
94 }
dan sinclair7456f422020-04-08 19:58:35 +000095};
96
97class FakeExpr : public ast::Expression {
98 public:
Ben Clayton604bc722020-12-12 01:24:53 +000099 explicit FakeExpr(Source source) : ast::Expression(source) {}
Ben Clayton1e29f4b2021-01-21 16:20:40 +0000100 FakeExpr* Clone(CloneContext*) const override { return nullptr; }
dan sinclair7456f422020-04-08 19:58:35 +0000101 bool IsValid() const override { return true; }
Ben Claytondd1b6fc2021-01-29 10:55:40 +0000102 void to_str(const semantic::Info&, std::ostream&, size_t) const override {}
dan sinclair7456f422020-04-08 19:58:35 +0000103};
104
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000105class TypeDeterminerHelper : public ProgramBuilder {
dan sinclairb7edc4c2020-04-07 12:46:30 +0000106 public:
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000107 TypeDeterminerHelper() : td_(std::make_unique<TypeDeterminer>(this)) {}
dan sinclairb7edc4c2020-04-07 12:46:30 +0000108
109 TypeDeterminer* td() const { return td_.get(); }
Ben Clayton62625922020-11-13 22:09:38 +0000110
Ben Claytonf97b9c92021-02-16 18:45:45 +0000111 ast::Statement* StmtOf(ast::Expression* expr) {
112 auto* sem_stmt = Sem().Get(expr)->Stmt();
113 return sem_stmt ? sem_stmt->Declaration() : nullptr;
114 }
115
James Pricec9af5972021-02-16 21:15:01 +0000116 bool CheckVarUsers(ast::Variable* var,
117 std::vector<ast::Expression*>&& expected_users) {
118 auto& var_users = Sem().Get(var)->Users();
119 if (var_users.size() != expected_users.size()) {
120 return false;
121 }
122 for (size_t i = 0; i < var_users.size(); i++) {
123 if (var_users[i]->Declaration() != expected_users[i]) {
124 return false;
125 }
126 }
127 return true;
128 }
129
dan sinclairb7edc4c2020-04-07 12:46:30 +0000130 private:
dan sinclairb7edc4c2020-04-07 12:46:30 +0000131 std::unique_ptr<TypeDeterminer> td_;
132};
133
dan sinclaircd077b02020-04-20 14:19:04 +0000134class TypeDeterminerTest : public TypeDeterminerHelper, public testing::Test {};
135
136template <typename T>
137class TypeDeterminerTestWithParam : public TypeDeterminerHelper,
138 public testing::TestWithParam<T> {};
139
dan sinclair7456f422020-04-08 19:58:35 +0000140TEST_F(TypeDeterminerTest, Error_WithEmptySource) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000141 auto* s = create<FakeStmt>();
Ben Clayton401b96b2021-02-03 17:19:59 +0000142 WrapInFunction(s);
dan sinclair7456f422020-04-08 19:58:35 +0000143
Ben Clayton401b96b2021-02-03 17:19:59 +0000144 EXPECT_FALSE(td()->Determine());
145
dan sinclair0975dd52020-07-27 15:25:00 +0000146 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +0000147 "error: unknown statement type for type determination: Fake");
dan sinclair7456f422020-04-08 19:58:35 +0000148}
149
150TEST_F(TypeDeterminerTest, Stmt_Error_Unknown) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000151 auto* s = create<FakeStmt>(Source{Source::Location{2, 30}});
Ben Clayton401b96b2021-02-03 17:19:59 +0000152 WrapInFunction(s);
dan sinclair7456f422020-04-08 19:58:35 +0000153
Ben Clayton401b96b2021-02-03 17:19:59 +0000154 EXPECT_FALSE(td()->Determine());
155
dan sinclair7456f422020-04-08 19:58:35 +0000156 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +0000157 "2:30 error: unknown statement type for type determination: Fake");
dan sinclair7456f422020-04-08 19:58:35 +0000158}
159
dan sinclair6c498fc2020-04-07 12:47:23 +0000160TEST_F(TypeDeterminerTest, Stmt_Assign) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000161 auto* lhs = Expr(2);
162 auto* rhs = Expr(2.3f);
dan sinclair6c498fc2020-04-07 12:47:23 +0000163
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000164 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
Ben Clayton401b96b2021-02-03 17:19:59 +0000165 WrapInFunction(assign);
dan sinclair6c498fc2020-04-07 12:47:23 +0000166
Ben Clayton401b96b2021-02-03 17:19:59 +0000167 EXPECT_TRUE(td()->Determine()) << td()->error();
168
Ben Clayton33352542021-01-29 16:43:41 +0000169 ASSERT_NE(TypeOf(lhs), nullptr);
170 ASSERT_NE(TypeOf(rhs), nullptr);
dan sinclair6c498fc2020-04-07 12:47:23 +0000171
Ben Clayton33352542021-01-29 16:43:41 +0000172 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
173 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +0000174 EXPECT_EQ(StmtOf(lhs), assign);
175 EXPECT_EQ(StmtOf(rhs), assign);
dan sinclair6c498fc2020-04-07 12:47:23 +0000176}
177
dan sinclair6010b292020-04-07 12:54:20 +0000178TEST_F(TypeDeterminerTest, Stmt_Case) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000179 auto* lhs = Expr(2);
180 auto* rhs = Expr(2.3f);
dan sinclair6010b292020-04-07 12:54:20 +0000181
Ben Claytonf97b9c92021-02-16 18:45:45 +0000182 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000183 auto* body = create<ast::BlockStatement>(ast::StatementList{
Ben Claytonf97b9c92021-02-16 18:45:45 +0000184 assign,
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000185 });
dan sinclair1aadbd42020-06-01 16:56:46 +0000186 ast::CaseSelectorList lit;
Ben Clayton8d391f72021-01-26 16:57:10 +0000187 lit.push_back(create<ast::SintLiteral>(ty.i32(), 3));
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000188 auto* cse = create<ast::CaseStatement>(lit, body);
Ben Clayton401b96b2021-02-03 17:19:59 +0000189 WrapInFunction(cse);
dan sinclair6010b292020-04-07 12:54:20 +0000190
Ben Clayton401b96b2021-02-03 17:19:59 +0000191 EXPECT_TRUE(td()->Determine()) << td()->error();
192
Ben Clayton33352542021-01-29 16:43:41 +0000193 ASSERT_NE(TypeOf(lhs), nullptr);
194 ASSERT_NE(TypeOf(rhs), nullptr);
195 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
196 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +0000197 EXPECT_EQ(StmtOf(lhs), assign);
198 EXPECT_EQ(StmtOf(rhs), assign);
dan sinclair6010b292020-04-07 12:54:20 +0000199}
200
dan sinclair0975dd52020-07-27 15:25:00 +0000201TEST_F(TypeDeterminerTest, Stmt_Block) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000202 auto* lhs = Expr(2);
203 auto* rhs = Expr(2.3f);
dan sinclair0975dd52020-07-27 15:25:00 +0000204
Ben Claytonf97b9c92021-02-16 18:45:45 +0000205 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000206 auto* block = create<ast::BlockStatement>(ast::StatementList{
Ben Claytonf97b9c92021-02-16 18:45:45 +0000207 assign,
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000208 });
Ben Clayton401b96b2021-02-03 17:19:59 +0000209 WrapInFunction(block);
dan sinclair0975dd52020-07-27 15:25:00 +0000210
Ben Clayton401b96b2021-02-03 17:19:59 +0000211 EXPECT_TRUE(td()->Determine()) << td()->error();
212
Ben Clayton33352542021-01-29 16:43:41 +0000213 ASSERT_NE(TypeOf(lhs), nullptr);
214 ASSERT_NE(TypeOf(rhs), nullptr);
215 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
216 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +0000217 EXPECT_EQ(StmtOf(lhs), assign);
218 EXPECT_EQ(StmtOf(rhs), assign);
dan sinclair0975dd52020-07-27 15:25:00 +0000219}
220
dan sinclair0cf685f2020-04-07 12:54:37 +0000221TEST_F(TypeDeterminerTest, Stmt_Else) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000222 auto* lhs = Expr(2);
223 auto* rhs = Expr(2.3f);
dan sinclair0cf685f2020-04-07 12:54:37 +0000224
Ben Claytonf97b9c92021-02-16 18:45:45 +0000225 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000226 auto* body = create<ast::BlockStatement>(ast::StatementList{
Ben Claytonf97b9c92021-02-16 18:45:45 +0000227 assign,
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000228 });
Ben Claytonf97b9c92021-02-16 18:45:45 +0000229 auto* cond = Expr(3);
230 auto* stmt = create<ast::ElseStatement>(cond, body);
Ben Clayton401b96b2021-02-03 17:19:59 +0000231 WrapInFunction(stmt);
dan sinclair0cf685f2020-04-07 12:54:37 +0000232
Ben Clayton401b96b2021-02-03 17:19:59 +0000233 EXPECT_TRUE(td()->Determine()) << td()->error();
234
Ben Clayton33352542021-01-29 16:43:41 +0000235 ASSERT_NE(TypeOf(stmt->condition()), nullptr);
236 ASSERT_NE(TypeOf(lhs), nullptr);
237 ASSERT_NE(TypeOf(rhs), nullptr);
238 EXPECT_TRUE(TypeOf(stmt->condition())->Is<type::I32>());
239 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
240 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +0000241 EXPECT_EQ(StmtOf(lhs), assign);
242 EXPECT_EQ(StmtOf(rhs), assign);
243 EXPECT_EQ(StmtOf(cond), stmt);
dan sinclair0cf685f2020-04-07 12:54:37 +0000244}
245
dan sinclair91c44a52020-04-07 12:55:25 +0000246TEST_F(TypeDeterminerTest, Stmt_If) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000247 auto* else_lhs = Expr(2);
248 auto* else_rhs = Expr(2.3f);
dan sinclair91c44a52020-04-07 12:55:25 +0000249
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000250 auto* else_body = create<ast::BlockStatement>(ast::StatementList{
251 create<ast::AssignmentStatement>(else_lhs, else_rhs),
252 });
dan sinclair91c44a52020-04-07 12:55:25 +0000253
Ben Claytonf97b9c92021-02-16 18:45:45 +0000254 auto* else_cond = Expr(3);
255 auto* else_stmt = create<ast::ElseStatement>(else_cond, else_body);
dan sinclair91c44a52020-04-07 12:55:25 +0000256
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000257 auto* lhs = Expr(2);
258 auto* rhs = Expr(2.3f);
dan sinclair91c44a52020-04-07 12:55:25 +0000259
Ben Claytonf97b9c92021-02-16 18:45:45 +0000260 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
261 auto* body = create<ast::BlockStatement>(ast::StatementList{assign});
262 auto* cond = Expr(3);
263 auto* stmt =
264 create<ast::IfStatement>(cond, body, ast::ElseStatementList{else_stmt});
Ben Clayton401b96b2021-02-03 17:19:59 +0000265 WrapInFunction(stmt);
dan sinclair91c44a52020-04-07 12:55:25 +0000266
Ben Clayton401b96b2021-02-03 17:19:59 +0000267 EXPECT_TRUE(td()->Determine()) << td()->error();
268
Ben Clayton33352542021-01-29 16:43:41 +0000269 ASSERT_NE(TypeOf(stmt->condition()), nullptr);
270 ASSERT_NE(TypeOf(else_lhs), nullptr);
271 ASSERT_NE(TypeOf(else_rhs), nullptr);
272 ASSERT_NE(TypeOf(lhs), nullptr);
273 ASSERT_NE(TypeOf(rhs), nullptr);
274 EXPECT_TRUE(TypeOf(stmt->condition())->Is<type::I32>());
275 EXPECT_TRUE(TypeOf(else_lhs)->Is<type::I32>());
276 EXPECT_TRUE(TypeOf(else_rhs)->Is<type::F32>());
277 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
278 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +0000279 EXPECT_EQ(StmtOf(lhs), assign);
280 EXPECT_EQ(StmtOf(rhs), assign);
281 EXPECT_EQ(StmtOf(cond), stmt);
282 EXPECT_EQ(StmtOf(else_cond), else_stmt);
dan sinclair91c44a52020-04-07 12:55:25 +0000283}
284
dan sinclairbc71eda2020-04-07 12:55:51 +0000285TEST_F(TypeDeterminerTest, Stmt_Loop) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000286 auto* body_lhs = Expr(2);
287 auto* body_rhs = Expr(2.3f);
dan sinclairbc71eda2020-04-07 12:55:51 +0000288
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000289 auto* body = create<ast::BlockStatement>(ast::StatementList{
290 create<ast::AssignmentStatement>(body_lhs, body_rhs),
291 });
292 auto* continuing_lhs = Expr(2);
293 auto* continuing_rhs = Expr(2.3f);
dan sinclairbc71eda2020-04-07 12:55:51 +0000294
Ben Claytondb5ce652020-12-14 20:25:27 +0000295 auto* continuing = create<ast::BlockStatement>(
dan sinclairbc71eda2020-04-07 12:55:51 +0000296
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000297 ast::StatementList{
298 create<ast::AssignmentStatement>(continuing_lhs, continuing_rhs),
299 });
300 auto* stmt = create<ast::LoopStatement>(body, continuing);
Ben Clayton401b96b2021-02-03 17:19:59 +0000301 WrapInFunction(stmt);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000302
Ben Clayton401b96b2021-02-03 17:19:59 +0000303 EXPECT_TRUE(td()->Determine()) << td()->error();
304
Ben Clayton33352542021-01-29 16:43:41 +0000305 ASSERT_NE(TypeOf(body_lhs), nullptr);
306 ASSERT_NE(TypeOf(body_rhs), nullptr);
307 ASSERT_NE(TypeOf(continuing_lhs), nullptr);
308 ASSERT_NE(TypeOf(continuing_rhs), nullptr);
309 EXPECT_TRUE(TypeOf(body_lhs)->Is<type::I32>());
310 EXPECT_TRUE(TypeOf(body_rhs)->Is<type::F32>());
311 EXPECT_TRUE(TypeOf(continuing_lhs)->Is<type::I32>());
312 EXPECT_TRUE(TypeOf(continuing_rhs)->Is<type::F32>());
dan sinclairbc71eda2020-04-07 12:55:51 +0000313}
314
dan sinclairbf0fff82020-04-07 12:56:24 +0000315TEST_F(TypeDeterminerTest, Stmt_Return) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000316 auto* cond = Expr(2);
dan sinclairbf0fff82020-04-07 12:56:24 +0000317
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000318 auto* ret = create<ast::ReturnStatement>(cond);
Ben Clayton401b96b2021-02-03 17:19:59 +0000319 WrapInFunction(ret);
dan sinclairbf0fff82020-04-07 12:56:24 +0000320
Ben Clayton401b96b2021-02-03 17:19:59 +0000321 EXPECT_TRUE(td()->Determine()) << td()->error();
322
Ben Clayton33352542021-01-29 16:43:41 +0000323 ASSERT_NE(TypeOf(cond), nullptr);
324 EXPECT_TRUE(TypeOf(cond)->Is<type::I32>());
dan sinclairbf0fff82020-04-07 12:56:24 +0000325}
326
dan sinclair327ed1b2020-04-07 19:27:21 +0000327TEST_F(TypeDeterminerTest, Stmt_Return_WithoutValue) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000328 auto* ret = create<ast::ReturnStatement>();
Ben Clayton401b96b2021-02-03 17:19:59 +0000329 WrapInFunction(ret);
330
331 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair327ed1b2020-04-07 19:27:21 +0000332}
333
dan sinclair18b32852020-04-07 12:56:45 +0000334TEST_F(TypeDeterminerTest, Stmt_Switch) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000335 auto* lhs = Expr(2);
336 auto* rhs = Expr(2.3f);
dan sinclair18b32852020-04-07 12:56:45 +0000337
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000338 auto* body = create<ast::BlockStatement>(ast::StatementList{
339 create<ast::AssignmentStatement>(lhs, rhs),
340 });
dan sinclair1aadbd42020-06-01 16:56:46 +0000341 ast::CaseSelectorList lit;
Ben Clayton8d391f72021-01-26 16:57:10 +0000342 lit.push_back(create<ast::SintLiteral>(ty.i32(), 3));
dan sinclair1aadbd42020-06-01 16:56:46 +0000343
dan sinclair18b32852020-04-07 12:56:45 +0000344 ast::CaseStatementList cases;
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000345 cases.push_back(create<ast::CaseStatement>(lit, body));
dan sinclair18b32852020-04-07 12:56:45 +0000346
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000347 auto* stmt = create<ast::SwitchStatement>(Expr(2), cases);
Ben Clayton401b96b2021-02-03 17:19:59 +0000348 WrapInFunction(stmt);
dan sinclair18b32852020-04-07 12:56:45 +0000349
Ben Clayton401b96b2021-02-03 17:19:59 +0000350 EXPECT_TRUE(td()->Determine()) << td()->error();
351
Ben Clayton33352542021-01-29 16:43:41 +0000352 ASSERT_NE(TypeOf(stmt->condition()), nullptr);
353 ASSERT_NE(TypeOf(lhs), nullptr);
354 ASSERT_NE(TypeOf(rhs), nullptr);
dan sinclair18b32852020-04-07 12:56:45 +0000355
Ben Clayton33352542021-01-29 16:43:41 +0000356 EXPECT_TRUE(TypeOf(stmt->condition())->Is<type::I32>());
357 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
358 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
dan sinclair18b32852020-04-07 12:56:45 +0000359}
360
dan sinclair50080b72020-07-21 13:42:13 +0000361TEST_F(TypeDeterminerTest, Stmt_Call) {
dan sinclair50080b72020-07-21 13:42:13 +0000362 ast::VariableList params;
Ben Clayton42d1e092021-02-02 14:29:15 +0000363 Func("my_func", params, ty.f32(), ast::StatementList{},
364 ast::FunctionDecorationList{});
dan sinclair50080b72020-07-21 13:42:13 +0000365
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000366 auto* expr = Call("my_func");
dan sinclair50080b72020-07-21 13:42:13 +0000367
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000368 auto* call = create<ast::CallStatement>(expr);
Ben Clayton401b96b2021-02-03 17:19:59 +0000369 WrapInFunction(call);
370
371 EXPECT_TRUE(td()->Determine()) << td()->error();
372
Ben Clayton33352542021-01-29 16:43:41 +0000373 ASSERT_NE(TypeOf(expr), nullptr);
374 EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +0000375 EXPECT_EQ(StmtOf(expr), call);
dan sinclair50080b72020-07-21 13:42:13 +0000376}
377
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000378TEST_F(TypeDeterminerTest, Stmt_Call_undeclared) {
379 // fn main() -> void {func(); return; }
380 // fn func() -> void { return; }
Ben Claytondb5ce652020-12-14 20:25:27 +0000381
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000382 SetSource(Source::Location{12, 34});
383 auto* call_expr = Call("func");
384 ast::VariableList params0;
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000385
Ben Clayton42d1e092021-02-02 14:29:15 +0000386 Func("main", params0, ty.f32(),
387 ast::StatementList{
388 create<ast::CallStatement>(call_expr),
389 create<ast::ReturnStatement>(),
390 },
391 ast::FunctionDecorationList{});
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000392
Ben Clayton42d1e092021-02-02 14:29:15 +0000393 Func("func", params0, ty.f32(),
394 ast::StatementList{
395 create<ast::ReturnStatement>(),
396 },
397 ast::FunctionDecorationList{});
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000398
Ben Clayton401b96b2021-02-03 17:19:59 +0000399 EXPECT_FALSE(td()->Determine());
400
Ben Clayton33a8cdd2021-02-24 13:31:22 +0000401 EXPECT_EQ(td()->error(),
402 "12:34 error: v-0006: unable to find called function: func");
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000403}
404
dan sinclairf8fa6cf2021-02-24 22:11:34 +0000405TEST_F(TypeDeterminerTest, Stmt_Call_recursive) {
406 // fn main() -> void {main(); }
407
408 SetSource(Source::Location{12, 34});
409 auto* call_expr = Call("main");
410 ast::VariableList params0;
411
412 Func("main", params0, ty.f32(),
413 ast::StatementList{
414 create<ast::CallStatement>(call_expr),
415 },
416 ast::FunctionDecorationList{
417 create<ast::StageDecoration>(ast::PipelineStage::kVertex),
418 });
419
420 EXPECT_FALSE(td()->Determine());
421
422 EXPECT_EQ(td()->error(),
423 "12:34 error: recursion is not permitted. 'main' attempted to call "
424 "itself.");
425}
426
dan sinclairca893e32020-04-07 12:57:12 +0000427TEST_F(TypeDeterminerTest, Stmt_VariableDecl) {
Ben Clayton81a29fe2021-02-17 00:26:52 +0000428 auto* var = Var("my_var", ty.i32(), ast::StorageClass::kNone, Expr(2));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000429 auto* init = var->constructor();
dan sinclairca893e32020-04-07 12:57:12 +0000430
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000431 auto* decl = create<ast::VariableDeclStatement>(var);
Ben Clayton401b96b2021-02-03 17:19:59 +0000432 WrapInFunction(decl);
dan sinclairca893e32020-04-07 12:57:12 +0000433
Ben Clayton401b96b2021-02-03 17:19:59 +0000434 EXPECT_TRUE(td()->Determine()) << td()->error();
435
Ben Clayton33352542021-01-29 16:43:41 +0000436 ASSERT_NE(TypeOf(init), nullptr);
437 EXPECT_TRUE(TypeOf(init)->Is<type::I32>());
dan sinclairca893e32020-04-07 12:57:12 +0000438}
439
Antonio Maiorano6ce2edf2021-02-26 18:25:56 +0000440TEST_F(TypeDeterminerTest, Stmt_VariableDecl_Alias) {
441 auto* my_int = ty.alias("MyInt", ty.i32());
442 auto* var = Var("my_var", my_int, ast::StorageClass::kNone, Expr(2));
443 auto* init = var->constructor();
444
445 auto* decl = create<ast::VariableDeclStatement>(var);
446 WrapInFunction(decl);
447
448 EXPECT_TRUE(td()->Determine()) << td()->error();
449
450 ASSERT_NE(TypeOf(init), nullptr);
451 EXPECT_TRUE(TypeOf(init)->Is<type::I32>());
452}
453
454TEST_F(TypeDeterminerTest, Stmt_VariableDecl_MismatchedTypeScalarConstructor) {
455 u32 unsigned_value = 2u; // Type does not match variable type
456 auto* var =
457 Var("my_var", ty.i32(), ast::StorageClass::kNone, Expr(unsigned_value));
458
459 auto* decl =
460 create<ast::VariableDeclStatement>(Source{{{3, 3}, {3, 22}}}, var);
461 WrapInFunction(decl);
462
463 EXPECT_FALSE(td()->Determine());
464 EXPECT_EQ(
465 td()->error(),
466 R"(3:3 error: constructor expression type does not match variable type)");
467}
468
469TEST_F(TypeDeterminerTest,
470 Stmt_VariableDecl_MismatchedTypeScalarConstructor_Alias) {
471 auto* my_int = ty.alias("MyInt", ty.i32());
472 u32 unsigned_value = 2u; // Type does not match variable type
473 auto* var =
474 Var("my_var", my_int, ast::StorageClass::kNone, Expr(unsigned_value));
475
476 auto* decl =
477 create<ast::VariableDeclStatement>(Source{{{3, 3}, {3, 22}}}, var);
478 WrapInFunction(decl);
479
480 EXPECT_FALSE(td()->Determine());
481 EXPECT_EQ(
482 td()->error(),
483 R"(3:3 error: constructor expression type does not match variable type)");
484}
485
dan sinclair7be237a2020-06-15 20:55:09 +0000486TEST_F(TypeDeterminerTest, Stmt_VariableDecl_ModuleScope) {
Ben Claytonf97b9c92021-02-16 18:45:45 +0000487 auto* init = Expr(2);
Ben Clayton81a29fe2021-02-17 00:26:52 +0000488 Global("my_var", ty.i32(), ast::StorageClass::kNone, init);
dan sinclair7be237a2020-06-15 20:55:09 +0000489
Ben Clayton401b96b2021-02-03 17:19:59 +0000490 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair7be237a2020-06-15 20:55:09 +0000491
Ben Clayton33352542021-01-29 16:43:41 +0000492 ASSERT_NE(TypeOf(init), nullptr);
493 EXPECT_TRUE(TypeOf(init)->Is<type::I32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +0000494 EXPECT_EQ(StmtOf(init), nullptr);
dan sinclair7be237a2020-06-15 20:55:09 +0000495}
496
James Price77f4f022021-02-04 16:33:20 +0000497TEST_F(TypeDeterminerTest, Stmt_VariableDecl_OuterScopeAfterInnerScope) {
498 // fn func_i32() -> i32 {
499 // {
500 // var foo : i32 = 2;
501 // var bar : i32 = foo;
502 // }
503 // var foo : f32 = 2.0;
504 // var bar : f32 = foo;
505 // }
506
507 ast::VariableList params;
508
509 // Declare i32 "foo" inside a block
Ben Clayton81a29fe2021-02-17 00:26:52 +0000510 auto* foo_i32 = Var("foo", ty.i32(), ast::StorageClass::kNone, Expr(2));
James Price77f4f022021-02-04 16:33:20 +0000511 auto* foo_i32_init = foo_i32->constructor();
512 auto* foo_i32_decl = create<ast::VariableDeclStatement>(foo_i32);
513
514 // Reference "foo" inside the block
Ben Clayton81a29fe2021-02-17 00:26:52 +0000515 auto* bar_i32 = Var("bar", ty.i32(), ast::StorageClass::kNone, Expr("foo"));
James Price77f4f022021-02-04 16:33:20 +0000516 auto* bar_i32_init = bar_i32->constructor();
517 auto* bar_i32_decl = create<ast::VariableDeclStatement>(bar_i32);
518
519 auto* inner = create<ast::BlockStatement>(
520 ast::StatementList{foo_i32_decl, bar_i32_decl});
521
522 // Declare f32 "foo" at function scope
Ben Clayton81a29fe2021-02-17 00:26:52 +0000523 auto* foo_f32 = Var("foo", ty.f32(), ast::StorageClass::kNone, Expr(2.f));
James Price77f4f022021-02-04 16:33:20 +0000524 auto* foo_f32_init = foo_f32->constructor();
525 auto* foo_f32_decl = create<ast::VariableDeclStatement>(foo_f32);
526
527 // Reference "foo" at function scope
Ben Clayton81a29fe2021-02-17 00:26:52 +0000528 auto* bar_f32 = Var("bar", ty.f32(), ast::StorageClass::kNone, Expr("foo"));
James Price77f4f022021-02-04 16:33:20 +0000529 auto* bar_f32_init = bar_f32->constructor();
530 auto* bar_f32_decl = create<ast::VariableDeclStatement>(bar_f32);
531
532 Func("func", params, ty.f32(),
533 ast::StatementList{inner, foo_f32_decl, bar_f32_decl},
534 ast::FunctionDecorationList{});
535
536 EXPECT_TRUE(td()->Determine());
537 ASSERT_NE(TypeOf(foo_i32_init), nullptr);
538 EXPECT_TRUE(TypeOf(foo_i32_init)->Is<type::I32>());
539 ASSERT_NE(TypeOf(foo_f32_init), nullptr);
540 EXPECT_TRUE(TypeOf(foo_f32_init)->Is<type::F32>());
541 ASSERT_NE(TypeOf(bar_i32_init), nullptr);
542 EXPECT_TRUE(TypeOf(bar_i32_init)->UnwrapAll()->Is<type::I32>());
543 ASSERT_NE(TypeOf(bar_f32_init), nullptr);
544 EXPECT_TRUE(TypeOf(bar_f32_init)->UnwrapAll()->Is<type::F32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +0000545 EXPECT_EQ(StmtOf(foo_i32_init), foo_i32_decl);
546 EXPECT_EQ(StmtOf(bar_i32_init), bar_i32_decl);
547 EXPECT_EQ(StmtOf(foo_f32_init), foo_f32_decl);
548 EXPECT_EQ(StmtOf(bar_f32_init), bar_f32_decl);
James Pricec9af5972021-02-16 21:15:01 +0000549 EXPECT_TRUE(CheckVarUsers(foo_i32, {bar_i32->constructor()}));
550 EXPECT_TRUE(CheckVarUsers(foo_f32, {bar_f32->constructor()}));
James Price77f4f022021-02-04 16:33:20 +0000551}
552
553TEST_F(TypeDeterminerTest, Stmt_VariableDecl_ModuleScopeAfterFunctionScope) {
554 // fn func_i32() -> i32 {
555 // var foo : i32 = 2;
556 // }
557 // var foo : f32 = 2.0;
558 // fn func_f32() -> f32 {
559 // var bar : f32 = foo;
560 // }
561
562 ast::VariableList params;
563
564 // Declare i32 "foo" inside a function
Ben Clayton81a29fe2021-02-17 00:26:52 +0000565 auto* fn_i32 = Var("foo", ty.i32(), ast::StorageClass::kNone, Expr(2));
James Price77f4f022021-02-04 16:33:20 +0000566 auto* fn_i32_init = fn_i32->constructor();
567 auto* fn_i32_decl = create<ast::VariableDeclStatement>(fn_i32);
568 Func("func_i32", params, ty.i32(), ast::StatementList{fn_i32_decl},
569 ast::FunctionDecorationList{});
570
571 // Declare f32 "foo" at module scope
Ben Clayton81a29fe2021-02-17 00:26:52 +0000572 auto* mod_f32 = Var("foo", ty.f32(), ast::StorageClass::kNone, Expr(2.f));
James Price77f4f022021-02-04 16:33:20 +0000573 auto* mod_init = mod_f32->constructor();
574 AST().AddGlobalVariable(mod_f32);
575
576 // Reference "foo" in another function
Ben Clayton81a29fe2021-02-17 00:26:52 +0000577 auto* fn_f32 = Var("bar", ty.f32(), ast::StorageClass::kNone, Expr("foo"));
James Price77f4f022021-02-04 16:33:20 +0000578 auto* fn_f32_init = fn_f32->constructor();
579 auto* fn_f32_decl = create<ast::VariableDeclStatement>(fn_f32);
580 Func("func_f32", params, ty.f32(), ast::StatementList{fn_f32_decl},
581 ast::FunctionDecorationList{});
582
583 EXPECT_TRUE(td()->Determine());
584 ASSERT_NE(TypeOf(mod_init), nullptr);
585 EXPECT_TRUE(TypeOf(mod_init)->Is<type::F32>());
586 ASSERT_NE(TypeOf(fn_i32_init), nullptr);
587 EXPECT_TRUE(TypeOf(fn_i32_init)->Is<type::I32>());
588 ASSERT_NE(TypeOf(fn_f32_init), nullptr);
589 EXPECT_TRUE(TypeOf(fn_f32_init)->UnwrapAll()->Is<type::F32>());
Ben Claytonf97b9c92021-02-16 18:45:45 +0000590 EXPECT_EQ(StmtOf(fn_i32_init), fn_i32_decl);
591 EXPECT_EQ(StmtOf(mod_init), nullptr);
592 EXPECT_EQ(StmtOf(fn_f32_init), fn_f32_decl);
James Pricec9af5972021-02-16 21:15:01 +0000593 EXPECT_TRUE(CheckVarUsers(fn_i32, {}));
594 EXPECT_TRUE(CheckVarUsers(mod_f32, {fn_f32->constructor()}));
James Price77f4f022021-02-04 16:33:20 +0000595}
596
dan sinclair7456f422020-04-08 19:58:35 +0000597TEST_F(TypeDeterminerTest, Expr_Error_Unknown) {
Ben Clayton604bc722020-12-12 01:24:53 +0000598 FakeExpr e(Source{Source::Location{2, 30}});
Ben Clayton401b96b2021-02-03 17:19:59 +0000599 WrapInFunction(&e);
dan sinclair7456f422020-04-08 19:58:35 +0000600
Ben Clayton401b96b2021-02-03 17:19:59 +0000601 EXPECT_FALSE(td()->Determine());
602
Ben Clayton6b4924f2021-02-17 20:13:34 +0000603 EXPECT_EQ(td()->error(),
604 "2:30 error: unknown expression for type determination");
dan sinclair7456f422020-04-08 19:58:35 +0000605}
606
dan sinclair973bd6a2020-04-07 12:57:42 +0000607TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000608 auto* idx = Expr(2);
Ben Clayton37571bc2021-02-16 23:57:01 +0000609 Global("my_var", ty.array<f32, 3>(), ast::StorageClass::kFunction);
dan sinclair8eddb782020-04-23 22:26:52 +0000610
dan sinclair8b40a672020-12-16 11:49:10 +0000611 auto* acc = IndexAccessor("my_var", idx);
Ben Clayton401b96b2021-02-03 17:19:59 +0000612 WrapInFunction(acc);
613
614 EXPECT_TRUE(td()->Determine()) << td()->error();
615
Ben Clayton33352542021-01-29 16:43:41 +0000616 ASSERT_NE(TypeOf(acc), nullptr);
617 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000618
Ben Clayton33352542021-01-29 16:43:41 +0000619 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000620 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000621}
622
David Neto9c88ea52020-06-22 20:33:12 +0000623TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Alias_Array) {
Ben Clayton1637cbb2021-01-05 15:44:39 +0000624 auto* aary = ty.alias("myarrty", ty.array<f32, 3>());
David Neto9c88ea52020-06-22 20:33:12 +0000625
Ben Clayton37571bc2021-02-16 23:57:01 +0000626 Global("my_var", aary, ast::StorageClass::kFunction);
David Neto9c88ea52020-06-22 20:33:12 +0000627
dan sinclair8b40a672020-12-16 11:49:10 +0000628 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton401b96b2021-02-03 17:19:59 +0000629 WrapInFunction(acc);
630
631 EXPECT_TRUE(td()->Determine()) << td()->error();
632
Ben Clayton33352542021-01-29 16:43:41 +0000633 ASSERT_NE(TypeOf(acc), nullptr);
634 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
David Neto9c88ea52020-06-22 20:33:12 +0000635
Ben Clayton33352542021-01-29 16:43:41 +0000636 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000637 EXPECT_TRUE(ptr->type()->Is<type::F32>());
David Neto9c88ea52020-06-22 20:33:12 +0000638}
639
dan sinclair8eddb782020-04-23 22:26:52 +0000640TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array_Constant) {
Ben Clayton81a29fe2021-02-17 00:26:52 +0000641 GlobalConst("my_var", ty.array<f32, 3>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000642
dan sinclair8b40a672020-12-16 11:49:10 +0000643 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton401b96b2021-02-03 17:19:59 +0000644 WrapInFunction(acc);
645
646 EXPECT_TRUE(td()->Determine()) << td()->error();
647
Ben Clayton33352542021-01-29 16:43:41 +0000648 ASSERT_NE(TypeOf(acc), nullptr);
649 EXPECT_TRUE(TypeOf(acc)->Is<type::F32>()) << TypeOf(acc)->type_name();
dan sinclair973bd6a2020-04-07 12:57:42 +0000650}
651
652TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000653 Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kNone);
dan sinclair973bd6a2020-04-07 12:57:42 +0000654
dan sinclair8b40a672020-12-16 11:49:10 +0000655 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton401b96b2021-02-03 17:19:59 +0000656 WrapInFunction(acc);
657
658 EXPECT_TRUE(td()->Determine()) << td()->error();
659
Ben Clayton33352542021-01-29 16:43:41 +0000660 ASSERT_NE(TypeOf(acc), nullptr);
661 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000662
Ben Clayton33352542021-01-29 16:43:41 +0000663 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000664 ASSERT_TRUE(ptr->type()->Is<type::Vector>());
665 EXPECT_EQ(ptr->type()->As<type::Vector>()->size(), 3u);
dan sinclair973bd6a2020-04-07 12:57:42 +0000666}
667
668TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix_BothDimensions) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000669 Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kNone);
dan sinclair973bd6a2020-04-07 12:57:42 +0000670
dan sinclair8b40a672020-12-16 11:49:10 +0000671 auto* acc = IndexAccessor(IndexAccessor("my_var", 2), 1);
Ben Clayton401b96b2021-02-03 17:19:59 +0000672 WrapInFunction(acc);
dan sinclair973bd6a2020-04-07 12:57:42 +0000673
Ben Clayton401b96b2021-02-03 17:19:59 +0000674 EXPECT_TRUE(td()->Determine()) << td()->error();
675
Ben Clayton33352542021-01-29 16:43:41 +0000676 ASSERT_NE(TypeOf(acc), nullptr);
677 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000678
Ben Clayton33352542021-01-29 16:43:41 +0000679 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000680 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000681}
682
683TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Vector) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000684 Global("my_var", ty.vec3<f32>(), ast::StorageClass::kNone);
dan sinclair973bd6a2020-04-07 12:57:42 +0000685
dan sinclair8b40a672020-12-16 11:49:10 +0000686 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton401b96b2021-02-03 17:19:59 +0000687 WrapInFunction(acc);
688
689 EXPECT_TRUE(td()->Determine()) << td()->error();
690
Ben Clayton33352542021-01-29 16:43:41 +0000691 ASSERT_NE(TypeOf(acc), nullptr);
692 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000693
Ben Clayton33352542021-01-29 16:43:41 +0000694 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000695 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000696}
697
dan sinclaira7d498e2020-09-22 22:07:13 +0000698TEST_F(TypeDeterminerTest, Expr_Bitcast) {
Ben Clayton8d391f72021-01-26 16:57:10 +0000699 auto* bitcast = create<ast::BitcastExpression>(ty.f32(), Expr("name"));
Ben Clayton401b96b2021-02-03 17:19:59 +0000700 WrapInFunction(bitcast);
dan sinclaira01777c2020-04-07 12:57:52 +0000701
Ben Clayton37571bc2021-02-16 23:57:01 +0000702 Global("name", ty.f32(), ast::StorageClass::kPrivate);
dan sinclairff267ca2020-10-14 18:26:31 +0000703
Ben Clayton401b96b2021-02-03 17:19:59 +0000704 EXPECT_TRUE(td()->Determine()) << td()->error();
705
Ben Clayton33352542021-01-29 16:43:41 +0000706 ASSERT_NE(TypeOf(bitcast), nullptr);
707 EXPECT_TRUE(TypeOf(bitcast)->Is<type::F32>());
dan sinclaira01777c2020-04-07 12:57:52 +0000708}
709
dan sinclair3ca87462020-04-07 16:41:10 +0000710TEST_F(TypeDeterminerTest, Expr_Call) {
dan sinclair3ca87462020-04-07 16:41:10 +0000711 ast::VariableList params;
Ben Clayton42d1e092021-02-02 14:29:15 +0000712 Func("my_func", params, ty.f32(), ast::StatementList{},
713 ast::FunctionDecorationList{});
dan sinclair3ca87462020-04-07 16:41:10 +0000714
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000715 auto* call = Call("my_func");
Ben Clayton401b96b2021-02-03 17:19:59 +0000716 WrapInFunction(call);
717
718 EXPECT_TRUE(td()->Determine()) << td()->error();
719
Ben Clayton33352542021-01-29 16:43:41 +0000720 ASSERT_NE(TypeOf(call), nullptr);
721 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclair3ca87462020-04-07 16:41:10 +0000722}
723
Ben Clayton7b7d6982021-02-09 17:38:05 +0000724TEST_F(TypeDeterminerTest, Expr_Call_InBinaryOp) {
725 ast::VariableList params;
726 Func("func", params, ty.f32(), ast::StatementList{},
727 ast::FunctionDecorationList{});
728
729 auto* expr = Add(Call("func"), Call("func"));
730 WrapInFunction(expr);
731
732 EXPECT_TRUE(td()->Determine()) << td()->error();
733
734 ASSERT_NE(TypeOf(expr), nullptr);
735 EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
736}
737
dan sinclairccb52dc2020-04-20 14:18:54 +0000738TEST_F(TypeDeterminerTest, Expr_Call_WithParams) {
dan sinclairccb52dc2020-04-20 14:18:54 +0000739 ast::VariableList params;
Ben Clayton42d1e092021-02-02 14:29:15 +0000740 Func("my_func", params, ty.f32(), ast::StatementList{},
741 ast::FunctionDecorationList{});
dan sinclairccb52dc2020-04-20 14:18:54 +0000742
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000743 auto* param = Expr(2.4f);
dan sinclairccb52dc2020-04-20 14:18:54 +0000744
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000745 auto* call = Call("my_func", param);
Ben Clayton401b96b2021-02-03 17:19:59 +0000746 WrapInFunction(call);
747
748 EXPECT_TRUE(td()->Determine()) << td()->error();
749
Ben Clayton33352542021-01-29 16:43:41 +0000750 ASSERT_NE(TypeOf(param), nullptr);
751 EXPECT_TRUE(TypeOf(param)->Is<type::F32>());
dan sinclairccb52dc2020-04-20 14:18:54 +0000752}
753
dan sinclairb4fee2f2020-09-22 19:42:13 +0000754TEST_F(TypeDeterminerTest, Expr_Call_Intrinsic) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000755 auto* call = Call("round", 2.4f);
Ben Clayton401b96b2021-02-03 17:19:59 +0000756 WrapInFunction(call);
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000757
Ben Clayton401b96b2021-02-03 17:19:59 +0000758 EXPECT_TRUE(td()->Determine()) << td()->error();
759
Ben Clayton33352542021-01-29 16:43:41 +0000760 ASSERT_NE(TypeOf(call), nullptr);
761 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000762}
763
Ben Clayton33a8cdd2021-02-24 13:31:22 +0000764TEST_F(TypeDeterminerTest, Expr_DontCall_Function) {
765 Func("func", {}, ty.void_(), {}, {});
766 auto* ident = create<ast::IdentifierExpression>(
767 Source{{Source::Location{3, 3}, Source::Location{3, 8}}},
768 Symbols().Register("func"));
769 WrapInFunction(ident);
770
771 EXPECT_FALSE(td()->Determine());
772 EXPECT_EQ(td()->error(), "3:8 error: missing '(' for function call");
773}
774
775TEST_F(TypeDeterminerTest, Expr_DontCall_Intrinsic) {
776 auto* ident = create<ast::IdentifierExpression>(
777 Source{{Source::Location{3, 3}, Source::Location{3, 8}}},
778 Symbols().Register("round"));
779 WrapInFunction(ident);
780
781 EXPECT_FALSE(td()->Determine());
782 EXPECT_EQ(td()->error(), "3:8 error: missing '(' for intrinsic call");
783}
784
dan sinclair4e807952020-04-07 16:41:23 +0000785TEST_F(TypeDeterminerTest, Expr_Cast) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000786 Global("name", ty.f32(), ast::StorageClass::kPrivate);
Ben Clayton401b96b2021-02-03 17:19:59 +0000787
Ben Clayton8d391f72021-01-26 16:57:10 +0000788 auto* cast = Construct(ty.f32(), "name");
Ben Clayton401b96b2021-02-03 17:19:59 +0000789 WrapInFunction(cast);
dan sinclair3c025922020-09-24 14:38:44 +0000790
Ben Clayton401b96b2021-02-03 17:19:59 +0000791 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair4e807952020-04-07 16:41:23 +0000792
Ben Clayton33352542021-01-29 16:43:41 +0000793 ASSERT_NE(TypeOf(cast), nullptr);
794 EXPECT_TRUE(TypeOf(cast)->Is<type::F32>());
dan sinclair4e807952020-04-07 16:41:23 +0000795}
796
dan sinclairb7edc4c2020-04-07 12:46:30 +0000797TEST_F(TypeDeterminerTest, Expr_Constructor_Scalar) {
Ben Clayton1637cbb2021-01-05 15:44:39 +0000798 auto* s = Expr(1.0f);
Ben Clayton401b96b2021-02-03 17:19:59 +0000799 WrapInFunction(s);
800
801 EXPECT_TRUE(td()->Determine()) << td()->error();
802
Ben Clayton33352542021-01-29 16:43:41 +0000803 ASSERT_NE(TypeOf(s), nullptr);
804 EXPECT_TRUE(TypeOf(s)->Is<type::F32>());
dan sinclairb7edc4c2020-04-07 12:46:30 +0000805}
806
807TEST_F(TypeDeterminerTest, Expr_Constructor_Type) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000808 auto* tc = vec3<f32>(1.0f, 1.0f, 3.0f);
Ben Clayton401b96b2021-02-03 17:19:59 +0000809 WrapInFunction(tc);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000810
Ben Clayton401b96b2021-02-03 17:19:59 +0000811 EXPECT_TRUE(td()->Determine()) << td()->error();
812
Ben Clayton33352542021-01-29 16:43:41 +0000813 ASSERT_NE(TypeOf(tc), nullptr);
814 ASSERT_TRUE(TypeOf(tc)->Is<type::Vector>());
815 EXPECT_TRUE(TypeOf(tc)->As<type::Vector>()->type()->Is<type::F32>());
816 EXPECT_EQ(TypeOf(tc)->As<type::Vector>()->size(), 3u);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000817}
818
dan sinclaircab0e732020-04-07 12:57:27 +0000819TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalVariable) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000820 auto* my_var = Global("my_var", ty.f32(), ast::StorageClass::kNone);
dan sinclaircab0e732020-04-07 12:57:27 +0000821
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000822 auto* ident = Expr("my_var");
Ben Clayton401b96b2021-02-03 17:19:59 +0000823 WrapInFunction(ident);
824
825 EXPECT_TRUE(td()->Determine()) << td()->error();
826
Ben Clayton33352542021-01-29 16:43:41 +0000827 ASSERT_NE(TypeOf(ident), nullptr);
828 EXPECT_TRUE(TypeOf(ident)->Is<type::Pointer>());
829 EXPECT_TRUE(TypeOf(ident)->As<type::Pointer>()->type()->Is<type::F32>());
James Pricec9af5972021-02-16 21:15:01 +0000830 EXPECT_TRUE(CheckVarUsers(my_var, {ident}));
dan sinclair8eddb782020-04-23 22:26:52 +0000831}
832
833TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalConstant) {
Ben Clayton81a29fe2021-02-17 00:26:52 +0000834 auto* my_var = GlobalConst("my_var", ty.f32());
dan sinclair8eddb782020-04-23 22:26:52 +0000835
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000836 auto* ident = Expr("my_var");
Ben Clayton401b96b2021-02-03 17:19:59 +0000837 WrapInFunction(ident);
838
839 EXPECT_TRUE(td()->Determine()) << td()->error();
840
Ben Clayton33352542021-01-29 16:43:41 +0000841 ASSERT_NE(TypeOf(ident), nullptr);
842 EXPECT_TRUE(TypeOf(ident)->Is<type::F32>());
James Pricec9af5972021-02-16 21:15:01 +0000843 EXPECT_TRUE(CheckVarUsers(my_var, {ident}));
dan sinclaircab0e732020-04-07 12:57:27 +0000844}
845
dan sinclair8eddb782020-04-23 22:26:52 +0000846TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable_Const) {
Ben Claytonf97b9c92021-02-16 18:45:45 +0000847 auto* my_var_a = Expr("my_var");
848 auto* my_var_b = Expr("my_var");
Ben Clayton81a29fe2021-02-17 00:26:52 +0000849 auto* var = Const("my_var", ty.f32());
Ben Claytonf97b9c92021-02-16 18:45:45 +0000850 auto* assign = create<ast::AssignmentStatement>(my_var_a, my_var_b);
dan sinclair8eddb782020-04-23 22:26:52 +0000851
Ben Clayton401b96b2021-02-03 17:19:59 +0000852 Func("my_func", ast::VariableList{}, ty.f32(),
853 ast::StatementList{
854 create<ast::VariableDeclStatement>(var),
Ben Claytonf97b9c92021-02-16 18:45:45 +0000855 assign,
Ben Clayton401b96b2021-02-03 17:19:59 +0000856 },
857 ast::FunctionDecorationList{});
dan sinclair8eddb782020-04-23 22:26:52 +0000858
Ben Clayton401b96b2021-02-03 17:19:59 +0000859 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair8eddb782020-04-23 22:26:52 +0000860
Ben Claytonf97b9c92021-02-16 18:45:45 +0000861 ASSERT_NE(TypeOf(my_var_a), nullptr);
862 EXPECT_TRUE(TypeOf(my_var_a)->Is<type::F32>());
863 EXPECT_EQ(StmtOf(my_var_a), assign);
864 ASSERT_NE(TypeOf(my_var_b), nullptr);
865 EXPECT_TRUE(TypeOf(my_var_b)->Is<type::F32>());
866 EXPECT_EQ(StmtOf(my_var_b), assign);
James Pricec9af5972021-02-16 21:15:01 +0000867 EXPECT_TRUE(CheckVarUsers(var, {my_var_a, my_var_b}));
dan sinclair8eddb782020-04-23 22:26:52 +0000868}
869
dan sinclaircab0e732020-04-07 12:57:27 +0000870TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable) {
Ben Claytonf97b9c92021-02-16 18:45:45 +0000871 auto* my_var_a = Expr("my_var");
872 auto* my_var_b = Expr("my_var");
873 auto* assign = create<ast::AssignmentStatement>(my_var_a, my_var_b);
dan sinclaircab0e732020-04-07 12:57:27 +0000874
Ben Clayton37571bc2021-02-16 23:57:01 +0000875 auto* var = Var("my_var", ty.f32(), ast::StorageClass::kNone);
James Pricec9af5972021-02-16 21:15:01 +0000876
Ben Clayton401b96b2021-02-03 17:19:59 +0000877 Func("my_func", ast::VariableList{}, ty.f32(),
878 ast::StatementList{
James Pricec9af5972021-02-16 21:15:01 +0000879 create<ast::VariableDeclStatement>(var),
Ben Claytonf97b9c92021-02-16 18:45:45 +0000880 assign,
Ben Clayton401b96b2021-02-03 17:19:59 +0000881 },
882 ast::FunctionDecorationList{});
dan sinclaircab0e732020-04-07 12:57:27 +0000883
Ben Clayton401b96b2021-02-03 17:19:59 +0000884 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclaircab0e732020-04-07 12:57:27 +0000885
Ben Claytonf97b9c92021-02-16 18:45:45 +0000886 ASSERT_NE(TypeOf(my_var_a), nullptr);
887 EXPECT_TRUE(TypeOf(my_var_a)->Is<type::Pointer>());
888 EXPECT_TRUE(TypeOf(my_var_a)->As<type::Pointer>()->type()->Is<type::F32>());
889 EXPECT_EQ(StmtOf(my_var_a), assign);
890 ASSERT_NE(TypeOf(my_var_b), nullptr);
891 EXPECT_TRUE(TypeOf(my_var_b)->Is<type::Pointer>());
892 EXPECT_TRUE(TypeOf(my_var_b)->As<type::Pointer>()->type()->Is<type::F32>());
893 EXPECT_EQ(StmtOf(my_var_b), assign);
James Pricec9af5972021-02-16 21:15:01 +0000894 EXPECT_TRUE(CheckVarUsers(var, {my_var_a, my_var_b}));
dan sinclaircab0e732020-04-07 12:57:27 +0000895}
896
dan sinclair5e989302020-09-16 21:20:36 +0000897TEST_F(TypeDeterminerTest, Expr_Identifier_Function_Ptr) {
Ben Claytonf97b9c92021-02-16 18:45:45 +0000898 auto* my_var_a = Expr("my_var");
899 auto* my_var_b = Expr("my_var");
900 auto* assign = create<ast::AssignmentStatement>(my_var_a, my_var_b);
dan sinclair5e989302020-09-16 21:20:36 +0000901
Ben Clayton401b96b2021-02-03 17:19:59 +0000902 Func("my_func", ast::VariableList{}, ty.f32(),
903 ast::StatementList{
904 create<ast::VariableDeclStatement>(
Ben Clayton37571bc2021-02-16 23:57:01 +0000905 Var("my_var", ty.pointer<f32>(ast::StorageClass::kFunction),
906 ast::StorageClass::kNone)),
Ben Claytonf97b9c92021-02-16 18:45:45 +0000907 assign,
Ben Clayton401b96b2021-02-03 17:19:59 +0000908 },
909 ast::FunctionDecorationList{});
dan sinclair5e989302020-09-16 21:20:36 +0000910
Ben Clayton401b96b2021-02-03 17:19:59 +0000911 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair5e989302020-09-16 21:20:36 +0000912
Ben Claytonf97b9c92021-02-16 18:45:45 +0000913 ASSERT_NE(TypeOf(my_var_a), nullptr);
914 EXPECT_TRUE(TypeOf(my_var_a)->Is<type::Pointer>());
915 EXPECT_TRUE(TypeOf(my_var_a)->As<type::Pointer>()->type()->Is<type::F32>());
916 EXPECT_EQ(StmtOf(my_var_a), assign);
917 ASSERT_NE(TypeOf(my_var_b), nullptr);
918 EXPECT_TRUE(TypeOf(my_var_b)->Is<type::Pointer>());
919 EXPECT_TRUE(TypeOf(my_var_b)->As<type::Pointer>()->type()->Is<type::F32>());
920 EXPECT_EQ(StmtOf(my_var_b), assign);
dan sinclair5e989302020-09-16 21:20:36 +0000921}
922
Ben Clayton1618f4b2021-02-03 21:02:25 +0000923TEST_F(TypeDeterminerTest, Expr_Call_Function) {
Ben Clayton42d1e092021-02-02 14:29:15 +0000924 Func("my_func", ast::VariableList{}, ty.f32(), ast::StatementList{},
925 ast::FunctionDecorationList{});
dan sinclaircab0e732020-04-07 12:57:27 +0000926
Ben Clayton1618f4b2021-02-03 21:02:25 +0000927 auto* call = Call("my_func");
928 WrapInFunction(call);
Ben Clayton401b96b2021-02-03 17:19:59 +0000929
930 EXPECT_TRUE(td()->Determine()) << td()->error();
931
Ben Clayton1618f4b2021-02-03 21:02:25 +0000932 ASSERT_NE(TypeOf(call), nullptr);
933 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000934}
935
dan sinclairff267ca2020-10-14 18:26:31 +0000936TEST_F(TypeDeterminerTest, Expr_Identifier_Unknown) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000937 auto* a = Expr("a");
Ben Clayton401b96b2021-02-03 17:19:59 +0000938 WrapInFunction(a);
939
940 EXPECT_FALSE(td()->Determine());
dan sinclairff267ca2020-10-14 18:26:31 +0000941}
942
dan sinclair13d2a3b2020-06-22 20:52:24 +0000943TEST_F(TypeDeterminerTest, Function_RegisterInputOutputVariables) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000944 auto* in_var = Global("in_var", ty.f32(), ast::StorageClass::kInput);
945 auto* out_var = Global("out_var", ty.f32(), ast::StorageClass::kOutput);
946 auto* sb_var = Global("sb_var", ty.f32(), ast::StorageClass::kStorage);
947 auto* wg_var = Global("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
948 auto* priv_var = Global("priv_var", ty.f32(), ast::StorageClass::kPrivate);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000949
dan sinclair181d8ba2020-12-16 15:15:40 +0000950 auto* func = Func(
Ben Clayton8d391f72021-01-26 16:57:10 +0000951 "my_func", ast::VariableList{}, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000952 ast::StatementList{
953 create<ast::AssignmentStatement>(Expr("out_var"), Expr("in_var")),
954 create<ast::AssignmentStatement>(Expr("wg_var"), Expr("wg_var")),
955 create<ast::AssignmentStatement>(Expr("sb_var"), Expr("sb_var")),
956 create<ast::AssignmentStatement>(Expr("priv_var"), Expr("priv_var")),
957 },
958 ast::FunctionDecorationList{});
dan sinclair13d2a3b2020-06-22 20:52:24 +0000959
Ben Clayton401b96b2021-02-03 17:19:59 +0000960 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair13d2a3b2020-06-22 20:52:24 +0000961
Ben Clayton87c78dd2021-02-03 16:43:20 +0000962 auto* func_sem = Sem().Get(func);
963 ASSERT_NE(func_sem, nullptr);
964
965 const auto& vars = func_sem->ReferencedModuleVariables();
Ryan Harrison9a452c12020-06-23 16:38:47 +0000966 ASSERT_EQ(vars.size(), 5u);
Ben Claytonb17aea12021-02-03 17:51:09 +0000967 EXPECT_EQ(vars[0]->Declaration(), out_var);
968 EXPECT_EQ(vars[1]->Declaration(), in_var);
969 EXPECT_EQ(vars[2]->Declaration(), wg_var);
970 EXPECT_EQ(vars[3]->Declaration(), sb_var);
971 EXPECT_EQ(vars[4]->Declaration(), priv_var);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000972}
973
dan sinclairde2dd682020-07-14 20:37:28 +0000974TEST_F(TypeDeterminerTest, Function_RegisterInputOutputVariables_SubFunction) {
Ben Clayton37571bc2021-02-16 23:57:01 +0000975 auto* in_var = Global("in_var", ty.f32(), ast::StorageClass::kInput);
976 auto* out_var = Global("out_var", ty.f32(), ast::StorageClass::kOutput);
977 auto* sb_var = Global("sb_var", ty.f32(), ast::StorageClass::kStorage);
978 auto* wg_var = Global("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
979 auto* priv_var = Global("priv_var", ty.f32(), ast::StorageClass::kPrivate);
dan sinclairde2dd682020-07-14 20:37:28 +0000980
Ben Clayton42d1e092021-02-02 14:29:15 +0000981 Func("my_func", ast::VariableList{}, ty.f32(),
982 ast::StatementList{
983 create<ast::AssignmentStatement>(Expr("out_var"), Expr("in_var")),
984 create<ast::AssignmentStatement>(Expr("wg_var"), Expr("wg_var")),
985 create<ast::AssignmentStatement>(Expr("sb_var"), Expr("sb_var")),
986 create<ast::AssignmentStatement>(Expr("priv_var"), Expr("priv_var")),
987 },
988 ast::FunctionDecorationList{});
dan sinclairde2dd682020-07-14 20:37:28 +0000989
dan sinclair181d8ba2020-12-16 15:15:40 +0000990 auto* func2 = Func(
Ben Clayton8d391f72021-01-26 16:57:10 +0000991 "func", ast::VariableList{}, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000992 ast::StatementList{
993 create<ast::AssignmentStatement>(Expr("out_var"), Call("my_func")),
994 },
995 ast::FunctionDecorationList{});
dan sinclairde2dd682020-07-14 20:37:28 +0000996
Ben Clayton401b96b2021-02-03 17:19:59 +0000997 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclairde2dd682020-07-14 20:37:28 +0000998
Ben Clayton87c78dd2021-02-03 16:43:20 +0000999 auto* func2_sem = Sem().Get(func2);
1000 ASSERT_NE(func2_sem, nullptr);
1001
1002 const auto& vars = func2_sem->ReferencedModuleVariables();
dan sinclairde2dd682020-07-14 20:37:28 +00001003 ASSERT_EQ(vars.size(), 5u);
Ben Claytonb17aea12021-02-03 17:51:09 +00001004 EXPECT_EQ(vars[0]->Declaration(), out_var);
1005 EXPECT_EQ(vars[1]->Declaration(), in_var);
1006 EXPECT_EQ(vars[2]->Declaration(), wg_var);
1007 EXPECT_EQ(vars[3]->Declaration(), sb_var);
1008 EXPECT_EQ(vars[4]->Declaration(), priv_var);
dan sinclairde2dd682020-07-14 20:37:28 +00001009}
1010
dan sinclair13d2a3b2020-06-22 20:52:24 +00001011TEST_F(TypeDeterminerTest, Function_NotRegisterFunctionVariable) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001012 auto* var = Var("in_var", ty.f32(), ast::StorageClass::kFunction);
dan sinclair13d2a3b2020-06-22 20:52:24 +00001013
dan sinclair181d8ba2020-12-16 15:15:40 +00001014 auto* func =
Ben Clayton8d391f72021-01-26 16:57:10 +00001015 Func("my_func", ast::VariableList{}, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +00001016 ast::StatementList{
1017 create<ast::VariableDeclStatement>(var),
Ben Clayton1637cbb2021-01-05 15:44:39 +00001018 create<ast::AssignmentStatement>(Expr("var"), Expr(1.f)),
dan sinclair181d8ba2020-12-16 15:15:40 +00001019 },
1020 ast::FunctionDecorationList{});
dan sinclair13d2a3b2020-06-22 20:52:24 +00001021
Ben Clayton37571bc2021-02-16 23:57:01 +00001022 Global("var", ty.f32(), ast::StorageClass::kFunction);
dan sinclairff267ca2020-10-14 18:26:31 +00001023
dan sinclairff267ca2020-10-14 18:26:31 +00001024 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair13d2a3b2020-06-22 20:52:24 +00001025
Ben Clayton87c78dd2021-02-03 16:43:20 +00001026 auto* func_sem = Sem().Get(func);
1027 ASSERT_NE(func_sem, nullptr);
1028
1029 EXPECT_EQ(func_sem->ReferencedModuleVariables().size(), 0u);
dan sinclair13d2a3b2020-06-22 20:52:24 +00001030}
1031
dan sinclair8ee1d222020-04-07 16:41:33 +00001032TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct) {
dan sinclair5e5e36e2020-12-16 14:41:00 +00001033 auto* strct = create<ast::Struct>(
Ben Clayton8d391f72021-01-26 16:57:10 +00001034 ast::StructMemberList{Member("first_member", ty.i32()),
1035 Member("second_member", ty.f32())},
dan sinclair5e5e36e2020-12-16 14:41:00 +00001036 ast::StructDecorationList{});
dan sinclair8ee1d222020-04-07 16:41:33 +00001037
dan sinclairb5839932020-12-16 21:38:40 +00001038 auto* st = ty.struct_("S", strct);
Ben Clayton37571bc2021-02-16 23:57:01 +00001039 Global("my_struct", st, ast::StorageClass::kNone);
dan sinclair8ee1d222020-04-07 16:41:33 +00001040
dan sinclair8b40a672020-12-16 11:49:10 +00001041 auto* mem = MemberAccessor("my_struct", "second_member");
Ben Clayton401b96b2021-02-03 17:19:59 +00001042 WrapInFunction(mem);
1043
1044 EXPECT_TRUE(td()->Determine()) << td()->error();
1045
Ben Clayton33352542021-01-29 16:43:41 +00001046 ASSERT_NE(TypeOf(mem), nullptr);
1047 ASSERT_TRUE(TypeOf(mem)->Is<type::Pointer>());
dan sinclair8ee1d222020-04-07 16:41:33 +00001048
Ben Clayton33352542021-01-29 16:43:41 +00001049 auto* ptr = TypeOf(mem)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +00001050 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair8ee1d222020-04-07 16:41:33 +00001051}
1052
dan sinclairb445a9b2020-04-24 00:40:45 +00001053TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct_Alias) {
dan sinclair5e5e36e2020-12-16 14:41:00 +00001054 auto* strct = create<ast::Struct>(
Ben Clayton8d391f72021-01-26 16:57:10 +00001055 ast::StructMemberList{Member("first_member", ty.i32()),
1056 Member("second_member", ty.f32())},
dan sinclair5e5e36e2020-12-16 14:41:00 +00001057 ast::StructDecorationList{});
dan sinclairb445a9b2020-04-24 00:40:45 +00001058
dan sinclairb5839932020-12-16 21:38:40 +00001059 auto* st = ty.struct_("alias", strct);
1060 auto* alias = ty.alias("alias", st);
Ben Clayton37571bc2021-02-16 23:57:01 +00001061 Global("my_struct", alias, ast::StorageClass::kNone);
dan sinclairb445a9b2020-04-24 00:40:45 +00001062
dan sinclair8b40a672020-12-16 11:49:10 +00001063 auto* mem = MemberAccessor("my_struct", "second_member");
Ben Clayton401b96b2021-02-03 17:19:59 +00001064 WrapInFunction(mem);
1065
1066 EXPECT_TRUE(td()->Determine()) << td()->error();
1067
Ben Clayton33352542021-01-29 16:43:41 +00001068 ASSERT_NE(TypeOf(mem), nullptr);
1069 ASSERT_TRUE(TypeOf(mem)->Is<type::Pointer>());
dan sinclairb445a9b2020-04-24 00:40:45 +00001070
Ben Clayton33352542021-01-29 16:43:41 +00001071 auto* ptr = TypeOf(mem)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +00001072 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclairb445a9b2020-04-24 00:40:45 +00001073}
1074
dan sinclair8ee1d222020-04-07 16:41:33 +00001075TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001076 Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kNone);
dan sinclair8ee1d222020-04-07 16:41:33 +00001077
Ben Clayton6d612ad2021-02-24 14:15:02 +00001078 auto* mem = MemberAccessor("my_vec", "xzyw");
Ben Clayton401b96b2021-02-03 17:19:59 +00001079 WrapInFunction(mem);
1080
1081 EXPECT_TRUE(td()->Determine()) << td()->error();
1082
Ben Clayton33352542021-01-29 16:43:41 +00001083 ASSERT_NE(TypeOf(mem), nullptr);
1084 ASSERT_TRUE(TypeOf(mem)->Is<type::Vector>());
1085 EXPECT_TRUE(TypeOf(mem)->As<type::Vector>()->type()->Is<type::F32>());
Ben Clayton6d612ad2021-02-24 14:15:02 +00001086 EXPECT_EQ(TypeOf(mem)->As<type::Vector>()->size(), 4u);
1087 EXPECT_THAT(Sem().Get(mem)->Swizzle(), ElementsAre(0, 2, 1, 3));
dan sinclair8ee1d222020-04-07 16:41:33 +00001088}
1089
dan sinclairaac58652020-04-21 13:05:34 +00001090TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle_SingleElement) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001091 Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kNone);
dan sinclairaac58652020-04-21 13:05:34 +00001092
Ben Clayton6d612ad2021-02-24 14:15:02 +00001093 auto* mem = MemberAccessor("my_vec", "b");
Ben Clayton401b96b2021-02-03 17:19:59 +00001094 WrapInFunction(mem);
1095
1096 EXPECT_TRUE(td()->Determine()) << td()->error();
1097
Ben Clayton33352542021-01-29 16:43:41 +00001098 ASSERT_NE(TypeOf(mem), nullptr);
1099 ASSERT_TRUE(TypeOf(mem)->Is<type::Pointer>());
dan sinclairaac58652020-04-21 13:05:34 +00001100
Ben Clayton33352542021-01-29 16:43:41 +00001101 auto* ptr = TypeOf(mem)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +00001102 ASSERT_TRUE(ptr->type()->Is<type::F32>());
Ben Clayton6d612ad2021-02-24 14:15:02 +00001103 EXPECT_THAT(Sem().Get(mem)->Swizzle(), ElementsAre(2));
1104}
1105
1106TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle_BadChar) {
1107 Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kNone);
1108
1109 auto* ident = create<ast::IdentifierExpression>(
1110 Source{{Source::Location{3, 3}, Source::Location{3, 7}}},
1111 Symbols().Register("xyqz"));
1112
1113 auto* mem = MemberAccessor("my_vec", ident);
1114 WrapInFunction(mem);
1115
1116 EXPECT_FALSE(td()->Determine());
1117 EXPECT_EQ(td()->error(), "3:5 error: invalid vector swizzle character");
1118}
1119
Antonio Maioranofe2b4172021-03-01 20:01:39 +00001120TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle_MixedChars) {
1121 Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kNone);
1122
1123 auto* ident = create<ast::IdentifierExpression>(
1124 Source{{Source::Location{3, 3}, Source::Location{3, 7}}},
1125 Symbols().Register("rgyw"));
1126
1127 auto* mem = MemberAccessor("my_vec", ident);
1128 WrapInFunction(mem);
1129
1130 EXPECT_FALSE(td()->Determine());
1131 EXPECT_EQ(
1132 td()->error(),
1133 "3:3 error: invalid mixing of vector swizzle characters rgba with xyzw");
1134}
1135
Ben Clayton6d612ad2021-02-24 14:15:02 +00001136TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle_BadLength) {
1137 Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kNone);
1138
1139 auto* ident = create<ast::IdentifierExpression>(
1140 Source{{Source::Location{3, 3}, Source::Location{3, 8}}},
1141 Symbols().Register("zzzzz"));
1142 auto* mem = MemberAccessor("my_vec", ident);
1143 WrapInFunction(mem);
1144
1145 EXPECT_FALSE(td()->Determine());
1146 EXPECT_EQ(td()->error(), "3:3 error: invalid vector swizzle size");
dan sinclairaac58652020-04-21 13:05:34 +00001147}
1148
dan sinclair8eddb782020-04-23 22:26:52 +00001149TEST_F(TypeDeterminerTest, Expr_Accessor_MultiLevel) {
dan sinclair8ee1d222020-04-07 16:41:33 +00001150 // struct b {
1151 // vec4<f32> foo
1152 // }
1153 // struct A {
1154 // vec3<struct b> mem
1155 // }
1156 // var c : A
1157 // c.mem[0].foo.yx
1158 // -> vec2<f32>
1159 //
1160 // MemberAccessor{
1161 // MemberAccessor{
1162 // ArrayAccessor{
1163 // MemberAccessor{
1164 // Identifier{c}
1165 // Identifier{mem}
1166 // }
1167 // ScalarConstructor{0}
1168 // }
1169 // Identifier{foo}
1170 // }
1171 // Identifier{yx}
1172 // }
1173 //
dan sinclair8ee1d222020-04-07 16:41:33 +00001174
dan sinclair5e5e36e2020-12-16 14:41:00 +00001175 auto* strctB =
1176 create<ast::Struct>(ast::StructMemberList{Member("foo", ty.vec4<f32>())},
1177 ast::StructDecorationList{});
dan sinclairb5839932020-12-16 21:38:40 +00001178 auto* stB = ty.struct_("B", strctB);
dan sinclair8ee1d222020-04-07 16:41:33 +00001179
Ben Clayton207b5e22021-01-21 15:42:10 +00001180 type::Vector vecB(stB, 3);
dan sinclair5e5e36e2020-12-16 14:41:00 +00001181 auto* strctA = create<ast::Struct>(
1182 ast::StructMemberList{Member("mem", &vecB)}, ast::StructDecorationList{});
dan sinclair8ee1d222020-04-07 16:41:33 +00001183
dan sinclairb5839932020-12-16 21:38:40 +00001184 auto* stA = ty.struct_("A", strctA);
Ben Clayton37571bc2021-02-16 23:57:01 +00001185 Global("c", stA, ast::StorageClass::kNone);
dan sinclair8ee1d222020-04-07 16:41:33 +00001186
dan sinclair8b40a672020-12-16 11:49:10 +00001187 auto* mem = MemberAccessor(
1188 MemberAccessor(IndexAccessor(MemberAccessor("c", "mem"), 0), "foo"),
1189 "yx");
Ben Clayton401b96b2021-02-03 17:19:59 +00001190 WrapInFunction(mem);
1191
1192 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair8ee1d222020-04-07 16:41:33 +00001193
Ben Clayton33352542021-01-29 16:43:41 +00001194 ASSERT_NE(TypeOf(mem), nullptr);
1195 ASSERT_TRUE(TypeOf(mem)->Is<type::Vector>());
1196 EXPECT_TRUE(TypeOf(mem)->As<type::Vector>()->type()->Is<type::F32>());
1197 EXPECT_EQ(TypeOf(mem)->As<type::Vector>()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +00001198}
1199
Ben Clayton7b7d6982021-02-09 17:38:05 +00001200TEST_F(TypeDeterminerTest, Expr_MemberAccessor_InBinaryOp) {
1201 auto* strct = create<ast::Struct>(
1202 ast::StructMemberList{Member("first_member", ty.f32()),
1203 Member("second_member", ty.f32())},
1204 ast::StructDecorationList{});
1205
1206 auto* st = ty.struct_("S", strct);
Ben Clayton37571bc2021-02-16 23:57:01 +00001207 Global("my_struct", st, ast::StorageClass::kNone);
Ben Clayton7b7d6982021-02-09 17:38:05 +00001208
1209 auto* expr = Add(MemberAccessor("my_struct", "first_member"),
1210 MemberAccessor("my_struct", "second_member"));
1211 WrapInFunction(expr);
1212
1213 EXPECT_TRUE(td()->Determine()) << td()->error();
1214
1215 ASSERT_NE(TypeOf(expr), nullptr);
1216 EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
1217}
1218
dan sinclaircd077b02020-04-20 14:19:04 +00001219using Expr_Binary_BitwiseTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +00001220TEST_P(Expr_Binary_BitwiseTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001221 auto op = GetParam();
1222
Ben Clayton37571bc2021-02-16 23:57:01 +00001223 Global("val", ty.i32(), ast::StorageClass::kNone);
dan sinclair9b978022020-04-07 19:26:39 +00001224
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001225 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001226 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001227
Ben Clayton401b96b2021-02-03 17:19:59 +00001228 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001229 ASSERT_NE(TypeOf(expr), nullptr);
1230 EXPECT_TRUE(TypeOf(expr)->Is<type::I32>());
dan sinclair9b978022020-04-07 19:26:39 +00001231}
1232
dan sinclair1c9b4862020-04-07 19:27:41 +00001233TEST_P(Expr_Binary_BitwiseTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001234 auto op = GetParam();
1235
Ben Clayton37571bc2021-02-16 23:57:01 +00001236 Global("val", ty.vec3<i32>(), ast::StorageClass::kNone);
dan sinclair9b978022020-04-07 19:26:39 +00001237
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001238 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001239 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001240
Ben Clayton401b96b2021-02-03 17:19:59 +00001241 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001242 ASSERT_NE(TypeOf(expr), nullptr);
1243 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1244 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::I32>());
1245 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001246}
1247INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +00001248 Expr_Binary_BitwiseTest,
1249 testing::Values(ast::BinaryOp::kAnd,
1250 ast::BinaryOp::kOr,
1251 ast::BinaryOp::kXor,
1252 ast::BinaryOp::kShiftLeft,
1253 ast::BinaryOp::kShiftRight,
dan sinclair1c9b4862020-04-07 19:27:41 +00001254 ast::BinaryOp::kAdd,
1255 ast::BinaryOp::kSubtract,
1256 ast::BinaryOp::kDivide,
1257 ast::BinaryOp::kModulo));
dan sinclair9b978022020-04-07 19:26:39 +00001258
dan sinclaircd077b02020-04-20 14:19:04 +00001259using Expr_Binary_LogicalTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +00001260TEST_P(Expr_Binary_LogicalTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001261 auto op = GetParam();
1262
Ben Clayton37571bc2021-02-16 23:57:01 +00001263 Global("val", ty.bool_(), ast::StorageClass::kNone);
dan sinclair9b978022020-04-07 19:26:39 +00001264
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001265 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001266 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001267
Ben Clayton401b96b2021-02-03 17:19:59 +00001268 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001269 ASSERT_NE(TypeOf(expr), nullptr);
1270 EXPECT_TRUE(TypeOf(expr)->Is<type::Bool>());
dan sinclair9b978022020-04-07 19:26:39 +00001271}
1272
dan sinclair1c9b4862020-04-07 19:27:41 +00001273TEST_P(Expr_Binary_LogicalTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001274 auto op = GetParam();
1275
Ben Clayton37571bc2021-02-16 23:57:01 +00001276 Global("val", ty.vec3<bool>(), ast::StorageClass::kNone);
dan sinclair9b978022020-04-07 19:26:39 +00001277
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001278 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001279 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001280
Ben Clayton401b96b2021-02-03 17:19:59 +00001281 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001282 ASSERT_NE(TypeOf(expr), nullptr);
1283 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1284 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::Bool>());
1285 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001286}
1287INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +00001288 Expr_Binary_LogicalTest,
1289 testing::Values(ast::BinaryOp::kLogicalAnd,
1290 ast::BinaryOp::kLogicalOr));
dan sinclair9b978022020-04-07 19:26:39 +00001291
dan sinclaircd077b02020-04-20 14:19:04 +00001292using Expr_Binary_CompareTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +00001293TEST_P(Expr_Binary_CompareTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001294 auto op = GetParam();
1295
Ben Clayton37571bc2021-02-16 23:57:01 +00001296 Global("val", ty.i32(), ast::StorageClass::kNone);
dan sinclair9b978022020-04-07 19:26:39 +00001297
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001298 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001299 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001300
Ben Clayton401b96b2021-02-03 17:19:59 +00001301 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001302 ASSERT_NE(TypeOf(expr), nullptr);
1303 EXPECT_TRUE(TypeOf(expr)->Is<type::Bool>());
dan sinclair9b978022020-04-07 19:26:39 +00001304}
1305
dan sinclair1c9b4862020-04-07 19:27:41 +00001306TEST_P(Expr_Binary_CompareTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001307 auto op = GetParam();
1308
Ben Clayton37571bc2021-02-16 23:57:01 +00001309 Global("val", ty.vec3<i32>(), ast::StorageClass::kNone);
dan sinclair9b978022020-04-07 19:26:39 +00001310
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001311 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001312 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001313
Ben Clayton401b96b2021-02-03 17:19:59 +00001314 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001315 ASSERT_NE(TypeOf(expr), nullptr);
1316 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1317 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::Bool>());
1318 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001319}
1320INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +00001321 Expr_Binary_CompareTest,
1322 testing::Values(ast::BinaryOp::kEqual,
1323 ast::BinaryOp::kNotEqual,
1324 ast::BinaryOp::kLessThan,
1325 ast::BinaryOp::kGreaterThan,
1326 ast::BinaryOp::kLessThanEqual,
1327 ast::BinaryOp::kGreaterThanEqual));
dan sinclair9b978022020-04-07 19:26:39 +00001328
dan sinclair1c9b4862020-04-07 19:27:41 +00001329TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Scalar) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001330 Global("val", ty.i32(), ast::StorageClass::kNone);
dan sinclair9b978022020-04-07 19:26:39 +00001331
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001332 auto* expr = Mul("val", "val");
Ben Clayton401b96b2021-02-03 17:19:59 +00001333 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001334
Ben Clayton401b96b2021-02-03 17:19:59 +00001335 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001336 ASSERT_NE(TypeOf(expr), nullptr);
1337 EXPECT_TRUE(TypeOf(expr)->Is<type::I32>());
dan sinclair9b978022020-04-07 19:26:39 +00001338}
1339
dan sinclair1c9b4862020-04-07 19:27:41 +00001340TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Scalar) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001341 Global("scalar", ty.f32(), ast::StorageClass::kNone);
1342 Global("vector", ty.vec3<f32>(), ast::StorageClass::kNone);
dan sinclair9b978022020-04-07 19:26:39 +00001343
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001344 auto* expr = Mul("vector", "scalar");
Ben Clayton401b96b2021-02-03 17:19:59 +00001345 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001346
Ben Clayton401b96b2021-02-03 17:19:59 +00001347 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001348 ASSERT_NE(TypeOf(expr), nullptr);
1349 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1350 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1351 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001352}
1353
dan sinclair1c9b4862020-04-07 19:27:41 +00001354TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Vector) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001355 Global("scalar", ty.f32(), ast::StorageClass::kNone);
1356 Global("vector", ty.vec3<f32>(), ast::StorageClass::kNone);
dan sinclair9b978022020-04-07 19:26:39 +00001357
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001358 auto* expr = Mul("scalar", "vector");
Ben Clayton401b96b2021-02-03 17:19:59 +00001359 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001360
Ben Clayton401b96b2021-02-03 17:19:59 +00001361 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001362 ASSERT_NE(TypeOf(expr), nullptr);
1363 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1364 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1365 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001366}
1367
dan sinclair1c9b4862020-04-07 19:27:41 +00001368TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Vector) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001369 Global("vector", ty.vec3<f32>(), ast::StorageClass::kNone);
dan sinclair9b978022020-04-07 19:26:39 +00001370
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001371 auto* expr = Mul("vector", "vector");
Ben Clayton401b96b2021-02-03 17:19:59 +00001372 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001373
Ben Clayton401b96b2021-02-03 17:19:59 +00001374 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001375 ASSERT_NE(TypeOf(expr), nullptr);
1376 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1377 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1378 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001379}
1380
dan sinclair1c9b4862020-04-07 19:27:41 +00001381TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Scalar) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001382 Global("scalar", ty.f32(), ast::StorageClass::kNone);
1383 Global("matrix", ty.mat2x3<f32>(), ast::StorageClass::kNone);
dan sinclair9b978022020-04-07 19:26:39 +00001384
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001385 auto* expr = Mul("matrix", "scalar");
Ben Clayton401b96b2021-02-03 17:19:59 +00001386 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001387
Ben Clayton401b96b2021-02-03 17:19:59 +00001388 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001389 ASSERT_NE(TypeOf(expr), nullptr);
1390 ASSERT_TRUE(TypeOf(expr)->Is<type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001391
Ben Clayton33352542021-01-29 16:43:41 +00001392 auto* mat = TypeOf(expr)->As<type::Matrix>();
Ben Clayton207b5e22021-01-21 15:42:10 +00001393 EXPECT_TRUE(mat->type()->Is<type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001394 EXPECT_EQ(mat->rows(), 3u);
1395 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001396}
1397
dan sinclair1c9b4862020-04-07 19:27:41 +00001398TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Matrix) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001399 Global("scalar", ty.f32(), ast::StorageClass::kNone);
1400 Global("matrix", ty.mat2x3<f32>(), ast::StorageClass::kNone);
dan sinclair9b978022020-04-07 19:26:39 +00001401
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001402 auto* expr = Mul("scalar", "matrix");
Ben Clayton401b96b2021-02-03 17:19:59 +00001403 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001404
Ben Clayton401b96b2021-02-03 17:19:59 +00001405 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001406 ASSERT_NE(TypeOf(expr), nullptr);
1407 ASSERT_TRUE(TypeOf(expr)->Is<type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001408
Ben Clayton33352542021-01-29 16:43:41 +00001409 auto* mat = TypeOf(expr)->As<type::Matrix>();
Ben Clayton207b5e22021-01-21 15:42:10 +00001410 EXPECT_TRUE(mat->type()->Is<type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001411 EXPECT_EQ(mat->rows(), 3u);
1412 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001413}
1414
dan sinclair1c9b4862020-04-07 19:27:41 +00001415TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Vector) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001416 Global("vector", ty.vec3<f32>(), ast::StorageClass::kNone);
1417 Global("matrix", ty.mat2x3<f32>(), ast::StorageClass::kNone);
dan sinclair9b978022020-04-07 19:26:39 +00001418
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001419 auto* expr = Mul("matrix", "vector");
Ben Clayton401b96b2021-02-03 17:19:59 +00001420 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001421
Ben Clayton401b96b2021-02-03 17:19:59 +00001422 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001423 ASSERT_NE(TypeOf(expr), nullptr);
1424 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1425 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1426 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001427}
1428
dan sinclair1c9b4862020-04-07 19:27:41 +00001429TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Matrix) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001430 Global("vector", ty.vec3<f32>(), ast::StorageClass::kNone);
1431 Global("matrix", ty.mat2x3<f32>(), ast::StorageClass::kNone);
dan sinclair9b978022020-04-07 19:26:39 +00001432
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001433 auto* expr = Mul("vector", "matrix");
Ben Clayton401b96b2021-02-03 17:19:59 +00001434 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001435
Ben Clayton401b96b2021-02-03 17:19:59 +00001436 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001437 ASSERT_NE(TypeOf(expr), nullptr);
1438 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1439 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1440 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001441}
1442
dan sinclair1c9b4862020-04-07 19:27:41 +00001443TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Matrix) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001444 Global("mat3x4", ty.mat3x4<f32>(), ast::StorageClass::kNone);
1445 Global("mat4x3", ty.mat4x3<f32>(), ast::StorageClass::kNone);
dan sinclair9b978022020-04-07 19:26:39 +00001446
Ben Clayton1637cbb2021-01-05 15:44:39 +00001447 auto* expr = Mul("mat3x4", "mat4x3");
Ben Clayton401b96b2021-02-03 17:19:59 +00001448 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001449
Ben Clayton401b96b2021-02-03 17:19:59 +00001450 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001451 ASSERT_NE(TypeOf(expr), nullptr);
1452 ASSERT_TRUE(TypeOf(expr)->Is<type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001453
Ben Clayton33352542021-01-29 16:43:41 +00001454 auto* mat = TypeOf(expr)->As<type::Matrix>();
Ben Clayton207b5e22021-01-21 15:42:10 +00001455 EXPECT_TRUE(mat->type()->Is<type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001456 EXPECT_EQ(mat->rows(), 4u);
1457 EXPECT_EQ(mat->columns(), 4u);
dan sinclair9b978022020-04-07 19:26:39 +00001458}
1459
dan sinclair46e959d2020-06-01 13:43:22 +00001460using IntrinsicDerivativeTest = TypeDeterminerTestWithParam<std::string>;
1461TEST_P(IntrinsicDerivativeTest, Scalar) {
1462 auto name = GetParam();
dan sinclairb1730562020-04-07 19:26:49 +00001463
Ben Clayton37571bc2021-02-16 23:57:01 +00001464 Global("ident", ty.f32(), ast::StorageClass::kNone);
dan sinclair46e959d2020-06-01 13:43:22 +00001465
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001466 auto* expr = Call(name, "ident");
Ben Clayton401b96b2021-02-03 17:19:59 +00001467 WrapInFunction(expr);
1468
1469 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair46e959d2020-06-01 13:43:22 +00001470
Ben Clayton33352542021-01-29 16:43:41 +00001471 ASSERT_NE(TypeOf(expr), nullptr);
1472 ASSERT_TRUE(TypeOf(expr)->Is<type::F32>());
dan sinclair46e959d2020-06-01 13:43:22 +00001473}
1474
1475TEST_P(IntrinsicDerivativeTest, Vector) {
1476 auto name = GetParam();
Ben Clayton37571bc2021-02-16 23:57:01 +00001477 Global("ident", ty.vec4<f32>(), ast::StorageClass::kNone);
dan sinclairb1730562020-04-07 19:26:49 +00001478
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001479 auto* expr = Call(name, "ident");
Ben Clayton401b96b2021-02-03 17:19:59 +00001480 WrapInFunction(expr);
1481
1482 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair46e959d2020-06-01 13:43:22 +00001483
Ben Clayton33352542021-01-29 16:43:41 +00001484 ASSERT_NE(TypeOf(expr), nullptr);
1485 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1486 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1487 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 4u);
dan sinclair46e959d2020-06-01 13:43:22 +00001488}
1489
1490TEST_P(IntrinsicDerivativeTest, MissingParam) {
1491 auto name = GetParam();
1492
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001493 auto* expr = Call(name);
Ben Clayton401b96b2021-02-03 17:19:59 +00001494 WrapInFunction(expr);
1495
1496 EXPECT_FALSE(td()->Determine());
1497
Ben Clayton6b4924f2021-02-17 20:13:34 +00001498 EXPECT_EQ(td()->error(), "error: no matching call to " + name +
Ben Clayton59d24732021-02-08 22:42:54 +00001499 "()\n\n"
1500 "2 candidate functions:\n " +
1501 name + "(f32) -> f32\n " + name +
1502 "(vecN<f32>) -> vecN<f32>\n");
dan sinclair46e959d2020-06-01 13:43:22 +00001503}
1504
dan sinclairb1730562020-04-07 19:26:49 +00001505INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair46e959d2020-06-01 13:43:22 +00001506 IntrinsicDerivativeTest,
1507 testing::Values("dpdx",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001508 "dpdxCoarse",
1509 "dpdxFine",
dan sinclair46e959d2020-06-01 13:43:22 +00001510 "dpdy",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001511 "dpdyCoarse",
1512 "dpdyFine",
dan sinclair46e959d2020-06-01 13:43:22 +00001513 "fwidth",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001514 "fwidthCoarse",
1515 "fwidthFine"));
dan sinclairb1730562020-04-07 19:26:49 +00001516
dan sinclair46e959d2020-06-01 13:43:22 +00001517using Intrinsic = TypeDeterminerTestWithParam<std::string>;
1518TEST_P(Intrinsic, Test) {
1519 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00001520
Ben Clayton37571bc2021-02-16 23:57:01 +00001521 Global("my_var", ty.vec3<bool>(), ast::StorageClass::kNone);
dan sinclair8dcfd102020-04-07 19:27:00 +00001522
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001523 auto* expr = Call(name, "my_var");
Ben Clayton401b96b2021-02-03 17:19:59 +00001524 WrapInFunction(expr);
dan sinclair8dcfd102020-04-07 19:27:00 +00001525
Ben Clayton401b96b2021-02-03 17:19:59 +00001526 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair8dcfd102020-04-07 19:27:00 +00001527
Ben Clayton33352542021-01-29 16:43:41 +00001528 ASSERT_NE(TypeOf(expr), nullptr);
1529 EXPECT_TRUE(TypeOf(expr)->Is<type::Bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001530}
1531INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair46e959d2020-06-01 13:43:22 +00001532 Intrinsic,
1533 testing::Values("any", "all"));
dan sinclair8dcfd102020-04-07 19:27:00 +00001534
dan sinclair46e959d2020-06-01 13:43:22 +00001535using Intrinsic_FloatMethod = TypeDeterminerTestWithParam<std::string>;
1536TEST_P(Intrinsic_FloatMethod, Vector) {
1537 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00001538
Ben Clayton37571bc2021-02-16 23:57:01 +00001539 Global("my_var", ty.vec3<f32>(), ast::StorageClass::kNone);
dan sinclair8dcfd102020-04-07 19:27:00 +00001540
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001541 auto* expr = Call(name, "my_var");
Ben Clayton401b96b2021-02-03 17:19:59 +00001542 WrapInFunction(expr);
dan sinclair8dcfd102020-04-07 19:27:00 +00001543
Ben Clayton401b96b2021-02-03 17:19:59 +00001544 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair8dcfd102020-04-07 19:27:00 +00001545
Ben Clayton33352542021-01-29 16:43:41 +00001546 ASSERT_NE(TypeOf(expr), nullptr);
1547 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1548 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::Bool>());
1549 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair8dcfd102020-04-07 19:27:00 +00001550}
dan sinclair46e959d2020-06-01 13:43:22 +00001551
1552TEST_P(Intrinsic_FloatMethod, Scalar) {
1553 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00001554
Ben Clayton37571bc2021-02-16 23:57:01 +00001555 Global("my_var", ty.f32(), ast::StorageClass::kNone);
dan sinclair8dcfd102020-04-07 19:27:00 +00001556
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001557 auto* expr = Call(name, "my_var");
Ben Clayton401b96b2021-02-03 17:19:59 +00001558 WrapInFunction(expr);
dan sinclair8dcfd102020-04-07 19:27:00 +00001559
Ben Clayton401b96b2021-02-03 17:19:59 +00001560 EXPECT_TRUE(td()->Determine()) << td()->error();
1561
Ben Clayton33352542021-01-29 16:43:41 +00001562 ASSERT_NE(TypeOf(expr), nullptr);
1563 EXPECT_TRUE(TypeOf(expr)->Is<type::Bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001564}
dan sinclair8dcfd102020-04-07 19:27:00 +00001565
dan sinclair46e959d2020-06-01 13:43:22 +00001566TEST_P(Intrinsic_FloatMethod, MissingParam) {
1567 auto name = GetParam();
1568
Ben Clayton37571bc2021-02-16 23:57:01 +00001569 Global("my_var", ty.f32(), ast::StorageClass::kNone);
dan sinclair46e959d2020-06-01 13:43:22 +00001570
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001571 auto* expr = Call(name);
Ben Clayton401b96b2021-02-03 17:19:59 +00001572 WrapInFunction(expr);
dan sinclair46e959d2020-06-01 13:43:22 +00001573
Ben Clayton401b96b2021-02-03 17:19:59 +00001574 EXPECT_FALSE(td()->Determine());
1575
Ben Clayton6b4924f2021-02-17 20:13:34 +00001576 EXPECT_EQ(td()->error(), "error: no matching call to " + name +
Ben Clayton59d24732021-02-08 22:42:54 +00001577 "()\n\n"
1578 "2 candidate functions:\n " +
1579 name + "(f32) -> bool\n " + name +
1580 "(vecN<f32>) -> vecN<bool>\n");
dan sinclair46e959d2020-06-01 13:43:22 +00001581}
1582
1583TEST_P(Intrinsic_FloatMethod, TooManyParams) {
1584 auto name = GetParam();
1585
Ben Clayton37571bc2021-02-16 23:57:01 +00001586 Global("my_var", ty.f32(), ast::StorageClass::kNone);
dan sinclair46e959d2020-06-01 13:43:22 +00001587
Ben Claytonfaca02d2021-02-10 21:34:25 +00001588 auto* expr = Call(name, "my_var", 1.23f);
Ben Clayton401b96b2021-02-03 17:19:59 +00001589 WrapInFunction(expr);
dan sinclair46e959d2020-06-01 13:43:22 +00001590
Ben Clayton401b96b2021-02-03 17:19:59 +00001591 EXPECT_FALSE(td()->Determine());
1592
Ben Clayton6b4924f2021-02-17 20:13:34 +00001593 EXPECT_EQ(td()->error(), "error: no matching call to " + name +
Ben Claytonfaca02d2021-02-10 21:34:25 +00001594 "(ptr<f32>, f32)\n\n"
Ben Clayton59d24732021-02-08 22:42:54 +00001595 "2 candidate functions:\n " +
1596 name + "(f32) -> bool\n " + name +
1597 "(vecN<f32>) -> vecN<bool>\n");
dan sinclair46e959d2020-06-01 13:43:22 +00001598}
1599INSTANTIATE_TEST_SUITE_P(
1600 TypeDeterminerTest,
1601 Intrinsic_FloatMethod,
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001602 testing::Values("isInf", "isNan", "isFinite", "isNormal"));
dan sinclair46e959d2020-06-01 13:43:22 +00001603
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001604enum class Texture { kF32, kI32, kU32 };
1605inline std::ostream& operator<<(std::ostream& out, Texture data) {
1606 if (data == Texture::kF32) {
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001607 out << "f32";
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001608 } else if (data == Texture::kI32) {
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001609 out << "i32";
1610 } else {
1611 out << "u32";
1612 }
1613 return out;
1614}
1615
1616struct TextureTestParams {
Ben Clayton207b5e22021-01-21 15:42:10 +00001617 type::TextureDimension dim;
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001618 Texture type = Texture::kF32;
Ben Clayton207b5e22021-01-21 15:42:10 +00001619 type::ImageFormat format = type::ImageFormat::kR16Float;
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001620};
1621inline std::ostream& operator<<(std::ostream& out, TextureTestParams data) {
1622 out << data.dim << "_" << data.type;
1623 return out;
1624}
1625
1626class Intrinsic_TextureOperation
1627 : public TypeDeterminerTestWithParam<TextureTestParams> {
1628 public:
Ben Clayton3b4f3d22021-02-08 20:24:52 +00001629 /// Gets an appropriate type for the coords parameter depending the the
1630 /// dimensionality of the texture being sampled.
1631 /// @param dim dimensionality of the texture being sampled
1632 /// @param scalar the scalar type
1633 /// @returns a pointer to a type appropriate for the coord param
1634 type::Type* GetCoordsType(type::TextureDimension dim, type::Type* scalar) {
1635 switch (dim) {
1636 case type::TextureDimension::k1d:
Ben Clayton3b4f3d22021-02-08 20:24:52 +00001637 return scalar;
1638 case type::TextureDimension::k2d:
1639 case type::TextureDimension::k2dArray:
1640 return create<type::Vector>(scalar, 2);
1641 case type::TextureDimension::k3d:
1642 case type::TextureDimension::kCube:
1643 case type::TextureDimension::kCubeArray:
1644 return create<type::Vector>(scalar, 3);
1645 default:
1646 [=]() { FAIL() << "Unsupported texture dimension: " << dim; }();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001647 }
Ben Clayton3b4f3d22021-02-08 20:24:52 +00001648 return nullptr;
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001649 }
1650
1651 void add_call_param(std::string name,
Ben Clayton207b5e22021-01-21 15:42:10 +00001652 type::Type* type,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001653 ast::ExpressionList* call_params) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001654 Global(name, type, ast::StorageClass::kNone);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001655 call_params->push_back(Expr(name));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001656 }
Ben Clayton281b6022021-01-21 16:35:10 +00001657 type::Type* subtype(Texture type) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001658 if (type == Texture::kF32) {
Ben Clayton281b6022021-01-21 16:35:10 +00001659 return create<type::F32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001660 }
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001661 if (type == Texture::kI32) {
Ben Clayton281b6022021-01-21 16:35:10 +00001662 return create<type::I32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001663 }
Ben Clayton281b6022021-01-21 16:35:10 +00001664 return create<type::U32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001665 }
1666};
1667
1668using Intrinsic_StorageTextureOperation = Intrinsic_TextureOperation;
1669TEST_P(Intrinsic_StorageTextureOperation, TextureLoadRo) {
1670 auto dim = GetParam().dim;
1671 auto type = GetParam().type;
1672 auto format = GetParam().format;
1673
Ben Clayton3b4f3d22021-02-08 20:24:52 +00001674 auto* coords_type = GetCoordsType(dim, ty.i32());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001675
Ben Claytonb57c19d2021-02-08 20:35:01 +00001676 auto* subtype = type::StorageTexture::SubtypeFor(format, Types());
Ben Claytonfaca02d2021-02-10 21:34:25 +00001677 auto* texture_type = create<type::StorageTexture>(dim, format, subtype);
1678 auto* ro_texture_type =
1679 create<type::AccessControl>(ast::AccessControl::kReadOnly, texture_type);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001680
1681 ast::ExpressionList call_params;
1682
Ben Claytonfaca02d2021-02-10 21:34:25 +00001683 add_call_param("texture", ro_texture_type, &call_params);
Ben Clayton281b6022021-01-21 16:35:10 +00001684 add_call_param("coords", coords_type, &call_params);
Ben Clayton3b4f3d22021-02-08 20:24:52 +00001685
1686 if (type::IsTextureArray(dim)) {
1687 add_call_param("array_index", ty.i32(), &call_params);
1688 }
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001689
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001690 auto* expr = Call("textureLoad", call_params);
Ben Clayton401b96b2021-02-03 17:19:59 +00001691 WrapInFunction(expr);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001692
Ben Clayton401b96b2021-02-03 17:19:59 +00001693 EXPECT_TRUE(td()->Determine()) << td()->error();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001694
Ben Clayton33352542021-01-29 16:43:41 +00001695 ASSERT_NE(TypeOf(expr), nullptr);
1696 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001697 if (type == Texture::kF32) {
Ben Clayton33352542021-01-29 16:43:41 +00001698 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001699 } else if (type == Texture::kI32) {
Ben Clayton33352542021-01-29 16:43:41 +00001700 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::I32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001701 } else {
Ben Clayton33352542021-01-29 16:43:41 +00001702 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::U32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001703 }
Ben Clayton33352542021-01-29 16:43:41 +00001704 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 4u);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001705}
1706
1707INSTANTIATE_TEST_SUITE_P(
1708 TypeDeterminerTest,
1709 Intrinsic_StorageTextureOperation,
1710 testing::Values(
Ben Clayton207b5e22021-01-21 15:42:10 +00001711 TextureTestParams{type::TextureDimension::k1d, Texture::kF32,
1712 type::ImageFormat::kR16Float},
1713 TextureTestParams{type::TextureDimension::k1d, Texture::kI32,
1714 type::ImageFormat::kR16Sint},
1715 TextureTestParams{type::TextureDimension::k1d, Texture::kF32,
1716 type::ImageFormat::kR8Unorm},
Ben Clayton207b5e22021-01-21 15:42:10 +00001717 TextureTestParams{type::TextureDimension::k2d, Texture::kF32,
1718 type::ImageFormat::kR16Float},
1719 TextureTestParams{type::TextureDimension::k2d, Texture::kI32,
1720 type::ImageFormat::kR16Sint},
1721 TextureTestParams{type::TextureDimension::k2d, Texture::kF32,
1722 type::ImageFormat::kR8Unorm},
1723 TextureTestParams{type::TextureDimension::k2dArray, Texture::kF32,
1724 type::ImageFormat::kR16Float},
1725 TextureTestParams{type::TextureDimension::k2dArray, Texture::kI32,
1726 type::ImageFormat::kR16Sint},
1727 TextureTestParams{type::TextureDimension::k2dArray, Texture::kF32,
1728 type::ImageFormat::kR8Unorm},
1729 TextureTestParams{type::TextureDimension::k3d, Texture::kF32,
1730 type::ImageFormat::kR16Float},
1731 TextureTestParams{type::TextureDimension::k3d, Texture::kI32,
1732 type::ImageFormat::kR16Sint},
1733 TextureTestParams{type::TextureDimension::k3d, Texture::kF32,
1734 type::ImageFormat::kR8Unorm}));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001735
1736using Intrinsic_SampledTextureOperation = Intrinsic_TextureOperation;
1737TEST_P(Intrinsic_SampledTextureOperation, TextureLoadSampled) {
1738 auto dim = GetParam().dim;
1739 auto type = GetParam().type;
1740
Ben Clayton281b6022021-01-21 16:35:10 +00001741 type::Type* s = subtype(type);
Ben Clayton3b4f3d22021-02-08 20:24:52 +00001742 auto* coords_type = GetCoordsType(dim, ty.i32());
Ben Clayton281b6022021-01-21 16:35:10 +00001743 auto* texture_type = create<type::SampledTexture>(dim, s);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001744
1745 ast::ExpressionList call_params;
1746
Ben Clayton281b6022021-01-21 16:35:10 +00001747 add_call_param("texture", texture_type, &call_params);
1748 add_call_param("coords", coords_type, &call_params);
Ryan Harrison2f8df722021-03-02 20:31:58 +00001749 if (dim == type::TextureDimension::k2dArray) {
1750 add_call_param("array_index", ty.i32(), &call_params);
1751 }
1752 add_call_param("level", ty.i32(), &call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001753
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001754 auto* expr = Call("textureLoad", call_params);
Ben Clayton401b96b2021-02-03 17:19:59 +00001755 WrapInFunction(expr);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001756
Ben Clayton401b96b2021-02-03 17:19:59 +00001757 EXPECT_TRUE(td()->Determine()) << td()->error();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001758
Ben Clayton33352542021-01-29 16:43:41 +00001759 ASSERT_NE(TypeOf(expr), nullptr);
1760 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001761 if (type == Texture::kF32) {
Ben Clayton33352542021-01-29 16:43:41 +00001762 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001763 } else if (type == Texture::kI32) {
Ben Clayton33352542021-01-29 16:43:41 +00001764 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::I32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001765 } else {
Ben Clayton33352542021-01-29 16:43:41 +00001766 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::U32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001767 }
Ben Clayton33352542021-01-29 16:43:41 +00001768 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 4u);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001769}
1770
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001771INSTANTIATE_TEST_SUITE_P(
1772 TypeDeterminerTest,
1773 Intrinsic_SampledTextureOperation,
Ben Clayton3b4f3d22021-02-08 20:24:52 +00001774 testing::Values(TextureTestParams{type::TextureDimension::k1d},
Ben Clayton3b4f3d22021-02-08 20:24:52 +00001775 TextureTestParams{type::TextureDimension::k2d},
Ben Clayton207b5e22021-01-21 15:42:10 +00001776 TextureTestParams{type::TextureDimension::k2dArray},
Ben Clayton3b4f3d22021-02-08 20:24:52 +00001777 TextureTestParams{type::TextureDimension::k3d}));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001778
Ben Clayton47c4d182021-02-10 21:42:35 +00001779TEST_F(TypeDeterminerTest, Intrinsic_Dot_Vec2) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001780 Global("my_var", ty.vec2<f32>(), ast::StorageClass::kNone);
Ben Clayton47c4d182021-02-10 21:42:35 +00001781
1782 auto* expr = Call("dot", "my_var", "my_var");
1783 WrapInFunction(expr);
1784
1785 EXPECT_TRUE(td()->Determine()) << td()->error();
1786
1787 ASSERT_NE(TypeOf(expr), nullptr);
1788 EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
1789}
1790
1791TEST_F(TypeDeterminerTest, Intrinsic_Dot_Vec3) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001792 Global("my_var", ty.vec3<f32>(), ast::StorageClass::kNone);
dan sinclair8dcfd102020-04-07 19:27:00 +00001793
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001794 auto* expr = Call("dot", "my_var", "my_var");
Ben Clayton401b96b2021-02-03 17:19:59 +00001795 WrapInFunction(expr);
dan sinclair8dcfd102020-04-07 19:27:00 +00001796
Ben Clayton401b96b2021-02-03 17:19:59 +00001797 EXPECT_TRUE(td()->Determine()) << td()->error();
1798
Ben Clayton33352542021-01-29 16:43:41 +00001799 ASSERT_NE(TypeOf(expr), nullptr);
1800 EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001801}
1802
Ben Clayton47c4d182021-02-10 21:42:35 +00001803TEST_F(TypeDeterminerTest, Intrinsic_Dot_Vec4) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001804 Global("my_var", ty.vec4<f32>(), ast::StorageClass::kNone);
Ben Clayton47c4d182021-02-10 21:42:35 +00001805
1806 auto* expr = Call("dot", "my_var", "my_var");
1807 WrapInFunction(expr);
1808
1809 EXPECT_TRUE(td()->Determine()) << td()->error();
1810
1811 ASSERT_NE(TypeOf(expr), nullptr);
1812 EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
1813}
1814
1815TEST_F(TypeDeterminerTest, Intrinsic_Dot_Error_Scalar) {
1816 auto* expr = Call("dot", 1.0f, 1.0f);
1817 WrapInFunction(expr);
1818
1819 EXPECT_FALSE(td()->Determine());
1820
1821 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00001822 R"(error: no matching call to dot(f32, f32)
Ben Clayton47c4d182021-02-10 21:42:35 +00001823
18241 candidate function:
1825 dot(vecN<f32>, vecN<f32>) -> f32
1826)");
1827}
1828
1829TEST_F(TypeDeterminerTest, Intrinsic_Dot_Error_VectorInt) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001830 Global("my_var", ty.vec4<i32>(), ast::StorageClass::kNone);
Ben Clayton47c4d182021-02-10 21:42:35 +00001831
1832 auto* expr = Call("dot", "my_var", "my_var");
1833 WrapInFunction(expr);
1834
1835 EXPECT_FALSE(td()->Determine());
1836
1837 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00001838 R"(error: no matching call to dot(ptr<vec4<i32>>, ptr<vec4<i32>>)
Ben Clayton47c4d182021-02-10 21:42:35 +00001839
18401 candidate function:
1841 dot(vecN<f32>, vecN<f32>) -> f32
1842)");
1843}
1844
dan sinclair16a2ea12020-07-21 17:44:44 +00001845TEST_F(TypeDeterminerTest, Intrinsic_Select) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001846 Global("my_var", ty.vec3<f32>(), ast::StorageClass::kNone);
dan sinclair16a2ea12020-07-21 17:44:44 +00001847
Ben Clayton37571bc2021-02-16 23:57:01 +00001848 Global("bool_var", ty.vec3<bool>(), ast::StorageClass::kNone);
dan sinclair16a2ea12020-07-21 17:44:44 +00001849
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001850 auto* expr = Call("select", "my_var", "my_var", "bool_var");
Ben Clayton401b96b2021-02-03 17:19:59 +00001851 WrapInFunction(expr);
dan sinclair16a2ea12020-07-21 17:44:44 +00001852
Ben Clayton401b96b2021-02-03 17:19:59 +00001853 EXPECT_TRUE(td()->Determine()) << td()->error();
1854
Ben Clayton33352542021-01-29 16:43:41 +00001855 ASSERT_NE(TypeOf(expr), nullptr);
1856 EXPECT_TRUE(TypeOf(expr)->Is<type::Vector>());
1857 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
1858 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00001859}
1860
Ben Clayton47c4d182021-02-10 21:42:35 +00001861TEST_F(TypeDeterminerTest, Intrinsic_Select_Error_NoParams) {
Alan Baker2e6a1bb2021-02-01 16:03:03 +00001862 auto* expr = Call("select");
Ben Clayton401b96b2021-02-03 17:19:59 +00001863 WrapInFunction(expr);
dan sinclair16a2ea12020-07-21 17:44:44 +00001864
Ben Clayton401b96b2021-02-03 17:19:59 +00001865 EXPECT_FALSE(td()->Determine());
1866
Ben Clayton59d24732021-02-08 22:42:54 +00001867 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00001868 R"(error: no matching call to select()
Ben Clayton59d24732021-02-08 22:42:54 +00001869
18702 candidate functions:
1871 select(T, T, bool) -> T where: T is scalar
1872 select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is scalar
1873)");
dan sinclair16a2ea12020-07-21 17:44:44 +00001874}
1875
Ben Clayton47c4d182021-02-10 21:42:35 +00001876TEST_F(TypeDeterminerTest, Intrinsic_Select_Error_SelectorInt) {
1877 auto* expr = Call("select", Expr(1), Expr(1), Expr(1));
1878 WrapInFunction(expr);
1879
1880 EXPECT_FALSE(td()->Determine());
1881
1882 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00001883 R"(error: no matching call to select(i32, i32, i32)
Ben Clayton47c4d182021-02-10 21:42:35 +00001884
18852 candidate functions:
1886 select(T, T, bool) -> T where: T is scalar
1887 select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is scalar
1888)");
1889}
1890
1891TEST_F(TypeDeterminerTest, Intrinsic_Select_Error_Matrix) {
1892 auto* mat = mat2x2<float>(vec2<float>(1.0f, 1.0f), vec2<float>(1.0f, 1.0f));
1893 auto* expr = Call("select", mat, mat, Expr(true));
1894 WrapInFunction(expr);
1895
1896 EXPECT_FALSE(td()->Determine());
1897
1898 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00001899 R"(error: no matching call to select(mat2x2<f32>, mat2x2<f32>, bool)
Ben Clayton47c4d182021-02-10 21:42:35 +00001900
19012 candidate functions:
1902 select(T, T, bool) -> T where: T is scalar
1903 select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is scalar
1904)");
1905}
1906
1907TEST_F(TypeDeterminerTest, Intrinsic_Select_Error_MismatchTypes) {
1908 auto* expr = Call("select", 1.0f, vec2<float>(2.0f, 3.0f), Expr(true));
1909 WrapInFunction(expr);
1910
1911 EXPECT_FALSE(td()->Determine());
1912
1913 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00001914 R"(error: no matching call to select(f32, vec2<f32>, bool)
Ben Clayton47c4d182021-02-10 21:42:35 +00001915
19162 candidate functions:
1917 select(T, T, bool) -> T where: T is scalar
1918 select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is scalar
1919)");
1920}
1921
1922TEST_F(TypeDeterminerTest, Intrinsic_Select_Error_MismatchVectorSize) {
1923 auto* expr = Call("select", vec2<float>(1.0f, 2.0f),
1924 vec3<float>(3.0f, 4.0f, 5.0f), Expr(true));
1925 WrapInFunction(expr);
1926
1927 EXPECT_FALSE(td()->Determine());
1928
1929 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00001930 R"(error: no matching call to select(vec2<f32>, vec3<f32>, bool)
Ben Clayton47c4d182021-02-10 21:42:35 +00001931
19322 candidate functions:
1933 select(T, T, bool) -> T where: T is scalar
1934 select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is scalar
1935)");
1936}
1937
dan sinclaircd077b02020-04-20 14:19:04 +00001938using UnaryOpExpressionTest = TypeDeterminerTestWithParam<ast::UnaryOp>;
dan sinclair0e257622020-04-07 19:27:11 +00001939TEST_P(UnaryOpExpressionTest, Expr_UnaryOp) {
1940 auto op = GetParam();
1941
Ben Clayton37571bc2021-02-16 23:57:01 +00001942 Global("ident", ty.vec4<f32>(), ast::StorageClass::kNone);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001943 auto* der = create<ast::UnaryOpExpression>(op, Expr("ident"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001944 WrapInFunction(der);
1945
1946 EXPECT_TRUE(td()->Determine()) << td()->error();
1947
Ben Clayton33352542021-01-29 16:43:41 +00001948 ASSERT_NE(TypeOf(der), nullptr);
1949 ASSERT_TRUE(TypeOf(der)->Is<type::Vector>());
1950 EXPECT_TRUE(TypeOf(der)->As<type::Vector>()->type()->Is<type::F32>());
1951 EXPECT_EQ(TypeOf(der)->As<type::Vector>()->size(), 4u);
dan sinclair0e257622020-04-07 19:27:11 +00001952}
1953INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
1954 UnaryOpExpressionTest,
1955 testing::Values(ast::UnaryOp::kNegation,
1956 ast::UnaryOp::kNot));
1957
dan sinclairee8ae042020-04-08 19:58:20 +00001958TEST_F(TypeDeterminerTest, StorageClass_SetsIfMissing) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001959 auto* var = Var("var", ty.i32(), ast::StorageClass::kNone);
dan sinclairee8ae042020-04-08 19:58:20 +00001960
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001961 auto* stmt = create<ast::VariableDeclStatement>(var);
Ben Clayton42d1e092021-02-02 14:29:15 +00001962 Func("func", ast::VariableList{}, ty.i32(), ast::StatementList{stmt},
1963 ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001964
dan sinclairb950e802020-04-20 14:20:01 +00001965 EXPECT_TRUE(td()->Determine()) << td()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +00001966
Ben Claytonb17aea12021-02-03 17:51:09 +00001967 EXPECT_EQ(Sem().Get(var)->StorageClass(), ast::StorageClass::kFunction);
dan sinclairee8ae042020-04-08 19:58:20 +00001968}
1969
1970TEST_F(TypeDeterminerTest, StorageClass_DoesNotSetOnConst) {
Ben Clayton81a29fe2021-02-17 00:26:52 +00001971 auto* var = Const("var", ty.i32());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001972 auto* stmt = create<ast::VariableDeclStatement>(var);
Ben Clayton42d1e092021-02-02 14:29:15 +00001973 Func("func", ast::VariableList{}, ty.i32(), ast::StatementList{stmt},
1974 ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001975
dan sinclairb950e802020-04-20 14:20:01 +00001976 EXPECT_TRUE(td()->Determine()) << td()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +00001977
Ben Claytonb17aea12021-02-03 17:51:09 +00001978 EXPECT_EQ(Sem().Get(var)->StorageClass(), ast::StorageClass::kNone);
dan sinclairee8ae042020-04-08 19:58:20 +00001979}
1980
1981TEST_F(TypeDeterminerTest, StorageClass_NonFunctionClassError) {
Ben Clayton37571bc2021-02-16 23:57:01 +00001982 auto* var = Var("var", ty.i32(), ast::StorageClass::kWorkgroup);
dan sinclairee8ae042020-04-08 19:58:20 +00001983
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001984 auto* stmt = create<ast::VariableDeclStatement>(var);
Ben Clayton42d1e092021-02-02 14:29:15 +00001985 Func("func", ast::VariableList{}, ty.i32(), ast::StatementList{stmt},
1986 ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001987
dan sinclairb950e802020-04-20 14:20:01 +00001988 EXPECT_FALSE(td()->Determine());
Ben Clayton401b96b2021-02-03 17:19:59 +00001989
dan sinclairee8ae042020-04-08 19:58:20 +00001990 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00001991 "error: function variable has a non-function storage class");
dan sinclairee8ae042020-04-08 19:58:20 +00001992}
1993
dan sinclairb4fee2f2020-09-22 19:42:13 +00001994struct IntrinsicData {
dan sinclairca1723e2020-04-20 15:47:55 +00001995 const char* name;
Ben Clayton052ab892021-02-08 19:53:42 +00001996 IntrinsicType intrinsic;
dan sinclairca1723e2020-04-20 15:47:55 +00001997};
dan sinclairb4fee2f2020-09-22 19:42:13 +00001998inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
dan sinclairca1723e2020-04-20 15:47:55 +00001999 out << data.name;
2000 return out;
2001}
dan sinclairb4fee2f2020-09-22 19:42:13 +00002002using IntrinsicDataTest = TypeDeterminerTestWithParam<IntrinsicData>;
2003TEST_P(IntrinsicDataTest, Lookup) {
2004 auto param = GetParam();
dan sinclairca1723e2020-04-20 15:47:55 +00002005
Ben Clayton316f9f62021-02-08 22:31:44 +00002006 EXPECT_EQ(TypeDeterminer::MatchIntrinsicType(param.name), param.intrinsic);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002007}
2008INSTANTIATE_TEST_SUITE_P(
2009 TypeDeterminerTest,
2010 IntrinsicDataTest,
2011 testing::Values(
Ben Clayton052ab892021-02-08 19:53:42 +00002012 IntrinsicData{"abs", IntrinsicType::kAbs},
2013 IntrinsicData{"acos", IntrinsicType::kAcos},
2014 IntrinsicData{"all", IntrinsicType::kAll},
2015 IntrinsicData{"any", IntrinsicType::kAny},
2016 IntrinsicData{"arrayLength", IntrinsicType::kArrayLength},
2017 IntrinsicData{"asin", IntrinsicType::kAsin},
2018 IntrinsicData{"atan", IntrinsicType::kAtan},
2019 IntrinsicData{"atan2", IntrinsicType::kAtan2},
2020 IntrinsicData{"ceil", IntrinsicType::kCeil},
2021 IntrinsicData{"clamp", IntrinsicType::kClamp},
2022 IntrinsicData{"cos", IntrinsicType::kCos},
2023 IntrinsicData{"cosh", IntrinsicType::kCosh},
2024 IntrinsicData{"countOneBits", IntrinsicType::kCountOneBits},
2025 IntrinsicData{"cross", IntrinsicType::kCross},
2026 IntrinsicData{"determinant", IntrinsicType::kDeterminant},
2027 IntrinsicData{"distance", IntrinsicType::kDistance},
2028 IntrinsicData{"dot", IntrinsicType::kDot},
2029 IntrinsicData{"dpdx", IntrinsicType::kDpdx},
2030 IntrinsicData{"dpdxCoarse", IntrinsicType::kDpdxCoarse},
2031 IntrinsicData{"dpdxFine", IntrinsicType::kDpdxFine},
2032 IntrinsicData{"dpdy", IntrinsicType::kDpdy},
2033 IntrinsicData{"dpdyCoarse", IntrinsicType::kDpdyCoarse},
2034 IntrinsicData{"dpdyFine", IntrinsicType::kDpdyFine},
2035 IntrinsicData{"exp", IntrinsicType::kExp},
2036 IntrinsicData{"exp2", IntrinsicType::kExp2},
2037 IntrinsicData{"faceForward", IntrinsicType::kFaceForward},
2038 IntrinsicData{"floor", IntrinsicType::kFloor},
2039 IntrinsicData{"fma", IntrinsicType::kFma},
2040 IntrinsicData{"fract", IntrinsicType::kFract},
2041 IntrinsicData{"frexp", IntrinsicType::kFrexp},
2042 IntrinsicData{"fwidth", IntrinsicType::kFwidth},
2043 IntrinsicData{"fwidthCoarse", IntrinsicType::kFwidthCoarse},
2044 IntrinsicData{"fwidthFine", IntrinsicType::kFwidthFine},
2045 IntrinsicData{"inverseSqrt", IntrinsicType::kInverseSqrt},
2046 IntrinsicData{"isFinite", IntrinsicType::kIsFinite},
2047 IntrinsicData{"isInf", IntrinsicType::kIsInf},
2048 IntrinsicData{"isNan", IntrinsicType::kIsNan},
2049 IntrinsicData{"isNormal", IntrinsicType::kIsNormal},
2050 IntrinsicData{"ldexp", IntrinsicType::kLdexp},
2051 IntrinsicData{"length", IntrinsicType::kLength},
2052 IntrinsicData{"log", IntrinsicType::kLog},
2053 IntrinsicData{"log2", IntrinsicType::kLog2},
2054 IntrinsicData{"max", IntrinsicType::kMax},
2055 IntrinsicData{"min", IntrinsicType::kMin},
2056 IntrinsicData{"mix", IntrinsicType::kMix},
2057 IntrinsicData{"modf", IntrinsicType::kModf},
2058 IntrinsicData{"normalize", IntrinsicType::kNormalize},
2059 IntrinsicData{"pow", IntrinsicType::kPow},
2060 IntrinsicData{"reflect", IntrinsicType::kReflect},
2061 IntrinsicData{"reverseBits", IntrinsicType::kReverseBits},
2062 IntrinsicData{"round", IntrinsicType::kRound},
2063 IntrinsicData{"select", IntrinsicType::kSelect},
2064 IntrinsicData{"sign", IntrinsicType::kSign},
2065 IntrinsicData{"sin", IntrinsicType::kSin},
2066 IntrinsicData{"sinh", IntrinsicType::kSinh},
2067 IntrinsicData{"smoothStep", IntrinsicType::kSmoothStep},
2068 IntrinsicData{"sqrt", IntrinsicType::kSqrt},
2069 IntrinsicData{"step", IntrinsicType::kStep},
2070 IntrinsicData{"tan", IntrinsicType::kTan},
2071 IntrinsicData{"tanh", IntrinsicType::kTanh},
2072 IntrinsicData{"textureDimensions", IntrinsicType::kTextureDimensions},
2073 IntrinsicData{"textureLoad", IntrinsicType::kTextureLoad},
2074 IntrinsicData{"textureNumLayers", IntrinsicType::kTextureNumLayers},
2075 IntrinsicData{"textureNumLevels", IntrinsicType::kTextureNumLevels},
2076 IntrinsicData{"textureNumSamples", IntrinsicType::kTextureNumSamples},
2077 IntrinsicData{"textureSample", IntrinsicType::kTextureSample},
2078 IntrinsicData{"textureSampleBias", IntrinsicType::kTextureSampleBias},
dan sinclairb4fee2f2020-09-22 19:42:13 +00002079 IntrinsicData{"textureSampleCompare",
Ben Clayton052ab892021-02-08 19:53:42 +00002080 IntrinsicType::kTextureSampleCompare},
2081 IntrinsicData{"textureSampleGrad", IntrinsicType::kTextureSampleGrad},
2082 IntrinsicData{"textureSampleLevel", IntrinsicType::kTextureSampleLevel},
2083 IntrinsicData{"trunc", IntrinsicType::kTrunc}));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002084
Ben Clayton1618f4b2021-02-03 21:02:25 +00002085TEST_F(TypeDeterminerTest, MatchIntrinsicNoMatch) {
Ben Clayton316f9f62021-02-08 22:31:44 +00002086 EXPECT_EQ(TypeDeterminer::MatchIntrinsicType("not_intrinsic"),
Ben Clayton052ab892021-02-08 19:53:42 +00002087 IntrinsicType::kNone);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002088}
2089
Ben Clayton2522b292021-02-10 21:40:36 +00002090using Intrinsic_DataPackingTest = TypeDeterminerTestWithParam<IntrinsicData>;
2091TEST_P(Intrinsic_DataPackingTest, InferType) {
Alan Bakerc63e1c02021-02-04 16:17:49 +00002092 auto param = GetParam();
2093
Ben Claytona51aa1f2021-02-08 21:10:11 +00002094 bool pack4 = param.intrinsic == IntrinsicType::kPack4x8Snorm ||
2095 param.intrinsic == IntrinsicType::kPack4x8Unorm;
2096
2097 auto* call = pack4 ? Call(param.name, vec4<f32>(1.f, 2.f, 3.f, 4.f))
2098 : Call(param.name, vec2<f32>(1.f, 2.f));
Alan Bakerc63e1c02021-02-04 16:17:49 +00002099 WrapInFunction(call);
2100
2101 EXPECT_TRUE(td()->Determine()) << td()->error();
2102 ASSERT_NE(TypeOf(call), nullptr);
2103 EXPECT_TRUE(TypeOf(call)->Is<type::U32>());
2104}
2105
Ben Clayton47c4d182021-02-10 21:42:35 +00002106TEST_P(Intrinsic_DataPackingTest, Error_IncorrectParamType) {
2107 auto param = GetParam();
2108
2109 bool pack4 = param.intrinsic == IntrinsicType::kPack4x8Snorm ||
2110 param.intrinsic == IntrinsicType::kPack4x8Unorm;
2111
2112 auto* call = pack4 ? Call(param.name, vec4<i32>(1, 2, 3, 4))
2113 : Call(param.name, vec2<i32>(1, 2));
2114 WrapInFunction(call);
2115
2116 EXPECT_FALSE(td()->Determine());
2117
Ben Clayton6b4924f2021-02-17 20:13:34 +00002118 EXPECT_THAT(td()->error(), HasSubstr("error: no matching call to " +
2119 std::string(param.name)));
Ben Clayton47c4d182021-02-10 21:42:35 +00002120}
2121
2122TEST_P(Intrinsic_DataPackingTest, Error_NoParams) {
2123 auto param = GetParam();
2124
2125 auto* call = Call(param.name);
2126 WrapInFunction(call);
2127
2128 EXPECT_FALSE(td()->Determine());
2129
Ben Clayton6b4924f2021-02-17 20:13:34 +00002130 EXPECT_THAT(td()->error(), HasSubstr("error: no matching call to " +
2131 std::string(param.name)));
Ben Clayton47c4d182021-02-10 21:42:35 +00002132}
2133
2134TEST_P(Intrinsic_DataPackingTest, Error_TooManyParams) {
2135 auto param = GetParam();
2136
2137 bool pack4 = param.intrinsic == IntrinsicType::kPack4x8Snorm ||
2138 param.intrinsic == IntrinsicType::kPack4x8Unorm;
2139
2140 auto* call = pack4 ? Call(param.name, vec4<f32>(1.f, 2.f, 3.f, 4.f), 1.0f)
2141 : Call(param.name, vec2<f32>(1.f, 2.f), 1.0f);
2142 WrapInFunction(call);
2143
2144 EXPECT_FALSE(td()->Determine());
2145
Ben Clayton6b4924f2021-02-17 20:13:34 +00002146 EXPECT_THAT(td()->error(), HasSubstr("error: no matching call to " +
2147 std::string(param.name)));
Ben Clayton47c4d182021-02-10 21:42:35 +00002148}
2149
Alan Bakerc63e1c02021-02-04 16:17:49 +00002150INSTANTIATE_TEST_SUITE_P(
2151 TypeDeterminerTest,
Ben Clayton2522b292021-02-10 21:40:36 +00002152 Intrinsic_DataPackingTest,
Alan Bakerc63e1c02021-02-04 16:17:49 +00002153 testing::Values(
Ben Clayton052ab892021-02-08 19:53:42 +00002154 IntrinsicData{"pack4x8snorm", IntrinsicType::kPack4x8Snorm},
2155 IntrinsicData{"pack4x8unorm", IntrinsicType::kPack4x8Unorm},
2156 IntrinsicData{"pack2x16snorm", IntrinsicType::kPack2x16Snorm},
2157 IntrinsicData{"pack2x16unorm", IntrinsicType::kPack2x16Unorm},
2158 IntrinsicData{"pack2x16float", IntrinsicType::kPack2x16Float}));
Alan Bakerc63e1c02021-02-04 16:17:49 +00002159
Ben Clayton2522b292021-02-10 21:40:36 +00002160using Intrinsic_DataUnpackingTest = TypeDeterminerTestWithParam<IntrinsicData>;
2161TEST_P(Intrinsic_DataUnpackingTest, InferType) {
Alan Bakercd17ea82021-02-09 21:23:00 +00002162 auto param = GetParam();
2163
2164 bool pack4 = param.intrinsic == IntrinsicType::kUnpack4x8Snorm ||
2165 param.intrinsic == IntrinsicType::kUnpack4x8Unorm;
2166
2167 auto* call = Call(param.name, 1u);
2168 WrapInFunction(call);
2169
2170 EXPECT_TRUE(td()->Determine()) << td()->error();
2171 ASSERT_NE(TypeOf(call), nullptr);
2172 EXPECT_TRUE(TypeOf(call)->is_float_vector());
2173 if (pack4) {
2174 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 4u);
2175 } else {
2176 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 2u);
2177 }
2178}
2179
2180INSTANTIATE_TEST_SUITE_P(
2181 TypeDeterminerTest,
Ben Clayton2522b292021-02-10 21:40:36 +00002182 Intrinsic_DataUnpackingTest,
Alan Bakercd17ea82021-02-09 21:23:00 +00002183 testing::Values(
2184 IntrinsicData{"unpack4x8snorm", IntrinsicType::kUnpack4x8Snorm},
2185 IntrinsicData{"unpack4x8unorm", IntrinsicType::kUnpack4x8Unorm},
2186 IntrinsicData{"unpack2x16snorm", IntrinsicType::kUnpack2x16Snorm},
2187 IntrinsicData{"unpack2x16unorm", IntrinsicType::kUnpack2x16Unorm},
2188 IntrinsicData{"unpack2x16float", IntrinsicType::kUnpack2x16Float}));
2189
Ben Clayton2522b292021-02-10 21:40:36 +00002190using Intrinsic_SingleParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
2191TEST_P(Intrinsic_SingleParamTest, Scalar) {
dan sinclairca1723e2020-04-20 15:47:55 +00002192 auto param = GetParam();
2193
Ben Claytona51aa1f2021-02-08 21:10:11 +00002194 auto* call = Call(param.name, 1.f);
Ben Clayton401b96b2021-02-03 17:19:59 +00002195 WrapInFunction(call);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002196
Ben Clayton401b96b2021-02-03 17:19:59 +00002197 EXPECT_TRUE(td()->Determine()) << td()->error();
2198
Ben Clayton1618f4b2021-02-03 21:02:25 +00002199 ASSERT_NE(TypeOf(call), nullptr);
2200 EXPECT_TRUE(TypeOf(call)->is_float_scalar());
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002201}
2202
Ben Clayton2522b292021-02-10 21:40:36 +00002203TEST_P(Intrinsic_SingleParamTest, Vector) {
dan sinclairca1723e2020-04-20 15:47:55 +00002204 auto param = GetParam();
2205
Ben Claytona51aa1f2021-02-08 21:10:11 +00002206 auto* call = Call(param.name, vec3<f32>(1.0f, 1.0f, 3.0f));
Ben Clayton401b96b2021-02-03 17:19:59 +00002207 WrapInFunction(call);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002208
Ben Clayton401b96b2021-02-03 17:19:59 +00002209 EXPECT_TRUE(td()->Determine()) << td()->error();
2210
Ben Clayton1618f4b2021-02-03 21:02:25 +00002211 ASSERT_NE(TypeOf(call), nullptr);
2212 EXPECT_TRUE(TypeOf(call)->is_float_vector());
2213 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002214}
2215
Ben Clayton2522b292021-02-10 21:40:36 +00002216TEST_P(Intrinsic_SingleParamTest, Error_NoParams) {
dan sinclairca1723e2020-04-20 15:47:55 +00002217 auto param = GetParam();
2218
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002219 auto* call = Call(param.name);
Ben Clayton401b96b2021-02-03 17:19:59 +00002220 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002221
Ben Clayton401b96b2021-02-03 17:19:59 +00002222 EXPECT_FALSE(td()->Determine());
2223
Ben Clayton6b4924f2021-02-17 20:13:34 +00002224 EXPECT_EQ(td()->error(),
2225 "error: no matching call to " + std::string(param.name) +
2226 "()\n\n"
2227 "2 candidate functions:\n " +
2228 std::string(param.name) + "(f32) -> f32\n " +
2229 std::string(param.name) + "(vecN<f32>) -> vecN<f32>\n");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002230}
2231
Ben Clayton47c4d182021-02-10 21:42:35 +00002232TEST_P(Intrinsic_SingleParamTest, Error_TooManyParams) {
2233 auto param = GetParam();
2234
2235 auto* call = Call(param.name, 1, 2, 3);
2236 WrapInFunction(call);
2237
2238 EXPECT_FALSE(td()->Determine());
2239
Ben Clayton6b4924f2021-02-17 20:13:34 +00002240 EXPECT_EQ(td()->error(),
2241 "error: no matching call to " + std::string(param.name) +
2242 "(i32, i32, i32)\n\n"
2243 "2 candidate functions:\n " +
2244 std::string(param.name) + "(f32) -> f32\n " +
2245 std::string(param.name) + "(vecN<f32>) -> vecN<f32>\n");
Ben Clayton47c4d182021-02-10 21:42:35 +00002246}
2247
dan sinclaira49328f2020-04-20 15:49:50 +00002248INSTANTIATE_TEST_SUITE_P(
2249 TypeDeterminerTest,
Ben Clayton2522b292021-02-10 21:40:36 +00002250 Intrinsic_SingleParamTest,
Ben Clayton052ab892021-02-08 19:53:42 +00002251 testing::Values(IntrinsicData{"acos", IntrinsicType::kAcos},
2252 IntrinsicData{"asin", IntrinsicType::kAsin},
2253 IntrinsicData{"atan", IntrinsicType::kAtan},
2254 IntrinsicData{"ceil", IntrinsicType::kCeil},
2255 IntrinsicData{"cos", IntrinsicType::kCos},
2256 IntrinsicData{"cosh", IntrinsicType::kCosh},
2257 IntrinsicData{"exp", IntrinsicType::kExp},
2258 IntrinsicData{"exp2", IntrinsicType::kExp2},
2259 IntrinsicData{"floor", IntrinsicType::kFloor},
2260 IntrinsicData{"fract", IntrinsicType::kFract},
2261 IntrinsicData{"inverseSqrt", IntrinsicType::kInverseSqrt},
2262 IntrinsicData{"log", IntrinsicType::kLog},
2263 IntrinsicData{"log2", IntrinsicType::kLog2},
Ben Clayton052ab892021-02-08 19:53:42 +00002264 IntrinsicData{"round", IntrinsicType::kRound},
2265 IntrinsicData{"sign", IntrinsicType::kSign},
2266 IntrinsicData{"sin", IntrinsicType::kSin},
2267 IntrinsicData{"sinh", IntrinsicType::kSinh},
2268 IntrinsicData{"sqrt", IntrinsicType::kSqrt},
2269 IntrinsicData{"tan", IntrinsicType::kTan},
2270 IntrinsicData{"tanh", IntrinsicType::kTanh},
2271 IntrinsicData{"trunc", IntrinsicType::kTrunc}));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002272
Ben Clayton47c4d182021-02-10 21:42:35 +00002273TEST_F(IntrinsicDataTest, ArrayLength_Vector) {
Ben Clayton37571bc2021-02-16 23:57:01 +00002274 Global("arr", ty.array<int>(), ast::StorageClass::kNone);
Ben Clayton47c4d182021-02-10 21:42:35 +00002275 auto* call = Call("arrayLength", "arr");
2276 WrapInFunction(call);
2277
2278 EXPECT_TRUE(td()->Determine()) << td()->error();
2279
2280 ASSERT_NE(TypeOf(call), nullptr);
2281 EXPECT_TRUE(TypeOf(call)->Is<type::U32>());
2282}
2283
2284TEST_F(IntrinsicDataTest, ArrayLength_Error_ArraySized) {
Ben Clayton37571bc2021-02-16 23:57:01 +00002285 Global("arr", ty.array<int, 4>(), ast::StorageClass::kNone);
Ben Clayton47c4d182021-02-10 21:42:35 +00002286 auto* call = Call("arrayLength", "arr");
2287 WrapInFunction(call);
2288
2289 EXPECT_FALSE(td()->Determine());
2290
2291 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00002292 "error: no matching call to arrayLength(ptr<array<i32, 4>>)\n\n"
Ben Clayton47c4d182021-02-10 21:42:35 +00002293 "1 candidate function:\n"
2294 " arrayLength(array<T>) -> u32\n");
2295}
2296
Ben Claytona51aa1f2021-02-08 21:10:11 +00002297TEST_F(IntrinsicDataTest, Normalize_Vector) {
2298 auto* call = Call("normalize", vec3<f32>(1.0f, 1.0f, 3.0f));
2299 WrapInFunction(call);
2300
2301 EXPECT_TRUE(td()->Determine()) << td()->error();
2302
2303 ASSERT_NE(TypeOf(call), nullptr);
2304 EXPECT_TRUE(TypeOf(call)->is_float_vector());
2305 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
2306}
2307
2308TEST_F(IntrinsicDataTest, Normalize_Error_NoParams) {
2309 auto* call = Call("normalize");
2310 WrapInFunction(call);
2311
2312 EXPECT_FALSE(td()->Determine());
2313
2314 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00002315 "error: no matching call to normalize()\n\n"
Ben Clayton47c4d182021-02-10 21:42:35 +00002316 "1 candidate function:\n"
2317 " normalize(vecN<f32>) -> vecN<f32>\n");
2318}
2319
2320TEST_F(IntrinsicDataTest, FrexpScalar) {
Ben Clayton37571bc2021-02-16 23:57:01 +00002321 Global("exp", ty.i32(), ast::StorageClass::kWorkgroup);
Ben Clayton47c4d182021-02-10 21:42:35 +00002322 auto* call = Call("frexp", 1.0f, "exp");
2323 WrapInFunction(call);
2324
2325 EXPECT_TRUE(td()->Determine()) << td()->error();
2326
2327 ASSERT_NE(TypeOf(call), nullptr);
2328 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
2329}
2330
2331TEST_F(IntrinsicDataTest, FrexpVector) {
Ben Clayton37571bc2021-02-16 23:57:01 +00002332 Global("exp", ty.vec3<i32>(), ast::StorageClass::kWorkgroup);
Ben Clayton47c4d182021-02-10 21:42:35 +00002333 auto* call = Call("frexp", vec3<f32>(1.0f, 2.0f, 3.0f), "exp");
2334 WrapInFunction(call);
2335
2336 EXPECT_TRUE(td()->Determine()) << td()->error();
2337
2338 ASSERT_NE(TypeOf(call), nullptr);
2339 EXPECT_TRUE(TypeOf(call)->Is<type::Vector>());
2340 EXPECT_TRUE(TypeOf(call)->As<type::Vector>()->type()->Is<type::F32>());
2341}
2342
2343TEST_F(IntrinsicDataTest, Frexp_Error_FirstParamInt) {
Ben Clayton37571bc2021-02-16 23:57:01 +00002344 Global("exp", ty.i32(), ast::StorageClass::kWorkgroup);
Ben Clayton47c4d182021-02-10 21:42:35 +00002345 auto* call = Call("frexp", 1, "exp");
2346 WrapInFunction(call);
2347
2348 EXPECT_FALSE(td()->Determine());
2349
2350 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00002351 "error: no matching call to frexp(i32, ptr<workgroup, i32>)\n\n"
Ben Clayton47c4d182021-02-10 21:42:35 +00002352 "2 candidate functions:\n"
2353 " frexp(f32, ptr<T>) -> f32 where: T is i32 or u32\n"
2354 " frexp(vecN<f32>, ptr<vecN<T>>) -> vecN<f32> "
2355 "where: T is i32 or u32\n");
2356}
2357
2358TEST_F(IntrinsicDataTest, Frexp_Error_SecondParamFloatPtr) {
Ben Clayton37571bc2021-02-16 23:57:01 +00002359 Global("exp", ty.f32(), ast::StorageClass::kWorkgroup);
Ben Clayton47c4d182021-02-10 21:42:35 +00002360 auto* call = Call("frexp", 1.0f, "exp");
2361 WrapInFunction(call);
2362
2363 EXPECT_FALSE(td()->Determine());
2364
2365 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00002366 "error: no matching call to frexp(f32, ptr<workgroup, f32>)\n\n"
Ben Clayton47c4d182021-02-10 21:42:35 +00002367 "2 candidate functions:\n"
2368 " frexp(f32, ptr<T>) -> f32 where: T is i32 or u32\n"
2369 " frexp(vecN<f32>, ptr<vecN<T>>) -> vecN<f32> "
2370 "where: T is i32 or u32\n");
2371}
2372
2373TEST_F(IntrinsicDataTest, Frexp_Error_SecondParamNotAPointer) {
2374 auto* call = Call("frexp", 1.0f, 1);
2375 WrapInFunction(call);
2376
2377 EXPECT_FALSE(td()->Determine());
2378
2379 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00002380 "error: no matching call to frexp(f32, i32)\n\n"
Ben Clayton47c4d182021-02-10 21:42:35 +00002381 "2 candidate functions:\n"
2382 " frexp(f32, ptr<T>) -> f32 where: T is i32 or u32\n"
2383 " frexp(vecN<f32>, ptr<vecN<T>>) -> vecN<f32> "
2384 "where: T is i32 or u32\n");
2385}
2386
2387TEST_F(IntrinsicDataTest, Frexp_Error_VectorSizesDontMatch) {
Ben Clayton37571bc2021-02-16 23:57:01 +00002388 Global("exp", ty.vec4<i32>(), ast::StorageClass::kWorkgroup);
Ben Clayton47c4d182021-02-10 21:42:35 +00002389 auto* call = Call("frexp", vec2<f32>(1.0f, 2.0f), "exp");
2390 WrapInFunction(call);
2391
2392 EXPECT_FALSE(td()->Determine());
2393
Ben Clayton6b4924f2021-02-17 20:13:34 +00002394 EXPECT_EQ(td()->error(),
2395 "error: no matching call to frexp(vec2<f32>, ptr<workgroup, "
2396 "vec4<i32>>)\n\n"
2397 "2 candidate functions:\n"
2398 " frexp(f32, ptr<T>) -> f32 where: T is i32 or u32\n"
2399 " frexp(vecN<f32>, ptr<vecN<T>>) -> vecN<f32> "
2400 "where: T is i32 or u32\n");
Ben Clayton47c4d182021-02-10 21:42:35 +00002401}
2402
2403TEST_F(IntrinsicDataTest, ModfScalar) {
Ben Clayton37571bc2021-02-16 23:57:01 +00002404 Global("whole", ty.f32(), ast::StorageClass::kWorkgroup);
Ben Clayton47c4d182021-02-10 21:42:35 +00002405 auto* call = Call("modf", 1.0f, "whole");
2406 WrapInFunction(call);
2407
2408 EXPECT_TRUE(td()->Determine()) << td()->error();
2409
2410 ASSERT_NE(TypeOf(call), nullptr);
2411 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
2412}
2413
2414TEST_F(IntrinsicDataTest, ModfVector) {
Ben Clayton37571bc2021-02-16 23:57:01 +00002415 Global("whole", ty.vec3<f32>(), ast::StorageClass::kWorkgroup);
Ben Clayton47c4d182021-02-10 21:42:35 +00002416 auto* call = Call("modf", vec3<f32>(1.0f, 2.0f, 3.0f), "whole");
2417 WrapInFunction(call);
2418
2419 EXPECT_TRUE(td()->Determine()) << td()->error();
2420
2421 ASSERT_NE(TypeOf(call), nullptr);
2422 EXPECT_TRUE(TypeOf(call)->Is<type::Vector>());
2423 EXPECT_TRUE(TypeOf(call)->As<type::Vector>()->type()->Is<type::F32>());
2424}
2425
2426TEST_F(IntrinsicDataTest, Modf_Error_FirstParamInt) {
Ben Clayton37571bc2021-02-16 23:57:01 +00002427 Global("whole", ty.f32(), ast::StorageClass::kWorkgroup);
Ben Clayton47c4d182021-02-10 21:42:35 +00002428 auto* call = Call("modf", 1, "whole");
2429 WrapInFunction(call);
2430
2431 EXPECT_FALSE(td()->Determine());
2432
2433 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00002434 "error: no matching call to modf(i32, ptr<workgroup, f32>)\n\n"
Ben Clayton47c4d182021-02-10 21:42:35 +00002435 "2 candidate functions:\n"
2436 " modf(f32, ptr<f32>) -> f32\n"
2437 " modf(vecN<f32>, ptr<vecN<f32>>) -> vecN<f32>\n");
2438}
2439
2440TEST_F(IntrinsicDataTest, Modf_Error_SecondParamIntPtr) {
Ben Clayton37571bc2021-02-16 23:57:01 +00002441 Global("whole", ty.i32(), ast::StorageClass::kWorkgroup);
Ben Clayton47c4d182021-02-10 21:42:35 +00002442 auto* call = Call("modf", 1.0f, "whole");
2443 WrapInFunction(call);
2444
2445 EXPECT_FALSE(td()->Determine());
2446
2447 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00002448 "error: no matching call to modf(f32, ptr<workgroup, i32>)\n\n"
Ben Clayton47c4d182021-02-10 21:42:35 +00002449 "2 candidate functions:\n"
2450 " modf(f32, ptr<f32>) -> f32\n"
2451 " modf(vecN<f32>, ptr<vecN<f32>>) -> vecN<f32>\n");
2452}
2453
2454TEST_F(IntrinsicDataTest, Modf_Error_SecondParamNotAPointer) {
2455 auto* call = Call("modf", 1.0f, 1.0f);
2456 WrapInFunction(call);
2457
2458 EXPECT_FALSE(td()->Determine());
2459
2460 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00002461 "error: no matching call to modf(f32, f32)\n\n"
Ben Clayton47c4d182021-02-10 21:42:35 +00002462 "2 candidate functions:\n"
2463 " modf(f32, ptr<f32>) -> f32\n"
2464 " modf(vecN<f32>, ptr<vecN<f32>>) -> vecN<f32>\n");
2465}
2466
2467TEST_F(IntrinsicDataTest, Modf_Error_VectorSizesDontMatch) {
Ben Clayton37571bc2021-02-16 23:57:01 +00002468 Global("whole", ty.vec4<f32>(), ast::StorageClass::kWorkgroup);
Ben Clayton47c4d182021-02-10 21:42:35 +00002469 auto* call = Call("modf", vec2<f32>(1.0f, 2.0f), "whole");
2470 WrapInFunction(call);
2471
2472 EXPECT_FALSE(td()->Determine());
2473
2474 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00002475 "error: no matching call to modf(vec2<f32>, ptr<workgroup, "
2476 "vec4<f32>>)\n\n"
Ben Clayton47c4d182021-02-10 21:42:35 +00002477 "2 candidate functions:\n"
2478 " modf(vecN<f32>, ptr<vecN<f32>>) -> vecN<f32>\n"
2479 " modf(f32, ptr<f32>) -> f32\n");
Ben Claytona51aa1f2021-02-08 21:10:11 +00002480}
2481
Ben Clayton2522b292021-02-10 21:40:36 +00002482using Intrinsic_SingleParam_FloatOrInt_Test =
dan sinclairb4fee2f2020-09-22 19:42:13 +00002483 TypeDeterminerTestWithParam<IntrinsicData>;
Ben Clayton2522b292021-02-10 21:40:36 +00002484TEST_P(Intrinsic_SingleParam_FloatOrInt_Test, Float_Scalar) {
dan sinclairb4fee2f2020-09-22 19:42:13 +00002485 auto param = GetParam();
2486
Ben Claytona51aa1f2021-02-08 21:10:11 +00002487 auto* call = Call(param.name, 1.f);
Ben Clayton401b96b2021-02-03 17:19:59 +00002488 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002489
Ben Clayton401b96b2021-02-03 17:19:59 +00002490 EXPECT_TRUE(td()->Determine()) << td()->error();
2491
Ben Clayton1618f4b2021-02-03 21:02:25 +00002492 ASSERT_NE(TypeOf(call), nullptr);
2493 EXPECT_TRUE(TypeOf(call)->is_float_scalar());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002494}
2495
Ben Clayton2522b292021-02-10 21:40:36 +00002496TEST_P(Intrinsic_SingleParam_FloatOrInt_Test, Float_Vector) {
dan sinclairb4fee2f2020-09-22 19:42:13 +00002497 auto param = GetParam();
2498
Ben Claytona51aa1f2021-02-08 21:10:11 +00002499 auto* call = Call(param.name, vec3<f32>(1.0f, 1.0f, 3.0f));
Ben Clayton401b96b2021-02-03 17:19:59 +00002500 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002501
Ben Clayton401b96b2021-02-03 17:19:59 +00002502 EXPECT_TRUE(td()->Determine()) << td()->error();
2503
Ben Clayton1618f4b2021-02-03 21:02:25 +00002504 ASSERT_NE(TypeOf(call), nullptr);
2505 EXPECT_TRUE(TypeOf(call)->is_float_vector());
2506 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002507}
2508
Ben Clayton2522b292021-02-10 21:40:36 +00002509TEST_P(Intrinsic_SingleParam_FloatOrInt_Test, Sint_Scalar) {
dan sinclairb4fee2f2020-09-22 19:42:13 +00002510 auto param = GetParam();
2511
Ben Claytona51aa1f2021-02-08 21:10:11 +00002512 auto* call = Call(param.name, -1);
Ben Clayton401b96b2021-02-03 17:19:59 +00002513 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002514
Ben Clayton401b96b2021-02-03 17:19:59 +00002515 EXPECT_TRUE(td()->Determine()) << td()->error();
2516
Ben Clayton1618f4b2021-02-03 21:02:25 +00002517 ASSERT_NE(TypeOf(call), nullptr);
2518 EXPECT_TRUE(TypeOf(call)->Is<type::I32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002519}
2520
Ben Clayton2522b292021-02-10 21:40:36 +00002521TEST_P(Intrinsic_SingleParam_FloatOrInt_Test, Sint_Vector) {
dan sinclairb4fee2f2020-09-22 19:42:13 +00002522 auto param = GetParam();
2523
dan sinclairb4fee2f2020-09-22 19:42:13 +00002524 ast::ExpressionList vals;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002525 vals.push_back(Expr(1));
2526 vals.push_back(Expr(1));
2527 vals.push_back(Expr(3));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002528
2529 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002530 params.push_back(vec3<i32>(vals));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002531
Ben Claytona51aa1f2021-02-08 21:10:11 +00002532 auto* call = Call(param.name, params);
Ben Clayton401b96b2021-02-03 17:19:59 +00002533 WrapInFunction(call);
Ben Clayton4bfe4612020-11-16 16:41:47 +00002534
Ben Clayton401b96b2021-02-03 17:19:59 +00002535 EXPECT_TRUE(td()->Determine()) << td()->error();
2536
Ben Clayton1618f4b2021-02-03 21:02:25 +00002537 ASSERT_NE(TypeOf(call), nullptr);
2538 EXPECT_TRUE(TypeOf(call)->is_signed_integer_vector());
2539 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002540}
2541
Ben Clayton2522b292021-02-10 21:40:36 +00002542TEST_P(Intrinsic_SingleParam_FloatOrInt_Test, Uint_Scalar) {
dan sinclairb4fee2f2020-09-22 19:42:13 +00002543 auto param = GetParam();
2544
dan sinclairb4fee2f2020-09-22 19:42:13 +00002545 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002546 params.push_back(Expr(1u));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002547
Ben Claytona51aa1f2021-02-08 21:10:11 +00002548 auto* call = Call(param.name, params);
Ben Clayton401b96b2021-02-03 17:19:59 +00002549 WrapInFunction(call);
Ben Clayton4bfe4612020-11-16 16:41:47 +00002550
Ben Clayton401b96b2021-02-03 17:19:59 +00002551 EXPECT_TRUE(td()->Determine()) << td()->error();
2552
Ben Clayton1618f4b2021-02-03 21:02:25 +00002553 ASSERT_NE(TypeOf(call), nullptr);
2554 EXPECT_TRUE(TypeOf(call)->Is<type::U32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002555}
2556
Ben Clayton2522b292021-02-10 21:40:36 +00002557TEST_P(Intrinsic_SingleParam_FloatOrInt_Test, Uint_Vector) {
dan sinclairb4fee2f2020-09-22 19:42:13 +00002558 auto param = GetParam();
2559
Ben Claytona51aa1f2021-02-08 21:10:11 +00002560 auto* call = Call(param.name, vec3<u32>(1u, 1u, 3u));
Ben Clayton401b96b2021-02-03 17:19:59 +00002561 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002562
Ben Clayton401b96b2021-02-03 17:19:59 +00002563 EXPECT_TRUE(td()->Determine()) << td()->error();
2564
Ben Clayton1618f4b2021-02-03 21:02:25 +00002565 ASSERT_NE(TypeOf(call), nullptr);
2566 EXPECT_TRUE(TypeOf(call)->is_unsigned_integer_vector());
2567 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002568}
2569
Ben Clayton2522b292021-02-10 21:40:36 +00002570TEST_P(Intrinsic_SingleParam_FloatOrInt_Test, Error_NoParams) {
dan sinclairb4fee2f2020-09-22 19:42:13 +00002571 auto param = GetParam();
2572
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002573 auto* call = Call(param.name);
Ben Clayton401b96b2021-02-03 17:19:59 +00002574 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002575
Ben Clayton401b96b2021-02-03 17:19:59 +00002576 EXPECT_FALSE(td()->Determine());
2577
Alan Bakere809fb32021-02-01 15:33:13 +00002578 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00002579 "error: no matching call to " + std::string(param.name) +
Ben Clayton59d24732021-02-08 22:42:54 +00002580 "()\n\n"
2581 "2 candidate functions:\n " +
2582 std::string(param.name) +
2583 "(T) -> T where: T is f32, i32 or u32\n " +
2584 std::string(param.name) +
2585 "(vecN<T>) -> vecN<T> where: T is f32, i32 or u32\n");
dan sinclairb4fee2f2020-09-22 19:42:13 +00002586}
2587
2588INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
Ben Clayton2522b292021-02-10 21:40:36 +00002589 Intrinsic_SingleParam_FloatOrInt_Test,
Ben Clayton052ab892021-02-08 19:53:42 +00002590 testing::Values(IntrinsicData{"abs",
2591 IntrinsicType::kAbs}));
dan sinclairca1723e2020-04-20 15:47:55 +00002592
Ben Clayton2522b292021-02-10 21:40:36 +00002593TEST_F(TypeDeterminerTest, Intrinsic_Length_Scalar) {
Ben Claytona51aa1f2021-02-08 21:10:11 +00002594 auto* call = Call("length", 1.f);
Ben Clayton401b96b2021-02-03 17:19:59 +00002595 WrapInFunction(call);
dan sinclair652a4b92020-04-20 21:09:14 +00002596
Ben Clayton401b96b2021-02-03 17:19:59 +00002597 EXPECT_TRUE(td()->Determine()) << td()->error();
2598
Ben Clayton1618f4b2021-02-03 21:02:25 +00002599 ASSERT_NE(TypeOf(call), nullptr);
2600 EXPECT_TRUE(TypeOf(call)->is_float_scalar());
dan sinclair652a4b92020-04-20 21:09:14 +00002601}
2602
Ben Clayton2522b292021-02-10 21:40:36 +00002603TEST_F(TypeDeterminerTest, Intrinsic_Length_FloatVector) {
dan sinclair652a4b92020-04-20 21:09:14 +00002604 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002605 params.push_back(vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair652a4b92020-04-20 21:09:14 +00002606
Ben Claytona51aa1f2021-02-08 21:10:11 +00002607 auto* call = Call("length", params);
Ben Clayton401b96b2021-02-03 17:19:59 +00002608 WrapInFunction(call);
dan sinclair652a4b92020-04-20 21:09:14 +00002609
Ben Clayton401b96b2021-02-03 17:19:59 +00002610 EXPECT_TRUE(td()->Determine()) << td()->error();
2611
Ben Clayton1618f4b2021-02-03 21:02:25 +00002612 ASSERT_NE(TypeOf(call), nullptr);
2613 EXPECT_TRUE(TypeOf(call)->is_float_scalar());
dan sinclair652a4b92020-04-20 21:09:14 +00002614}
2615
Ben Clayton2522b292021-02-10 21:40:36 +00002616using Intrinsic_TwoParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
2617TEST_P(Intrinsic_TwoParamTest, Scalar) {
dan sinclair37d62c92020-04-21 12:55:06 +00002618 auto param = GetParam();
2619
Ben Claytona51aa1f2021-02-08 21:10:11 +00002620 auto* call = Call(param.name, 1.f, 1.f);
Ben Clayton401b96b2021-02-03 17:19:59 +00002621 WrapInFunction(call);
dan sinclair37d62c92020-04-21 12:55:06 +00002622
Ben Clayton401b96b2021-02-03 17:19:59 +00002623 EXPECT_TRUE(td()->Determine()) << td()->error();
2624
Ben Clayton1618f4b2021-02-03 21:02:25 +00002625 ASSERT_NE(TypeOf(call), nullptr);
2626 EXPECT_TRUE(TypeOf(call)->is_float_scalar());
dan sinclair37d62c92020-04-21 12:55:06 +00002627}
2628
Ben Clayton2522b292021-02-10 21:40:36 +00002629TEST_P(Intrinsic_TwoParamTest, Vector) {
dan sinclair37d62c92020-04-21 12:55:06 +00002630 auto param = GetParam();
2631
Ben Claytona51aa1f2021-02-08 21:10:11 +00002632 auto* call = Call(param.name, vec3<f32>(1.0f, 1.0f, 3.0f),
2633 vec3<f32>(1.0f, 1.0f, 3.0f));
Ben Clayton401b96b2021-02-03 17:19:59 +00002634 WrapInFunction(call);
dan sinclair37d62c92020-04-21 12:55:06 +00002635
Ben Clayton401b96b2021-02-03 17:19:59 +00002636 EXPECT_TRUE(td()->Determine()) << td()->error();
2637
Ben Clayton1618f4b2021-02-03 21:02:25 +00002638 ASSERT_NE(TypeOf(call), nullptr);
2639 EXPECT_TRUE(TypeOf(call)->is_float_vector());
2640 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclair37d62c92020-04-21 12:55:06 +00002641}
Ben Clayton47c4d182021-02-10 21:42:35 +00002642
2643TEST_P(Intrinsic_TwoParamTest, Error_NoTooManyParams) {
2644 auto param = GetParam();
2645
2646 auto* call = Call(param.name, 1, 2, 3);
2647 WrapInFunction(call);
2648
2649 EXPECT_FALSE(td()->Determine());
2650
Ben Clayton6b4924f2021-02-17 20:13:34 +00002651 EXPECT_EQ(td()->error(),
2652 "error: no matching call to " + std::string(param.name) +
2653 "(i32, i32, i32)\n\n"
2654 "2 candidate functions:\n " +
2655 std::string(param.name) + "(f32, f32) -> f32\n " +
2656 std::string(param.name) +
2657 "(vecN<f32>, vecN<f32>) -> vecN<f32>\n");
Ben Clayton47c4d182021-02-10 21:42:35 +00002658}
2659
Ben Clayton2522b292021-02-10 21:40:36 +00002660TEST_P(Intrinsic_TwoParamTest, Error_NoParams) {
dan sinclair37d62c92020-04-21 12:55:06 +00002661 auto param = GetParam();
2662
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002663 auto* call = Call(param.name);
Ben Clayton401b96b2021-02-03 17:19:59 +00002664 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002665
Ben Clayton401b96b2021-02-03 17:19:59 +00002666 EXPECT_FALSE(td()->Determine());
2667
Ben Clayton6b4924f2021-02-17 20:13:34 +00002668 EXPECT_EQ(td()->error(),
2669 "error: no matching call to " + std::string(param.name) +
2670 "()\n\n"
2671 "2 candidate functions:\n " +
2672 std::string(param.name) + "(f32, f32) -> f32\n " +
2673 std::string(param.name) +
2674 "(vecN<f32>, vecN<f32>) -> vecN<f32>\n");
dan sinclair37d62c92020-04-21 12:55:06 +00002675}
Ben Clayton47c4d182021-02-10 21:42:35 +00002676
dan sinclairb4fee2f2020-09-22 19:42:13 +00002677INSTANTIATE_TEST_SUITE_P(
2678 TypeDeterminerTest,
Ben Clayton2522b292021-02-10 21:40:36 +00002679 Intrinsic_TwoParamTest,
Ben Clayton052ab892021-02-08 19:53:42 +00002680 testing::Values(IntrinsicData{"atan2", IntrinsicType::kAtan2},
2681 IntrinsicData{"pow", IntrinsicType::kPow},
2682 IntrinsicData{"step", IntrinsicType::kStep},
2683 IntrinsicData{"reflect", IntrinsicType::kReflect}));
dan sinclair37d62c92020-04-21 12:55:06 +00002684
Ben Clayton2522b292021-02-10 21:40:36 +00002685TEST_F(TypeDeterminerTest, Intrinsic_Distance_Scalar) {
Ben Claytona51aa1f2021-02-08 21:10:11 +00002686 auto* call = Call("distance", 1.f, 1.f);
Ben Clayton401b96b2021-02-03 17:19:59 +00002687 WrapInFunction(call);
dan sinclair54444382020-04-21 13:04:15 +00002688
Ben Clayton401b96b2021-02-03 17:19:59 +00002689 EXPECT_TRUE(td()->Determine()) << td()->error();
2690
Ben Clayton1618f4b2021-02-03 21:02:25 +00002691 ASSERT_NE(TypeOf(call), nullptr);
2692 EXPECT_TRUE(TypeOf(call)->is_float_scalar());
dan sinclair54444382020-04-21 13:04:15 +00002693}
2694
Ben Clayton2522b292021-02-10 21:40:36 +00002695TEST_F(TypeDeterminerTest, Intrinsic_Distance_Vector) {
Ben Claytona51aa1f2021-02-08 21:10:11 +00002696 auto* call = Call("distance", vec3<f32>(1.0f, 1.0f, 3.0f),
2697 vec3<f32>(1.0f, 1.0f, 3.0f));
Ben Clayton401b96b2021-02-03 17:19:59 +00002698 WrapInFunction(call);
dan sinclair54444382020-04-21 13:04:15 +00002699
Ben Clayton401b96b2021-02-03 17:19:59 +00002700 EXPECT_TRUE(td()->Determine()) << td()->error();
2701
Ben Clayton1618f4b2021-02-03 21:02:25 +00002702 ASSERT_NE(TypeOf(call), nullptr);
2703 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclair54444382020-04-21 13:04:15 +00002704}
2705
Ben Clayton2522b292021-02-10 21:40:36 +00002706TEST_F(TypeDeterminerTest, Intrinsic_Cross) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002707 auto* call =
Ben Clayton47c4d182021-02-10 21:42:35 +00002708 Call("cross", vec3<f32>(1.0f, 2.0f, 3.0f), vec3<f32>(1.0f, 2.0f, 3.0f));
Ben Clayton401b96b2021-02-03 17:19:59 +00002709 WrapInFunction(call);
dan sinclairee392252020-06-08 23:48:15 +00002710
Ben Clayton401b96b2021-02-03 17:19:59 +00002711 EXPECT_TRUE(td()->Determine()) << td()->error();
2712
Ben Clayton1618f4b2021-02-03 21:02:25 +00002713 ASSERT_NE(TypeOf(call), nullptr);
2714 EXPECT_TRUE(TypeOf(call)->is_float_vector());
2715 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairee392252020-06-08 23:48:15 +00002716}
2717
Ben Clayton47c4d182021-02-10 21:42:35 +00002718TEST_F(TypeDeterminerTest, Intrinsic_Cross_Error_NoArgs) {
Ben Claytona51aa1f2021-02-08 21:10:11 +00002719 auto* call = Call("cross");
Ben Clayton401b96b2021-02-03 17:19:59 +00002720 WrapInFunction(call);
dan sinclairee392252020-06-08 23:48:15 +00002721
Ben Clayton59d24732021-02-08 22:42:54 +00002722 EXPECT_FALSE(td()->Determine());
2723
Ben Clayton6b4924f2021-02-17 20:13:34 +00002724 EXPECT_EQ(td()->error(), R"(error: no matching call to cross()
Ben Clayton59d24732021-02-08 22:42:54 +00002725
27261 candidate function:
2727 cross(vec3<f32>, vec3<f32>) -> vec3<f32>
2728)");
2729}
2730
Ben Clayton47c4d182021-02-10 21:42:35 +00002731TEST_F(TypeDeterminerTest, Intrinsic_Cross_Error_Scalar) {
2732 auto* call = Call("cross", 1.0f, 1.0f);
2733 WrapInFunction(call);
2734
2735 EXPECT_FALSE(td()->Determine());
2736
Ben Clayton6b4924f2021-02-17 20:13:34 +00002737 EXPECT_EQ(td()->error(), R"(error: no matching call to cross(f32, f32)
Ben Clayton47c4d182021-02-10 21:42:35 +00002738
27391 candidate function:
2740 cross(vec3<f32>, vec3<f32>) -> vec3<f32>
2741)");
2742}
2743
2744TEST_F(TypeDeterminerTest, Intrinsic_Cross_Error_Vec3Int) {
2745 auto* call = Call("cross", vec3<i32>(1, 2, 3), vec3<i32>(1, 2, 3));
2746 WrapInFunction(call);
2747
2748 EXPECT_FALSE(td()->Determine());
2749
Ben Clayton6b4924f2021-02-17 20:13:34 +00002750 EXPECT_EQ(td()->error(),
2751 R"(error: no matching call to cross(vec3<i32>, vec3<i32>)
Ben Clayton47c4d182021-02-10 21:42:35 +00002752
27531 candidate function:
2754 cross(vec3<f32>, vec3<f32>) -> vec3<f32>
2755)");
2756}
2757
2758TEST_F(TypeDeterminerTest, Intrinsic_Cross_Error_Vec4) {
2759 auto* call = Call("cross", vec4<f32>(1.0f, 2.0f, 3.0f, 4.0f),
2760 vec4<f32>(1.0f, 2.0f, 3.0f, 4.0f));
2761
2762 WrapInFunction(call);
2763
2764 EXPECT_FALSE(td()->Determine());
2765
Ben Clayton6b4924f2021-02-17 20:13:34 +00002766 EXPECT_EQ(td()->error(),
2767 R"(error: no matching call to cross(vec4<f32>, vec4<f32>)
Ben Clayton47c4d182021-02-10 21:42:35 +00002768
27691 candidate function:
2770 cross(vec3<f32>, vec3<f32>) -> vec3<f32>
2771)");
2772}
2773
2774TEST_F(TypeDeterminerTest, Intrinsic_Cross_Error_TooManyParams) {
2775 auto* call = Call("cross", vec3<f32>(1.0f, 2.0f, 3.0f),
2776 vec3<f32>(1.0f, 2.0f, 3.0f), vec3<f32>(1.0f, 2.0f, 3.0f));
2777
2778 WrapInFunction(call);
2779
2780 EXPECT_FALSE(td()->Determine());
2781
2782 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00002783 R"(error: no matching call to cross(vec3<f32>, vec3<f32>, vec3<f32>)
Ben Clayton47c4d182021-02-10 21:42:35 +00002784
27851 candidate function:
2786 cross(vec3<f32>, vec3<f32>) -> vec3<f32>
2787)");
2788}
Ben Clayton2522b292021-02-10 21:40:36 +00002789TEST_F(TypeDeterminerTest, Intrinsic_Normalize) {
Ben Clayton59d24732021-02-08 22:42:54 +00002790 auto* call = Call("normalize", vec3<f32>(1.0f, 1.0f, 3.0f));
2791 WrapInFunction(call);
2792
Ben Clayton401b96b2021-02-03 17:19:59 +00002793 EXPECT_TRUE(td()->Determine()) << td()->error();
2794
Ben Clayton1618f4b2021-02-03 21:02:25 +00002795 ASSERT_NE(TypeOf(call), nullptr);
2796 EXPECT_TRUE(TypeOf(call)->is_float_vector());
2797 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairee392252020-06-08 23:48:15 +00002798}
2799
Ben Clayton2522b292021-02-10 21:40:36 +00002800TEST_F(TypeDeterminerTest, Intrinsic_Normalize_NoArgs) {
Ben Clayton59d24732021-02-08 22:42:54 +00002801 auto* call = Call("normalize");
2802 WrapInFunction(call);
2803
2804 EXPECT_FALSE(td()->Determine());
2805
Ben Clayton6b4924f2021-02-17 20:13:34 +00002806 EXPECT_EQ(td()->error(), R"(error: no matching call to normalize()
Ben Clayton59d24732021-02-08 22:42:54 +00002807
28081 candidate function:
2809 normalize(vecN<f32>) -> vecN<f32>
2810)");
2811}
2812
Ben Clayton2522b292021-02-10 21:40:36 +00002813using Intrinsic_ThreeParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
2814TEST_P(Intrinsic_ThreeParamTest, Scalar) {
dan sinclair2287d012020-04-22 00:23:57 +00002815 auto param = GetParam();
2816
Ben Claytona51aa1f2021-02-08 21:10:11 +00002817 auto* call = Call(param.name, 1.f, 1.f, 1.f);
Ben Clayton401b96b2021-02-03 17:19:59 +00002818 WrapInFunction(call);
dan sinclair2287d012020-04-22 00:23:57 +00002819
Ben Clayton401b96b2021-02-03 17:19:59 +00002820 EXPECT_TRUE(td()->Determine()) << td()->error();
2821
Ben Clayton1618f4b2021-02-03 21:02:25 +00002822 ASSERT_NE(TypeOf(call), nullptr);
2823 EXPECT_TRUE(TypeOf(call)->is_float_scalar());
dan sinclair2287d012020-04-22 00:23:57 +00002824}
2825
Ben Clayton2522b292021-02-10 21:40:36 +00002826TEST_P(Intrinsic_ThreeParamTest, Vector) {
dan sinclair2287d012020-04-22 00:23:57 +00002827 auto param = GetParam();
2828
Ben Claytona51aa1f2021-02-08 21:10:11 +00002829 auto* call = Call(param.name, vec3<f32>(1.0f, 1.0f, 3.0f),
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002830 vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
Ben Clayton401b96b2021-02-03 17:19:59 +00002831 WrapInFunction(call);
dan sinclair2287d012020-04-22 00:23:57 +00002832
Ben Clayton401b96b2021-02-03 17:19:59 +00002833 EXPECT_TRUE(td()->Determine()) << td()->error();
2834
Ben Clayton1618f4b2021-02-03 21:02:25 +00002835 ASSERT_NE(TypeOf(call), nullptr);
2836 EXPECT_TRUE(TypeOf(call)->is_float_vector());
2837 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclair2287d012020-04-22 00:23:57 +00002838}
Ben Clayton2522b292021-02-10 21:40:36 +00002839TEST_P(Intrinsic_ThreeParamTest, Error_NoParams) {
dan sinclair2287d012020-04-22 00:23:57 +00002840 auto param = GetParam();
2841
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002842 auto* call = Call(param.name);
Ben Clayton401b96b2021-02-03 17:19:59 +00002843 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002844
Ben Clayton401b96b2021-02-03 17:19:59 +00002845 EXPECT_FALSE(td()->Determine());
2846
dan sinclair2287d012020-04-22 00:23:57 +00002847 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00002848 "error: no matching call to " + std::string(param.name) +
Ben Clayton59d24732021-02-08 22:42:54 +00002849 "()\n\n"
2850 "2 candidate functions:\n " +
2851 std::string(param.name) + "(f32, f32, f32) -> f32\n " +
2852 std::string(param.name) +
2853 "(vecN<f32>, vecN<f32>, vecN<f32>) -> vecN<f32>\n");
dan sinclair2287d012020-04-22 00:23:57 +00002854}
2855
2856INSTANTIATE_TEST_SUITE_P(
2857 TypeDeterminerTest,
Ben Clayton2522b292021-02-10 21:40:36 +00002858 Intrinsic_ThreeParamTest,
Ben Clayton052ab892021-02-08 19:53:42 +00002859 testing::Values(IntrinsicData{"mix", IntrinsicType::kMix},
2860 IntrinsicData{"smoothStep", IntrinsicType::kSmoothStep},
2861 IntrinsicData{"fma", IntrinsicType::kFma},
2862 IntrinsicData{"faceForward", IntrinsicType::kFaceForward}));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002863
Ben Clayton2522b292021-02-10 21:40:36 +00002864using Intrinsic_ThreeParam_FloatOrInt_Test =
dan sinclairb4fee2f2020-09-22 19:42:13 +00002865 TypeDeterminerTestWithParam<IntrinsicData>;
Ben Clayton2522b292021-02-10 21:40:36 +00002866TEST_P(Intrinsic_ThreeParam_FloatOrInt_Test, Float_Scalar) {
dan sinclairb4fee2f2020-09-22 19:42:13 +00002867 auto param = GetParam();
2868
Ben Claytona51aa1f2021-02-08 21:10:11 +00002869 auto* call = Call(param.name, 1.f, 1.f, 1.f);
Ben Clayton401b96b2021-02-03 17:19:59 +00002870 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002871
Ben Clayton401b96b2021-02-03 17:19:59 +00002872 EXPECT_TRUE(td()->Determine()) << td()->error();
2873
Ben Clayton1618f4b2021-02-03 21:02:25 +00002874 ASSERT_NE(TypeOf(call), nullptr);
2875 EXPECT_TRUE(TypeOf(call)->is_float_scalar());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002876}
2877
Ben Clayton2522b292021-02-10 21:40:36 +00002878TEST_P(Intrinsic_ThreeParam_FloatOrInt_Test, Float_Vector) {
dan sinclairb4fee2f2020-09-22 19:42:13 +00002879 auto param = GetParam();
2880
Ben Claytona51aa1f2021-02-08 21:10:11 +00002881 auto* call = Call(param.name, vec3<f32>(1.0f, 1.0f, 3.0f),
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002882 vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
Ben Clayton401b96b2021-02-03 17:19:59 +00002883 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002884
Ben Clayton401b96b2021-02-03 17:19:59 +00002885 EXPECT_TRUE(td()->Determine()) << td()->error();
2886
Ben Clayton1618f4b2021-02-03 21:02:25 +00002887 ASSERT_NE(TypeOf(call), nullptr);
2888 EXPECT_TRUE(TypeOf(call)->is_float_vector());
2889 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002890}
2891
Ben Clayton2522b292021-02-10 21:40:36 +00002892TEST_P(Intrinsic_ThreeParam_FloatOrInt_Test, Sint_Scalar) {
dan sinclairb4fee2f2020-09-22 19:42:13 +00002893 auto param = GetParam();
2894
Ben Claytona51aa1f2021-02-08 21:10:11 +00002895 auto* call = Call(param.name, 1, 1, 1);
Ben Clayton401b96b2021-02-03 17:19:59 +00002896 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002897
Ben Clayton401b96b2021-02-03 17:19:59 +00002898 EXPECT_TRUE(td()->Determine()) << td()->error();
2899
Ben Clayton1618f4b2021-02-03 21:02:25 +00002900 ASSERT_NE(TypeOf(call), nullptr);
2901 EXPECT_TRUE(TypeOf(call)->Is<type::I32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002902}
2903
Ben Clayton2522b292021-02-10 21:40:36 +00002904TEST_P(Intrinsic_ThreeParam_FloatOrInt_Test, Sint_Vector) {
dan sinclairb4fee2f2020-09-22 19:42:13 +00002905 auto param = GetParam();
2906
Ben Claytona51aa1f2021-02-08 21:10:11 +00002907 auto* call = Call(param.name, vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3),
2908 vec3<i32>(1, 1, 3));
Ben Clayton401b96b2021-02-03 17:19:59 +00002909 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002910
Ben Clayton401b96b2021-02-03 17:19:59 +00002911 EXPECT_TRUE(td()->Determine()) << td()->error();
2912
Ben Clayton1618f4b2021-02-03 21:02:25 +00002913 ASSERT_NE(TypeOf(call), nullptr);
2914 EXPECT_TRUE(TypeOf(call)->is_signed_integer_vector());
2915 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002916}
2917
Ben Clayton2522b292021-02-10 21:40:36 +00002918TEST_P(Intrinsic_ThreeParam_FloatOrInt_Test, Uint_Scalar) {
dan sinclairb4fee2f2020-09-22 19:42:13 +00002919 auto param = GetParam();
2920
Ben Claytona51aa1f2021-02-08 21:10:11 +00002921 auto* call = Call(param.name, 1u, 1u, 1u);
Ben Clayton401b96b2021-02-03 17:19:59 +00002922 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002923
Ben Clayton401b96b2021-02-03 17:19:59 +00002924 EXPECT_TRUE(td()->Determine()) << td()->error();
2925
Ben Clayton1618f4b2021-02-03 21:02:25 +00002926 ASSERT_NE(TypeOf(call), nullptr);
2927 EXPECT_TRUE(TypeOf(call)->Is<type::U32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002928}
2929
Ben Clayton2522b292021-02-10 21:40:36 +00002930TEST_P(Intrinsic_ThreeParam_FloatOrInt_Test, Uint_Vector) {
dan sinclairb4fee2f2020-09-22 19:42:13 +00002931 auto param = GetParam();
2932
Ben Claytona51aa1f2021-02-08 21:10:11 +00002933 auto* call = Call(param.name, vec3<u32>(1u, 1u, 3u), vec3<u32>(1u, 1u, 3u),
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002934 vec3<u32>(1u, 1u, 3u));
Ben Clayton401b96b2021-02-03 17:19:59 +00002935 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002936
Ben Clayton401b96b2021-02-03 17:19:59 +00002937 EXPECT_TRUE(td()->Determine()) << td()->error();
2938
Ben Clayton1618f4b2021-02-03 21:02:25 +00002939 ASSERT_NE(TypeOf(call), nullptr);
2940 EXPECT_TRUE(TypeOf(call)->is_unsigned_integer_vector());
2941 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002942}
2943
Ben Clayton2522b292021-02-10 21:40:36 +00002944TEST_P(Intrinsic_ThreeParam_FloatOrInt_Test, Error_NoParams) {
dan sinclairb4fee2f2020-09-22 19:42:13 +00002945 auto param = GetParam();
2946
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002947 auto* call = Call(param.name);
Ben Clayton401b96b2021-02-03 17:19:59 +00002948 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002949
Ben Clayton401b96b2021-02-03 17:19:59 +00002950 EXPECT_FALSE(td()->Determine());
2951
dan sinclairb4fee2f2020-09-22 19:42:13 +00002952 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00002953 "error: no matching call to " + std::string(param.name) +
Ben Clayton59d24732021-02-08 22:42:54 +00002954 "()\n\n"
2955 "2 candidate functions:\n " +
2956 std::string(param.name) +
2957 "(T, T, T) -> T where: T is f32, i32 or u32\n " +
2958 std::string(param.name) +
2959 "(vecN<T>, vecN<T>, vecN<T>) -> vecN<T> where: T is f32, i32 "
2960 "or u32\n");
dan sinclairb4fee2f2020-09-22 19:42:13 +00002961}
2962
2963INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
Ben Clayton2522b292021-02-10 21:40:36 +00002964 Intrinsic_ThreeParam_FloatOrInt_Test,
Ben Clayton052ab892021-02-08 19:53:42 +00002965 testing::Values(IntrinsicData{"clamp",
2966 IntrinsicType::kClamp}));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002967
Ben Clayton2522b292021-02-10 21:40:36 +00002968using Intrinsic_Int_SingleParamTest =
dan sinclairb4fee2f2020-09-22 19:42:13 +00002969 TypeDeterminerTestWithParam<IntrinsicData>;
Ben Clayton2522b292021-02-10 21:40:36 +00002970TEST_P(Intrinsic_Int_SingleParamTest, Scalar) {
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002971 auto param = GetParam();
2972
Ben Claytona51aa1f2021-02-08 21:10:11 +00002973 auto* call = Call(param.name, 1);
Ben Clayton401b96b2021-02-03 17:19:59 +00002974 WrapInFunction(call);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002975
Ben Clayton401b96b2021-02-03 17:19:59 +00002976 EXPECT_TRUE(td()->Determine()) << td()->error();
2977
Ben Clayton1618f4b2021-02-03 21:02:25 +00002978 ASSERT_NE(TypeOf(call), nullptr);
2979 EXPECT_TRUE(TypeOf(call)->is_integer_scalar());
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002980}
2981
Ben Clayton2522b292021-02-10 21:40:36 +00002982TEST_P(Intrinsic_Int_SingleParamTest, Vector) {
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002983 auto param = GetParam();
2984
Ben Claytona51aa1f2021-02-08 21:10:11 +00002985 auto* call = Call(param.name, vec3<i32>(1, 1, 3));
Ben Clayton401b96b2021-02-03 17:19:59 +00002986 WrapInFunction(call);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002987
Ben Clayton401b96b2021-02-03 17:19:59 +00002988 EXPECT_TRUE(td()->Determine()) << td()->error();
2989
Ben Clayton1618f4b2021-02-03 21:02:25 +00002990 ASSERT_NE(TypeOf(call), nullptr);
2991 EXPECT_TRUE(TypeOf(call)->is_signed_integer_vector());
2992 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002993}
2994
Ben Clayton2522b292021-02-10 21:40:36 +00002995TEST_P(Intrinsic_Int_SingleParamTest, Error_NoParams) {
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002996 auto param = GetParam();
2997
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002998 auto* call = Call(param.name);
Ben Clayton401b96b2021-02-03 17:19:59 +00002999 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003000
Ben Clayton401b96b2021-02-03 17:19:59 +00003001 EXPECT_FALSE(td()->Determine());
3002
Alan Bakere809fb32021-02-01 15:33:13 +00003003 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00003004 "error: no matching call to " + std::string(param.name) +
Ben Clayton59d24732021-02-08 22:42:54 +00003005 "()\n\n"
3006 "2 candidate functions:\n " +
3007 std::string(param.name) +
3008 "(T) -> T where: T is i32 or u32\n " +
3009 std::string(param.name) +
3010 "(vecN<T>) -> vecN<T> where: T is i32 or u32\n");
dan sinclair5e5fb9c2020-06-08 19:01:07 +00003011}
3012
dan sinclairaf5df702020-06-08 23:48:26 +00003013INSTANTIATE_TEST_SUITE_P(
3014 TypeDeterminerTest,
Ben Clayton2522b292021-02-10 21:40:36 +00003015 Intrinsic_Int_SingleParamTest,
Ben Clayton052ab892021-02-08 19:53:42 +00003016 testing::Values(IntrinsicData{"countOneBits", IntrinsicType::kCountOneBits},
3017 IntrinsicData{"reverseBits", IntrinsicType::kReverseBits}));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00003018
Ben Clayton2522b292021-02-10 21:40:36 +00003019using Intrinsic_FloatOrInt_TwoParamTest =
dan sinclairb4fee2f2020-09-22 19:42:13 +00003020 TypeDeterminerTestWithParam<IntrinsicData>;
Ben Clayton2522b292021-02-10 21:40:36 +00003021TEST_P(Intrinsic_FloatOrInt_TwoParamTest, Scalar_Signed) {
dan sinclair92bb5572020-06-08 23:48:07 +00003022 auto param = GetParam();
3023
Ben Claytona51aa1f2021-02-08 21:10:11 +00003024 auto* call = Call(param.name, 1, 1);
Ben Clayton401b96b2021-02-03 17:19:59 +00003025 WrapInFunction(call);
dan sinclair92bb5572020-06-08 23:48:07 +00003026
Ben Clayton401b96b2021-02-03 17:19:59 +00003027 EXPECT_TRUE(td()->Determine()) << td()->error();
3028
Ben Clayton1618f4b2021-02-03 21:02:25 +00003029 ASSERT_NE(TypeOf(call), nullptr);
3030 EXPECT_TRUE(TypeOf(call)->Is<type::I32>());
dan sinclair92bb5572020-06-08 23:48:07 +00003031}
3032
Ben Clayton2522b292021-02-10 21:40:36 +00003033TEST_P(Intrinsic_FloatOrInt_TwoParamTest, Scalar_Unsigned) {
dan sinclair92bb5572020-06-08 23:48:07 +00003034 auto param = GetParam();
3035
Ben Claytona51aa1f2021-02-08 21:10:11 +00003036 auto* call = Call(param.name, 1u, 1u);
Ben Clayton401b96b2021-02-03 17:19:59 +00003037 WrapInFunction(call);
dan sinclair92bb5572020-06-08 23:48:07 +00003038
Ben Clayton401b96b2021-02-03 17:19:59 +00003039 EXPECT_TRUE(td()->Determine()) << td()->error();
3040
Ben Clayton1618f4b2021-02-03 21:02:25 +00003041 ASSERT_NE(TypeOf(call), nullptr);
3042 EXPECT_TRUE(TypeOf(call)->Is<type::U32>());
dan sinclair92bb5572020-06-08 23:48:07 +00003043}
3044
Ben Clayton2522b292021-02-10 21:40:36 +00003045TEST_P(Intrinsic_FloatOrInt_TwoParamTest, Scalar_Float) {
dan sinclairb4fee2f2020-09-22 19:42:13 +00003046 auto param = GetParam();
3047
Ben Claytona51aa1f2021-02-08 21:10:11 +00003048 auto* call = Call(param.name, 1.0f, 1.0f);
Ben Clayton401b96b2021-02-03 17:19:59 +00003049 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003050
Ben Clayton401b96b2021-02-03 17:19:59 +00003051 EXPECT_TRUE(td()->Determine()) << td()->error();
3052
Ben Clayton1618f4b2021-02-03 21:02:25 +00003053 ASSERT_NE(TypeOf(call), nullptr);
3054 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00003055}
3056
Ben Clayton2522b292021-02-10 21:40:36 +00003057TEST_P(Intrinsic_FloatOrInt_TwoParamTest, Vector_Signed) {
dan sinclair92bb5572020-06-08 23:48:07 +00003058 auto param = GetParam();
3059
Ben Claytona51aa1f2021-02-08 21:10:11 +00003060 auto* call = Call(param.name, vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3));
Ben Clayton401b96b2021-02-03 17:19:59 +00003061 WrapInFunction(call);
dan sinclair92bb5572020-06-08 23:48:07 +00003062
Ben Clayton401b96b2021-02-03 17:19:59 +00003063 EXPECT_TRUE(td()->Determine()) << td()->error();
3064
Ben Clayton1618f4b2021-02-03 21:02:25 +00003065 ASSERT_NE(TypeOf(call), nullptr);
3066 EXPECT_TRUE(TypeOf(call)->is_signed_integer_vector());
3067 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclair92bb5572020-06-08 23:48:07 +00003068}
3069
Ben Clayton2522b292021-02-10 21:40:36 +00003070TEST_P(Intrinsic_FloatOrInt_TwoParamTest, Vector_Unsigned) {
dan sinclair92bb5572020-06-08 23:48:07 +00003071 auto param = GetParam();
3072
Ben Claytona51aa1f2021-02-08 21:10:11 +00003073 auto* call = Call(param.name, vec3<u32>(1u, 1u, 3u), vec3<u32>(1u, 1u, 3u));
Ben Clayton401b96b2021-02-03 17:19:59 +00003074 WrapInFunction(call);
dan sinclair92bb5572020-06-08 23:48:07 +00003075
Ben Clayton401b96b2021-02-03 17:19:59 +00003076 EXPECT_TRUE(td()->Determine()) << td()->error();
3077
Ben Clayton1618f4b2021-02-03 21:02:25 +00003078 ASSERT_NE(TypeOf(call), nullptr);
3079 EXPECT_TRUE(TypeOf(call)->is_unsigned_integer_vector());
3080 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclair92bb5572020-06-08 23:48:07 +00003081}
3082
Ben Clayton2522b292021-02-10 21:40:36 +00003083TEST_P(Intrinsic_FloatOrInt_TwoParamTest, Vector_Float) {
dan sinclair92bb5572020-06-08 23:48:07 +00003084 auto param = GetParam();
3085
Ben Claytona51aa1f2021-02-08 21:10:11 +00003086 auto* call =
3087 Call(param.name, vec3<f32>(1.f, 1.f, 3.f), vec3<f32>(1.f, 1.f, 3.f));
Ben Clayton401b96b2021-02-03 17:19:59 +00003088 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003089
Ben Clayton401b96b2021-02-03 17:19:59 +00003090 EXPECT_TRUE(td()->Determine()) << td()->error();
3091
Ben Clayton1618f4b2021-02-03 21:02:25 +00003092 ASSERT_NE(TypeOf(call), nullptr);
3093 EXPECT_TRUE(TypeOf(call)->is_float_vector());
3094 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003095}
3096
Ben Clayton2522b292021-02-10 21:40:36 +00003097TEST_P(Intrinsic_FloatOrInt_TwoParamTest, Error_NoParams) {
dan sinclair92bb5572020-06-08 23:48:07 +00003098 auto param = GetParam();
3099
Ben Clayton7eaf4b52020-12-14 22:08:27 +00003100 auto* call = Call(param.name);
Ben Clayton401b96b2021-02-03 17:19:59 +00003101 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003102
Ben Clayton401b96b2021-02-03 17:19:59 +00003103 EXPECT_FALSE(td()->Determine());
3104
dan sinclair92bb5572020-06-08 23:48:07 +00003105 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00003106 "error: no matching call to " + std::string(param.name) +
Ben Clayton59d24732021-02-08 22:42:54 +00003107 "()\n\n"
3108 "2 candidate functions:\n " +
3109 std::string(param.name) +
3110 "(T, T) -> T where: T is f32, i32 or u32\n " +
3111 std::string(param.name) +
3112 "(vecN<T>, vecN<T>) -> vecN<T> where: T is f32, i32 or u32\n");
dan sinclair92bb5572020-06-08 23:48:07 +00003113}
3114
dan sinclairb4fee2f2020-09-22 19:42:13 +00003115INSTANTIATE_TEST_SUITE_P(
3116 TypeDeterminerTest,
Ben Clayton2522b292021-02-10 21:40:36 +00003117 Intrinsic_FloatOrInt_TwoParamTest,
Ben Clayton052ab892021-02-08 19:53:42 +00003118 testing::Values(IntrinsicData{"min", IntrinsicType::kMin},
3119 IntrinsicData{"max", IntrinsicType::kMax}));
dan sinclair92bb5572020-06-08 23:48:07 +00003120
Ben Clayton47c4d182021-02-10 21:42:35 +00003121TEST_F(TypeDeterminerTest, Intrinsic_Determinant_2x2) {
Ben Clayton37571bc2021-02-16 23:57:01 +00003122 Global("var", ty.mat2x2<f32>(), ast::StorageClass::kFunction);
Ben Clayton47c4d182021-02-10 21:42:35 +00003123
3124 auto* call = Call("determinant", "var");
3125 WrapInFunction(call);
3126
3127 EXPECT_TRUE(td()->Determine()) << td()->error();
3128
3129 ASSERT_NE(TypeOf(call), nullptr);
3130 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
3131}
3132
3133TEST_F(TypeDeterminerTest, Intrinsic_Determinant_3x3) {
Ben Clayton37571bc2021-02-16 23:57:01 +00003134 Global("var", ty.mat3x3<f32>(), ast::StorageClass::kFunction);
dan sinclair3819c262020-06-17 18:39:17 +00003135
Ben Claytona51aa1f2021-02-08 21:10:11 +00003136 auto* call = Call("determinant", "var");
Ben Clayton401b96b2021-02-03 17:19:59 +00003137 WrapInFunction(call);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003138
Ben Clayton401b96b2021-02-03 17:19:59 +00003139 EXPECT_TRUE(td()->Determine()) << td()->error();
3140
Ben Clayton1618f4b2021-02-03 21:02:25 +00003141 ASSERT_NE(TypeOf(call), nullptr);
3142 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclair3819c262020-06-17 18:39:17 +00003143}
3144
Ben Clayton47c4d182021-02-10 21:42:35 +00003145TEST_F(TypeDeterminerTest, Intrinsic_Determinant_4x4) {
Ben Clayton37571bc2021-02-16 23:57:01 +00003146 Global("var", ty.mat4x4<f32>(), ast::StorageClass::kFunction);
dan sinclair3819c262020-06-17 18:39:17 +00003147
Ben Clayton47c4d182021-02-10 21:42:35 +00003148 auto* call = Call("determinant", "var");
3149 WrapInFunction(call);
dan sinclair3238eaa2020-06-17 20:22:08 +00003150
Ben Clayton47c4d182021-02-10 21:42:35 +00003151 EXPECT_TRUE(td()->Determine()) << td()->error();
3152
3153 ASSERT_NE(TypeOf(call), nullptr);
3154 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
3155}
3156
3157TEST_F(TypeDeterminerTest, Intrinsic_Determinant_NotSquare) {
Ben Clayton37571bc2021-02-16 23:57:01 +00003158 Global("var", ty.mat2x3<f32>(), ast::StorageClass::kFunction);
Ben Clayton47c4d182021-02-10 21:42:35 +00003159
3160 auto* call = Call("determinant", "var");
Ben Clayton401b96b2021-02-03 17:19:59 +00003161 WrapInFunction(call);
dan sinclair3819c262020-06-17 18:39:17 +00003162
Ben Clayton59d24732021-02-08 22:42:54 +00003163 EXPECT_FALSE(td()->Determine());
Ben Clayton401b96b2021-02-03 17:19:59 +00003164
Ben Clayton6b4924f2021-02-17 20:13:34 +00003165 EXPECT_EQ(
3166 td()->error(),
3167 "error: no matching call to determinant(ptr<function, mat2x3<f32>>)\n\n"
3168 "1 candidate function:\n"
3169 " determinant(matNxN<f32>) -> f32\n");
dan sinclair3819c262020-06-17 18:39:17 +00003170}
3171
Ben Clayton47c4d182021-02-10 21:42:35 +00003172TEST_F(TypeDeterminerTest, Intrinsic_Determinant_NotMatrix) {
Ben Clayton37571bc2021-02-16 23:57:01 +00003173 Global("var", ty.f32(), ast::StorageClass::kFunction);
Ben Clayton47c4d182021-02-10 21:42:35 +00003174
3175 auto* call = Call("determinant", "var");
3176 WrapInFunction(call);
3177
3178 EXPECT_FALSE(td()->Determine());
3179
3180 EXPECT_EQ(td()->error(),
Ben Clayton6b4924f2021-02-17 20:13:34 +00003181 "error: no matching call to determinant(ptr<function, f32>)\n\n"
Ben Clayton47c4d182021-02-10 21:42:35 +00003182 "1 candidate function:\n"
3183 " determinant(matNxN<f32>) -> f32\n");
3184}
dan sinclaire9598d62020-06-18 18:03:00 +00003185
dan sinclair05926432020-09-21 17:51:31 +00003186TEST_F(TypeDeterminerTest, Function_EntryPoints_StageDecoration) {
dan sinclair05926432020-09-21 17:51:31 +00003187 // fn b() {}
3188 // fn c() { b(); }
3189 // fn a() { c(); }
3190 // fn ep_1() { a(); b(); }
3191 // fn ep_2() { c();}
3192 //
3193 // c -> {ep_1, ep_2}
3194 // a -> {ep_1}
3195 // b -> {ep_1, ep_2}
3196 // ep_1 -> {}
3197 // ep_2 -> {}
3198
3199 ast::VariableList params;
Ben Clayton8d391f72021-01-26 16:57:10 +00003200 auto* func_b = Func("b", params, ty.f32(), ast::StatementList{},
dan sinclair181d8ba2020-12-16 15:15:40 +00003201 ast::FunctionDecorationList{});
dan sinclaira41132f2020-12-11 18:24:53 +00003202 auto* func_c =
Ben Clayton8d391f72021-01-26 16:57:10 +00003203 Func("c", params, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +00003204 ast::StatementList{
3205 create<ast::AssignmentStatement>(Expr("second"), Call("b")),
3206 },
3207 ast::FunctionDecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00003208
dan sinclaira41132f2020-12-11 18:24:53 +00003209 auto* func_a =
Ben Clayton8d391f72021-01-26 16:57:10 +00003210 Func("a", params, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +00003211 ast::StatementList{
3212 create<ast::AssignmentStatement>(Expr("first"), Call("c")),
3213 },
3214 ast::FunctionDecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00003215
dan sinclair181d8ba2020-12-16 15:15:40 +00003216 auto* ep_1 =
Ben Clayton8d391f72021-01-26 16:57:10 +00003217 Func("ep_1", params, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +00003218 ast::StatementList{
3219 create<ast::AssignmentStatement>(Expr("call_a"), Call("a")),
3220 create<ast::AssignmentStatement>(Expr("call_b"), Call("b")),
3221 },
3222 ast::FunctionDecorationList{
3223 create<ast::StageDecoration>(ast::PipelineStage::kVertex),
3224 });
Ben Clayton7eaf4b52020-12-14 22:08:27 +00003225
dan sinclair181d8ba2020-12-16 15:15:40 +00003226 auto* ep_2 =
Ben Clayton8d391f72021-01-26 16:57:10 +00003227 Func("ep_2", params, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +00003228 ast::StatementList{
3229 create<ast::AssignmentStatement>(Expr("call_c"), Call("c")),
3230 },
3231 ast::FunctionDecorationList{
3232 create<ast::StageDecoration>(ast::PipelineStage::kVertex),
3233 });
dan sinclair05926432020-09-21 17:51:31 +00003234
Ben Clayton37571bc2021-02-16 23:57:01 +00003235 Global("first", ty.f32(), ast::StorageClass::kPrivate);
3236 Global("second", ty.f32(), ast::StorageClass::kPrivate);
3237 Global("call_a", ty.f32(), ast::StorageClass::kPrivate);
3238 Global("call_b", ty.f32(), ast::StorageClass::kPrivate);
3239 Global("call_c", ty.f32(), ast::StorageClass::kPrivate);
dan sinclairff267ca2020-10-14 18:26:31 +00003240
dan sinclair05926432020-09-21 17:51:31 +00003241 ASSERT_TRUE(td()->Determine()) << td()->error();
3242
Ben Clayton87c78dd2021-02-03 16:43:20 +00003243 auto* func_b_sem = Sem().Get(func_b);
3244 auto* func_a_sem = Sem().Get(func_a);
3245 auto* func_c_sem = Sem().Get(func_c);
3246 auto* ep_1_sem = Sem().Get(ep_1);
3247 auto* ep_2_sem = Sem().Get(ep_2);
3248 ASSERT_NE(func_b_sem, nullptr);
3249 ASSERT_NE(func_a_sem, nullptr);
3250 ASSERT_NE(func_c_sem, nullptr);
3251 ASSERT_NE(ep_1_sem, nullptr);
3252 ASSERT_NE(ep_2_sem, nullptr);
3253
3254 const auto& b_eps = func_b_sem->AncestorEntryPoints();
dan sinclair05926432020-09-21 17:51:31 +00003255 ASSERT_EQ(2u, b_eps.size());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00003256 EXPECT_EQ(Symbols().Register("ep_1"), b_eps[0]);
3257 EXPECT_EQ(Symbols().Register("ep_2"), b_eps[1]);
dan sinclair05926432020-09-21 17:51:31 +00003258
Ben Clayton87c78dd2021-02-03 16:43:20 +00003259 const auto& a_eps = func_a_sem->AncestorEntryPoints();
dan sinclair05926432020-09-21 17:51:31 +00003260 ASSERT_EQ(1u, a_eps.size());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00003261 EXPECT_EQ(Symbols().Register("ep_1"), a_eps[0]);
dan sinclair05926432020-09-21 17:51:31 +00003262
Ben Clayton87c78dd2021-02-03 16:43:20 +00003263 const auto& c_eps = func_c_sem->AncestorEntryPoints();
dan sinclair05926432020-09-21 17:51:31 +00003264 ASSERT_EQ(2u, c_eps.size());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00003265 EXPECT_EQ(Symbols().Register("ep_1"), c_eps[0]);
3266 EXPECT_EQ(Symbols().Register("ep_2"), c_eps[1]);
dan sinclair05926432020-09-21 17:51:31 +00003267
Ben Clayton87c78dd2021-02-03 16:43:20 +00003268 EXPECT_TRUE(ep_1_sem->AncestorEntryPoints().empty());
3269 EXPECT_TRUE(ep_2_sem->AncestorEntryPoints().empty());
dan sinclair05926432020-09-21 17:51:31 +00003270}
3271
Ben Clayton3ea3c992020-11-18 21:19:22 +00003272using TypeDeterminerTextureIntrinsicTest =
3273 TypeDeterminerTestWithParam<ast::intrinsic::test::TextureOverloadCase>;
3274
3275INSTANTIATE_TEST_SUITE_P(
3276 TypeDeterminerTest,
3277 TypeDeterminerTextureIntrinsicTest,
3278 testing::ValuesIn(ast::intrinsic::test::TextureOverloadCase::ValidCases()));
3279
3280std::string to_str(const std::string& function,
dan sinclair81302442021-02-09 15:37:44 +00003281 const semantic::ParameterList& params) {
Ben Clayton3ea3c992020-11-18 21:19:22 +00003282 std::stringstream out;
3283 out << function << "(";
3284 bool first = true;
Ben Clayton316f9f62021-02-08 22:31:44 +00003285 for (auto& param : params) {
Ben Clayton3ea3c992020-11-18 21:19:22 +00003286 if (!first) {
3287 out << ", ";
3288 }
Ben Clayton316f9f62021-02-08 22:31:44 +00003289 out << semantic::str(param.usage);
Ben Clayton3ea3c992020-11-18 21:19:22 +00003290 first = false;
3291 }
3292 out << ")";
3293 return out.str();
3294}
3295
3296const char* expected_texture_overload(
3297 ast::intrinsic::test::ValidTextureOverload overload) {
3298 using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
3299 switch (overload) {
Ben Clayton4a0b9f72021-01-11 21:07:32 +00003300 case ValidTextureOverload::kDimensions1d:
Ben Clayton4a0b9f72021-01-11 21:07:32 +00003301 case ValidTextureOverload::kDimensions2d:
3302 case ValidTextureOverload::kDimensions2dArray:
3303 case ValidTextureOverload::kDimensions3d:
3304 case ValidTextureOverload::kDimensionsCube:
3305 case ValidTextureOverload::kDimensionsCubeArray:
Ben Clayton6e5b5ec2021-01-14 18:09:07 +00003306 case ValidTextureOverload::kDimensionsMultisampled2d:
3307 case ValidTextureOverload::kDimensionsMultisampled2dArray:
Ben Clayton4a0b9f72021-01-11 21:07:32 +00003308 case ValidTextureOverload::kDimensionsDepth2d:
3309 case ValidTextureOverload::kDimensionsDepth2dArray:
3310 case ValidTextureOverload::kDimensionsDepthCube:
3311 case ValidTextureOverload::kDimensionsDepthCubeArray:
3312 case ValidTextureOverload::kDimensionsStorageRO1d:
Ben Clayton4a0b9f72021-01-11 21:07:32 +00003313 case ValidTextureOverload::kDimensionsStorageRO2d:
3314 case ValidTextureOverload::kDimensionsStorageRO2dArray:
3315 case ValidTextureOverload::kDimensionsStorageRO3d:
3316 case ValidTextureOverload::kDimensionsStorageWO1d:
Ben Clayton4a0b9f72021-01-11 21:07:32 +00003317 case ValidTextureOverload::kDimensionsStorageWO2d:
3318 case ValidTextureOverload::kDimensionsStorageWO2dArray:
3319 case ValidTextureOverload::kDimensionsStorageWO3d:
3320 return R"(textureDimensions(texture))";
Ben Claytonc21f1f92021-01-14 16:50:07 +00003321 case ValidTextureOverload::kNumLayers2dArray:
3322 case ValidTextureOverload::kNumLayersCubeArray:
Ben Clayton6e5b5ec2021-01-14 18:09:07 +00003323 case ValidTextureOverload::kNumLayersMultisampled2dArray:
Ben Claytonc21f1f92021-01-14 16:50:07 +00003324 case ValidTextureOverload::kNumLayersDepth2dArray:
3325 case ValidTextureOverload::kNumLayersDepthCubeArray:
Ben Claytonc21f1f92021-01-14 16:50:07 +00003326 case ValidTextureOverload::kNumLayersStorageWO2dArray:
3327 return R"(textureNumLayers(texture))";
Ben Claytond9713202021-01-14 18:06:57 +00003328 case ValidTextureOverload::kNumLevels2d:
3329 case ValidTextureOverload::kNumLevels2dArray:
3330 case ValidTextureOverload::kNumLevels3d:
3331 case ValidTextureOverload::kNumLevelsCube:
3332 case ValidTextureOverload::kNumLevelsCubeArray:
3333 case ValidTextureOverload::kNumLevelsDepth2d:
3334 case ValidTextureOverload::kNumLevelsDepth2dArray:
3335 case ValidTextureOverload::kNumLevelsDepthCube:
3336 case ValidTextureOverload::kNumLevelsDepthCubeArray:
3337 return R"(textureNumLevels(texture))";
Ben Clayton0a68b362021-01-14 18:11:17 +00003338 case ValidTextureOverload::kNumSamplesMultisampled2d:
3339 case ValidTextureOverload::kNumSamplesMultisampled2dArray:
3340 return R"(textureNumSamples(texture))";
Ben Clayton4a0b9f72021-01-11 21:07:32 +00003341 case ValidTextureOverload::kDimensions2dLevel:
3342 case ValidTextureOverload::kDimensions2dArrayLevel:
3343 case ValidTextureOverload::kDimensions3dLevel:
3344 case ValidTextureOverload::kDimensionsCubeLevel:
3345 case ValidTextureOverload::kDimensionsCubeArrayLevel:
3346 case ValidTextureOverload::kDimensionsDepth2dLevel:
3347 case ValidTextureOverload::kDimensionsDepth2dArrayLevel:
3348 case ValidTextureOverload::kDimensionsDepthCubeLevel:
3349 case ValidTextureOverload::kDimensionsDepthCubeArrayLevel:
3350 return R"(textureDimensions(texture, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003351 case ValidTextureOverload::kSample1dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003352 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003353 case ValidTextureOverload::kSample2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003354 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003355 case ValidTextureOverload::kSample2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003356 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003357 case ValidTextureOverload::kSample2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003358 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003359 case ValidTextureOverload::kSample2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003360 return R"(textureSample(texture, sampler, coords, array_index, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003361 case ValidTextureOverload::kSample3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003362 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003363 case ValidTextureOverload::kSample3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003364 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003365 case ValidTextureOverload::kSampleCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003366 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003367 case ValidTextureOverload::kSampleCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003368 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003369 case ValidTextureOverload::kSampleDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003370 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003371 case ValidTextureOverload::kSampleDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003372 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003373 case ValidTextureOverload::kSampleDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003374 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003375 case ValidTextureOverload::kSampleDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003376 return R"(textureSample(texture, sampler, coords, array_index, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003377 case ValidTextureOverload::kSampleDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003378 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003379 case ValidTextureOverload::kSampleDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003380 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003381 case ValidTextureOverload::kSampleBias2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003382 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003383 case ValidTextureOverload::kSampleBias2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003384 return R"(textureSampleBias(texture, sampler, coords, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003385 case ValidTextureOverload::kSampleBias2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003386 return R"(textureSampleBias(texture, sampler, coords, array_index, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003387 case ValidTextureOverload::kSampleBias2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003388 return R"(textureSampleBias(texture, sampler, coords, array_index, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003389 case ValidTextureOverload::kSampleBias3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003390 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003391 case ValidTextureOverload::kSampleBias3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003392 return R"(textureSampleBias(texture, sampler, coords, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003393 case ValidTextureOverload::kSampleBiasCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003394 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003395 case ValidTextureOverload::kSampleBiasCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003396 return R"(textureSampleBias(texture, sampler, coords, array_index, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003397 case ValidTextureOverload::kSampleLevel2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003398 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003399 case ValidTextureOverload::kSampleLevel2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003400 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003401 case ValidTextureOverload::kSampleLevel2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003402 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003403 case ValidTextureOverload::kSampleLevel2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003404 return R"(textureSampleLevel(texture, sampler, coords, array_index, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003405 case ValidTextureOverload::kSampleLevel3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003406 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003407 case ValidTextureOverload::kSampleLevel3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003408 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003409 case ValidTextureOverload::kSampleLevelCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003410 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003411 case ValidTextureOverload::kSampleLevelCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003412 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003413 case ValidTextureOverload::kSampleLevelDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003414 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003415 case ValidTextureOverload::kSampleLevelDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003416 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003417 case ValidTextureOverload::kSampleLevelDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003418 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003419 case ValidTextureOverload::kSampleLevelDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003420 return R"(textureSampleLevel(texture, sampler, coords, array_index, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003421 case ValidTextureOverload::kSampleLevelDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003422 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003423 case ValidTextureOverload::kSampleLevelDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003424 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003425 case ValidTextureOverload::kSampleGrad2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003426 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003427 case ValidTextureOverload::kSampleGrad2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003428 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003429 case ValidTextureOverload::kSampleGrad2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003430 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003431 case ValidTextureOverload::kSampleGrad2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003432 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003433 case ValidTextureOverload::kSampleGrad3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003434 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003435 case ValidTextureOverload::kSampleGrad3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003436 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003437 case ValidTextureOverload::kSampleGradCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003438 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003439 case ValidTextureOverload::kSampleGradCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003440 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy))";
Ben Clayton57166262021-01-13 16:36:51 +00003441 case ValidTextureOverload::kSampleCompareDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003442 return R"(textureSampleCompare(texture, sampler, coords, depth_ref))";
Ben Clayton57166262021-01-13 16:36:51 +00003443 case ValidTextureOverload::kSampleCompareDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003444 return R"(textureSampleCompare(texture, sampler, coords, depth_ref, offset))";
Ben Clayton57166262021-01-13 16:36:51 +00003445 case ValidTextureOverload::kSampleCompareDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003446 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref))";
Ben Clayton57166262021-01-13 16:36:51 +00003447 case ValidTextureOverload::kSampleCompareDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003448 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref, offset))";
Ben Clayton57166262021-01-13 16:36:51 +00003449 case ValidTextureOverload::kSampleCompareDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003450 return R"(textureSampleCompare(texture, sampler, coords, depth_ref))";
Ben Clayton57166262021-01-13 16:36:51 +00003451 case ValidTextureOverload::kSampleCompareDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003452 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref))";
Ryan Harrisone5c105d2021-02-25 23:57:28 +00003453 case ValidTextureOverload::kLoad1dLevelF32:
3454 return R"(textureLoad(texture, coords, level))";
3455 case ValidTextureOverload::kLoad1dLevelU32:
3456 return R"(textureLoad(texture, coords, level))";
3457 case ValidTextureOverload::kLoad1dLevelI32:
3458 return R"(textureLoad(texture, coords, level))";
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003459 case ValidTextureOverload::kLoad2dLevelF32:
3460 return R"(textureLoad(texture, coords, level))";
3461 case ValidTextureOverload::kLoad2dLevelU32:
3462 return R"(textureLoad(texture, coords, level))";
3463 case ValidTextureOverload::kLoad2dLevelI32:
3464 return R"(textureLoad(texture, coords, level))";
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003465 case ValidTextureOverload::kLoad2dArrayLevelF32:
3466 return R"(textureLoad(texture, coords, array_index, level))";
3467 case ValidTextureOverload::kLoad2dArrayLevelU32:
3468 return R"(textureLoad(texture, coords, array_index, level))";
3469 case ValidTextureOverload::kLoad2dArrayLevelI32:
3470 return R"(textureLoad(texture, coords, array_index, level))";
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003471 case ValidTextureOverload::kLoad3dLevelF32:
3472 return R"(textureLoad(texture, coords, level))";
3473 case ValidTextureOverload::kLoad3dLevelU32:
3474 return R"(textureLoad(texture, coords, level))";
3475 case ValidTextureOverload::kLoad3dLevelI32:
3476 return R"(textureLoad(texture, coords, level))";
3477 case ValidTextureOverload::kLoadMultisampled2dF32:
3478 return R"(textureLoad(texture, coords, sample_index))";
3479 case ValidTextureOverload::kLoadMultisampled2dU32:
3480 return R"(textureLoad(texture, coords, sample_index))";
3481 case ValidTextureOverload::kLoadMultisampled2dI32:
3482 return R"(textureLoad(texture, coords, sample_index))";
3483 case ValidTextureOverload::kLoadMultisampled2dArrayF32:
3484 return R"(textureLoad(texture, coords, array_index, sample_index))";
3485 case ValidTextureOverload::kLoadMultisampled2dArrayU32:
3486 return R"(textureLoad(texture, coords, array_index, sample_index))";
3487 case ValidTextureOverload::kLoadMultisampled2dArrayI32:
3488 return R"(textureLoad(texture, coords, array_index, sample_index))";
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003489 case ValidTextureOverload::kLoadDepth2dLevelF32:
3490 return R"(textureLoad(texture, coords, level))";
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003491 case ValidTextureOverload::kLoadDepth2dArrayLevelF32:
3492 return R"(textureLoad(texture, coords, array_index, level))";
3493 case ValidTextureOverload::kLoadStorageRO1dRgba32float:
3494 return R"(textureLoad(texture, coords))";
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003495 case ValidTextureOverload::kLoadStorageRO2dRgba8unorm:
3496 case ValidTextureOverload::kLoadStorageRO2dRgba8snorm:
3497 case ValidTextureOverload::kLoadStorageRO2dRgba8uint:
3498 case ValidTextureOverload::kLoadStorageRO2dRgba8sint:
3499 case ValidTextureOverload::kLoadStorageRO2dRgba16uint:
3500 case ValidTextureOverload::kLoadStorageRO2dRgba16sint:
3501 case ValidTextureOverload::kLoadStorageRO2dRgba16float:
3502 case ValidTextureOverload::kLoadStorageRO2dR32uint:
3503 case ValidTextureOverload::kLoadStorageRO2dR32sint:
3504 case ValidTextureOverload::kLoadStorageRO2dR32float:
3505 case ValidTextureOverload::kLoadStorageRO2dRg32uint:
3506 case ValidTextureOverload::kLoadStorageRO2dRg32sint:
3507 case ValidTextureOverload::kLoadStorageRO2dRg32float:
3508 case ValidTextureOverload::kLoadStorageRO2dRgba32uint:
3509 case ValidTextureOverload::kLoadStorageRO2dRgba32sint:
3510 case ValidTextureOverload::kLoadStorageRO2dRgba32float:
3511 return R"(textureLoad(texture, coords))";
3512 case ValidTextureOverload::kLoadStorageRO2dArrayRgba32float:
3513 return R"(textureLoad(texture, coords, array_index))";
3514 case ValidTextureOverload::kLoadStorageRO3dRgba32float:
3515 return R"(textureLoad(texture, coords))";
Ben Clayton591268d2020-12-10 18:39:41 +00003516 case ValidTextureOverload::kStoreWO1dRgba32float:
3517 return R"(textureStore(texture, coords, value))";
Ben Clayton591268d2020-12-10 18:39:41 +00003518 case ValidTextureOverload::kStoreWO2dRgba32float:
3519 return R"(textureStore(texture, coords, value))";
3520 case ValidTextureOverload::kStoreWO2dArrayRgba32float:
3521 return R"(textureStore(texture, coords, array_index, value))";
3522 case ValidTextureOverload::kStoreWO3dRgba32float:
3523 return R"(textureStore(texture, coords, value))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003524 }
3525 return "<unmatched texture overload>";
3526}
3527
3528TEST_P(TypeDeterminerTextureIntrinsicTest, Call) {
3529 auto param = GetParam();
3530
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003531 param.buildTextureVariable(this);
3532 param.buildSamplerVariable(this);
Ben Clayton3ea3c992020-11-18 21:19:22 +00003533
Ben Claytona51aa1f2021-02-08 21:10:11 +00003534 auto* call = Call(param.function, param.args(this));
Ben Clayton401b96b2021-02-03 17:19:59 +00003535 WrapInFunction(call);
Ben Clayton3ea3c992020-11-18 21:19:22 +00003536
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003537 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton3ea3c992020-11-18 21:19:22 +00003538
Ben Clayton4a0b9f72021-01-11 21:07:32 +00003539 if (std::string(param.function) == "textureDimensions") {
3540 switch (param.texture_dimension) {
3541 default:
3542 FAIL() << "invalid texture dimensions: " << param.texture_dimension;
Ben Clayton207b5e22021-01-21 15:42:10 +00003543 case type::TextureDimension::k1d:
Ben Clayton33352542021-01-29 16:43:41 +00003544 EXPECT_EQ(TypeOf(call)->type_name(), ty.i32()->type_name());
Ben Clayton4a0b9f72021-01-11 21:07:32 +00003545 break;
Ben Clayton207b5e22021-01-21 15:42:10 +00003546 case type::TextureDimension::k2d:
3547 case type::TextureDimension::k2dArray:
Ben Clayton33352542021-01-29 16:43:41 +00003548 EXPECT_EQ(TypeOf(call)->type_name(), ty.vec2<i32>()->type_name());
Ben Clayton4a0b9f72021-01-11 21:07:32 +00003549 break;
Ben Clayton207b5e22021-01-21 15:42:10 +00003550 case type::TextureDimension::k3d:
3551 case type::TextureDimension::kCube:
3552 case type::TextureDimension::kCubeArray:
Ben Clayton33352542021-01-29 16:43:41 +00003553 EXPECT_EQ(TypeOf(call)->type_name(), ty.vec3<i32>()->type_name());
Ben Clayton4a0b9f72021-01-11 21:07:32 +00003554 break;
3555 }
Ben Claytonc21f1f92021-01-14 16:50:07 +00003556 } else if (std::string(param.function) == "textureNumLayers") {
Ben Clayton33352542021-01-29 16:43:41 +00003557 EXPECT_EQ(TypeOf(call), ty.i32());
Ben Claytond9713202021-01-14 18:06:57 +00003558 } else if (std::string(param.function) == "textureNumLevels") {
Ben Clayton33352542021-01-29 16:43:41 +00003559 EXPECT_EQ(TypeOf(call), ty.i32());
Ben Clayton0a68b362021-01-14 18:11:17 +00003560 } else if (std::string(param.function) == "textureNumSamples") {
Ben Clayton33352542021-01-29 16:43:41 +00003561 EXPECT_EQ(TypeOf(call), ty.i32());
Ben Clayton4a0b9f72021-01-11 21:07:32 +00003562 } else if (std::string(param.function) == "textureStore") {
Ben Clayton33352542021-01-29 16:43:41 +00003563 EXPECT_EQ(TypeOf(call), ty.void_());
Ben Clayton591268d2020-12-10 18:39:41 +00003564 } else {
3565 switch (param.texture_kind) {
3566 case ast::intrinsic::test::TextureKind::kRegular:
3567 case ast::intrinsic::test::TextureKind::kMultisampled:
3568 case ast::intrinsic::test::TextureKind::kStorage: {
3569 auto* datatype = param.resultVectorComponentType(this);
Ben Clayton33352542021-01-29 16:43:41 +00003570 ASSERT_TRUE(TypeOf(call)->Is<type::Vector>());
3571 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->type(), datatype);
Ben Clayton591268d2020-12-10 18:39:41 +00003572 break;
3573 }
3574 case ast::intrinsic::test::TextureKind::kDepth: {
Ben Clayton33352542021-01-29 16:43:41 +00003575 EXPECT_EQ(TypeOf(call), ty.f32());
Ben Clayton591268d2020-12-10 18:39:41 +00003576 break;
3577 }
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003578 }
Ben Clayton3ea3c992020-11-18 21:19:22 +00003579 }
3580
Ben Clayton316f9f62021-02-08 22:31:44 +00003581 auto* call_sem = Sem().Get(call);
3582 ASSERT_NE(call_sem, nullptr);
3583 auto* target = call_sem->Target();
3584 ASSERT_NE(target, nullptr);
Ben Clayton3ea3c992020-11-18 21:19:22 +00003585
Ben Clayton316f9f62021-02-08 22:31:44 +00003586 auto got = ::tint::to_str(param.function, target->Parameters());
Ben Clayton3ea3c992020-11-18 21:19:22 +00003587 auto* expected = expected_texture_overload(param.overload);
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003588 EXPECT_EQ(got, expected);
Ben Clayton3ea3c992020-11-18 21:19:22 +00003589}
3590
dan sinclairb7edc4c2020-04-07 12:46:30 +00003591} // namespace
3592} // namespace tint