blob: fc46468fc830e25f8e3e73274c0ace71684f7c3d [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
22#include "gtest/gtest.h"
dan sinclair973bd6a2020-04-07 12:57:42 +000023#include "src/ast/array_accessor_expression.h"
dan sinclair6c498fc2020-04-07 12:47:23 +000024#include "src/ast/assignment_statement.h"
dan sinclair1c9b4862020-04-07 19:27:41 +000025#include "src/ast/binary_expression.h"
dan sinclaira7d498e2020-09-22 22:07:13 +000026#include "src/ast/bitcast_expression.h"
dan sinclair0975dd52020-07-27 15:25:00 +000027#include "src/ast/block_statement.h"
dan sinclairb4fee2f2020-09-22 19:42:13 +000028#include "src/ast/bool_literal.h"
dan sinclairb7ea6e22020-04-07 12:54:10 +000029#include "src/ast/break_statement.h"
dan sinclair3ca87462020-04-07 16:41:10 +000030#include "src/ast/call_expression.h"
dan sinclair50080b72020-07-21 13:42:13 +000031#include "src/ast/call_statement.h"
dan sinclair6010b292020-04-07 12:54:20 +000032#include "src/ast/case_statement.h"
dan sinclairaec965e2020-04-07 12:54:29 +000033#include "src/ast/continue_statement.h"
dan sinclair0cf685f2020-04-07 12:54:37 +000034#include "src/ast/else_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000035#include "src/ast/float_literal.h"
dan sinclaircab0e732020-04-07 12:57:27 +000036#include "src/ast/identifier_expression.h"
dan sinclair91c44a52020-04-07 12:55:25 +000037#include "src/ast/if_statement.h"
Ben Clayton3ea3c992020-11-18 21:19:22 +000038#include "src/ast/intrinsic_texture_helper_test.h"
dan sinclairbc71eda2020-04-07 12:55:51 +000039#include "src/ast/loop_statement.h"
dan sinclair8ee1d222020-04-07 16:41:33 +000040#include "src/ast/member_accessor_expression.h"
dan sinclair05926432020-09-21 17:51:31 +000041#include "src/ast/pipeline_stage.h"
dan sinclairbf0fff82020-04-07 12:56:24 +000042#include "src/ast/return_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000043#include "src/ast/scalar_constructor_expression.h"
dan sinclairc6f29472020-06-02 20:11:44 +000044#include "src/ast/sint_literal.h"
dan sinclair05926432020-09-21 17:51:31 +000045#include "src/ast/stage_decoration.h"
dan sinclair8ee1d222020-04-07 16:41:33 +000046#include "src/ast/struct.h"
47#include "src/ast/struct_member.h"
dan sinclair18b32852020-04-07 12:56:45 +000048#include "src/ast/switch_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000049#include "src/ast/type_constructor_expression.h"
dan sinclair92bb5572020-06-08 23:48:07 +000050#include "src/ast/uint_literal.h"
dan sinclair327ed1b2020-04-07 19:27:21 +000051#include "src/ast/unary_op_expression.h"
dan sinclairca893e32020-04-07 12:57:12 +000052#include "src/ast/variable_decl_statement.h"
Ben Claytona6b9a8e2021-01-26 16:57:10 +000053#include "src/program_builder.h"
Ben Clayton1618f4b2021-02-03 21:02:25 +000054#include "src/semantic/call.h"
Ben Clayton33352542021-01-29 16:43:41 +000055#include "src/semantic/expression.h"
Ben Clayton87c78dd2021-02-03 16:43:20 +000056#include "src/semantic/function.h"
Ben Claytonb17aea12021-02-03 17:51:09 +000057#include "src/semantic/variable.h"
Ben Clayton207b5e22021-01-21 15:42:10 +000058#include "src/type/alias_type.h"
59#include "src/type/array_type.h"
60#include "src/type/bool_type.h"
61#include "src/type/depth_texture_type.h"
62#include "src/type/f32_type.h"
63#include "src/type/i32_type.h"
64#include "src/type/matrix_type.h"
65#include "src/type/multisampled_texture_type.h"
66#include "src/type/pointer_type.h"
67#include "src/type/sampled_texture_type.h"
68#include "src/type/sampler_type.h"
69#include "src/type/storage_texture_type.h"
70#include "src/type/struct_type.h"
71#include "src/type/texture_type.h"
72#include "src/type/u32_type.h"
73#include "src/type/vector_type.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000074
75namespace tint {
76namespace {
77
Ben Clayton052ab892021-02-08 19:53:42 +000078using IntrinsicType = semantic::IntrinsicType;
79
dan sinclair7456f422020-04-08 19:58:35 +000080class FakeStmt : public ast::Statement {
81 public:
Ben Clayton604bc722020-12-12 01:24:53 +000082 explicit FakeStmt(Source source) : ast::Statement(source) {}
Ben Clayton1e29f4b2021-01-21 16:20:40 +000083 FakeStmt* Clone(CloneContext*) const override { return nullptr; }
dan sinclair7456f422020-04-08 19:58:35 +000084 bool IsValid() const override { return true; }
Ben Claytondd1b6fc2021-01-29 10:55:40 +000085 void to_str(const semantic::Info&, std::ostream& out, size_t) const override {
86 out << "Fake";
87 }
dan sinclair7456f422020-04-08 19:58:35 +000088};
89
90class FakeExpr : public ast::Expression {
91 public:
Ben Clayton604bc722020-12-12 01:24:53 +000092 explicit FakeExpr(Source source) : ast::Expression(source) {}
Ben Clayton1e29f4b2021-01-21 16:20:40 +000093 FakeExpr* Clone(CloneContext*) const override { return nullptr; }
dan sinclair7456f422020-04-08 19:58:35 +000094 bool IsValid() const override { return true; }
Ben Claytondd1b6fc2021-01-29 10:55:40 +000095 void to_str(const semantic::Info&, std::ostream&, size_t) const override {}
dan sinclair7456f422020-04-08 19:58:35 +000096};
97
Ben Claytona6b9a8e2021-01-26 16:57:10 +000098class TypeDeterminerHelper : public ProgramBuilder {
dan sinclairb7edc4c2020-04-07 12:46:30 +000099 public:
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000100 TypeDeterminerHelper() : td_(std::make_unique<TypeDeterminer>(this)) {}
dan sinclairb7edc4c2020-04-07 12:46:30 +0000101
102 TypeDeterminer* td() const { return td_.get(); }
Ben Clayton62625922020-11-13 22:09:38 +0000103
dan sinclairb7edc4c2020-04-07 12:46:30 +0000104 private:
dan sinclairb7edc4c2020-04-07 12:46:30 +0000105 std::unique_ptr<TypeDeterminer> td_;
106};
107
dan sinclaircd077b02020-04-20 14:19:04 +0000108class TypeDeterminerTest : public TypeDeterminerHelper, public testing::Test {};
109
110template <typename T>
111class TypeDeterminerTestWithParam : public TypeDeterminerHelper,
112 public testing::TestWithParam<T> {};
113
dan sinclair7456f422020-04-08 19:58:35 +0000114TEST_F(TypeDeterminerTest, Error_WithEmptySource) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000115 auto* s = create<FakeStmt>();
Ben Clayton401b96b2021-02-03 17:19:59 +0000116 WrapInFunction(s);
dan sinclair7456f422020-04-08 19:58:35 +0000117
Ben Clayton401b96b2021-02-03 17:19:59 +0000118 EXPECT_FALSE(td()->Determine());
119
dan sinclair0975dd52020-07-27 15:25:00 +0000120 EXPECT_EQ(td()->error(),
121 "unknown statement type for type determination: Fake");
dan sinclair7456f422020-04-08 19:58:35 +0000122}
123
124TEST_F(TypeDeterminerTest, Stmt_Error_Unknown) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000125 auto* s = create<FakeStmt>(Source{Source::Location{2, 30}});
Ben Clayton401b96b2021-02-03 17:19:59 +0000126 WrapInFunction(s);
dan sinclair7456f422020-04-08 19:58:35 +0000127
Ben Clayton401b96b2021-02-03 17:19:59 +0000128 EXPECT_FALSE(td()->Determine());
129
dan sinclair7456f422020-04-08 19:58:35 +0000130 EXPECT_EQ(td()->error(),
dan sinclair0975dd52020-07-27 15:25:00 +0000131 "2:30: unknown statement type for type determination: Fake");
dan sinclair7456f422020-04-08 19:58:35 +0000132}
133
dan sinclair6c498fc2020-04-07 12:47:23 +0000134TEST_F(TypeDeterminerTest, Stmt_Assign) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000135 auto* lhs = Expr(2);
136 auto* rhs = Expr(2.3f);
dan sinclair6c498fc2020-04-07 12:47:23 +0000137
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000138 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
Ben Clayton401b96b2021-02-03 17:19:59 +0000139 WrapInFunction(assign);
dan sinclair6c498fc2020-04-07 12:47:23 +0000140
Ben Clayton401b96b2021-02-03 17:19:59 +0000141 EXPECT_TRUE(td()->Determine()) << td()->error();
142
Ben Clayton33352542021-01-29 16:43:41 +0000143 ASSERT_NE(TypeOf(lhs), nullptr);
144 ASSERT_NE(TypeOf(rhs), nullptr);
dan sinclair6c498fc2020-04-07 12:47:23 +0000145
Ben Clayton33352542021-01-29 16:43:41 +0000146 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
147 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
dan sinclair6c498fc2020-04-07 12:47:23 +0000148}
149
dan sinclair6010b292020-04-07 12:54:20 +0000150TEST_F(TypeDeterminerTest, Stmt_Case) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000151 auto* lhs = Expr(2);
152 auto* rhs = Expr(2.3f);
dan sinclair6010b292020-04-07 12:54:20 +0000153
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000154 auto* body = create<ast::BlockStatement>(ast::StatementList{
155 create<ast::AssignmentStatement>(lhs, rhs),
156 });
dan sinclair1aadbd42020-06-01 16:56:46 +0000157 ast::CaseSelectorList lit;
Ben Clayton8d391f72021-01-26 16:57:10 +0000158 lit.push_back(create<ast::SintLiteral>(ty.i32(), 3));
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000159 auto* cse = create<ast::CaseStatement>(lit, body);
Ben Clayton401b96b2021-02-03 17:19:59 +0000160 WrapInFunction(cse);
dan sinclair6010b292020-04-07 12:54:20 +0000161
Ben Clayton401b96b2021-02-03 17:19:59 +0000162 EXPECT_TRUE(td()->Determine()) << td()->error();
163
Ben Clayton33352542021-01-29 16:43:41 +0000164 ASSERT_NE(TypeOf(lhs), nullptr);
165 ASSERT_NE(TypeOf(rhs), nullptr);
166 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
167 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
dan sinclair6010b292020-04-07 12:54:20 +0000168}
169
dan sinclair0975dd52020-07-27 15:25:00 +0000170TEST_F(TypeDeterminerTest, Stmt_Block) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000171 auto* lhs = Expr(2);
172 auto* rhs = Expr(2.3f);
dan sinclair0975dd52020-07-27 15:25:00 +0000173
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000174 auto* block = create<ast::BlockStatement>(ast::StatementList{
175 create<ast::AssignmentStatement>(lhs, rhs),
176 });
Ben Clayton401b96b2021-02-03 17:19:59 +0000177 WrapInFunction(block);
dan sinclair0975dd52020-07-27 15:25:00 +0000178
Ben Clayton401b96b2021-02-03 17:19:59 +0000179 EXPECT_TRUE(td()->Determine()) << td()->error();
180
Ben Clayton33352542021-01-29 16:43:41 +0000181 ASSERT_NE(TypeOf(lhs), nullptr);
182 ASSERT_NE(TypeOf(rhs), nullptr);
183 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
184 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
dan sinclair0975dd52020-07-27 15:25:00 +0000185}
186
dan sinclair0cf685f2020-04-07 12:54:37 +0000187TEST_F(TypeDeterminerTest, Stmt_Else) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000188 auto* lhs = Expr(2);
189 auto* rhs = Expr(2.3f);
dan sinclair0cf685f2020-04-07 12:54:37 +0000190
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000191 auto* body = create<ast::BlockStatement>(ast::StatementList{
192 create<ast::AssignmentStatement>(lhs, rhs),
193 });
194 auto* stmt = create<ast::ElseStatement>(Expr(3), body);
Ben Clayton401b96b2021-02-03 17:19:59 +0000195 WrapInFunction(stmt);
dan sinclair0cf685f2020-04-07 12:54:37 +0000196
Ben Clayton401b96b2021-02-03 17:19:59 +0000197 EXPECT_TRUE(td()->Determine()) << td()->error();
198
Ben Clayton33352542021-01-29 16:43:41 +0000199 ASSERT_NE(TypeOf(stmt->condition()), nullptr);
200 ASSERT_NE(TypeOf(lhs), nullptr);
201 ASSERT_NE(TypeOf(rhs), nullptr);
202 EXPECT_TRUE(TypeOf(stmt->condition())->Is<type::I32>());
203 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
204 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
dan sinclair0cf685f2020-04-07 12:54:37 +0000205}
206
dan sinclair91c44a52020-04-07 12:55:25 +0000207TEST_F(TypeDeterminerTest, Stmt_If) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000208 auto* else_lhs = Expr(2);
209 auto* else_rhs = Expr(2.3f);
dan sinclair91c44a52020-04-07 12:55:25 +0000210
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000211 auto* else_body = create<ast::BlockStatement>(ast::StatementList{
212 create<ast::AssignmentStatement>(else_lhs, else_rhs),
213 });
dan sinclair91c44a52020-04-07 12:55:25 +0000214
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000215 auto* else_stmt = create<ast::ElseStatement>(Expr(3), else_body);
dan sinclair91c44a52020-04-07 12:55:25 +0000216
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000217 auto* lhs = Expr(2);
218 auto* rhs = Expr(2.3f);
dan sinclair91c44a52020-04-07 12:55:25 +0000219
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000220 auto* body = create<ast::BlockStatement>(ast::StatementList{
221 create<ast::AssignmentStatement>(lhs, rhs),
222 });
223 auto* stmt = create<ast::IfStatement>(Expr(3), body,
224 ast::ElseStatementList{else_stmt});
Ben Clayton401b96b2021-02-03 17:19:59 +0000225 WrapInFunction(stmt);
dan sinclair91c44a52020-04-07 12:55:25 +0000226
Ben Clayton401b96b2021-02-03 17:19:59 +0000227 EXPECT_TRUE(td()->Determine()) << td()->error();
228
Ben Clayton33352542021-01-29 16:43:41 +0000229 ASSERT_NE(TypeOf(stmt->condition()), nullptr);
230 ASSERT_NE(TypeOf(else_lhs), nullptr);
231 ASSERT_NE(TypeOf(else_rhs), nullptr);
232 ASSERT_NE(TypeOf(lhs), nullptr);
233 ASSERT_NE(TypeOf(rhs), nullptr);
234 EXPECT_TRUE(TypeOf(stmt->condition())->Is<type::I32>());
235 EXPECT_TRUE(TypeOf(else_lhs)->Is<type::I32>());
236 EXPECT_TRUE(TypeOf(else_rhs)->Is<type::F32>());
237 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
238 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
dan sinclair91c44a52020-04-07 12:55:25 +0000239}
240
dan sinclairbc71eda2020-04-07 12:55:51 +0000241TEST_F(TypeDeterminerTest, Stmt_Loop) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000242 auto* body_lhs = Expr(2);
243 auto* body_rhs = Expr(2.3f);
dan sinclairbc71eda2020-04-07 12:55:51 +0000244
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000245 auto* body = create<ast::BlockStatement>(ast::StatementList{
246 create<ast::AssignmentStatement>(body_lhs, body_rhs),
247 });
248 auto* continuing_lhs = Expr(2);
249 auto* continuing_rhs = Expr(2.3f);
dan sinclairbc71eda2020-04-07 12:55:51 +0000250
Ben Claytondb5ce652020-12-14 20:25:27 +0000251 auto* continuing = create<ast::BlockStatement>(
dan sinclairbc71eda2020-04-07 12:55:51 +0000252
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000253 ast::StatementList{
254 create<ast::AssignmentStatement>(continuing_lhs, continuing_rhs),
255 });
256 auto* stmt = create<ast::LoopStatement>(body, continuing);
Ben Clayton401b96b2021-02-03 17:19:59 +0000257 WrapInFunction(stmt);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000258
Ben Clayton401b96b2021-02-03 17:19:59 +0000259 EXPECT_TRUE(td()->Determine()) << td()->error();
260
Ben Clayton33352542021-01-29 16:43:41 +0000261 ASSERT_NE(TypeOf(body_lhs), nullptr);
262 ASSERT_NE(TypeOf(body_rhs), nullptr);
263 ASSERT_NE(TypeOf(continuing_lhs), nullptr);
264 ASSERT_NE(TypeOf(continuing_rhs), nullptr);
265 EXPECT_TRUE(TypeOf(body_lhs)->Is<type::I32>());
266 EXPECT_TRUE(TypeOf(body_rhs)->Is<type::F32>());
267 EXPECT_TRUE(TypeOf(continuing_lhs)->Is<type::I32>());
268 EXPECT_TRUE(TypeOf(continuing_rhs)->Is<type::F32>());
dan sinclairbc71eda2020-04-07 12:55:51 +0000269}
270
dan sinclairbf0fff82020-04-07 12:56:24 +0000271TEST_F(TypeDeterminerTest, Stmt_Return) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000272 auto* cond = Expr(2);
dan sinclairbf0fff82020-04-07 12:56:24 +0000273
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000274 auto* ret = create<ast::ReturnStatement>(cond);
Ben Clayton401b96b2021-02-03 17:19:59 +0000275 WrapInFunction(ret);
dan sinclairbf0fff82020-04-07 12:56:24 +0000276
Ben Clayton401b96b2021-02-03 17:19:59 +0000277 EXPECT_TRUE(td()->Determine()) << td()->error();
278
Ben Clayton33352542021-01-29 16:43:41 +0000279 ASSERT_NE(TypeOf(cond), nullptr);
280 EXPECT_TRUE(TypeOf(cond)->Is<type::I32>());
dan sinclairbf0fff82020-04-07 12:56:24 +0000281}
282
dan sinclair327ed1b2020-04-07 19:27:21 +0000283TEST_F(TypeDeterminerTest, Stmt_Return_WithoutValue) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000284 auto* ret = create<ast::ReturnStatement>();
Ben Clayton401b96b2021-02-03 17:19:59 +0000285 WrapInFunction(ret);
286
287 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair327ed1b2020-04-07 19:27:21 +0000288}
289
dan sinclair18b32852020-04-07 12:56:45 +0000290TEST_F(TypeDeterminerTest, Stmt_Switch) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000291 auto* lhs = Expr(2);
292 auto* rhs = Expr(2.3f);
dan sinclair18b32852020-04-07 12:56:45 +0000293
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000294 auto* body = create<ast::BlockStatement>(ast::StatementList{
295 create<ast::AssignmentStatement>(lhs, rhs),
296 });
dan sinclair1aadbd42020-06-01 16:56:46 +0000297 ast::CaseSelectorList lit;
Ben Clayton8d391f72021-01-26 16:57:10 +0000298 lit.push_back(create<ast::SintLiteral>(ty.i32(), 3));
dan sinclair1aadbd42020-06-01 16:56:46 +0000299
dan sinclair18b32852020-04-07 12:56:45 +0000300 ast::CaseStatementList cases;
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000301 cases.push_back(create<ast::CaseStatement>(lit, body));
dan sinclair18b32852020-04-07 12:56:45 +0000302
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000303 auto* stmt = create<ast::SwitchStatement>(Expr(2), cases);
Ben Clayton401b96b2021-02-03 17:19:59 +0000304 WrapInFunction(stmt);
dan sinclair18b32852020-04-07 12:56:45 +0000305
Ben Clayton401b96b2021-02-03 17:19:59 +0000306 EXPECT_TRUE(td()->Determine()) << td()->error();
307
Ben Clayton33352542021-01-29 16:43:41 +0000308 ASSERT_NE(TypeOf(stmt->condition()), nullptr);
309 ASSERT_NE(TypeOf(lhs), nullptr);
310 ASSERT_NE(TypeOf(rhs), nullptr);
dan sinclair18b32852020-04-07 12:56:45 +0000311
Ben Clayton33352542021-01-29 16:43:41 +0000312 EXPECT_TRUE(TypeOf(stmt->condition())->Is<type::I32>());
313 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
314 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
dan sinclair18b32852020-04-07 12:56:45 +0000315}
316
dan sinclair50080b72020-07-21 13:42:13 +0000317TEST_F(TypeDeterminerTest, Stmt_Call) {
dan sinclair50080b72020-07-21 13:42:13 +0000318 ast::VariableList params;
Ben Clayton42d1e092021-02-02 14:29:15 +0000319 Func("my_func", params, ty.f32(), ast::StatementList{},
320 ast::FunctionDecorationList{});
dan sinclair50080b72020-07-21 13:42:13 +0000321
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000322 auto* expr = Call("my_func");
dan sinclair50080b72020-07-21 13:42:13 +0000323
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000324 auto* call = create<ast::CallStatement>(expr);
Ben Clayton401b96b2021-02-03 17:19:59 +0000325 WrapInFunction(call);
326
327 EXPECT_TRUE(td()->Determine()) << td()->error();
328
Ben Clayton33352542021-01-29 16:43:41 +0000329 ASSERT_NE(TypeOf(expr), nullptr);
330 EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
dan sinclair50080b72020-07-21 13:42:13 +0000331}
332
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000333TEST_F(TypeDeterminerTest, Stmt_Call_undeclared) {
334 // fn main() -> void {func(); return; }
335 // fn func() -> void { return; }
Ben Claytondb5ce652020-12-14 20:25:27 +0000336
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000337 SetSource(Source::Location{12, 34});
338 auto* call_expr = Call("func");
339 ast::VariableList params0;
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000340
Ben Clayton42d1e092021-02-02 14:29:15 +0000341 Func("main", params0, ty.f32(),
342 ast::StatementList{
343 create<ast::CallStatement>(call_expr),
344 create<ast::ReturnStatement>(),
345 },
346 ast::FunctionDecorationList{});
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000347
Ben Clayton42d1e092021-02-02 14:29:15 +0000348 Func("func", params0, ty.f32(),
349 ast::StatementList{
350 create<ast::ReturnStatement>(),
351 },
352 ast::FunctionDecorationList{});
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000353
Ben Clayton401b96b2021-02-03 17:19:59 +0000354 EXPECT_FALSE(td()->Determine());
355
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000356 EXPECT_EQ(td()->error(),
dan sinclairff267ca2020-10-14 18:26:31 +0000357 "12:34: v-0006: identifier must be declared before use: func");
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000358}
359
dan sinclairca893e32020-04-07 12:57:12 +0000360TEST_F(TypeDeterminerTest, Stmt_VariableDecl) {
Ben Clayton8d391f72021-01-26 16:57:10 +0000361 auto* var = Var("my_var", ast::StorageClass::kNone, ty.i32(), Expr(2),
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000362 ast::VariableDecorationList{});
Ben Clayton4bfe4612020-11-16 16:41:47 +0000363 auto* init = var->constructor();
dan sinclairca893e32020-04-07 12:57:12 +0000364
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000365 auto* decl = create<ast::VariableDeclStatement>(var);
Ben Clayton401b96b2021-02-03 17:19:59 +0000366 WrapInFunction(decl);
dan sinclairca893e32020-04-07 12:57:12 +0000367
Ben Clayton401b96b2021-02-03 17:19:59 +0000368 EXPECT_TRUE(td()->Determine()) << td()->error();
369
Ben Clayton33352542021-01-29 16:43:41 +0000370 ASSERT_NE(TypeOf(init), nullptr);
371 EXPECT_TRUE(TypeOf(init)->Is<type::I32>());
dan sinclairca893e32020-04-07 12:57:12 +0000372}
373
dan sinclair7be237a2020-06-15 20:55:09 +0000374TEST_F(TypeDeterminerTest, Stmt_VariableDecl_ModuleScope) {
Ben Clayton401b96b2021-02-03 17:19:59 +0000375 auto* var = Global("my_var", ast::StorageClass::kNone, ty.i32(), Expr(2),
376 ast::VariableDecorationList{});
Ben Clayton4bfe4612020-11-16 16:41:47 +0000377 auto* init = var->constructor();
dan sinclair7be237a2020-06-15 20:55:09 +0000378
Ben Clayton401b96b2021-02-03 17:19:59 +0000379 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair7be237a2020-06-15 20:55:09 +0000380
Ben Clayton33352542021-01-29 16:43:41 +0000381 ASSERT_NE(TypeOf(init), nullptr);
382 EXPECT_TRUE(TypeOf(init)->Is<type::I32>());
dan sinclair7be237a2020-06-15 20:55:09 +0000383}
384
James Price77f4f022021-02-04 16:33:20 +0000385TEST_F(TypeDeterminerTest, Stmt_VariableDecl_OuterScopeAfterInnerScope) {
386 // fn func_i32() -> i32 {
387 // {
388 // var foo : i32 = 2;
389 // var bar : i32 = foo;
390 // }
391 // var foo : f32 = 2.0;
392 // var bar : f32 = foo;
393 // }
394
395 ast::VariableList params;
396
397 // Declare i32 "foo" inside a block
398 auto* foo_i32 = Var("foo", ast::StorageClass::kNone, ty.i32(), Expr(2),
399 ast::VariableDecorationList{});
400 auto* foo_i32_init = foo_i32->constructor();
401 auto* foo_i32_decl = create<ast::VariableDeclStatement>(foo_i32);
402
403 // Reference "foo" inside the block
404 auto* bar_i32 = Var("bar", ast::StorageClass::kNone, ty.i32(), Expr("foo"),
405 ast::VariableDecorationList{});
406 auto* bar_i32_init = bar_i32->constructor();
407 auto* bar_i32_decl = create<ast::VariableDeclStatement>(bar_i32);
408
409 auto* inner = create<ast::BlockStatement>(
410 ast::StatementList{foo_i32_decl, bar_i32_decl});
411
412 // Declare f32 "foo" at function scope
413 auto* foo_f32 = Var("foo", ast::StorageClass::kNone, ty.f32(), Expr(2.f),
414 ast::VariableDecorationList{});
415 auto* foo_f32_init = foo_f32->constructor();
416 auto* foo_f32_decl = create<ast::VariableDeclStatement>(foo_f32);
417
418 // Reference "foo" at function scope
419 auto* bar_f32 = Var("bar", ast::StorageClass::kNone, ty.f32(), Expr("foo"),
420 ast::VariableDecorationList{});
421 auto* bar_f32_init = bar_f32->constructor();
422 auto* bar_f32_decl = create<ast::VariableDeclStatement>(bar_f32);
423
424 Func("func", params, ty.f32(),
425 ast::StatementList{inner, foo_f32_decl, bar_f32_decl},
426 ast::FunctionDecorationList{});
427
428 EXPECT_TRUE(td()->Determine());
429 ASSERT_NE(TypeOf(foo_i32_init), nullptr);
430 EXPECT_TRUE(TypeOf(foo_i32_init)->Is<type::I32>());
431 ASSERT_NE(TypeOf(foo_f32_init), nullptr);
432 EXPECT_TRUE(TypeOf(foo_f32_init)->Is<type::F32>());
433 ASSERT_NE(TypeOf(bar_i32_init), nullptr);
434 EXPECT_TRUE(TypeOf(bar_i32_init)->UnwrapAll()->Is<type::I32>());
435 ASSERT_NE(TypeOf(bar_f32_init), nullptr);
436 EXPECT_TRUE(TypeOf(bar_f32_init)->UnwrapAll()->Is<type::F32>());
437}
438
439TEST_F(TypeDeterminerTest, Stmt_VariableDecl_ModuleScopeAfterFunctionScope) {
440 // fn func_i32() -> i32 {
441 // var foo : i32 = 2;
442 // }
443 // var foo : f32 = 2.0;
444 // fn func_f32() -> f32 {
445 // var bar : f32 = foo;
446 // }
447
448 ast::VariableList params;
449
450 // Declare i32 "foo" inside a function
451 auto* fn_i32 = Var("foo", ast::StorageClass::kNone, ty.i32(), Expr(2),
452 ast::VariableDecorationList{});
453 auto* fn_i32_init = fn_i32->constructor();
454 auto* fn_i32_decl = create<ast::VariableDeclStatement>(fn_i32);
455 Func("func_i32", params, ty.i32(), ast::StatementList{fn_i32_decl},
456 ast::FunctionDecorationList{});
457
458 // Declare f32 "foo" at module scope
459 auto* mod_f32 = Var("foo", ast::StorageClass::kNone, ty.f32(), Expr(2.f),
460 ast::VariableDecorationList{});
461 auto* mod_init = mod_f32->constructor();
462 AST().AddGlobalVariable(mod_f32);
463
464 // Reference "foo" in another function
465 auto* fn_f32 = Var("bar", ast::StorageClass::kNone, ty.f32(), Expr("foo"),
466 ast::VariableDecorationList{});
467 auto* fn_f32_init = fn_f32->constructor();
468 auto* fn_f32_decl = create<ast::VariableDeclStatement>(fn_f32);
469 Func("func_f32", params, ty.f32(), ast::StatementList{fn_f32_decl},
470 ast::FunctionDecorationList{});
471
472 EXPECT_TRUE(td()->Determine());
473 ASSERT_NE(TypeOf(mod_init), nullptr);
474 EXPECT_TRUE(TypeOf(mod_init)->Is<type::F32>());
475 ASSERT_NE(TypeOf(fn_i32_init), nullptr);
476 EXPECT_TRUE(TypeOf(fn_i32_init)->Is<type::I32>());
477 ASSERT_NE(TypeOf(fn_f32_init), nullptr);
478 EXPECT_TRUE(TypeOf(fn_f32_init)->UnwrapAll()->Is<type::F32>());
479}
480
dan sinclair7456f422020-04-08 19:58:35 +0000481TEST_F(TypeDeterminerTest, Expr_Error_Unknown) {
Ben Clayton604bc722020-12-12 01:24:53 +0000482 FakeExpr e(Source{Source::Location{2, 30}});
Ben Clayton401b96b2021-02-03 17:19:59 +0000483 WrapInFunction(&e);
dan sinclair7456f422020-04-08 19:58:35 +0000484
Ben Clayton401b96b2021-02-03 17:19:59 +0000485 EXPECT_FALSE(td()->Determine());
486
dan sinclair7456f422020-04-08 19:58:35 +0000487 EXPECT_EQ(td()->error(), "2:30: unknown expression for type determination");
488}
489
dan sinclair973bd6a2020-04-07 12:57:42 +0000490TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000491 auto* idx = Expr(2);
Ben Clayton401b96b2021-02-03 17:19:59 +0000492 Global("my_var", ast::StorageClass::kFunction, ty.array<f32, 3>());
dan sinclair8eddb782020-04-23 22:26:52 +0000493
dan sinclair8b40a672020-12-16 11:49:10 +0000494 auto* acc = IndexAccessor("my_var", idx);
Ben Clayton401b96b2021-02-03 17:19:59 +0000495 WrapInFunction(acc);
496
497 EXPECT_TRUE(td()->Determine()) << td()->error();
498
Ben Clayton33352542021-01-29 16:43:41 +0000499 ASSERT_NE(TypeOf(acc), nullptr);
500 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000501
Ben Clayton33352542021-01-29 16:43:41 +0000502 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000503 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000504}
505
David Neto9c88ea52020-06-22 20:33:12 +0000506TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Alias_Array) {
Ben Clayton1637cbb2021-01-05 15:44:39 +0000507 auto* aary = ty.alias("myarrty", ty.array<f32, 3>());
David Neto9c88ea52020-06-22 20:33:12 +0000508
Ben Clayton401b96b2021-02-03 17:19:59 +0000509 Global("my_var", ast::StorageClass::kFunction, aary);
David Neto9c88ea52020-06-22 20:33:12 +0000510
dan sinclair8b40a672020-12-16 11:49:10 +0000511 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton401b96b2021-02-03 17:19:59 +0000512 WrapInFunction(acc);
513
514 EXPECT_TRUE(td()->Determine()) << td()->error();
515
Ben Clayton33352542021-01-29 16:43:41 +0000516 ASSERT_NE(TypeOf(acc), nullptr);
517 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
David Neto9c88ea52020-06-22 20:33:12 +0000518
Ben Clayton33352542021-01-29 16:43:41 +0000519 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000520 EXPECT_TRUE(ptr->type()->Is<type::F32>());
David Neto9c88ea52020-06-22 20:33:12 +0000521}
522
dan sinclair8eddb782020-04-23 22:26:52 +0000523TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array_Constant) {
Ben Clayton401b96b2021-02-03 17:19:59 +0000524 GlobalConst("my_var", ast::StorageClass::kFunction, ty.array<f32, 3>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000525
dan sinclair8b40a672020-12-16 11:49:10 +0000526 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton401b96b2021-02-03 17:19:59 +0000527 WrapInFunction(acc);
528
529 EXPECT_TRUE(td()->Determine()) << td()->error();
530
Ben Clayton33352542021-01-29 16:43:41 +0000531 ASSERT_NE(TypeOf(acc), nullptr);
532 EXPECT_TRUE(TypeOf(acc)->Is<type::F32>()) << TypeOf(acc)->type_name();
dan sinclair973bd6a2020-04-07 12:57:42 +0000533}
534
535TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix) {
Ben Clayton401b96b2021-02-03 17:19:59 +0000536 Global("my_var", ast::StorageClass::kNone, ty.mat2x3<f32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000537
dan sinclair8b40a672020-12-16 11:49:10 +0000538 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton401b96b2021-02-03 17:19:59 +0000539 WrapInFunction(acc);
540
541 EXPECT_TRUE(td()->Determine()) << td()->error();
542
Ben Clayton33352542021-01-29 16:43:41 +0000543 ASSERT_NE(TypeOf(acc), nullptr);
544 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000545
Ben Clayton33352542021-01-29 16:43:41 +0000546 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000547 ASSERT_TRUE(ptr->type()->Is<type::Vector>());
548 EXPECT_EQ(ptr->type()->As<type::Vector>()->size(), 3u);
dan sinclair973bd6a2020-04-07 12:57:42 +0000549}
550
551TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix_BothDimensions) {
Ben Clayton401b96b2021-02-03 17:19:59 +0000552 Global("my_var", ast::StorageClass::kNone, ty.mat2x3<f32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000553
dan sinclair8b40a672020-12-16 11:49:10 +0000554 auto* acc = IndexAccessor(IndexAccessor("my_var", 2), 1);
Ben Clayton401b96b2021-02-03 17:19:59 +0000555 WrapInFunction(acc);
dan sinclair973bd6a2020-04-07 12:57:42 +0000556
Ben Clayton401b96b2021-02-03 17:19:59 +0000557 EXPECT_TRUE(td()->Determine()) << td()->error();
558
Ben Clayton33352542021-01-29 16:43:41 +0000559 ASSERT_NE(TypeOf(acc), nullptr);
560 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000561
Ben Clayton33352542021-01-29 16:43:41 +0000562 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000563 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000564}
565
566TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Vector) {
Ben Clayton401b96b2021-02-03 17:19:59 +0000567 Global("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000568
dan sinclair8b40a672020-12-16 11:49:10 +0000569 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton401b96b2021-02-03 17:19:59 +0000570 WrapInFunction(acc);
571
572 EXPECT_TRUE(td()->Determine()) << td()->error();
573
Ben Clayton33352542021-01-29 16:43:41 +0000574 ASSERT_NE(TypeOf(acc), nullptr);
575 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000576
Ben Clayton33352542021-01-29 16:43:41 +0000577 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000578 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000579}
580
dan sinclaira7d498e2020-09-22 22:07:13 +0000581TEST_F(TypeDeterminerTest, Expr_Bitcast) {
Ben Clayton8d391f72021-01-26 16:57:10 +0000582 auto* bitcast = create<ast::BitcastExpression>(ty.f32(), Expr("name"));
Ben Clayton401b96b2021-02-03 17:19:59 +0000583 WrapInFunction(bitcast);
dan sinclaira01777c2020-04-07 12:57:52 +0000584
Ben Clayton401b96b2021-02-03 17:19:59 +0000585 Global("name", ast::StorageClass::kPrivate, ty.f32());
dan sinclairff267ca2020-10-14 18:26:31 +0000586
Ben Clayton401b96b2021-02-03 17:19:59 +0000587 EXPECT_TRUE(td()->Determine()) << td()->error();
588
Ben Clayton33352542021-01-29 16:43:41 +0000589 ASSERT_NE(TypeOf(bitcast), nullptr);
590 EXPECT_TRUE(TypeOf(bitcast)->Is<type::F32>());
dan sinclaira01777c2020-04-07 12:57:52 +0000591}
592
dan sinclair3ca87462020-04-07 16:41:10 +0000593TEST_F(TypeDeterminerTest, Expr_Call) {
dan sinclair3ca87462020-04-07 16:41:10 +0000594 ast::VariableList params;
Ben Clayton42d1e092021-02-02 14:29:15 +0000595 Func("my_func", params, ty.f32(), ast::StatementList{},
596 ast::FunctionDecorationList{});
dan sinclair3ca87462020-04-07 16:41:10 +0000597
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000598 auto* call = Call("my_func");
Ben Clayton401b96b2021-02-03 17:19:59 +0000599 WrapInFunction(call);
600
601 EXPECT_TRUE(td()->Determine()) << td()->error();
602
Ben Clayton33352542021-01-29 16:43:41 +0000603 ASSERT_NE(TypeOf(call), nullptr);
604 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclair3ca87462020-04-07 16:41:10 +0000605}
606
Ben Clayton7b7d6982021-02-09 17:38:05 +0000607TEST_F(TypeDeterminerTest, Expr_Call_InBinaryOp) {
608 ast::VariableList params;
609 Func("func", params, ty.f32(), ast::StatementList{},
610 ast::FunctionDecorationList{});
611
612 auto* expr = Add(Call("func"), Call("func"));
613 WrapInFunction(expr);
614
615 EXPECT_TRUE(td()->Determine()) << td()->error();
616
617 ASSERT_NE(TypeOf(expr), nullptr);
618 EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
619}
620
dan sinclairccb52dc2020-04-20 14:18:54 +0000621TEST_F(TypeDeterminerTest, Expr_Call_WithParams) {
dan sinclairccb52dc2020-04-20 14:18:54 +0000622 ast::VariableList params;
Ben Clayton42d1e092021-02-02 14:29:15 +0000623 Func("my_func", params, ty.f32(), ast::StatementList{},
624 ast::FunctionDecorationList{});
dan sinclairccb52dc2020-04-20 14:18:54 +0000625
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000626 auto* param = Expr(2.4f);
dan sinclairccb52dc2020-04-20 14:18:54 +0000627
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000628 auto* call = Call("my_func", param);
Ben Clayton401b96b2021-02-03 17:19:59 +0000629 WrapInFunction(call);
630
631 EXPECT_TRUE(td()->Determine()) << td()->error();
632
Ben Clayton33352542021-01-29 16:43:41 +0000633 ASSERT_NE(TypeOf(param), nullptr);
634 EXPECT_TRUE(TypeOf(param)->Is<type::F32>());
dan sinclairccb52dc2020-04-20 14:18:54 +0000635}
636
dan sinclairb4fee2f2020-09-22 19:42:13 +0000637TEST_F(TypeDeterminerTest, Expr_Call_Intrinsic) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000638 auto* call = Call("round", 2.4f);
Ben Clayton401b96b2021-02-03 17:19:59 +0000639 WrapInFunction(call);
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000640
Ben Clayton401b96b2021-02-03 17:19:59 +0000641 EXPECT_TRUE(td()->Determine()) << td()->error();
642
Ben Clayton33352542021-01-29 16:43:41 +0000643 ASSERT_NE(TypeOf(call), nullptr);
644 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000645}
646
dan sinclair4e807952020-04-07 16:41:23 +0000647TEST_F(TypeDeterminerTest, Expr_Cast) {
Ben Clayton401b96b2021-02-03 17:19:59 +0000648 Global("name", ast::StorageClass::kPrivate, ty.f32());
649
Ben Clayton8d391f72021-01-26 16:57:10 +0000650 auto* cast = Construct(ty.f32(), "name");
Ben Clayton401b96b2021-02-03 17:19:59 +0000651 WrapInFunction(cast);
dan sinclair3c025922020-09-24 14:38:44 +0000652
Ben Clayton401b96b2021-02-03 17:19:59 +0000653 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair4e807952020-04-07 16:41:23 +0000654
Ben Clayton33352542021-01-29 16:43:41 +0000655 ASSERT_NE(TypeOf(cast), nullptr);
656 EXPECT_TRUE(TypeOf(cast)->Is<type::F32>());
dan sinclair4e807952020-04-07 16:41:23 +0000657}
658
dan sinclairb7edc4c2020-04-07 12:46:30 +0000659TEST_F(TypeDeterminerTest, Expr_Constructor_Scalar) {
Ben Clayton1637cbb2021-01-05 15:44:39 +0000660 auto* s = Expr(1.0f);
Ben Clayton401b96b2021-02-03 17:19:59 +0000661 WrapInFunction(s);
662
663 EXPECT_TRUE(td()->Determine()) << td()->error();
664
Ben Clayton33352542021-01-29 16:43:41 +0000665 ASSERT_NE(TypeOf(s), nullptr);
666 EXPECT_TRUE(TypeOf(s)->Is<type::F32>());
dan sinclairb7edc4c2020-04-07 12:46:30 +0000667}
668
669TEST_F(TypeDeterminerTest, Expr_Constructor_Type) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000670 auto* tc = vec3<f32>(1.0f, 1.0f, 3.0f);
Ben Clayton401b96b2021-02-03 17:19:59 +0000671 WrapInFunction(tc);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000672
Ben Clayton401b96b2021-02-03 17:19:59 +0000673 EXPECT_TRUE(td()->Determine()) << td()->error();
674
Ben Clayton33352542021-01-29 16:43:41 +0000675 ASSERT_NE(TypeOf(tc), nullptr);
676 ASSERT_TRUE(TypeOf(tc)->Is<type::Vector>());
677 EXPECT_TRUE(TypeOf(tc)->As<type::Vector>()->type()->Is<type::F32>());
678 EXPECT_EQ(TypeOf(tc)->As<type::Vector>()->size(), 3u);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000679}
680
dan sinclaircab0e732020-04-07 12:57:27 +0000681TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalVariable) {
Ben Clayton401b96b2021-02-03 17:19:59 +0000682 Global("my_var", ast::StorageClass::kNone, ty.f32());
dan sinclaircab0e732020-04-07 12:57:27 +0000683
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000684 auto* ident = Expr("my_var");
Ben Clayton401b96b2021-02-03 17:19:59 +0000685 WrapInFunction(ident);
686
687 EXPECT_TRUE(td()->Determine()) << td()->error();
688
Ben Clayton33352542021-01-29 16:43:41 +0000689 ASSERT_NE(TypeOf(ident), nullptr);
690 EXPECT_TRUE(TypeOf(ident)->Is<type::Pointer>());
691 EXPECT_TRUE(TypeOf(ident)->As<type::Pointer>()->type()->Is<type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000692}
693
694TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalConstant) {
Ben Clayton401b96b2021-02-03 17:19:59 +0000695 GlobalConst("my_var", ast::StorageClass::kNone, ty.f32());
dan sinclair8eddb782020-04-23 22:26:52 +0000696
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000697 auto* ident = Expr("my_var");
Ben Clayton401b96b2021-02-03 17:19:59 +0000698 WrapInFunction(ident);
699
700 EXPECT_TRUE(td()->Determine()) << td()->error();
701
Ben Clayton33352542021-01-29 16:43:41 +0000702 ASSERT_NE(TypeOf(ident), nullptr);
703 EXPECT_TRUE(TypeOf(ident)->Is<type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000704}
705
dan sinclair8eddb782020-04-23 22:26:52 +0000706TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable_Const) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000707 auto* my_var = Expr("my_var");
dan sinclair8eddb782020-04-23 22:26:52 +0000708
Ben Clayton8d391f72021-01-26 16:57:10 +0000709 auto* var = Const("my_var", ast::StorageClass::kNone, ty.f32());
dan sinclair8eddb782020-04-23 22:26:52 +0000710
Ben Clayton401b96b2021-02-03 17:19:59 +0000711 Func("my_func", ast::VariableList{}, ty.f32(),
712 ast::StatementList{
713 create<ast::VariableDeclStatement>(var),
714 create<ast::AssignmentStatement>(my_var, Expr("my_var")),
715 },
716 ast::FunctionDecorationList{});
dan sinclair8eddb782020-04-23 22:26:52 +0000717
Ben Clayton401b96b2021-02-03 17:19:59 +0000718 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair8eddb782020-04-23 22:26:52 +0000719
Ben Clayton33352542021-01-29 16:43:41 +0000720 ASSERT_NE(TypeOf(my_var), nullptr);
721 EXPECT_TRUE(TypeOf(my_var)->Is<type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000722}
723
dan sinclaircab0e732020-04-07 12:57:27 +0000724TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000725 auto* my_var = Expr("my_var");
dan sinclaircab0e732020-04-07 12:57:27 +0000726
Ben Clayton401b96b2021-02-03 17:19:59 +0000727 Func("my_func", ast::VariableList{}, ty.f32(),
728 ast::StatementList{
729 create<ast::VariableDeclStatement>(
730 Var("my_var", ast::StorageClass::kNone, ty.f32())),
731 create<ast::AssignmentStatement>(my_var, Expr("my_var")),
732 },
733 ast::FunctionDecorationList{});
dan sinclaircab0e732020-04-07 12:57:27 +0000734
Ben Clayton401b96b2021-02-03 17:19:59 +0000735 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclaircab0e732020-04-07 12:57:27 +0000736
Ben Clayton33352542021-01-29 16:43:41 +0000737 ASSERT_NE(TypeOf(my_var), nullptr);
738 EXPECT_TRUE(TypeOf(my_var)->Is<type::Pointer>());
739 EXPECT_TRUE(TypeOf(my_var)->As<type::Pointer>()->type()->Is<type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000740}
741
dan sinclair5e989302020-09-16 21:20:36 +0000742TEST_F(TypeDeterminerTest, Expr_Identifier_Function_Ptr) {
Ben Clayton8d391f72021-01-26 16:57:10 +0000743 type::Pointer ptr(ty.f32(), ast::StorageClass::kFunction);
dan sinclair5e989302020-09-16 21:20:36 +0000744
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000745 auto* my_var = Expr("my_var");
dan sinclair5e989302020-09-16 21:20:36 +0000746
Ben Clayton401b96b2021-02-03 17:19:59 +0000747 Func("my_func", ast::VariableList{}, ty.f32(),
748 ast::StatementList{
749 create<ast::VariableDeclStatement>(
750 Var("my_var", ast::StorageClass::kNone, &ptr)),
751 create<ast::AssignmentStatement>(my_var, Expr("my_var")),
752 },
753 ast::FunctionDecorationList{});
dan sinclair5e989302020-09-16 21:20:36 +0000754
Ben Clayton401b96b2021-02-03 17:19:59 +0000755 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair5e989302020-09-16 21:20:36 +0000756
Ben Clayton33352542021-01-29 16:43:41 +0000757 ASSERT_NE(TypeOf(my_var), nullptr);
758 EXPECT_TRUE(TypeOf(my_var)->Is<type::Pointer>());
759 EXPECT_TRUE(TypeOf(my_var)->As<type::Pointer>()->type()->Is<type::F32>());
dan sinclair5e989302020-09-16 21:20:36 +0000760}
761
Ben Clayton1618f4b2021-02-03 21:02:25 +0000762TEST_F(TypeDeterminerTest, Expr_Call_Function) {
Ben Clayton42d1e092021-02-02 14:29:15 +0000763 Func("my_func", ast::VariableList{}, ty.f32(), ast::StatementList{},
764 ast::FunctionDecorationList{});
dan sinclaircab0e732020-04-07 12:57:27 +0000765
Ben Clayton1618f4b2021-02-03 21:02:25 +0000766 auto* call = Call("my_func");
767 WrapInFunction(call);
Ben Clayton401b96b2021-02-03 17:19:59 +0000768
769 EXPECT_TRUE(td()->Determine()) << td()->error();
770
Ben Clayton1618f4b2021-02-03 21:02:25 +0000771 ASSERT_NE(TypeOf(call), nullptr);
772 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000773}
774
dan sinclairff267ca2020-10-14 18:26:31 +0000775TEST_F(TypeDeterminerTest, Expr_Identifier_Unknown) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000776 auto* a = Expr("a");
Ben Clayton401b96b2021-02-03 17:19:59 +0000777 WrapInFunction(a);
778
779 EXPECT_FALSE(td()->Determine());
dan sinclairff267ca2020-10-14 18:26:31 +0000780}
781
dan sinclair13d2a3b2020-06-22 20:52:24 +0000782TEST_F(TypeDeterminerTest, Function_RegisterInputOutputVariables) {
Ben Clayton401b96b2021-02-03 17:19:59 +0000783 auto* in_var = Global("in_var", ast::StorageClass::kInput, ty.f32());
784 auto* out_var = Global("out_var", ast::StorageClass::kOutput, ty.f32());
785 auto* sb_var = Global("sb_var", ast::StorageClass::kStorage, ty.f32());
786 auto* wg_var = Global("wg_var", ast::StorageClass::kWorkgroup, ty.f32());
787 auto* priv_var = Global("priv_var", ast::StorageClass::kPrivate, ty.f32());
dan sinclair13d2a3b2020-06-22 20:52:24 +0000788
dan sinclair181d8ba2020-12-16 15:15:40 +0000789 auto* func = Func(
Ben Clayton8d391f72021-01-26 16:57:10 +0000790 "my_func", ast::VariableList{}, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000791 ast::StatementList{
792 create<ast::AssignmentStatement>(Expr("out_var"), Expr("in_var")),
793 create<ast::AssignmentStatement>(Expr("wg_var"), Expr("wg_var")),
794 create<ast::AssignmentStatement>(Expr("sb_var"), Expr("sb_var")),
795 create<ast::AssignmentStatement>(Expr("priv_var"), Expr("priv_var")),
796 },
797 ast::FunctionDecorationList{});
dan sinclair13d2a3b2020-06-22 20:52:24 +0000798
Ben Clayton401b96b2021-02-03 17:19:59 +0000799 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair13d2a3b2020-06-22 20:52:24 +0000800
Ben Clayton87c78dd2021-02-03 16:43:20 +0000801 auto* func_sem = Sem().Get(func);
802 ASSERT_NE(func_sem, nullptr);
803
804 const auto& vars = func_sem->ReferencedModuleVariables();
Ryan Harrison9a452c12020-06-23 16:38:47 +0000805 ASSERT_EQ(vars.size(), 5u);
Ben Claytonb17aea12021-02-03 17:51:09 +0000806 EXPECT_EQ(vars[0]->Declaration(), out_var);
807 EXPECT_EQ(vars[1]->Declaration(), in_var);
808 EXPECT_EQ(vars[2]->Declaration(), wg_var);
809 EXPECT_EQ(vars[3]->Declaration(), sb_var);
810 EXPECT_EQ(vars[4]->Declaration(), priv_var);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000811}
812
dan sinclairde2dd682020-07-14 20:37:28 +0000813TEST_F(TypeDeterminerTest, Function_RegisterInputOutputVariables_SubFunction) {
Ben Clayton401b96b2021-02-03 17:19:59 +0000814 auto* in_var = Global("in_var", ast::StorageClass::kInput, ty.f32());
815 auto* out_var = Global("out_var", ast::StorageClass::kOutput, ty.f32());
816 auto* sb_var = Global("sb_var", ast::StorageClass::kStorage, ty.f32());
817 auto* wg_var = Global("wg_var", ast::StorageClass::kWorkgroup, ty.f32());
818 auto* priv_var = Global("priv_var", ast::StorageClass::kPrivate, ty.f32());
dan sinclairde2dd682020-07-14 20:37:28 +0000819
Ben Clayton42d1e092021-02-02 14:29:15 +0000820 Func("my_func", ast::VariableList{}, ty.f32(),
821 ast::StatementList{
822 create<ast::AssignmentStatement>(Expr("out_var"), Expr("in_var")),
823 create<ast::AssignmentStatement>(Expr("wg_var"), Expr("wg_var")),
824 create<ast::AssignmentStatement>(Expr("sb_var"), Expr("sb_var")),
825 create<ast::AssignmentStatement>(Expr("priv_var"), Expr("priv_var")),
826 },
827 ast::FunctionDecorationList{});
dan sinclairde2dd682020-07-14 20:37:28 +0000828
dan sinclair181d8ba2020-12-16 15:15:40 +0000829 auto* func2 = Func(
Ben Clayton8d391f72021-01-26 16:57:10 +0000830 "func", ast::VariableList{}, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000831 ast::StatementList{
832 create<ast::AssignmentStatement>(Expr("out_var"), Call("my_func")),
833 },
834 ast::FunctionDecorationList{});
dan sinclairde2dd682020-07-14 20:37:28 +0000835
Ben Clayton401b96b2021-02-03 17:19:59 +0000836 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclairde2dd682020-07-14 20:37:28 +0000837
Ben Clayton87c78dd2021-02-03 16:43:20 +0000838 auto* func2_sem = Sem().Get(func2);
839 ASSERT_NE(func2_sem, nullptr);
840
841 const auto& vars = func2_sem->ReferencedModuleVariables();
dan sinclairde2dd682020-07-14 20:37:28 +0000842 ASSERT_EQ(vars.size(), 5u);
Ben Claytonb17aea12021-02-03 17:51:09 +0000843 EXPECT_EQ(vars[0]->Declaration(), out_var);
844 EXPECT_EQ(vars[1]->Declaration(), in_var);
845 EXPECT_EQ(vars[2]->Declaration(), wg_var);
846 EXPECT_EQ(vars[3]->Declaration(), sb_var);
847 EXPECT_EQ(vars[4]->Declaration(), priv_var);
dan sinclairde2dd682020-07-14 20:37:28 +0000848}
849
dan sinclair13d2a3b2020-06-22 20:52:24 +0000850TEST_F(TypeDeterminerTest, Function_NotRegisterFunctionVariable) {
Ben Clayton8d391f72021-01-26 16:57:10 +0000851 auto* var = Var("in_var", ast::StorageClass::kFunction, ty.f32());
dan sinclair13d2a3b2020-06-22 20:52:24 +0000852
dan sinclair181d8ba2020-12-16 15:15:40 +0000853 auto* func =
Ben Clayton8d391f72021-01-26 16:57:10 +0000854 Func("my_func", ast::VariableList{}, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000855 ast::StatementList{
856 create<ast::VariableDeclStatement>(var),
Ben Clayton1637cbb2021-01-05 15:44:39 +0000857 create<ast::AssignmentStatement>(Expr("var"), Expr(1.f)),
dan sinclair181d8ba2020-12-16 15:15:40 +0000858 },
859 ast::FunctionDecorationList{});
dan sinclair13d2a3b2020-06-22 20:52:24 +0000860
Ben Clayton401b96b2021-02-03 17:19:59 +0000861 Global("var", ast::StorageClass::kFunction, ty.f32());
dan sinclairff267ca2020-10-14 18:26:31 +0000862
dan sinclairff267ca2020-10-14 18:26:31 +0000863 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair13d2a3b2020-06-22 20:52:24 +0000864
Ben Clayton87c78dd2021-02-03 16:43:20 +0000865 auto* func_sem = Sem().Get(func);
866 ASSERT_NE(func_sem, nullptr);
867
868 EXPECT_EQ(func_sem->ReferencedModuleVariables().size(), 0u);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000869}
870
dan sinclair8ee1d222020-04-07 16:41:33 +0000871TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct) {
dan sinclair5e5e36e2020-12-16 14:41:00 +0000872 auto* strct = create<ast::Struct>(
Ben Clayton8d391f72021-01-26 16:57:10 +0000873 ast::StructMemberList{Member("first_member", ty.i32()),
874 Member("second_member", ty.f32())},
dan sinclair5e5e36e2020-12-16 14:41:00 +0000875 ast::StructDecorationList{});
dan sinclair8ee1d222020-04-07 16:41:33 +0000876
dan sinclairb5839932020-12-16 21:38:40 +0000877 auto* st = ty.struct_("S", strct);
Ben Clayton401b96b2021-02-03 17:19:59 +0000878 Global("my_struct", ast::StorageClass::kNone, st);
dan sinclair8ee1d222020-04-07 16:41:33 +0000879
dan sinclair8b40a672020-12-16 11:49:10 +0000880 auto* mem = MemberAccessor("my_struct", "second_member");
Ben Clayton401b96b2021-02-03 17:19:59 +0000881 WrapInFunction(mem);
882
883 EXPECT_TRUE(td()->Determine()) << td()->error();
884
Ben Clayton33352542021-01-29 16:43:41 +0000885 ASSERT_NE(TypeOf(mem), nullptr);
886 ASSERT_TRUE(TypeOf(mem)->Is<type::Pointer>());
dan sinclair8ee1d222020-04-07 16:41:33 +0000887
Ben Clayton33352542021-01-29 16:43:41 +0000888 auto* ptr = TypeOf(mem)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000889 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair8ee1d222020-04-07 16:41:33 +0000890}
891
dan sinclairb445a9b2020-04-24 00:40:45 +0000892TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct_Alias) {
dan sinclair5e5e36e2020-12-16 14:41:00 +0000893 auto* strct = create<ast::Struct>(
Ben Clayton8d391f72021-01-26 16:57:10 +0000894 ast::StructMemberList{Member("first_member", ty.i32()),
895 Member("second_member", ty.f32())},
dan sinclair5e5e36e2020-12-16 14:41:00 +0000896 ast::StructDecorationList{});
dan sinclairb445a9b2020-04-24 00:40:45 +0000897
dan sinclairb5839932020-12-16 21:38:40 +0000898 auto* st = ty.struct_("alias", strct);
899 auto* alias = ty.alias("alias", st);
Ben Clayton401b96b2021-02-03 17:19:59 +0000900 Global("my_struct", ast::StorageClass::kNone, alias);
dan sinclairb445a9b2020-04-24 00:40:45 +0000901
dan sinclair8b40a672020-12-16 11:49:10 +0000902 auto* mem = MemberAccessor("my_struct", "second_member");
Ben Clayton401b96b2021-02-03 17:19:59 +0000903 WrapInFunction(mem);
904
905 EXPECT_TRUE(td()->Determine()) << td()->error();
906
Ben Clayton33352542021-01-29 16:43:41 +0000907 ASSERT_NE(TypeOf(mem), nullptr);
908 ASSERT_TRUE(TypeOf(mem)->Is<type::Pointer>());
dan sinclairb445a9b2020-04-24 00:40:45 +0000909
Ben Clayton33352542021-01-29 16:43:41 +0000910 auto* ptr = TypeOf(mem)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000911 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclairb445a9b2020-04-24 00:40:45 +0000912}
913
dan sinclair8ee1d222020-04-07 16:41:33 +0000914TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle) {
Ben Clayton401b96b2021-02-03 17:19:59 +0000915 Global("my_vec", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair8ee1d222020-04-07 16:41:33 +0000916
dan sinclair8b40a672020-12-16 11:49:10 +0000917 auto* mem = MemberAccessor("my_vec", "xy");
Ben Clayton401b96b2021-02-03 17:19:59 +0000918 WrapInFunction(mem);
919
920 EXPECT_TRUE(td()->Determine()) << td()->error();
921
Ben Clayton33352542021-01-29 16:43:41 +0000922 ASSERT_NE(TypeOf(mem), nullptr);
923 ASSERT_TRUE(TypeOf(mem)->Is<type::Vector>());
924 EXPECT_TRUE(TypeOf(mem)->As<type::Vector>()->type()->Is<type::F32>());
925 EXPECT_EQ(TypeOf(mem)->As<type::Vector>()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +0000926}
927
dan sinclairaac58652020-04-21 13:05:34 +0000928TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle_SingleElement) {
Ben Clayton401b96b2021-02-03 17:19:59 +0000929 Global("my_vec", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclairaac58652020-04-21 13:05:34 +0000930
dan sinclair8b40a672020-12-16 11:49:10 +0000931 auto* mem = MemberAccessor("my_vec", "x");
Ben Clayton401b96b2021-02-03 17:19:59 +0000932 WrapInFunction(mem);
933
934 EXPECT_TRUE(td()->Determine()) << td()->error();
935
Ben Clayton33352542021-01-29 16:43:41 +0000936 ASSERT_NE(TypeOf(mem), nullptr);
937 ASSERT_TRUE(TypeOf(mem)->Is<type::Pointer>());
dan sinclairaac58652020-04-21 13:05:34 +0000938
Ben Clayton33352542021-01-29 16:43:41 +0000939 auto* ptr = TypeOf(mem)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000940 ASSERT_TRUE(ptr->type()->Is<type::F32>());
dan sinclairaac58652020-04-21 13:05:34 +0000941}
942
dan sinclair8eddb782020-04-23 22:26:52 +0000943TEST_F(TypeDeterminerTest, Expr_Accessor_MultiLevel) {
dan sinclair8ee1d222020-04-07 16:41:33 +0000944 // struct b {
945 // vec4<f32> foo
946 // }
947 // struct A {
948 // vec3<struct b> mem
949 // }
950 // var c : A
951 // c.mem[0].foo.yx
952 // -> vec2<f32>
953 //
954 // MemberAccessor{
955 // MemberAccessor{
956 // ArrayAccessor{
957 // MemberAccessor{
958 // Identifier{c}
959 // Identifier{mem}
960 // }
961 // ScalarConstructor{0}
962 // }
963 // Identifier{foo}
964 // }
965 // Identifier{yx}
966 // }
967 //
dan sinclair8ee1d222020-04-07 16:41:33 +0000968
dan sinclair5e5e36e2020-12-16 14:41:00 +0000969 auto* strctB =
970 create<ast::Struct>(ast::StructMemberList{Member("foo", ty.vec4<f32>())},
971 ast::StructDecorationList{});
dan sinclairb5839932020-12-16 21:38:40 +0000972 auto* stB = ty.struct_("B", strctB);
dan sinclair8ee1d222020-04-07 16:41:33 +0000973
Ben Clayton207b5e22021-01-21 15:42:10 +0000974 type::Vector vecB(stB, 3);
dan sinclair5e5e36e2020-12-16 14:41:00 +0000975 auto* strctA = create<ast::Struct>(
976 ast::StructMemberList{Member("mem", &vecB)}, ast::StructDecorationList{});
dan sinclair8ee1d222020-04-07 16:41:33 +0000977
dan sinclairb5839932020-12-16 21:38:40 +0000978 auto* stA = ty.struct_("A", strctA);
Ben Clayton401b96b2021-02-03 17:19:59 +0000979 Global("c", ast::StorageClass::kNone, stA);
dan sinclair8ee1d222020-04-07 16:41:33 +0000980
dan sinclair8b40a672020-12-16 11:49:10 +0000981 auto* mem = MemberAccessor(
982 MemberAccessor(IndexAccessor(MemberAccessor("c", "mem"), 0), "foo"),
983 "yx");
Ben Clayton401b96b2021-02-03 17:19:59 +0000984 WrapInFunction(mem);
985
986 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair8ee1d222020-04-07 16:41:33 +0000987
Ben Clayton33352542021-01-29 16:43:41 +0000988 ASSERT_NE(TypeOf(mem), nullptr);
989 ASSERT_TRUE(TypeOf(mem)->Is<type::Vector>());
990 EXPECT_TRUE(TypeOf(mem)->As<type::Vector>()->type()->Is<type::F32>());
991 EXPECT_EQ(TypeOf(mem)->As<type::Vector>()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +0000992}
993
Ben Clayton7b7d6982021-02-09 17:38:05 +0000994TEST_F(TypeDeterminerTest, Expr_MemberAccessor_InBinaryOp) {
995 auto* strct = create<ast::Struct>(
996 ast::StructMemberList{Member("first_member", ty.f32()),
997 Member("second_member", ty.f32())},
998 ast::StructDecorationList{});
999
1000 auto* st = ty.struct_("S", strct);
1001 Global("my_struct", ast::StorageClass::kNone, st);
1002
1003 auto* expr = Add(MemberAccessor("my_struct", "first_member"),
1004 MemberAccessor("my_struct", "second_member"));
1005 WrapInFunction(expr);
1006
1007 EXPECT_TRUE(td()->Determine()) << td()->error();
1008
1009 ASSERT_NE(TypeOf(expr), nullptr);
1010 EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
1011}
1012
dan sinclaircd077b02020-04-20 14:19:04 +00001013using Expr_Binary_BitwiseTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +00001014TEST_P(Expr_Binary_BitwiseTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001015 auto op = GetParam();
1016
Ben Clayton401b96b2021-02-03 17:19:59 +00001017 Global("val", ast::StorageClass::kNone, ty.i32());
dan sinclair9b978022020-04-07 19:26:39 +00001018
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001019 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001020 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001021
Ben Clayton401b96b2021-02-03 17:19:59 +00001022 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001023 ASSERT_NE(TypeOf(expr), nullptr);
1024 EXPECT_TRUE(TypeOf(expr)->Is<type::I32>());
dan sinclair9b978022020-04-07 19:26:39 +00001025}
1026
dan sinclair1c9b4862020-04-07 19:27:41 +00001027TEST_P(Expr_Binary_BitwiseTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001028 auto op = GetParam();
1029
Ben Clayton401b96b2021-02-03 17:19:59 +00001030 Global("val", ast::StorageClass::kNone, ty.vec3<i32>());
dan sinclair9b978022020-04-07 19:26:39 +00001031
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001032 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001033 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001034
Ben Clayton401b96b2021-02-03 17:19:59 +00001035 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001036 ASSERT_NE(TypeOf(expr), nullptr);
1037 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1038 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::I32>());
1039 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001040}
1041INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +00001042 Expr_Binary_BitwiseTest,
1043 testing::Values(ast::BinaryOp::kAnd,
1044 ast::BinaryOp::kOr,
1045 ast::BinaryOp::kXor,
1046 ast::BinaryOp::kShiftLeft,
1047 ast::BinaryOp::kShiftRight,
dan sinclair1c9b4862020-04-07 19:27:41 +00001048 ast::BinaryOp::kAdd,
1049 ast::BinaryOp::kSubtract,
1050 ast::BinaryOp::kDivide,
1051 ast::BinaryOp::kModulo));
dan sinclair9b978022020-04-07 19:26:39 +00001052
dan sinclaircd077b02020-04-20 14:19:04 +00001053using Expr_Binary_LogicalTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +00001054TEST_P(Expr_Binary_LogicalTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001055 auto op = GetParam();
1056
Ben Clayton401b96b2021-02-03 17:19:59 +00001057 Global("val", ast::StorageClass::kNone, ty.bool_());
dan sinclair9b978022020-04-07 19:26:39 +00001058
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001059 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001060 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001061
Ben Clayton401b96b2021-02-03 17:19:59 +00001062 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001063 ASSERT_NE(TypeOf(expr), nullptr);
1064 EXPECT_TRUE(TypeOf(expr)->Is<type::Bool>());
dan sinclair9b978022020-04-07 19:26:39 +00001065}
1066
dan sinclair1c9b4862020-04-07 19:27:41 +00001067TEST_P(Expr_Binary_LogicalTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001068 auto op = GetParam();
1069
Ben Clayton401b96b2021-02-03 17:19:59 +00001070 Global("val", ast::StorageClass::kNone, ty.vec3<bool>());
dan sinclair9b978022020-04-07 19:26:39 +00001071
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001072 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001073 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001074
Ben Clayton401b96b2021-02-03 17:19:59 +00001075 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001076 ASSERT_NE(TypeOf(expr), nullptr);
1077 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1078 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::Bool>());
1079 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001080}
1081INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +00001082 Expr_Binary_LogicalTest,
1083 testing::Values(ast::BinaryOp::kLogicalAnd,
1084 ast::BinaryOp::kLogicalOr));
dan sinclair9b978022020-04-07 19:26:39 +00001085
dan sinclaircd077b02020-04-20 14:19:04 +00001086using Expr_Binary_CompareTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +00001087TEST_P(Expr_Binary_CompareTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001088 auto op = GetParam();
1089
Ben Clayton401b96b2021-02-03 17:19:59 +00001090 Global("val", ast::StorageClass::kNone, ty.i32());
dan sinclair9b978022020-04-07 19:26:39 +00001091
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001092 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001093 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001094
Ben Clayton401b96b2021-02-03 17:19:59 +00001095 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001096 ASSERT_NE(TypeOf(expr), nullptr);
1097 EXPECT_TRUE(TypeOf(expr)->Is<type::Bool>());
dan sinclair9b978022020-04-07 19:26:39 +00001098}
1099
dan sinclair1c9b4862020-04-07 19:27:41 +00001100TEST_P(Expr_Binary_CompareTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001101 auto op = GetParam();
1102
Ben Clayton401b96b2021-02-03 17:19:59 +00001103 Global("val", ast::StorageClass::kNone, ty.vec3<i32>());
dan sinclair9b978022020-04-07 19:26:39 +00001104
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001105 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001106 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001107
Ben Clayton401b96b2021-02-03 17:19:59 +00001108 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001109 ASSERT_NE(TypeOf(expr), nullptr);
1110 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1111 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::Bool>());
1112 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001113}
1114INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +00001115 Expr_Binary_CompareTest,
1116 testing::Values(ast::BinaryOp::kEqual,
1117 ast::BinaryOp::kNotEqual,
1118 ast::BinaryOp::kLessThan,
1119 ast::BinaryOp::kGreaterThan,
1120 ast::BinaryOp::kLessThanEqual,
1121 ast::BinaryOp::kGreaterThanEqual));
dan sinclair9b978022020-04-07 19:26:39 +00001122
dan sinclair1c9b4862020-04-07 19:27:41 +00001123TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Scalar) {
Ben Clayton401b96b2021-02-03 17:19:59 +00001124 Global("val", ast::StorageClass::kNone, ty.i32());
dan sinclair9b978022020-04-07 19:26:39 +00001125
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001126 auto* expr = Mul("val", "val");
Ben Clayton401b96b2021-02-03 17:19:59 +00001127 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001128
Ben Clayton401b96b2021-02-03 17:19:59 +00001129 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001130 ASSERT_NE(TypeOf(expr), nullptr);
1131 EXPECT_TRUE(TypeOf(expr)->Is<type::I32>());
dan sinclair9b978022020-04-07 19:26:39 +00001132}
1133
dan sinclair1c9b4862020-04-07 19:27:41 +00001134TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Scalar) {
Ben Clayton401b96b2021-02-03 17:19:59 +00001135 Global("scalar", ast::StorageClass::kNone, ty.f32());
1136 Global("vector", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair9b978022020-04-07 19:26:39 +00001137
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001138 auto* expr = Mul("vector", "scalar");
Ben Clayton401b96b2021-02-03 17:19:59 +00001139 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001140
Ben Clayton401b96b2021-02-03 17:19:59 +00001141 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001142 ASSERT_NE(TypeOf(expr), nullptr);
1143 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1144 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1145 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001146}
1147
dan sinclair1c9b4862020-04-07 19:27:41 +00001148TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Vector) {
Ben Clayton401b96b2021-02-03 17:19:59 +00001149 Global("scalar", ast::StorageClass::kNone, ty.f32());
1150 Global("vector", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair9b978022020-04-07 19:26:39 +00001151
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001152 auto* expr = Mul("scalar", "vector");
Ben Clayton401b96b2021-02-03 17:19:59 +00001153 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001154
Ben Clayton401b96b2021-02-03 17:19:59 +00001155 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001156 ASSERT_NE(TypeOf(expr), nullptr);
1157 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1158 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1159 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001160}
1161
dan sinclair1c9b4862020-04-07 19:27:41 +00001162TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Vector) {
Ben Clayton401b96b2021-02-03 17:19:59 +00001163 Global("vector", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair9b978022020-04-07 19:26:39 +00001164
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001165 auto* expr = Mul("vector", "vector");
Ben Clayton401b96b2021-02-03 17:19:59 +00001166 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001167
Ben Clayton401b96b2021-02-03 17:19:59 +00001168 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001169 ASSERT_NE(TypeOf(expr), nullptr);
1170 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1171 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1172 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001173}
1174
dan sinclair1c9b4862020-04-07 19:27:41 +00001175TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Scalar) {
Ben Clayton401b96b2021-02-03 17:19:59 +00001176 Global("scalar", ast::StorageClass::kNone, ty.f32());
1177 Global("matrix", ast::StorageClass::kNone, ty.mat2x3<f32>());
dan sinclair9b978022020-04-07 19:26:39 +00001178
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001179 auto* expr = Mul("matrix", "scalar");
Ben Clayton401b96b2021-02-03 17:19:59 +00001180 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001181
Ben Clayton401b96b2021-02-03 17:19:59 +00001182 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001183 ASSERT_NE(TypeOf(expr), nullptr);
1184 ASSERT_TRUE(TypeOf(expr)->Is<type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001185
Ben Clayton33352542021-01-29 16:43:41 +00001186 auto* mat = TypeOf(expr)->As<type::Matrix>();
Ben Clayton207b5e22021-01-21 15:42:10 +00001187 EXPECT_TRUE(mat->type()->Is<type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001188 EXPECT_EQ(mat->rows(), 3u);
1189 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001190}
1191
dan sinclair1c9b4862020-04-07 19:27:41 +00001192TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Matrix) {
Ben Clayton401b96b2021-02-03 17:19:59 +00001193 Global("scalar", ast::StorageClass::kNone, ty.f32());
1194 Global("matrix", ast::StorageClass::kNone, ty.mat2x3<f32>());
dan sinclair9b978022020-04-07 19:26:39 +00001195
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001196 auto* expr = Mul("scalar", "matrix");
Ben Clayton401b96b2021-02-03 17:19:59 +00001197 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001198
Ben Clayton401b96b2021-02-03 17:19:59 +00001199 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001200 ASSERT_NE(TypeOf(expr), nullptr);
1201 ASSERT_TRUE(TypeOf(expr)->Is<type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001202
Ben Clayton33352542021-01-29 16:43:41 +00001203 auto* mat = TypeOf(expr)->As<type::Matrix>();
Ben Clayton207b5e22021-01-21 15:42:10 +00001204 EXPECT_TRUE(mat->type()->Is<type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001205 EXPECT_EQ(mat->rows(), 3u);
1206 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001207}
1208
dan sinclair1c9b4862020-04-07 19:27:41 +00001209TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Vector) {
Ben Clayton401b96b2021-02-03 17:19:59 +00001210 Global("vector", ast::StorageClass::kNone, ty.vec3<f32>());
1211 Global("matrix", ast::StorageClass::kNone, ty.mat2x3<f32>());
dan sinclair9b978022020-04-07 19:26:39 +00001212
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001213 auto* expr = Mul("matrix", "vector");
Ben Clayton401b96b2021-02-03 17:19:59 +00001214 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001215
Ben Clayton401b96b2021-02-03 17:19:59 +00001216 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001217 ASSERT_NE(TypeOf(expr), nullptr);
1218 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1219 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1220 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001221}
1222
dan sinclair1c9b4862020-04-07 19:27:41 +00001223TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Matrix) {
Ben Clayton401b96b2021-02-03 17:19:59 +00001224 Global("vector", ast::StorageClass::kNone, ty.vec3<f32>());
1225 Global("matrix", ast::StorageClass::kNone, ty.mat2x3<f32>());
dan sinclair9b978022020-04-07 19:26:39 +00001226
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001227 auto* expr = Mul("vector", "matrix");
Ben Clayton401b96b2021-02-03 17:19:59 +00001228 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001229
Ben Clayton401b96b2021-02-03 17:19:59 +00001230 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001231 ASSERT_NE(TypeOf(expr), nullptr);
1232 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1233 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1234 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001235}
1236
dan sinclair1c9b4862020-04-07 19:27:41 +00001237TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Matrix) {
Ben Clayton401b96b2021-02-03 17:19:59 +00001238 Global("mat3x4", ast::StorageClass::kNone, ty.mat3x4<f32>());
1239 Global("mat4x3", ast::StorageClass::kNone, ty.mat4x3<f32>());
dan sinclair9b978022020-04-07 19:26:39 +00001240
Ben Clayton1637cbb2021-01-05 15:44:39 +00001241 auto* expr = Mul("mat3x4", "mat4x3");
Ben Clayton401b96b2021-02-03 17:19:59 +00001242 WrapInFunction(expr);
dan sinclair9b978022020-04-07 19:26:39 +00001243
Ben Clayton401b96b2021-02-03 17:19:59 +00001244 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001245 ASSERT_NE(TypeOf(expr), nullptr);
1246 ASSERT_TRUE(TypeOf(expr)->Is<type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001247
Ben Clayton33352542021-01-29 16:43:41 +00001248 auto* mat = TypeOf(expr)->As<type::Matrix>();
Ben Clayton207b5e22021-01-21 15:42:10 +00001249 EXPECT_TRUE(mat->type()->Is<type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001250 EXPECT_EQ(mat->rows(), 4u);
1251 EXPECT_EQ(mat->columns(), 4u);
dan sinclair9b978022020-04-07 19:26:39 +00001252}
1253
dan sinclair46e959d2020-06-01 13:43:22 +00001254using IntrinsicDerivativeTest = TypeDeterminerTestWithParam<std::string>;
1255TEST_P(IntrinsicDerivativeTest, Scalar) {
1256 auto name = GetParam();
dan sinclairb1730562020-04-07 19:26:49 +00001257
Ben Clayton401b96b2021-02-03 17:19:59 +00001258 Global("ident", ast::StorageClass::kNone, ty.f32());
dan sinclair46e959d2020-06-01 13:43:22 +00001259
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001260 auto* expr = Call(name, "ident");
Ben Clayton401b96b2021-02-03 17:19:59 +00001261 WrapInFunction(expr);
1262
1263 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair46e959d2020-06-01 13:43:22 +00001264
Ben Clayton33352542021-01-29 16:43:41 +00001265 ASSERT_NE(TypeOf(expr), nullptr);
1266 ASSERT_TRUE(TypeOf(expr)->Is<type::F32>());
dan sinclair46e959d2020-06-01 13:43:22 +00001267}
1268
1269TEST_P(IntrinsicDerivativeTest, Vector) {
1270 auto name = GetParam();
Ben Clayton401b96b2021-02-03 17:19:59 +00001271 Global("ident", ast::StorageClass::kNone, ty.vec4<f32>());
dan sinclairb1730562020-04-07 19:26:49 +00001272
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001273 auto* expr = Call(name, "ident");
Ben Clayton401b96b2021-02-03 17:19:59 +00001274 WrapInFunction(expr);
1275
1276 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair46e959d2020-06-01 13:43:22 +00001277
Ben Clayton33352542021-01-29 16:43:41 +00001278 ASSERT_NE(TypeOf(expr), nullptr);
1279 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1280 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1281 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 4u);
dan sinclair46e959d2020-06-01 13:43:22 +00001282}
1283
1284TEST_P(IntrinsicDerivativeTest, MissingParam) {
1285 auto name = GetParam();
1286
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001287 auto* expr = Call(name);
Ben Clayton401b96b2021-02-03 17:19:59 +00001288 WrapInFunction(expr);
1289
1290 EXPECT_FALSE(td()->Determine());
1291
Ben Clayton59d24732021-02-08 22:42:54 +00001292 EXPECT_EQ(td()->error(), "no matching call to " + name +
1293 "()\n\n"
1294 "2 candidate functions:\n " +
1295 name + "(f32) -> f32\n " + name +
1296 "(vecN<f32>) -> vecN<f32>\n");
dan sinclair46e959d2020-06-01 13:43:22 +00001297}
1298
dan sinclairb1730562020-04-07 19:26:49 +00001299INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair46e959d2020-06-01 13:43:22 +00001300 IntrinsicDerivativeTest,
1301 testing::Values("dpdx",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001302 "dpdxCoarse",
1303 "dpdxFine",
dan sinclair46e959d2020-06-01 13:43:22 +00001304 "dpdy",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001305 "dpdyCoarse",
1306 "dpdyFine",
dan sinclair46e959d2020-06-01 13:43:22 +00001307 "fwidth",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001308 "fwidthCoarse",
1309 "fwidthFine"));
dan sinclairb1730562020-04-07 19:26:49 +00001310
dan sinclair46e959d2020-06-01 13:43:22 +00001311using Intrinsic = TypeDeterminerTestWithParam<std::string>;
1312TEST_P(Intrinsic, Test) {
1313 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00001314
Ben Clayton401b96b2021-02-03 17:19:59 +00001315 Global("my_var", ast::StorageClass::kNone, ty.vec3<bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001316
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001317 auto* expr = Call(name, "my_var");
Ben Clayton401b96b2021-02-03 17:19:59 +00001318 WrapInFunction(expr);
dan sinclair8dcfd102020-04-07 19:27:00 +00001319
Ben Clayton401b96b2021-02-03 17:19:59 +00001320 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair8dcfd102020-04-07 19:27:00 +00001321
Ben Clayton33352542021-01-29 16:43:41 +00001322 ASSERT_NE(TypeOf(expr), nullptr);
1323 EXPECT_TRUE(TypeOf(expr)->Is<type::Bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001324}
1325INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair46e959d2020-06-01 13:43:22 +00001326 Intrinsic,
1327 testing::Values("any", "all"));
dan sinclair8dcfd102020-04-07 19:27:00 +00001328
dan sinclair46e959d2020-06-01 13:43:22 +00001329using Intrinsic_FloatMethod = TypeDeterminerTestWithParam<std::string>;
1330TEST_P(Intrinsic_FloatMethod, Vector) {
1331 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00001332
Ben Clayton401b96b2021-02-03 17:19:59 +00001333 Global("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001334
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001335 auto* expr = Call(name, "my_var");
Ben Clayton401b96b2021-02-03 17:19:59 +00001336 WrapInFunction(expr);
dan sinclair8dcfd102020-04-07 19:27:00 +00001337
Ben Clayton401b96b2021-02-03 17:19:59 +00001338 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair8dcfd102020-04-07 19:27:00 +00001339
Ben Clayton33352542021-01-29 16:43:41 +00001340 ASSERT_NE(TypeOf(expr), nullptr);
1341 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1342 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::Bool>());
1343 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair8dcfd102020-04-07 19:27:00 +00001344}
dan sinclair46e959d2020-06-01 13:43:22 +00001345
1346TEST_P(Intrinsic_FloatMethod, Scalar) {
1347 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00001348
Ben Clayton401b96b2021-02-03 17:19:59 +00001349 Global("my_var", ast::StorageClass::kNone, ty.f32());
dan sinclair8dcfd102020-04-07 19:27:00 +00001350
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001351 auto* expr = Call(name, "my_var");
Ben Clayton401b96b2021-02-03 17:19:59 +00001352 WrapInFunction(expr);
dan sinclair8dcfd102020-04-07 19:27:00 +00001353
Ben Clayton401b96b2021-02-03 17:19:59 +00001354 EXPECT_TRUE(td()->Determine()) << td()->error();
1355
Ben Clayton33352542021-01-29 16:43:41 +00001356 ASSERT_NE(TypeOf(expr), nullptr);
1357 EXPECT_TRUE(TypeOf(expr)->Is<type::Bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001358}
dan sinclair8dcfd102020-04-07 19:27:00 +00001359
dan sinclair46e959d2020-06-01 13:43:22 +00001360TEST_P(Intrinsic_FloatMethod, MissingParam) {
1361 auto name = GetParam();
1362
Ben Clayton401b96b2021-02-03 17:19:59 +00001363 Global("my_var", ast::StorageClass::kNone, ty.f32());
dan sinclair46e959d2020-06-01 13:43:22 +00001364
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001365 auto* expr = Call(name);
Ben Clayton401b96b2021-02-03 17:19:59 +00001366 WrapInFunction(expr);
dan sinclair46e959d2020-06-01 13:43:22 +00001367
Ben Clayton401b96b2021-02-03 17:19:59 +00001368 EXPECT_FALSE(td()->Determine());
1369
Ben Clayton59d24732021-02-08 22:42:54 +00001370 EXPECT_EQ(td()->error(), "no matching call to " + name +
1371 "()\n\n"
1372 "2 candidate functions:\n " +
1373 name + "(f32) -> bool\n " + name +
1374 "(vecN<f32>) -> vecN<bool>\n");
dan sinclair46e959d2020-06-01 13:43:22 +00001375}
1376
1377TEST_P(Intrinsic_FloatMethod, TooManyParams) {
1378 auto name = GetParam();
1379
Ben Clayton401b96b2021-02-03 17:19:59 +00001380 Global("my_var", ast::StorageClass::kNone, ty.f32());
dan sinclair46e959d2020-06-01 13:43:22 +00001381
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001382 auto* expr = Call(name, "my_var", "my_var");
Ben Clayton401b96b2021-02-03 17:19:59 +00001383 WrapInFunction(expr);
dan sinclair46e959d2020-06-01 13:43:22 +00001384
Ben Clayton401b96b2021-02-03 17:19:59 +00001385 EXPECT_FALSE(td()->Determine());
1386
Ben Clayton59d24732021-02-08 22:42:54 +00001387 EXPECT_EQ(td()->error(), "no matching call to " + name +
1388 "(f32, f32)\n\n"
1389 "2 candidate functions:\n " +
1390 name + "(f32) -> bool\n " + name +
1391 "(vecN<f32>) -> vecN<bool>\n");
dan sinclair46e959d2020-06-01 13:43:22 +00001392}
1393INSTANTIATE_TEST_SUITE_P(
1394 TypeDeterminerTest,
1395 Intrinsic_FloatMethod,
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001396 testing::Values("isInf", "isNan", "isFinite", "isNormal"));
dan sinclair46e959d2020-06-01 13:43:22 +00001397
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001398enum class Texture { kF32, kI32, kU32 };
1399inline std::ostream& operator<<(std::ostream& out, Texture data) {
1400 if (data == Texture::kF32) {
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001401 out << "f32";
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001402 } else if (data == Texture::kI32) {
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001403 out << "i32";
1404 } else {
1405 out << "u32";
1406 }
1407 return out;
1408}
1409
1410struct TextureTestParams {
Ben Clayton207b5e22021-01-21 15:42:10 +00001411 type::TextureDimension dim;
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001412 Texture type = Texture::kF32;
Ben Clayton207b5e22021-01-21 15:42:10 +00001413 type::ImageFormat format = type::ImageFormat::kR16Float;
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001414};
1415inline std::ostream& operator<<(std::ostream& out, TextureTestParams data) {
1416 out << data.dim << "_" << data.type;
1417 return out;
1418}
1419
1420class Intrinsic_TextureOperation
1421 : public TypeDeterminerTestWithParam<TextureTestParams> {
1422 public:
Ben Clayton3b4f3d22021-02-08 20:24:52 +00001423 /// Gets an appropriate type for the coords parameter depending the the
1424 /// dimensionality of the texture being sampled.
1425 /// @param dim dimensionality of the texture being sampled
1426 /// @param scalar the scalar type
1427 /// @returns a pointer to a type appropriate for the coord param
1428 type::Type* GetCoordsType(type::TextureDimension dim, type::Type* scalar) {
1429 switch (dim) {
1430 case type::TextureDimension::k1d:
1431 case type::TextureDimension::k1dArray:
1432 return scalar;
1433 case type::TextureDimension::k2d:
1434 case type::TextureDimension::k2dArray:
1435 return create<type::Vector>(scalar, 2);
1436 case type::TextureDimension::k3d:
1437 case type::TextureDimension::kCube:
1438 case type::TextureDimension::kCubeArray:
1439 return create<type::Vector>(scalar, 3);
1440 default:
1441 [=]() { FAIL() << "Unsupported texture dimension: " << dim; }();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001442 }
Ben Clayton3b4f3d22021-02-08 20:24:52 +00001443 return nullptr;
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001444 }
1445
1446 void add_call_param(std::string name,
Ben Clayton207b5e22021-01-21 15:42:10 +00001447 type::Type* type,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001448 ast::ExpressionList* call_params) {
Ben Clayton401b96b2021-02-03 17:19:59 +00001449 Global(name, ast::StorageClass::kNone, type);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001450 call_params->push_back(Expr(name));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001451 }
Ben Clayton281b6022021-01-21 16:35:10 +00001452 type::Type* subtype(Texture type) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001453 if (type == Texture::kF32) {
Ben Clayton281b6022021-01-21 16:35:10 +00001454 return create<type::F32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001455 }
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001456 if (type == Texture::kI32) {
Ben Clayton281b6022021-01-21 16:35:10 +00001457 return create<type::I32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001458 }
Ben Clayton281b6022021-01-21 16:35:10 +00001459 return create<type::U32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001460 }
1461};
1462
1463using Intrinsic_StorageTextureOperation = Intrinsic_TextureOperation;
1464TEST_P(Intrinsic_StorageTextureOperation, TextureLoadRo) {
1465 auto dim = GetParam().dim;
1466 auto type = GetParam().type;
1467 auto format = GetParam().format;
1468
Ben Clayton3b4f3d22021-02-08 20:24:52 +00001469 auto* coords_type = GetCoordsType(dim, ty.i32());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001470
Ben Claytonb57c19d2021-02-08 20:35:01 +00001471 auto* subtype = type::StorageTexture::SubtypeFor(format, Types());
Ben Clayton48b38412021-02-03 20:28:26 +00001472 type::Type* texture_type = create<type::StorageTexture>(dim, format, subtype);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001473
1474 ast::ExpressionList call_params;
1475
1476 add_call_param("texture", texture_type, &call_params);
Ben Clayton281b6022021-01-21 16:35:10 +00001477 add_call_param("coords", coords_type, &call_params);
Ben Clayton3b4f3d22021-02-08 20:24:52 +00001478
1479 if (type::IsTextureArray(dim)) {
1480 add_call_param("array_index", ty.i32(), &call_params);
1481 }
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001482
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001483 auto* expr = Call("textureLoad", call_params);
Ben Clayton401b96b2021-02-03 17:19:59 +00001484 WrapInFunction(expr);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001485
Ben Clayton401b96b2021-02-03 17:19:59 +00001486 EXPECT_TRUE(td()->Determine()) << td()->error();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001487
Ben Clayton33352542021-01-29 16:43:41 +00001488 ASSERT_NE(TypeOf(expr), nullptr);
1489 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001490 if (type == Texture::kF32) {
Ben Clayton33352542021-01-29 16:43:41 +00001491 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001492 } else if (type == Texture::kI32) {
Ben Clayton33352542021-01-29 16:43:41 +00001493 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::I32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001494 } else {
Ben Clayton33352542021-01-29 16:43:41 +00001495 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::U32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001496 }
Ben Clayton33352542021-01-29 16:43:41 +00001497 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 4u);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001498}
1499
1500INSTANTIATE_TEST_SUITE_P(
1501 TypeDeterminerTest,
1502 Intrinsic_StorageTextureOperation,
1503 testing::Values(
Ben Clayton207b5e22021-01-21 15:42:10 +00001504 TextureTestParams{type::TextureDimension::k1d, Texture::kF32,
1505 type::ImageFormat::kR16Float},
1506 TextureTestParams{type::TextureDimension::k1d, Texture::kI32,
1507 type::ImageFormat::kR16Sint},
1508 TextureTestParams{type::TextureDimension::k1d, Texture::kF32,
1509 type::ImageFormat::kR8Unorm},
1510 TextureTestParams{type::TextureDimension::k1dArray, Texture::kF32,
1511 type::ImageFormat::kR16Float},
1512 TextureTestParams{type::TextureDimension::k1dArray, Texture::kI32,
1513 type::ImageFormat::kR16Sint},
1514 TextureTestParams{type::TextureDimension::k1dArray, Texture::kF32,
1515 type::ImageFormat::kR8Unorm},
1516 TextureTestParams{type::TextureDimension::k2d, Texture::kF32,
1517 type::ImageFormat::kR16Float},
1518 TextureTestParams{type::TextureDimension::k2d, Texture::kI32,
1519 type::ImageFormat::kR16Sint},
1520 TextureTestParams{type::TextureDimension::k2d, Texture::kF32,
1521 type::ImageFormat::kR8Unorm},
1522 TextureTestParams{type::TextureDimension::k2dArray, Texture::kF32,
1523 type::ImageFormat::kR16Float},
1524 TextureTestParams{type::TextureDimension::k2dArray, Texture::kI32,
1525 type::ImageFormat::kR16Sint},
1526 TextureTestParams{type::TextureDimension::k2dArray, Texture::kF32,
1527 type::ImageFormat::kR8Unorm},
1528 TextureTestParams{type::TextureDimension::k3d, Texture::kF32,
1529 type::ImageFormat::kR16Float},
1530 TextureTestParams{type::TextureDimension::k3d, Texture::kI32,
1531 type::ImageFormat::kR16Sint},
1532 TextureTestParams{type::TextureDimension::k3d, Texture::kF32,
1533 type::ImageFormat::kR8Unorm}));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001534
1535using Intrinsic_SampledTextureOperation = Intrinsic_TextureOperation;
1536TEST_P(Intrinsic_SampledTextureOperation, TextureLoadSampled) {
1537 auto dim = GetParam().dim;
1538 auto type = GetParam().type;
1539
Ben Clayton281b6022021-01-21 16:35:10 +00001540 type::Type* s = subtype(type);
Ben Clayton3b4f3d22021-02-08 20:24:52 +00001541 auto* coords_type = GetCoordsType(dim, ty.i32());
Ben Clayton281b6022021-01-21 16:35:10 +00001542 auto* texture_type = create<type::SampledTexture>(dim, s);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001543
1544 ast::ExpressionList call_params;
1545
Ben Clayton281b6022021-01-21 16:35:10 +00001546 add_call_param("texture", texture_type, &call_params);
1547 add_call_param("coords", coords_type, &call_params);
Ben Clayton8d391f72021-01-26 16:57:10 +00001548 add_call_param("lod", ty.i32(), &call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001549
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001550 auto* expr = Call("textureLoad", call_params);
Ben Clayton401b96b2021-02-03 17:19:59 +00001551 WrapInFunction(expr);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001552
Ben Clayton401b96b2021-02-03 17:19:59 +00001553 EXPECT_TRUE(td()->Determine()) << td()->error();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001554
Ben Clayton33352542021-01-29 16:43:41 +00001555 ASSERT_NE(TypeOf(expr), nullptr);
1556 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001557 if (type == Texture::kF32) {
Ben Clayton33352542021-01-29 16:43:41 +00001558 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001559 } else if (type == Texture::kI32) {
Ben Clayton33352542021-01-29 16:43:41 +00001560 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::I32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001561 } else {
Ben Clayton33352542021-01-29 16:43:41 +00001562 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::U32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001563 }
Ben Clayton33352542021-01-29 16:43:41 +00001564 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 4u);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001565}
1566
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001567INSTANTIATE_TEST_SUITE_P(
1568 TypeDeterminerTest,
1569 Intrinsic_SampledTextureOperation,
Ben Clayton3b4f3d22021-02-08 20:24:52 +00001570 testing::Values(TextureTestParams{type::TextureDimension::k1d},
1571 TextureTestParams{type::TextureDimension::k1dArray},
1572 TextureTestParams{type::TextureDimension::k2d},
Ben Clayton207b5e22021-01-21 15:42:10 +00001573 TextureTestParams{type::TextureDimension::k2dArray},
Ben Clayton3b4f3d22021-02-08 20:24:52 +00001574 TextureTestParams{type::TextureDimension::k3d}));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001575
dan sinclair46e959d2020-06-01 13:43:22 +00001576TEST_F(TypeDeterminerTest, Intrinsic_Dot) {
Ben Clayton401b96b2021-02-03 17:19:59 +00001577 Global("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001578
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001579 auto* expr = Call("dot", "my_var", "my_var");
Ben Clayton401b96b2021-02-03 17:19:59 +00001580 WrapInFunction(expr);
dan sinclair8dcfd102020-04-07 19:27:00 +00001581
Ben Clayton401b96b2021-02-03 17:19:59 +00001582 EXPECT_TRUE(td()->Determine()) << td()->error();
1583
Ben Clayton33352542021-01-29 16:43:41 +00001584 ASSERT_NE(TypeOf(expr), nullptr);
1585 EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001586}
1587
dan sinclair16a2ea12020-07-21 17:44:44 +00001588TEST_F(TypeDeterminerTest, Intrinsic_Select) {
Ben Clayton401b96b2021-02-03 17:19:59 +00001589 Global("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00001590
Ben Clayton401b96b2021-02-03 17:19:59 +00001591 Global("bool_var", ast::StorageClass::kNone, ty.vec3<bool>());
dan sinclair16a2ea12020-07-21 17:44:44 +00001592
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001593 auto* expr = Call("select", "my_var", "my_var", "bool_var");
Ben Clayton401b96b2021-02-03 17:19:59 +00001594 WrapInFunction(expr);
dan sinclair16a2ea12020-07-21 17:44:44 +00001595
Ben Clayton401b96b2021-02-03 17:19:59 +00001596 EXPECT_TRUE(td()->Determine()) << td()->error();
1597
Ben Clayton33352542021-01-29 16:43:41 +00001598 ASSERT_NE(TypeOf(expr), nullptr);
1599 EXPECT_TRUE(TypeOf(expr)->Is<type::Vector>());
1600 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
1601 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00001602}
1603
Alan Baker2e6a1bb2021-02-01 16:03:03 +00001604TEST_F(TypeDeterminerTest, Intrinsic_Select_NoParams) {
1605 auto* expr = Call("select");
Ben Clayton401b96b2021-02-03 17:19:59 +00001606 WrapInFunction(expr);
dan sinclair16a2ea12020-07-21 17:44:44 +00001607
Ben Clayton401b96b2021-02-03 17:19:59 +00001608 EXPECT_FALSE(td()->Determine());
1609
Ben Clayton59d24732021-02-08 22:42:54 +00001610 EXPECT_EQ(td()->error(),
1611 R"(no matching call to select()
1612
16132 candidate functions:
1614 select(T, T, bool) -> T where: T is scalar
1615 select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is scalar
1616)");
dan sinclair16a2ea12020-07-21 17:44:44 +00001617}
1618
dan sinclaircd077b02020-04-20 14:19:04 +00001619using UnaryOpExpressionTest = TypeDeterminerTestWithParam<ast::UnaryOp>;
dan sinclair0e257622020-04-07 19:27:11 +00001620TEST_P(UnaryOpExpressionTest, Expr_UnaryOp) {
1621 auto op = GetParam();
1622
Ben Clayton401b96b2021-02-03 17:19:59 +00001623 Global("ident", ast::StorageClass::kNone, ty.vec4<f32>());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001624 auto* der = create<ast::UnaryOpExpression>(op, Expr("ident"));
Ben Clayton401b96b2021-02-03 17:19:59 +00001625 WrapInFunction(der);
1626
1627 EXPECT_TRUE(td()->Determine()) << td()->error();
1628
Ben Clayton33352542021-01-29 16:43:41 +00001629 ASSERT_NE(TypeOf(der), nullptr);
1630 ASSERT_TRUE(TypeOf(der)->Is<type::Vector>());
1631 EXPECT_TRUE(TypeOf(der)->As<type::Vector>()->type()->Is<type::F32>());
1632 EXPECT_EQ(TypeOf(der)->As<type::Vector>()->size(), 4u);
dan sinclair0e257622020-04-07 19:27:11 +00001633}
1634INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
1635 UnaryOpExpressionTest,
1636 testing::Values(ast::UnaryOp::kNegation,
1637 ast::UnaryOp::kNot));
1638
dan sinclairee8ae042020-04-08 19:58:20 +00001639TEST_F(TypeDeterminerTest, StorageClass_SetsIfMissing) {
Ben Clayton8d391f72021-01-26 16:57:10 +00001640 auto* var = Var("var", ast::StorageClass::kNone, ty.i32());
dan sinclairee8ae042020-04-08 19:58:20 +00001641
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001642 auto* stmt = create<ast::VariableDeclStatement>(var);
Ben Clayton42d1e092021-02-02 14:29:15 +00001643 Func("func", ast::VariableList{}, ty.i32(), ast::StatementList{stmt},
1644 ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001645
dan sinclairb950e802020-04-20 14:20:01 +00001646 EXPECT_TRUE(td()->Determine()) << td()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +00001647
Ben Claytonb17aea12021-02-03 17:51:09 +00001648 EXPECT_EQ(Sem().Get(var)->StorageClass(), ast::StorageClass::kFunction);
dan sinclairee8ae042020-04-08 19:58:20 +00001649}
1650
1651TEST_F(TypeDeterminerTest, StorageClass_DoesNotSetOnConst) {
Ben Clayton8d391f72021-01-26 16:57:10 +00001652 auto* var = Const("var", ast::StorageClass::kNone, ty.i32());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001653 auto* stmt = create<ast::VariableDeclStatement>(var);
Ben Clayton42d1e092021-02-02 14:29:15 +00001654 Func("func", ast::VariableList{}, ty.i32(), ast::StatementList{stmt},
1655 ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001656
dan sinclairb950e802020-04-20 14:20:01 +00001657 EXPECT_TRUE(td()->Determine()) << td()->error();
Ben Clayton401b96b2021-02-03 17:19:59 +00001658
Ben Claytonb17aea12021-02-03 17:51:09 +00001659 EXPECT_EQ(Sem().Get(var)->StorageClass(), ast::StorageClass::kNone);
dan sinclairee8ae042020-04-08 19:58:20 +00001660}
1661
1662TEST_F(TypeDeterminerTest, StorageClass_NonFunctionClassError) {
Ben Clayton8d391f72021-01-26 16:57:10 +00001663 auto* var = Var("var", ast::StorageClass::kWorkgroup, ty.i32());
dan sinclairee8ae042020-04-08 19:58:20 +00001664
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001665 auto* stmt = create<ast::VariableDeclStatement>(var);
Ben Clayton42d1e092021-02-02 14:29:15 +00001666 Func("func", ast::VariableList{}, ty.i32(), ast::StatementList{stmt},
1667 ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001668
dan sinclairb950e802020-04-20 14:20:01 +00001669 EXPECT_FALSE(td()->Determine());
Ben Clayton401b96b2021-02-03 17:19:59 +00001670
dan sinclairee8ae042020-04-08 19:58:20 +00001671 EXPECT_EQ(td()->error(),
1672 "function variable has a non-function storage class");
1673}
1674
dan sinclairb4fee2f2020-09-22 19:42:13 +00001675struct IntrinsicData {
dan sinclairca1723e2020-04-20 15:47:55 +00001676 const char* name;
Ben Clayton052ab892021-02-08 19:53:42 +00001677 IntrinsicType intrinsic;
dan sinclairca1723e2020-04-20 15:47:55 +00001678};
dan sinclairb4fee2f2020-09-22 19:42:13 +00001679inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
dan sinclairca1723e2020-04-20 15:47:55 +00001680 out << data.name;
1681 return out;
1682}
dan sinclairb4fee2f2020-09-22 19:42:13 +00001683using IntrinsicDataTest = TypeDeterminerTestWithParam<IntrinsicData>;
1684TEST_P(IntrinsicDataTest, Lookup) {
1685 auto param = GetParam();
dan sinclairca1723e2020-04-20 15:47:55 +00001686
Ben Clayton316f9f62021-02-08 22:31:44 +00001687 EXPECT_EQ(TypeDeterminer::MatchIntrinsicType(param.name), param.intrinsic);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001688}
1689INSTANTIATE_TEST_SUITE_P(
1690 TypeDeterminerTest,
1691 IntrinsicDataTest,
1692 testing::Values(
Ben Clayton052ab892021-02-08 19:53:42 +00001693 IntrinsicData{"abs", IntrinsicType::kAbs},
1694 IntrinsicData{"acos", IntrinsicType::kAcos},
1695 IntrinsicData{"all", IntrinsicType::kAll},
1696 IntrinsicData{"any", IntrinsicType::kAny},
1697 IntrinsicData{"arrayLength", IntrinsicType::kArrayLength},
1698 IntrinsicData{"asin", IntrinsicType::kAsin},
1699 IntrinsicData{"atan", IntrinsicType::kAtan},
1700 IntrinsicData{"atan2", IntrinsicType::kAtan2},
1701 IntrinsicData{"ceil", IntrinsicType::kCeil},
1702 IntrinsicData{"clamp", IntrinsicType::kClamp},
1703 IntrinsicData{"cos", IntrinsicType::kCos},
1704 IntrinsicData{"cosh", IntrinsicType::kCosh},
1705 IntrinsicData{"countOneBits", IntrinsicType::kCountOneBits},
1706 IntrinsicData{"cross", IntrinsicType::kCross},
1707 IntrinsicData{"determinant", IntrinsicType::kDeterminant},
1708 IntrinsicData{"distance", IntrinsicType::kDistance},
1709 IntrinsicData{"dot", IntrinsicType::kDot},
1710 IntrinsicData{"dpdx", IntrinsicType::kDpdx},
1711 IntrinsicData{"dpdxCoarse", IntrinsicType::kDpdxCoarse},
1712 IntrinsicData{"dpdxFine", IntrinsicType::kDpdxFine},
1713 IntrinsicData{"dpdy", IntrinsicType::kDpdy},
1714 IntrinsicData{"dpdyCoarse", IntrinsicType::kDpdyCoarse},
1715 IntrinsicData{"dpdyFine", IntrinsicType::kDpdyFine},
1716 IntrinsicData{"exp", IntrinsicType::kExp},
1717 IntrinsicData{"exp2", IntrinsicType::kExp2},
1718 IntrinsicData{"faceForward", IntrinsicType::kFaceForward},
1719 IntrinsicData{"floor", IntrinsicType::kFloor},
1720 IntrinsicData{"fma", IntrinsicType::kFma},
1721 IntrinsicData{"fract", IntrinsicType::kFract},
1722 IntrinsicData{"frexp", IntrinsicType::kFrexp},
1723 IntrinsicData{"fwidth", IntrinsicType::kFwidth},
1724 IntrinsicData{"fwidthCoarse", IntrinsicType::kFwidthCoarse},
1725 IntrinsicData{"fwidthFine", IntrinsicType::kFwidthFine},
1726 IntrinsicData{"inverseSqrt", IntrinsicType::kInverseSqrt},
1727 IntrinsicData{"isFinite", IntrinsicType::kIsFinite},
1728 IntrinsicData{"isInf", IntrinsicType::kIsInf},
1729 IntrinsicData{"isNan", IntrinsicType::kIsNan},
1730 IntrinsicData{"isNormal", IntrinsicType::kIsNormal},
1731 IntrinsicData{"ldexp", IntrinsicType::kLdexp},
1732 IntrinsicData{"length", IntrinsicType::kLength},
1733 IntrinsicData{"log", IntrinsicType::kLog},
1734 IntrinsicData{"log2", IntrinsicType::kLog2},
1735 IntrinsicData{"max", IntrinsicType::kMax},
1736 IntrinsicData{"min", IntrinsicType::kMin},
1737 IntrinsicData{"mix", IntrinsicType::kMix},
1738 IntrinsicData{"modf", IntrinsicType::kModf},
1739 IntrinsicData{"normalize", IntrinsicType::kNormalize},
1740 IntrinsicData{"pow", IntrinsicType::kPow},
1741 IntrinsicData{"reflect", IntrinsicType::kReflect},
1742 IntrinsicData{"reverseBits", IntrinsicType::kReverseBits},
1743 IntrinsicData{"round", IntrinsicType::kRound},
1744 IntrinsicData{"select", IntrinsicType::kSelect},
1745 IntrinsicData{"sign", IntrinsicType::kSign},
1746 IntrinsicData{"sin", IntrinsicType::kSin},
1747 IntrinsicData{"sinh", IntrinsicType::kSinh},
1748 IntrinsicData{"smoothStep", IntrinsicType::kSmoothStep},
1749 IntrinsicData{"sqrt", IntrinsicType::kSqrt},
1750 IntrinsicData{"step", IntrinsicType::kStep},
1751 IntrinsicData{"tan", IntrinsicType::kTan},
1752 IntrinsicData{"tanh", IntrinsicType::kTanh},
1753 IntrinsicData{"textureDimensions", IntrinsicType::kTextureDimensions},
1754 IntrinsicData{"textureLoad", IntrinsicType::kTextureLoad},
1755 IntrinsicData{"textureNumLayers", IntrinsicType::kTextureNumLayers},
1756 IntrinsicData{"textureNumLevels", IntrinsicType::kTextureNumLevels},
1757 IntrinsicData{"textureNumSamples", IntrinsicType::kTextureNumSamples},
1758 IntrinsicData{"textureSample", IntrinsicType::kTextureSample},
1759 IntrinsicData{"textureSampleBias", IntrinsicType::kTextureSampleBias},
dan sinclairb4fee2f2020-09-22 19:42:13 +00001760 IntrinsicData{"textureSampleCompare",
Ben Clayton052ab892021-02-08 19:53:42 +00001761 IntrinsicType::kTextureSampleCompare},
1762 IntrinsicData{"textureSampleGrad", IntrinsicType::kTextureSampleGrad},
1763 IntrinsicData{"textureSampleLevel", IntrinsicType::kTextureSampleLevel},
1764 IntrinsicData{"trunc", IntrinsicType::kTrunc}));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001765
Ben Clayton1618f4b2021-02-03 21:02:25 +00001766TEST_F(TypeDeterminerTest, MatchIntrinsicNoMatch) {
Ben Clayton316f9f62021-02-08 22:31:44 +00001767 EXPECT_EQ(TypeDeterminer::MatchIntrinsicType("not_intrinsic"),
Ben Clayton052ab892021-02-08 19:53:42 +00001768 IntrinsicType::kNone);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001769}
1770
Alan Bakerc63e1c02021-02-04 16:17:49 +00001771using ImportData_DataPackingTest = TypeDeterminerTestWithParam<IntrinsicData>;
1772TEST_P(ImportData_DataPackingTest, InferType) {
1773 auto param = GetParam();
1774
Ben Claytona51aa1f2021-02-08 21:10:11 +00001775 bool pack4 = param.intrinsic == IntrinsicType::kPack4x8Snorm ||
1776 param.intrinsic == IntrinsicType::kPack4x8Unorm;
1777
1778 auto* call = pack4 ? Call(param.name, vec4<f32>(1.f, 2.f, 3.f, 4.f))
1779 : Call(param.name, vec2<f32>(1.f, 2.f));
Alan Bakerc63e1c02021-02-04 16:17:49 +00001780 WrapInFunction(call);
1781
1782 EXPECT_TRUE(td()->Determine()) << td()->error();
1783 ASSERT_NE(TypeOf(call), nullptr);
1784 EXPECT_TRUE(TypeOf(call)->Is<type::U32>());
1785}
1786
1787INSTANTIATE_TEST_SUITE_P(
1788 TypeDeterminerTest,
1789 ImportData_DataPackingTest,
1790 testing::Values(
Ben Clayton052ab892021-02-08 19:53:42 +00001791 IntrinsicData{"pack4x8snorm", IntrinsicType::kPack4x8Snorm},
1792 IntrinsicData{"pack4x8unorm", IntrinsicType::kPack4x8Unorm},
1793 IntrinsicData{"pack2x16snorm", IntrinsicType::kPack2x16Snorm},
1794 IntrinsicData{"pack2x16unorm", IntrinsicType::kPack2x16Unorm},
1795 IntrinsicData{"pack2x16float", IntrinsicType::kPack2x16Float}));
Alan Bakerc63e1c02021-02-04 16:17:49 +00001796
Alan Bakercd17ea82021-02-09 21:23:00 +00001797using ImportData_DataUnpackingTest = TypeDeterminerTestWithParam<IntrinsicData>;
1798TEST_P(ImportData_DataUnpackingTest, InferType) {
1799 auto param = GetParam();
1800
1801 bool pack4 = param.intrinsic == IntrinsicType::kUnpack4x8Snorm ||
1802 param.intrinsic == IntrinsicType::kUnpack4x8Unorm;
1803
1804 auto* call = Call(param.name, 1u);
1805 WrapInFunction(call);
1806
1807 EXPECT_TRUE(td()->Determine()) << td()->error();
1808 ASSERT_NE(TypeOf(call), nullptr);
1809 EXPECT_TRUE(TypeOf(call)->is_float_vector());
1810 if (pack4) {
1811 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 4u);
1812 } else {
1813 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 2u);
1814 }
1815}
1816
1817INSTANTIATE_TEST_SUITE_P(
1818 TypeDeterminerTest,
1819 ImportData_DataUnpackingTest,
1820 testing::Values(
1821 IntrinsicData{"unpack4x8snorm", IntrinsicType::kUnpack4x8Snorm},
1822 IntrinsicData{"unpack4x8unorm", IntrinsicType::kUnpack4x8Unorm},
1823 IntrinsicData{"unpack2x16snorm", IntrinsicType::kUnpack2x16Snorm},
1824 IntrinsicData{"unpack2x16unorm", IntrinsicType::kUnpack2x16Unorm},
1825 IntrinsicData{"unpack2x16float", IntrinsicType::kUnpack2x16Float}));
1826
dan sinclairb4fee2f2020-09-22 19:42:13 +00001827using ImportData_SingleParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair37d62c92020-04-21 12:55:06 +00001828TEST_P(ImportData_SingleParamTest, Scalar) {
dan sinclairca1723e2020-04-20 15:47:55 +00001829 auto param = GetParam();
1830
Ben Claytona51aa1f2021-02-08 21:10:11 +00001831 auto* call = Call(param.name, 1.f);
Ben Clayton401b96b2021-02-03 17:19:59 +00001832 WrapInFunction(call);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001833
Ben Clayton401b96b2021-02-03 17:19:59 +00001834 EXPECT_TRUE(td()->Determine()) << td()->error();
1835
Ben Clayton1618f4b2021-02-03 21:02:25 +00001836 ASSERT_NE(TypeOf(call), nullptr);
1837 EXPECT_TRUE(TypeOf(call)->is_float_scalar());
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001838}
1839
dan sinclair37d62c92020-04-21 12:55:06 +00001840TEST_P(ImportData_SingleParamTest, Vector) {
dan sinclairca1723e2020-04-20 15:47:55 +00001841 auto param = GetParam();
1842
Ben Claytona51aa1f2021-02-08 21:10:11 +00001843 auto* call = Call(param.name, vec3<f32>(1.0f, 1.0f, 3.0f));
Ben Clayton401b96b2021-02-03 17:19:59 +00001844 WrapInFunction(call);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001845
Ben Clayton401b96b2021-02-03 17:19:59 +00001846 EXPECT_TRUE(td()->Determine()) << td()->error();
1847
Ben Clayton1618f4b2021-02-03 21:02:25 +00001848 ASSERT_NE(TypeOf(call), nullptr);
1849 EXPECT_TRUE(TypeOf(call)->is_float_vector());
1850 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001851}
1852
dan sinclair37d62c92020-04-21 12:55:06 +00001853TEST_P(ImportData_SingleParamTest, Error_NoParams) {
dan sinclairca1723e2020-04-20 15:47:55 +00001854 auto param = GetParam();
1855
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001856 auto* call = Call(param.name);
Ben Clayton401b96b2021-02-03 17:19:59 +00001857 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001858
Ben Clayton401b96b2021-02-03 17:19:59 +00001859 EXPECT_FALSE(td()->Determine());
1860
Ben Clayton59d24732021-02-08 22:42:54 +00001861 EXPECT_EQ(td()->error(), "no matching call to " + std::string(param.name) +
1862 "()\n\n"
1863 "2 candidate functions:\n " +
1864 std::string(param.name) + "(f32) -> f32\n " +
1865 std::string(param.name) +
1866 "(vecN<f32>) -> vecN<f32>\n");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001867}
1868
dan sinclaira49328f2020-04-20 15:49:50 +00001869INSTANTIATE_TEST_SUITE_P(
1870 TypeDeterminerTest,
dan sinclair37d62c92020-04-21 12:55:06 +00001871 ImportData_SingleParamTest,
Ben Clayton052ab892021-02-08 19:53:42 +00001872 testing::Values(IntrinsicData{"acos", IntrinsicType::kAcos},
1873 IntrinsicData{"asin", IntrinsicType::kAsin},
1874 IntrinsicData{"atan", IntrinsicType::kAtan},
1875 IntrinsicData{"ceil", IntrinsicType::kCeil},
1876 IntrinsicData{"cos", IntrinsicType::kCos},
1877 IntrinsicData{"cosh", IntrinsicType::kCosh},
1878 IntrinsicData{"exp", IntrinsicType::kExp},
1879 IntrinsicData{"exp2", IntrinsicType::kExp2},
1880 IntrinsicData{"floor", IntrinsicType::kFloor},
1881 IntrinsicData{"fract", IntrinsicType::kFract},
1882 IntrinsicData{"inverseSqrt", IntrinsicType::kInverseSqrt},
1883 IntrinsicData{"log", IntrinsicType::kLog},
1884 IntrinsicData{"log2", IntrinsicType::kLog2},
Ben Clayton052ab892021-02-08 19:53:42 +00001885 IntrinsicData{"round", IntrinsicType::kRound},
1886 IntrinsicData{"sign", IntrinsicType::kSign},
1887 IntrinsicData{"sin", IntrinsicType::kSin},
1888 IntrinsicData{"sinh", IntrinsicType::kSinh},
1889 IntrinsicData{"sqrt", IntrinsicType::kSqrt},
1890 IntrinsicData{"tan", IntrinsicType::kTan},
1891 IntrinsicData{"tanh", IntrinsicType::kTanh},
1892 IntrinsicData{"trunc", IntrinsicType::kTrunc}));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001893
Ben Claytona51aa1f2021-02-08 21:10:11 +00001894TEST_F(IntrinsicDataTest, Normalize_Vector) {
1895 auto* call = Call("normalize", vec3<f32>(1.0f, 1.0f, 3.0f));
1896 WrapInFunction(call);
1897
1898 EXPECT_TRUE(td()->Determine()) << td()->error();
1899
1900 ASSERT_NE(TypeOf(call), nullptr);
1901 EXPECT_TRUE(TypeOf(call)->is_float_vector());
1902 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
1903}
1904
1905TEST_F(IntrinsicDataTest, Normalize_Error_NoParams) {
1906 auto* call = Call("normalize");
1907 WrapInFunction(call);
1908
1909 EXPECT_FALSE(td()->Determine());
1910
1911 EXPECT_EQ(td()->error(),
Ben Clayton59d24732021-02-08 22:42:54 +00001912 "no matching call to normalize()\n\n"
1913 "1 candidate function:\n "
1914 "normalize(vecN<f32>) -> vecN<f32>\n");
Ben Claytona51aa1f2021-02-08 21:10:11 +00001915}
1916
dan sinclairb4fee2f2020-09-22 19:42:13 +00001917using ImportData_SingleParam_FloatOrInt_Test =
1918 TypeDeterminerTestWithParam<IntrinsicData>;
1919TEST_P(ImportData_SingleParam_FloatOrInt_Test, Float_Scalar) {
1920 auto param = GetParam();
1921
Ben Claytona51aa1f2021-02-08 21:10:11 +00001922 auto* call = Call(param.name, 1.f);
Ben Clayton401b96b2021-02-03 17:19:59 +00001923 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001924
Ben Clayton401b96b2021-02-03 17:19:59 +00001925 EXPECT_TRUE(td()->Determine()) << td()->error();
1926
Ben Clayton1618f4b2021-02-03 21:02:25 +00001927 ASSERT_NE(TypeOf(call), nullptr);
1928 EXPECT_TRUE(TypeOf(call)->is_float_scalar());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001929}
1930
1931TEST_P(ImportData_SingleParam_FloatOrInt_Test, Float_Vector) {
1932 auto param = GetParam();
1933
Ben Claytona51aa1f2021-02-08 21:10:11 +00001934 auto* call = Call(param.name, vec3<f32>(1.0f, 1.0f, 3.0f));
Ben Clayton401b96b2021-02-03 17:19:59 +00001935 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001936
Ben Clayton401b96b2021-02-03 17:19:59 +00001937 EXPECT_TRUE(td()->Determine()) << td()->error();
1938
Ben Clayton1618f4b2021-02-03 21:02:25 +00001939 ASSERT_NE(TypeOf(call), nullptr);
1940 EXPECT_TRUE(TypeOf(call)->is_float_vector());
1941 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001942}
1943
1944TEST_P(ImportData_SingleParam_FloatOrInt_Test, Sint_Scalar) {
1945 auto param = GetParam();
1946
Ben Claytona51aa1f2021-02-08 21:10:11 +00001947 auto* call = Call(param.name, -1);
Ben Clayton401b96b2021-02-03 17:19:59 +00001948 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001949
Ben Clayton401b96b2021-02-03 17:19:59 +00001950 EXPECT_TRUE(td()->Determine()) << td()->error();
1951
Ben Clayton1618f4b2021-02-03 21:02:25 +00001952 ASSERT_NE(TypeOf(call), nullptr);
1953 EXPECT_TRUE(TypeOf(call)->Is<type::I32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001954}
1955
1956TEST_P(ImportData_SingleParam_FloatOrInt_Test, Sint_Vector) {
1957 auto param = GetParam();
1958
dan sinclairb4fee2f2020-09-22 19:42:13 +00001959 ast::ExpressionList vals;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001960 vals.push_back(Expr(1));
1961 vals.push_back(Expr(1));
1962 vals.push_back(Expr(3));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001963
1964 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001965 params.push_back(vec3<i32>(vals));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001966
Ben Claytona51aa1f2021-02-08 21:10:11 +00001967 auto* call = Call(param.name, params);
Ben Clayton401b96b2021-02-03 17:19:59 +00001968 WrapInFunction(call);
Ben Clayton4bfe4612020-11-16 16:41:47 +00001969
Ben Clayton401b96b2021-02-03 17:19:59 +00001970 EXPECT_TRUE(td()->Determine()) << td()->error();
1971
Ben Clayton1618f4b2021-02-03 21:02:25 +00001972 ASSERT_NE(TypeOf(call), nullptr);
1973 EXPECT_TRUE(TypeOf(call)->is_signed_integer_vector());
1974 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001975}
1976
1977TEST_P(ImportData_SingleParam_FloatOrInt_Test, Uint_Scalar) {
1978 auto param = GetParam();
1979
dan sinclairb4fee2f2020-09-22 19:42:13 +00001980 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001981 params.push_back(Expr(1u));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001982
Ben Claytona51aa1f2021-02-08 21:10:11 +00001983 auto* call = Call(param.name, params);
Ben Clayton401b96b2021-02-03 17:19:59 +00001984 WrapInFunction(call);
Ben Clayton4bfe4612020-11-16 16:41:47 +00001985
Ben Clayton401b96b2021-02-03 17:19:59 +00001986 EXPECT_TRUE(td()->Determine()) << td()->error();
1987
Ben Clayton1618f4b2021-02-03 21:02:25 +00001988 ASSERT_NE(TypeOf(call), nullptr);
1989 EXPECT_TRUE(TypeOf(call)->Is<type::U32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001990}
1991
1992TEST_P(ImportData_SingleParam_FloatOrInt_Test, Uint_Vector) {
1993 auto param = GetParam();
1994
Ben Claytona51aa1f2021-02-08 21:10:11 +00001995 auto* call = Call(param.name, vec3<u32>(1u, 1u, 3u));
Ben Clayton401b96b2021-02-03 17:19:59 +00001996 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001997
Ben Clayton401b96b2021-02-03 17:19:59 +00001998 EXPECT_TRUE(td()->Determine()) << td()->error();
1999
Ben Clayton1618f4b2021-02-03 21:02:25 +00002000 ASSERT_NE(TypeOf(call), nullptr);
2001 EXPECT_TRUE(TypeOf(call)->is_unsigned_integer_vector());
2002 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002003}
2004
dan sinclairb4fee2f2020-09-22 19:42:13 +00002005TEST_P(ImportData_SingleParam_FloatOrInt_Test, Error_NoParams) {
2006 auto param = GetParam();
2007
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002008 auto* call = Call(param.name);
Ben Clayton401b96b2021-02-03 17:19:59 +00002009 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002010
Ben Clayton401b96b2021-02-03 17:19:59 +00002011 EXPECT_FALSE(td()->Determine());
2012
Alan Bakere809fb32021-02-01 15:33:13 +00002013 EXPECT_EQ(td()->error(),
Ben Clayton59d24732021-02-08 22:42:54 +00002014 "no matching call to " + std::string(param.name) +
2015 "()\n\n"
2016 "2 candidate functions:\n " +
2017 std::string(param.name) +
2018 "(T) -> T where: T is f32, i32 or u32\n " +
2019 std::string(param.name) +
2020 "(vecN<T>) -> vecN<T> where: T is f32, i32 or u32\n");
dan sinclairb4fee2f2020-09-22 19:42:13 +00002021}
2022
2023INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
2024 ImportData_SingleParam_FloatOrInt_Test,
Ben Clayton052ab892021-02-08 19:53:42 +00002025 testing::Values(IntrinsicData{"abs",
2026 IntrinsicType::kAbs}));
dan sinclairca1723e2020-04-20 15:47:55 +00002027
dan sinclair652a4b92020-04-20 21:09:14 +00002028TEST_F(TypeDeterminerTest, ImportData_Length_Scalar) {
Ben Claytona51aa1f2021-02-08 21:10:11 +00002029 auto* call = Call("length", 1.f);
Ben Clayton401b96b2021-02-03 17:19:59 +00002030 WrapInFunction(call);
dan sinclair652a4b92020-04-20 21:09:14 +00002031
Ben Clayton401b96b2021-02-03 17:19:59 +00002032 EXPECT_TRUE(td()->Determine()) << td()->error();
2033
Ben Clayton1618f4b2021-02-03 21:02:25 +00002034 ASSERT_NE(TypeOf(call), nullptr);
2035 EXPECT_TRUE(TypeOf(call)->is_float_scalar());
dan sinclair652a4b92020-04-20 21:09:14 +00002036}
2037
2038TEST_F(TypeDeterminerTest, ImportData_Length_FloatVector) {
dan sinclair652a4b92020-04-20 21:09:14 +00002039 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002040 params.push_back(vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair652a4b92020-04-20 21:09:14 +00002041
Ben Claytona51aa1f2021-02-08 21:10:11 +00002042 auto* call = Call("length", params);
Ben Clayton401b96b2021-02-03 17:19:59 +00002043 WrapInFunction(call);
dan sinclair652a4b92020-04-20 21:09:14 +00002044
Ben Clayton401b96b2021-02-03 17:19:59 +00002045 EXPECT_TRUE(td()->Determine()) << td()->error();
2046
Ben Clayton1618f4b2021-02-03 21:02:25 +00002047 ASSERT_NE(TypeOf(call), nullptr);
2048 EXPECT_TRUE(TypeOf(call)->is_float_scalar());
dan sinclair652a4b92020-04-20 21:09:14 +00002049}
2050
dan sinclairb4fee2f2020-09-22 19:42:13 +00002051using ImportData_TwoParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair37d62c92020-04-21 12:55:06 +00002052TEST_P(ImportData_TwoParamTest, Scalar) {
2053 auto param = GetParam();
2054
Ben Claytona51aa1f2021-02-08 21:10:11 +00002055 auto* call = Call(param.name, 1.f, 1.f);
Ben Clayton401b96b2021-02-03 17:19:59 +00002056 WrapInFunction(call);
dan sinclair37d62c92020-04-21 12:55:06 +00002057
Ben Clayton401b96b2021-02-03 17:19:59 +00002058 EXPECT_TRUE(td()->Determine()) << td()->error();
2059
Ben Clayton1618f4b2021-02-03 21:02:25 +00002060 ASSERT_NE(TypeOf(call), nullptr);
2061 EXPECT_TRUE(TypeOf(call)->is_float_scalar());
dan sinclair37d62c92020-04-21 12:55:06 +00002062}
2063
2064TEST_P(ImportData_TwoParamTest, Vector) {
2065 auto param = GetParam();
2066
Ben Claytona51aa1f2021-02-08 21:10:11 +00002067 auto* call = Call(param.name, vec3<f32>(1.0f, 1.0f, 3.0f),
2068 vec3<f32>(1.0f, 1.0f, 3.0f));
Ben Clayton401b96b2021-02-03 17:19:59 +00002069 WrapInFunction(call);
dan sinclair37d62c92020-04-21 12:55:06 +00002070
Ben Clayton401b96b2021-02-03 17:19:59 +00002071 EXPECT_TRUE(td()->Determine()) << td()->error();
2072
Ben Clayton1618f4b2021-02-03 21:02:25 +00002073 ASSERT_NE(TypeOf(call), nullptr);
2074 EXPECT_TRUE(TypeOf(call)->is_float_vector());
2075 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclair37d62c92020-04-21 12:55:06 +00002076}
dan sinclair37d62c92020-04-21 12:55:06 +00002077TEST_P(ImportData_TwoParamTest, Error_NoParams) {
2078 auto param = GetParam();
2079
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002080 auto* call = Call(param.name);
Ben Clayton401b96b2021-02-03 17:19:59 +00002081 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002082
Ben Clayton401b96b2021-02-03 17:19:59 +00002083 EXPECT_FALSE(td()->Determine());
2084
Ben Clayton59d24732021-02-08 22:42:54 +00002085 EXPECT_EQ(td()->error(), "no matching call to " + std::string(param.name) +
2086 "()\n\n"
2087 "2 candidate functions:\n " +
2088 std::string(param.name) +
2089 "(f32, f32) -> f32\n " +
2090 std::string(param.name) +
2091 "(vecN<f32>, vecN<f32>) -> vecN<f32>\n");
dan sinclair37d62c92020-04-21 12:55:06 +00002092}
dan sinclairb4fee2f2020-09-22 19:42:13 +00002093INSTANTIATE_TEST_SUITE_P(
2094 TypeDeterminerTest,
2095 ImportData_TwoParamTest,
Ben Clayton052ab892021-02-08 19:53:42 +00002096 testing::Values(IntrinsicData{"atan2", IntrinsicType::kAtan2},
2097 IntrinsicData{"pow", IntrinsicType::kPow},
2098 IntrinsicData{"step", IntrinsicType::kStep},
2099 IntrinsicData{"reflect", IntrinsicType::kReflect}));
dan sinclair37d62c92020-04-21 12:55:06 +00002100
dan sinclair54444382020-04-21 13:04:15 +00002101TEST_F(TypeDeterminerTest, ImportData_Distance_Scalar) {
Ben Claytona51aa1f2021-02-08 21:10:11 +00002102 auto* call = Call("distance", 1.f, 1.f);
Ben Clayton401b96b2021-02-03 17:19:59 +00002103 WrapInFunction(call);
dan sinclair54444382020-04-21 13:04:15 +00002104
Ben Clayton401b96b2021-02-03 17:19:59 +00002105 EXPECT_TRUE(td()->Determine()) << td()->error();
2106
Ben Clayton1618f4b2021-02-03 21:02:25 +00002107 ASSERT_NE(TypeOf(call), nullptr);
2108 EXPECT_TRUE(TypeOf(call)->is_float_scalar());
dan sinclair54444382020-04-21 13:04:15 +00002109}
2110
2111TEST_F(TypeDeterminerTest, ImportData_Distance_Vector) {
Ben Claytona51aa1f2021-02-08 21:10:11 +00002112 auto* call = Call("distance", vec3<f32>(1.0f, 1.0f, 3.0f),
2113 vec3<f32>(1.0f, 1.0f, 3.0f));
Ben Clayton401b96b2021-02-03 17:19:59 +00002114 WrapInFunction(call);
dan sinclair54444382020-04-21 13:04:15 +00002115
Ben Clayton401b96b2021-02-03 17:19:59 +00002116 EXPECT_TRUE(td()->Determine()) << td()->error();
2117
Ben Clayton1618f4b2021-02-03 21:02:25 +00002118 ASSERT_NE(TypeOf(call), nullptr);
2119 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclair54444382020-04-21 13:04:15 +00002120}
2121
dan sinclairee392252020-06-08 23:48:15 +00002122TEST_F(TypeDeterminerTest, ImportData_Cross) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002123 auto* call =
Ben Claytona51aa1f2021-02-08 21:10:11 +00002124 Call("cross", vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
Ben Clayton401b96b2021-02-03 17:19:59 +00002125 WrapInFunction(call);
dan sinclairee392252020-06-08 23:48:15 +00002126
Ben Clayton401b96b2021-02-03 17:19:59 +00002127 EXPECT_TRUE(td()->Determine()) << td()->error();
2128
Ben Clayton1618f4b2021-02-03 21:02:25 +00002129 ASSERT_NE(TypeOf(call), nullptr);
2130 EXPECT_TRUE(TypeOf(call)->is_float_vector());
2131 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairee392252020-06-08 23:48:15 +00002132}
2133
Ben Clayton59d24732021-02-08 22:42:54 +00002134TEST_F(TypeDeterminerTest, ImportData_Cross_NoArgs) {
Ben Claytona51aa1f2021-02-08 21:10:11 +00002135 auto* call = Call("cross");
Ben Clayton401b96b2021-02-03 17:19:59 +00002136 WrapInFunction(call);
dan sinclairee392252020-06-08 23:48:15 +00002137
Ben Clayton59d24732021-02-08 22:42:54 +00002138 EXPECT_FALSE(td()->Determine());
2139
2140 EXPECT_EQ(td()->error(), R"(no matching call to cross()
2141
21421 candidate function:
2143 cross(vec3<f32>, vec3<f32>) -> vec3<f32>
2144)");
2145}
2146
2147TEST_F(TypeDeterminerTest, ImportData_Normalize) {
2148 auto* call = Call("normalize", vec3<f32>(1.0f, 1.0f, 3.0f));
2149 WrapInFunction(call);
2150
Ben Clayton401b96b2021-02-03 17:19:59 +00002151 EXPECT_TRUE(td()->Determine()) << td()->error();
2152
Ben Clayton1618f4b2021-02-03 21:02:25 +00002153 ASSERT_NE(TypeOf(call), nullptr);
2154 EXPECT_TRUE(TypeOf(call)->is_float_vector());
2155 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairee392252020-06-08 23:48:15 +00002156}
2157
Ben Clayton59d24732021-02-08 22:42:54 +00002158TEST_F(TypeDeterminerTest, ImportData_Normalize_NoArgs) {
2159 auto* call = Call("normalize");
2160 WrapInFunction(call);
2161
2162 EXPECT_FALSE(td()->Determine());
2163
2164 EXPECT_EQ(td()->error(), R"(no matching call to normalize()
2165
21661 candidate function:
2167 normalize(vecN<f32>) -> vecN<f32>
2168)");
2169}
2170
dan sinclairb4fee2f2020-09-22 19:42:13 +00002171using ImportData_ThreeParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair2287d012020-04-22 00:23:57 +00002172TEST_P(ImportData_ThreeParamTest, Scalar) {
2173 auto param = GetParam();
2174
Ben Claytona51aa1f2021-02-08 21:10:11 +00002175 auto* call = Call(param.name, 1.f, 1.f, 1.f);
Ben Clayton401b96b2021-02-03 17:19:59 +00002176 WrapInFunction(call);
dan sinclair2287d012020-04-22 00:23:57 +00002177
Ben Clayton401b96b2021-02-03 17:19:59 +00002178 EXPECT_TRUE(td()->Determine()) << td()->error();
2179
Ben Clayton1618f4b2021-02-03 21:02:25 +00002180 ASSERT_NE(TypeOf(call), nullptr);
2181 EXPECT_TRUE(TypeOf(call)->is_float_scalar());
dan sinclair2287d012020-04-22 00:23:57 +00002182}
2183
2184TEST_P(ImportData_ThreeParamTest, Vector) {
2185 auto param = GetParam();
2186
Ben Claytona51aa1f2021-02-08 21:10:11 +00002187 auto* call = Call(param.name, vec3<f32>(1.0f, 1.0f, 3.0f),
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002188 vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
Ben Clayton401b96b2021-02-03 17:19:59 +00002189 WrapInFunction(call);
dan sinclair2287d012020-04-22 00:23:57 +00002190
Ben Clayton401b96b2021-02-03 17:19:59 +00002191 EXPECT_TRUE(td()->Determine()) << td()->error();
2192
Ben Clayton1618f4b2021-02-03 21:02:25 +00002193 ASSERT_NE(TypeOf(call), nullptr);
2194 EXPECT_TRUE(TypeOf(call)->is_float_vector());
2195 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclair2287d012020-04-22 00:23:57 +00002196}
dan sinclair2287d012020-04-22 00:23:57 +00002197TEST_P(ImportData_ThreeParamTest, Error_NoParams) {
2198 auto param = GetParam();
2199
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002200 auto* call = Call(param.name);
Ben Clayton401b96b2021-02-03 17:19:59 +00002201 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002202
Ben Clayton401b96b2021-02-03 17:19:59 +00002203 EXPECT_FALSE(td()->Determine());
2204
dan sinclair2287d012020-04-22 00:23:57 +00002205 EXPECT_EQ(td()->error(),
Ben Clayton59d24732021-02-08 22:42:54 +00002206 "no matching call to " + std::string(param.name) +
2207 "()\n\n"
2208 "2 candidate functions:\n " +
2209 std::string(param.name) + "(f32, f32, f32) -> f32\n " +
2210 std::string(param.name) +
2211 "(vecN<f32>, vecN<f32>, vecN<f32>) -> vecN<f32>\n");
dan sinclair2287d012020-04-22 00:23:57 +00002212}
2213
2214INSTANTIATE_TEST_SUITE_P(
2215 TypeDeterminerTest,
2216 ImportData_ThreeParamTest,
Ben Clayton052ab892021-02-08 19:53:42 +00002217 testing::Values(IntrinsicData{"mix", IntrinsicType::kMix},
2218 IntrinsicData{"smoothStep", IntrinsicType::kSmoothStep},
2219 IntrinsicData{"fma", IntrinsicType::kFma},
2220 IntrinsicData{"faceForward", IntrinsicType::kFaceForward}));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002221
dan sinclairb4fee2f2020-09-22 19:42:13 +00002222using ImportData_ThreeParam_FloatOrInt_Test =
2223 TypeDeterminerTestWithParam<IntrinsicData>;
2224TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Float_Scalar) {
2225 auto param = GetParam();
2226
Ben Claytona51aa1f2021-02-08 21:10:11 +00002227 auto* call = Call(param.name, 1.f, 1.f, 1.f);
Ben Clayton401b96b2021-02-03 17:19:59 +00002228 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002229
Ben Clayton401b96b2021-02-03 17:19:59 +00002230 EXPECT_TRUE(td()->Determine()) << td()->error();
2231
Ben Clayton1618f4b2021-02-03 21:02:25 +00002232 ASSERT_NE(TypeOf(call), nullptr);
2233 EXPECT_TRUE(TypeOf(call)->is_float_scalar());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002234}
2235
2236TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Float_Vector) {
2237 auto param = GetParam();
2238
Ben Claytona51aa1f2021-02-08 21:10:11 +00002239 auto* call = Call(param.name, vec3<f32>(1.0f, 1.0f, 3.0f),
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002240 vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
Ben Clayton401b96b2021-02-03 17:19:59 +00002241 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002242
Ben Clayton401b96b2021-02-03 17:19:59 +00002243 EXPECT_TRUE(td()->Determine()) << td()->error();
2244
Ben Clayton1618f4b2021-02-03 21:02:25 +00002245 ASSERT_NE(TypeOf(call), nullptr);
2246 EXPECT_TRUE(TypeOf(call)->is_float_vector());
2247 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002248}
2249
2250TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Sint_Scalar) {
2251 auto param = GetParam();
2252
Ben Claytona51aa1f2021-02-08 21:10:11 +00002253 auto* call = Call(param.name, 1, 1, 1);
Ben Clayton401b96b2021-02-03 17:19:59 +00002254 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002255
Ben Clayton401b96b2021-02-03 17:19:59 +00002256 EXPECT_TRUE(td()->Determine()) << td()->error();
2257
Ben Clayton1618f4b2021-02-03 21:02:25 +00002258 ASSERT_NE(TypeOf(call), nullptr);
2259 EXPECT_TRUE(TypeOf(call)->Is<type::I32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002260}
2261
2262TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Sint_Vector) {
2263 auto param = GetParam();
2264
Ben Claytona51aa1f2021-02-08 21:10:11 +00002265 auto* call = Call(param.name, vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3),
2266 vec3<i32>(1, 1, 3));
Ben Clayton401b96b2021-02-03 17:19:59 +00002267 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002268
Ben Clayton401b96b2021-02-03 17:19:59 +00002269 EXPECT_TRUE(td()->Determine()) << td()->error();
2270
Ben Clayton1618f4b2021-02-03 21:02:25 +00002271 ASSERT_NE(TypeOf(call), nullptr);
2272 EXPECT_TRUE(TypeOf(call)->is_signed_integer_vector());
2273 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002274}
2275
2276TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Uint_Scalar) {
2277 auto param = GetParam();
2278
Ben Claytona51aa1f2021-02-08 21:10:11 +00002279 auto* call = Call(param.name, 1u, 1u, 1u);
Ben Clayton401b96b2021-02-03 17:19:59 +00002280 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002281
Ben Clayton401b96b2021-02-03 17:19:59 +00002282 EXPECT_TRUE(td()->Determine()) << td()->error();
2283
Ben Clayton1618f4b2021-02-03 21:02:25 +00002284 ASSERT_NE(TypeOf(call), nullptr);
2285 EXPECT_TRUE(TypeOf(call)->Is<type::U32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002286}
2287
2288TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Uint_Vector) {
2289 auto param = GetParam();
2290
Ben Claytona51aa1f2021-02-08 21:10:11 +00002291 auto* call = Call(param.name, vec3<u32>(1u, 1u, 3u), vec3<u32>(1u, 1u, 3u),
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002292 vec3<u32>(1u, 1u, 3u));
Ben Clayton401b96b2021-02-03 17:19:59 +00002293 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002294
Ben Clayton401b96b2021-02-03 17:19:59 +00002295 EXPECT_TRUE(td()->Determine()) << td()->error();
2296
Ben Clayton1618f4b2021-02-03 21:02:25 +00002297 ASSERT_NE(TypeOf(call), nullptr);
2298 EXPECT_TRUE(TypeOf(call)->is_unsigned_integer_vector());
2299 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002300}
2301
dan sinclairb4fee2f2020-09-22 19:42:13 +00002302TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_NoParams) {
2303 auto param = GetParam();
2304
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002305 auto* call = Call(param.name);
Ben Clayton401b96b2021-02-03 17:19:59 +00002306 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002307
Ben Clayton401b96b2021-02-03 17:19:59 +00002308 EXPECT_FALSE(td()->Determine());
2309
dan sinclairb4fee2f2020-09-22 19:42:13 +00002310 EXPECT_EQ(td()->error(),
Ben Clayton59d24732021-02-08 22:42:54 +00002311 "no matching call to " + std::string(param.name) +
2312 "()\n\n"
2313 "2 candidate functions:\n " +
2314 std::string(param.name) +
2315 "(T, T, T) -> T where: T is f32, i32 or u32\n " +
2316 std::string(param.name) +
2317 "(vecN<T>, vecN<T>, vecN<T>) -> vecN<T> where: T is f32, i32 "
2318 "or u32\n");
dan sinclairb4fee2f2020-09-22 19:42:13 +00002319}
2320
2321INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
2322 ImportData_ThreeParam_FloatOrInt_Test,
Ben Clayton052ab892021-02-08 19:53:42 +00002323 testing::Values(IntrinsicData{"clamp",
2324 IntrinsicType::kClamp}));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002325
2326using ImportData_Int_SingleParamTest =
2327 TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002328TEST_P(ImportData_Int_SingleParamTest, Scalar) {
2329 auto param = GetParam();
2330
Ben Claytona51aa1f2021-02-08 21:10:11 +00002331 auto* call = Call(param.name, 1);
Ben Clayton401b96b2021-02-03 17:19:59 +00002332 WrapInFunction(call);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002333
Ben Clayton401b96b2021-02-03 17:19:59 +00002334 EXPECT_TRUE(td()->Determine()) << td()->error();
2335
Ben Clayton1618f4b2021-02-03 21:02:25 +00002336 ASSERT_NE(TypeOf(call), nullptr);
2337 EXPECT_TRUE(TypeOf(call)->is_integer_scalar());
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002338}
2339
2340TEST_P(ImportData_Int_SingleParamTest, Vector) {
2341 auto param = GetParam();
2342
Ben Claytona51aa1f2021-02-08 21:10:11 +00002343 auto* call = Call(param.name, vec3<i32>(1, 1, 3));
Ben Clayton401b96b2021-02-03 17:19:59 +00002344 WrapInFunction(call);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002345
Ben Clayton401b96b2021-02-03 17:19:59 +00002346 EXPECT_TRUE(td()->Determine()) << td()->error();
2347
Ben Clayton1618f4b2021-02-03 21:02:25 +00002348 ASSERT_NE(TypeOf(call), nullptr);
2349 EXPECT_TRUE(TypeOf(call)->is_signed_integer_vector());
2350 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002351}
2352
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002353TEST_P(ImportData_Int_SingleParamTest, Error_NoParams) {
2354 auto param = GetParam();
2355
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002356 auto* call = Call(param.name);
Ben Clayton401b96b2021-02-03 17:19:59 +00002357 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002358
Ben Clayton401b96b2021-02-03 17:19:59 +00002359 EXPECT_FALSE(td()->Determine());
2360
Alan Bakere809fb32021-02-01 15:33:13 +00002361 EXPECT_EQ(td()->error(),
Ben Clayton59d24732021-02-08 22:42:54 +00002362 "no matching call to " + std::string(param.name) +
2363 "()\n\n"
2364 "2 candidate functions:\n " +
2365 std::string(param.name) +
2366 "(T) -> T where: T is i32 or u32\n " +
2367 std::string(param.name) +
2368 "(vecN<T>) -> vecN<T> where: T is i32 or u32\n");
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002369}
2370
dan sinclairaf5df702020-06-08 23:48:26 +00002371INSTANTIATE_TEST_SUITE_P(
2372 TypeDeterminerTest,
2373 ImportData_Int_SingleParamTest,
Ben Clayton052ab892021-02-08 19:53:42 +00002374 testing::Values(IntrinsicData{"countOneBits", IntrinsicType::kCountOneBits},
2375 IntrinsicData{"reverseBits", IntrinsicType::kReverseBits}));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002376
dan sinclairb4fee2f2020-09-22 19:42:13 +00002377using ImportData_FloatOrInt_TwoParamTest =
2378 TypeDeterminerTestWithParam<IntrinsicData>;
2379TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Signed) {
dan sinclair92bb5572020-06-08 23:48:07 +00002380 auto param = GetParam();
2381
Ben Claytona51aa1f2021-02-08 21:10:11 +00002382 auto* call = Call(param.name, 1, 1);
Ben Clayton401b96b2021-02-03 17:19:59 +00002383 WrapInFunction(call);
dan sinclair92bb5572020-06-08 23:48:07 +00002384
Ben Clayton401b96b2021-02-03 17:19:59 +00002385 EXPECT_TRUE(td()->Determine()) << td()->error();
2386
Ben Clayton1618f4b2021-02-03 21:02:25 +00002387 ASSERT_NE(TypeOf(call), nullptr);
2388 EXPECT_TRUE(TypeOf(call)->Is<type::I32>());
dan sinclair92bb5572020-06-08 23:48:07 +00002389}
2390
dan sinclairb4fee2f2020-09-22 19:42:13 +00002391TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Unsigned) {
dan sinclair92bb5572020-06-08 23:48:07 +00002392 auto param = GetParam();
2393
Ben Claytona51aa1f2021-02-08 21:10:11 +00002394 auto* call = Call(param.name, 1u, 1u);
Ben Clayton401b96b2021-02-03 17:19:59 +00002395 WrapInFunction(call);
dan sinclair92bb5572020-06-08 23:48:07 +00002396
Ben Clayton401b96b2021-02-03 17:19:59 +00002397 EXPECT_TRUE(td()->Determine()) << td()->error();
2398
Ben Clayton1618f4b2021-02-03 21:02:25 +00002399 ASSERT_NE(TypeOf(call), nullptr);
2400 EXPECT_TRUE(TypeOf(call)->Is<type::U32>());
dan sinclair92bb5572020-06-08 23:48:07 +00002401}
2402
dan sinclairb4fee2f2020-09-22 19:42:13 +00002403TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Float) {
2404 auto param = GetParam();
2405
Ben Claytona51aa1f2021-02-08 21:10:11 +00002406 auto* call = Call(param.name, 1.0f, 1.0f);
Ben Clayton401b96b2021-02-03 17:19:59 +00002407 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002408
Ben Clayton401b96b2021-02-03 17:19:59 +00002409 EXPECT_TRUE(td()->Determine()) << td()->error();
2410
Ben Clayton1618f4b2021-02-03 21:02:25 +00002411 ASSERT_NE(TypeOf(call), nullptr);
2412 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002413}
2414
2415TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Signed) {
dan sinclair92bb5572020-06-08 23:48:07 +00002416 auto param = GetParam();
2417
Ben Claytona51aa1f2021-02-08 21:10:11 +00002418 auto* call = Call(param.name, vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3));
Ben Clayton401b96b2021-02-03 17:19:59 +00002419 WrapInFunction(call);
dan sinclair92bb5572020-06-08 23:48:07 +00002420
Ben Clayton401b96b2021-02-03 17:19:59 +00002421 EXPECT_TRUE(td()->Determine()) << td()->error();
2422
Ben Clayton1618f4b2021-02-03 21:02:25 +00002423 ASSERT_NE(TypeOf(call), nullptr);
2424 EXPECT_TRUE(TypeOf(call)->is_signed_integer_vector());
2425 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclair92bb5572020-06-08 23:48:07 +00002426}
2427
dan sinclairb4fee2f2020-09-22 19:42:13 +00002428TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Unsigned) {
dan sinclair92bb5572020-06-08 23:48:07 +00002429 auto param = GetParam();
2430
Ben Claytona51aa1f2021-02-08 21:10:11 +00002431 auto* call = Call(param.name, vec3<u32>(1u, 1u, 3u), vec3<u32>(1u, 1u, 3u));
Ben Clayton401b96b2021-02-03 17:19:59 +00002432 WrapInFunction(call);
dan sinclair92bb5572020-06-08 23:48:07 +00002433
Ben Clayton401b96b2021-02-03 17:19:59 +00002434 EXPECT_TRUE(td()->Determine()) << td()->error();
2435
Ben Clayton1618f4b2021-02-03 21:02:25 +00002436 ASSERT_NE(TypeOf(call), nullptr);
2437 EXPECT_TRUE(TypeOf(call)->is_unsigned_integer_vector());
2438 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclair92bb5572020-06-08 23:48:07 +00002439}
2440
dan sinclairb4fee2f2020-09-22 19:42:13 +00002441TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Float) {
dan sinclair92bb5572020-06-08 23:48:07 +00002442 auto param = GetParam();
2443
Ben Claytona51aa1f2021-02-08 21:10:11 +00002444 auto* call =
2445 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 +00002446 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002447
Ben Clayton401b96b2021-02-03 17:19:59 +00002448 EXPECT_TRUE(td()->Determine()) << td()->error();
2449
Ben Clayton1618f4b2021-02-03 21:02:25 +00002450 ASSERT_NE(TypeOf(call), nullptr);
2451 EXPECT_TRUE(TypeOf(call)->is_float_vector());
2452 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002453}
2454
dan sinclairb4fee2f2020-09-22 19:42:13 +00002455TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_NoParams) {
dan sinclair92bb5572020-06-08 23:48:07 +00002456 auto param = GetParam();
2457
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002458 auto* call = Call(param.name);
Ben Clayton401b96b2021-02-03 17:19:59 +00002459 WrapInFunction(call);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002460
Ben Clayton401b96b2021-02-03 17:19:59 +00002461 EXPECT_FALSE(td()->Determine());
2462
dan sinclair92bb5572020-06-08 23:48:07 +00002463 EXPECT_EQ(td()->error(),
Ben Clayton59d24732021-02-08 22:42:54 +00002464 "no matching call to " + std::string(param.name) +
2465 "()\n\n"
2466 "2 candidate functions:\n " +
2467 std::string(param.name) +
2468 "(T, T) -> T where: T is f32, i32 or u32\n " +
2469 std::string(param.name) +
2470 "(vecN<T>, vecN<T>) -> vecN<T> where: T is f32, i32 or u32\n");
dan sinclair92bb5572020-06-08 23:48:07 +00002471}
2472
dan sinclairb4fee2f2020-09-22 19:42:13 +00002473INSTANTIATE_TEST_SUITE_P(
2474 TypeDeterminerTest,
2475 ImportData_FloatOrInt_TwoParamTest,
Ben Clayton052ab892021-02-08 19:53:42 +00002476 testing::Values(IntrinsicData{"min", IntrinsicType::kMin},
2477 IntrinsicData{"max", IntrinsicType::kMax}));
dan sinclair92bb5572020-06-08 23:48:07 +00002478
dan sinclair3238eaa2020-06-17 20:22:08 +00002479TEST_F(TypeDeterminerTest, ImportData_GLSL_Determinant) {
Ben Clayton401b96b2021-02-03 17:19:59 +00002480 Global("var", ast::StorageClass::kFunction, ty.mat3x3<f32>());
dan sinclair3819c262020-06-17 18:39:17 +00002481
Ben Claytona51aa1f2021-02-08 21:10:11 +00002482 auto* call = Call("determinant", "var");
Ben Clayton401b96b2021-02-03 17:19:59 +00002483 WrapInFunction(call);
Ben Clayton4bfe4612020-11-16 16:41:47 +00002484
Ben Clayton401b96b2021-02-03 17:19:59 +00002485 EXPECT_TRUE(td()->Determine()) << td()->error();
2486
Ben Clayton1618f4b2021-02-03 21:02:25 +00002487 ASSERT_NE(TypeOf(call), nullptr);
2488 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclair3819c262020-06-17 18:39:17 +00002489}
2490
dan sinclairb4fee2f2020-09-22 19:42:13 +00002491using ImportData_Matrix_OneParam_Test =
2492 TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair3819c262020-06-17 18:39:17 +00002493
dan sinclair3238eaa2020-06-17 20:22:08 +00002494TEST_P(ImportData_Matrix_OneParam_Test, NoParams) {
2495 auto param = GetParam();
2496
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002497 auto* call = Call(param.name);
Ben Clayton401b96b2021-02-03 17:19:59 +00002498 WrapInFunction(call);
dan sinclair3819c262020-06-17 18:39:17 +00002499
Ben Clayton59d24732021-02-08 22:42:54 +00002500 EXPECT_FALSE(td()->Determine());
Ben Clayton401b96b2021-02-03 17:19:59 +00002501
Alan Bakere809fb32021-02-01 15:33:13 +00002502 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
Ben Clayton59d24732021-02-08 22:42:54 +00002503 EXPECT_EQ(td()->error(),
2504 "no matching call to " + std::string(param.name) + R"(()
2505
25061 candidate function:
2507 determinant(maxNxN<f32>) -> f32
2508)");
dan sinclair3819c262020-06-17 18:39:17 +00002509}
2510
dan sinclaire9598d62020-06-18 18:03:00 +00002511INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00002512 ImportData_Matrix_OneParam_Test,
2513 testing::Values(IntrinsicData{
Ben Clayton052ab892021-02-08 19:53:42 +00002514 "determinant", IntrinsicType::kDeterminant}));
dan sinclaire9598d62020-06-18 18:03:00 +00002515
dan sinclair05926432020-09-21 17:51:31 +00002516TEST_F(TypeDeterminerTest, Function_EntryPoints_StageDecoration) {
dan sinclair05926432020-09-21 17:51:31 +00002517 // fn b() {}
2518 // fn c() { b(); }
2519 // fn a() { c(); }
2520 // fn ep_1() { a(); b(); }
2521 // fn ep_2() { c();}
2522 //
2523 // c -> {ep_1, ep_2}
2524 // a -> {ep_1}
2525 // b -> {ep_1, ep_2}
2526 // ep_1 -> {}
2527 // ep_2 -> {}
2528
2529 ast::VariableList params;
Ben Clayton8d391f72021-01-26 16:57:10 +00002530 auto* func_b = Func("b", params, ty.f32(), ast::StatementList{},
dan sinclair181d8ba2020-12-16 15:15:40 +00002531 ast::FunctionDecorationList{});
dan sinclaira41132f2020-12-11 18:24:53 +00002532 auto* func_c =
Ben Clayton8d391f72021-01-26 16:57:10 +00002533 Func("c", params, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +00002534 ast::StatementList{
2535 create<ast::AssignmentStatement>(Expr("second"), Call("b")),
2536 },
2537 ast::FunctionDecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00002538
dan sinclaira41132f2020-12-11 18:24:53 +00002539 auto* func_a =
Ben Clayton8d391f72021-01-26 16:57:10 +00002540 Func("a", params, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +00002541 ast::StatementList{
2542 create<ast::AssignmentStatement>(Expr("first"), Call("c")),
2543 },
2544 ast::FunctionDecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00002545
dan sinclair181d8ba2020-12-16 15:15:40 +00002546 auto* ep_1 =
Ben Clayton8d391f72021-01-26 16:57:10 +00002547 Func("ep_1", params, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +00002548 ast::StatementList{
2549 create<ast::AssignmentStatement>(Expr("call_a"), Call("a")),
2550 create<ast::AssignmentStatement>(Expr("call_b"), Call("b")),
2551 },
2552 ast::FunctionDecorationList{
2553 create<ast::StageDecoration>(ast::PipelineStage::kVertex),
2554 });
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002555
dan sinclair181d8ba2020-12-16 15:15:40 +00002556 auto* ep_2 =
Ben Clayton8d391f72021-01-26 16:57:10 +00002557 Func("ep_2", params, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +00002558 ast::StatementList{
2559 create<ast::AssignmentStatement>(Expr("call_c"), Call("c")),
2560 },
2561 ast::FunctionDecorationList{
2562 create<ast::StageDecoration>(ast::PipelineStage::kVertex),
2563 });
dan sinclair05926432020-09-21 17:51:31 +00002564
Ben Clayton401b96b2021-02-03 17:19:59 +00002565 Global("first", ast::StorageClass::kPrivate, ty.f32());
2566 Global("second", ast::StorageClass::kPrivate, ty.f32());
2567 Global("call_a", ast::StorageClass::kPrivate, ty.f32());
2568 Global("call_b", ast::StorageClass::kPrivate, ty.f32());
2569 Global("call_c", ast::StorageClass::kPrivate, ty.f32());
dan sinclairff267ca2020-10-14 18:26:31 +00002570
dan sinclair05926432020-09-21 17:51:31 +00002571 ASSERT_TRUE(td()->Determine()) << td()->error();
2572
Ben Clayton87c78dd2021-02-03 16:43:20 +00002573 auto* func_b_sem = Sem().Get(func_b);
2574 auto* func_a_sem = Sem().Get(func_a);
2575 auto* func_c_sem = Sem().Get(func_c);
2576 auto* ep_1_sem = Sem().Get(ep_1);
2577 auto* ep_2_sem = Sem().Get(ep_2);
2578 ASSERT_NE(func_b_sem, nullptr);
2579 ASSERT_NE(func_a_sem, nullptr);
2580 ASSERT_NE(func_c_sem, nullptr);
2581 ASSERT_NE(ep_1_sem, nullptr);
2582 ASSERT_NE(ep_2_sem, nullptr);
2583
2584 const auto& b_eps = func_b_sem->AncestorEntryPoints();
dan sinclair05926432020-09-21 17:51:31 +00002585 ASSERT_EQ(2u, b_eps.size());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00002586 EXPECT_EQ(Symbols().Register("ep_1"), b_eps[0]);
2587 EXPECT_EQ(Symbols().Register("ep_2"), b_eps[1]);
dan sinclair05926432020-09-21 17:51:31 +00002588
Ben Clayton87c78dd2021-02-03 16:43:20 +00002589 const auto& a_eps = func_a_sem->AncestorEntryPoints();
dan sinclair05926432020-09-21 17:51:31 +00002590 ASSERT_EQ(1u, a_eps.size());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00002591 EXPECT_EQ(Symbols().Register("ep_1"), a_eps[0]);
dan sinclair05926432020-09-21 17:51:31 +00002592
Ben Clayton87c78dd2021-02-03 16:43:20 +00002593 const auto& c_eps = func_c_sem->AncestorEntryPoints();
dan sinclair05926432020-09-21 17:51:31 +00002594 ASSERT_EQ(2u, c_eps.size());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00002595 EXPECT_EQ(Symbols().Register("ep_1"), c_eps[0]);
2596 EXPECT_EQ(Symbols().Register("ep_2"), c_eps[1]);
dan sinclair05926432020-09-21 17:51:31 +00002597
Ben Clayton87c78dd2021-02-03 16:43:20 +00002598 EXPECT_TRUE(ep_1_sem->AncestorEntryPoints().empty());
2599 EXPECT_TRUE(ep_2_sem->AncestorEntryPoints().empty());
dan sinclair05926432020-09-21 17:51:31 +00002600}
2601
Ben Clayton3ea3c992020-11-18 21:19:22 +00002602using TypeDeterminerTextureIntrinsicTest =
2603 TypeDeterminerTestWithParam<ast::intrinsic::test::TextureOverloadCase>;
2604
2605INSTANTIATE_TEST_SUITE_P(
2606 TypeDeterminerTest,
2607 TypeDeterminerTextureIntrinsicTest,
2608 testing::ValuesIn(ast::intrinsic::test::TextureOverloadCase::ValidCases()));
2609
2610std::string to_str(const std::string& function,
dan sinclair81302442021-02-09 15:37:44 +00002611 const semantic::ParameterList& params) {
Ben Clayton3ea3c992020-11-18 21:19:22 +00002612 std::stringstream out;
2613 out << function << "(";
2614 bool first = true;
Ben Clayton316f9f62021-02-08 22:31:44 +00002615 for (auto& param : params) {
Ben Clayton3ea3c992020-11-18 21:19:22 +00002616 if (!first) {
2617 out << ", ";
2618 }
Ben Clayton316f9f62021-02-08 22:31:44 +00002619 out << semantic::str(param.usage);
Ben Clayton3ea3c992020-11-18 21:19:22 +00002620 first = false;
2621 }
2622 out << ")";
2623 return out.str();
2624}
2625
2626const char* expected_texture_overload(
2627 ast::intrinsic::test::ValidTextureOverload overload) {
2628 using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
2629 switch (overload) {
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002630 case ValidTextureOverload::kDimensions1d:
2631 case ValidTextureOverload::kDimensions1dArray:
2632 case ValidTextureOverload::kDimensions2d:
2633 case ValidTextureOverload::kDimensions2dArray:
2634 case ValidTextureOverload::kDimensions3d:
2635 case ValidTextureOverload::kDimensionsCube:
2636 case ValidTextureOverload::kDimensionsCubeArray:
Ben Clayton6e5b5ec2021-01-14 18:09:07 +00002637 case ValidTextureOverload::kDimensionsMultisampled2d:
2638 case ValidTextureOverload::kDimensionsMultisampled2dArray:
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002639 case ValidTextureOverload::kDimensionsDepth2d:
2640 case ValidTextureOverload::kDimensionsDepth2dArray:
2641 case ValidTextureOverload::kDimensionsDepthCube:
2642 case ValidTextureOverload::kDimensionsDepthCubeArray:
2643 case ValidTextureOverload::kDimensionsStorageRO1d:
2644 case ValidTextureOverload::kDimensionsStorageRO1dArray:
2645 case ValidTextureOverload::kDimensionsStorageRO2d:
2646 case ValidTextureOverload::kDimensionsStorageRO2dArray:
2647 case ValidTextureOverload::kDimensionsStorageRO3d:
2648 case ValidTextureOverload::kDimensionsStorageWO1d:
2649 case ValidTextureOverload::kDimensionsStorageWO1dArray:
2650 case ValidTextureOverload::kDimensionsStorageWO2d:
2651 case ValidTextureOverload::kDimensionsStorageWO2dArray:
2652 case ValidTextureOverload::kDimensionsStorageWO3d:
2653 return R"(textureDimensions(texture))";
Ben Claytonc21f1f92021-01-14 16:50:07 +00002654 case ValidTextureOverload::kNumLayers1dArray:
2655 case ValidTextureOverload::kNumLayers2dArray:
2656 case ValidTextureOverload::kNumLayersCubeArray:
Ben Clayton6e5b5ec2021-01-14 18:09:07 +00002657 case ValidTextureOverload::kNumLayersMultisampled2dArray:
Ben Claytonc21f1f92021-01-14 16:50:07 +00002658 case ValidTextureOverload::kNumLayersDepth2dArray:
2659 case ValidTextureOverload::kNumLayersDepthCubeArray:
2660 case ValidTextureOverload::kNumLayersStorageWO1dArray:
2661 case ValidTextureOverload::kNumLayersStorageWO2dArray:
2662 return R"(textureNumLayers(texture))";
Ben Claytond9713202021-01-14 18:06:57 +00002663 case ValidTextureOverload::kNumLevels2d:
2664 case ValidTextureOverload::kNumLevels2dArray:
2665 case ValidTextureOverload::kNumLevels3d:
2666 case ValidTextureOverload::kNumLevelsCube:
2667 case ValidTextureOverload::kNumLevelsCubeArray:
2668 case ValidTextureOverload::kNumLevelsDepth2d:
2669 case ValidTextureOverload::kNumLevelsDepth2dArray:
2670 case ValidTextureOverload::kNumLevelsDepthCube:
2671 case ValidTextureOverload::kNumLevelsDepthCubeArray:
2672 return R"(textureNumLevels(texture))";
Ben Clayton0a68b362021-01-14 18:11:17 +00002673 case ValidTextureOverload::kNumSamplesMultisampled2d:
2674 case ValidTextureOverload::kNumSamplesMultisampled2dArray:
2675 return R"(textureNumSamples(texture))";
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002676 case ValidTextureOverload::kDimensions2dLevel:
2677 case ValidTextureOverload::kDimensions2dArrayLevel:
2678 case ValidTextureOverload::kDimensions3dLevel:
2679 case ValidTextureOverload::kDimensionsCubeLevel:
2680 case ValidTextureOverload::kDimensionsCubeArrayLevel:
2681 case ValidTextureOverload::kDimensionsDepth2dLevel:
2682 case ValidTextureOverload::kDimensionsDepth2dArrayLevel:
2683 case ValidTextureOverload::kDimensionsDepthCubeLevel:
2684 case ValidTextureOverload::kDimensionsDepthCubeArrayLevel:
2685 return R"(textureDimensions(texture, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002686 case ValidTextureOverload::kSample1dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002687 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002688 case ValidTextureOverload::kSample1dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002689 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002690 case ValidTextureOverload::kSample2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002691 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002692 case ValidTextureOverload::kSample2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002693 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002694 case ValidTextureOverload::kSample2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002695 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002696 case ValidTextureOverload::kSample2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002697 return R"(textureSample(texture, sampler, coords, array_index, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002698 case ValidTextureOverload::kSample3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002699 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002700 case ValidTextureOverload::kSample3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002701 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002702 case ValidTextureOverload::kSampleCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002703 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002704 case ValidTextureOverload::kSampleCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002705 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002706 case ValidTextureOverload::kSampleDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002707 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002708 case ValidTextureOverload::kSampleDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002709 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002710 case ValidTextureOverload::kSampleDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002711 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002712 case ValidTextureOverload::kSampleDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002713 return R"(textureSample(texture, sampler, coords, array_index, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002714 case ValidTextureOverload::kSampleDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002715 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002716 case ValidTextureOverload::kSampleDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002717 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002718 case ValidTextureOverload::kSampleBias2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002719 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002720 case ValidTextureOverload::kSampleBias2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002721 return R"(textureSampleBias(texture, sampler, coords, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002722 case ValidTextureOverload::kSampleBias2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002723 return R"(textureSampleBias(texture, sampler, coords, array_index, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002724 case ValidTextureOverload::kSampleBias2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002725 return R"(textureSampleBias(texture, sampler, coords, array_index, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002726 case ValidTextureOverload::kSampleBias3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002727 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002728 case ValidTextureOverload::kSampleBias3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002729 return R"(textureSampleBias(texture, sampler, coords, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002730 case ValidTextureOverload::kSampleBiasCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002731 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002732 case ValidTextureOverload::kSampleBiasCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002733 return R"(textureSampleBias(texture, sampler, coords, array_index, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002734 case ValidTextureOverload::kSampleLevel2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002735 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002736 case ValidTextureOverload::kSampleLevel2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002737 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002738 case ValidTextureOverload::kSampleLevel2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002739 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002740 case ValidTextureOverload::kSampleLevel2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002741 return R"(textureSampleLevel(texture, sampler, coords, array_index, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002742 case ValidTextureOverload::kSampleLevel3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002743 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002744 case ValidTextureOverload::kSampleLevel3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002745 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002746 case ValidTextureOverload::kSampleLevelCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002747 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002748 case ValidTextureOverload::kSampleLevelCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002749 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002750 case ValidTextureOverload::kSampleLevelDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002751 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002752 case ValidTextureOverload::kSampleLevelDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002753 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002754 case ValidTextureOverload::kSampleLevelDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002755 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002756 case ValidTextureOverload::kSampleLevelDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002757 return R"(textureSampleLevel(texture, sampler, coords, array_index, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002758 case ValidTextureOverload::kSampleLevelDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002759 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002760 case ValidTextureOverload::kSampleLevelDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002761 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002762 case ValidTextureOverload::kSampleGrad2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002763 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002764 case ValidTextureOverload::kSampleGrad2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002765 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002766 case ValidTextureOverload::kSampleGrad2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002767 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002768 case ValidTextureOverload::kSampleGrad2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002769 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002770 case ValidTextureOverload::kSampleGrad3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002771 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002772 case ValidTextureOverload::kSampleGrad3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002773 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002774 case ValidTextureOverload::kSampleGradCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002775 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002776 case ValidTextureOverload::kSampleGradCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002777 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy))";
Ben Clayton57166262021-01-13 16:36:51 +00002778 case ValidTextureOverload::kSampleCompareDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002779 return R"(textureSampleCompare(texture, sampler, coords, depth_ref))";
Ben Clayton57166262021-01-13 16:36:51 +00002780 case ValidTextureOverload::kSampleCompareDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002781 return R"(textureSampleCompare(texture, sampler, coords, depth_ref, offset))";
Ben Clayton57166262021-01-13 16:36:51 +00002782 case ValidTextureOverload::kSampleCompareDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002783 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref))";
Ben Clayton57166262021-01-13 16:36:51 +00002784 case ValidTextureOverload::kSampleCompareDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002785 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref, offset))";
Ben Clayton57166262021-01-13 16:36:51 +00002786 case ValidTextureOverload::kSampleCompareDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002787 return R"(textureSampleCompare(texture, sampler, coords, depth_ref))";
Ben Clayton57166262021-01-13 16:36:51 +00002788 case ValidTextureOverload::kSampleCompareDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002789 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref))";
2790 case ValidTextureOverload::kLoad1dF32:
2791 return R"(textureLoad(texture, coords))";
2792 case ValidTextureOverload::kLoad1dU32:
2793 return R"(textureLoad(texture, coords))";
2794 case ValidTextureOverload::kLoad1dI32:
2795 return R"(textureLoad(texture, coords))";
2796 case ValidTextureOverload::kLoad1dArrayF32:
2797 return R"(textureLoad(texture, coords, array_index))";
2798 case ValidTextureOverload::kLoad1dArrayU32:
2799 return R"(textureLoad(texture, coords, array_index))";
2800 case ValidTextureOverload::kLoad1dArrayI32:
2801 return R"(textureLoad(texture, coords, array_index))";
2802 case ValidTextureOverload::kLoad2dF32:
2803 return R"(textureLoad(texture, coords))";
2804 case ValidTextureOverload::kLoad2dU32:
2805 return R"(textureLoad(texture, coords))";
2806 case ValidTextureOverload::kLoad2dI32:
2807 return R"(textureLoad(texture, coords))";
2808 case ValidTextureOverload::kLoad2dLevelF32:
2809 return R"(textureLoad(texture, coords, level))";
2810 case ValidTextureOverload::kLoad2dLevelU32:
2811 return R"(textureLoad(texture, coords, level))";
2812 case ValidTextureOverload::kLoad2dLevelI32:
2813 return R"(textureLoad(texture, coords, level))";
2814 case ValidTextureOverload::kLoad2dArrayF32:
2815 return R"(textureLoad(texture, coords, array_index))";
2816 case ValidTextureOverload::kLoad2dArrayU32:
2817 return R"(textureLoad(texture, coords, array_index))";
2818 case ValidTextureOverload::kLoad2dArrayI32:
2819 return R"(textureLoad(texture, coords, array_index))";
2820 case ValidTextureOverload::kLoad2dArrayLevelF32:
2821 return R"(textureLoad(texture, coords, array_index, level))";
2822 case ValidTextureOverload::kLoad2dArrayLevelU32:
2823 return R"(textureLoad(texture, coords, array_index, level))";
2824 case ValidTextureOverload::kLoad2dArrayLevelI32:
2825 return R"(textureLoad(texture, coords, array_index, level))";
2826 case ValidTextureOverload::kLoad3dF32:
2827 return R"(textureLoad(texture, coords))";
2828 case ValidTextureOverload::kLoad3dU32:
2829 return R"(textureLoad(texture, coords))";
2830 case ValidTextureOverload::kLoad3dI32:
2831 return R"(textureLoad(texture, coords))";
2832 case ValidTextureOverload::kLoad3dLevelF32:
2833 return R"(textureLoad(texture, coords, level))";
2834 case ValidTextureOverload::kLoad3dLevelU32:
2835 return R"(textureLoad(texture, coords, level))";
2836 case ValidTextureOverload::kLoad3dLevelI32:
2837 return R"(textureLoad(texture, coords, level))";
2838 case ValidTextureOverload::kLoadMultisampled2dF32:
2839 return R"(textureLoad(texture, coords, sample_index))";
2840 case ValidTextureOverload::kLoadMultisampled2dU32:
2841 return R"(textureLoad(texture, coords, sample_index))";
2842 case ValidTextureOverload::kLoadMultisampled2dI32:
2843 return R"(textureLoad(texture, coords, sample_index))";
2844 case ValidTextureOverload::kLoadMultisampled2dArrayF32:
2845 return R"(textureLoad(texture, coords, array_index, sample_index))";
2846 case ValidTextureOverload::kLoadMultisampled2dArrayU32:
2847 return R"(textureLoad(texture, coords, array_index, sample_index))";
2848 case ValidTextureOverload::kLoadMultisampled2dArrayI32:
2849 return R"(textureLoad(texture, coords, array_index, sample_index))";
2850 case ValidTextureOverload::kLoadDepth2dF32:
2851 return R"(textureLoad(texture, coords))";
2852 case ValidTextureOverload::kLoadDepth2dLevelF32:
2853 return R"(textureLoad(texture, coords, level))";
2854 case ValidTextureOverload::kLoadDepth2dArrayF32:
2855 return R"(textureLoad(texture, coords, array_index))";
2856 case ValidTextureOverload::kLoadDepth2dArrayLevelF32:
2857 return R"(textureLoad(texture, coords, array_index, level))";
2858 case ValidTextureOverload::kLoadStorageRO1dRgba32float:
2859 return R"(textureLoad(texture, coords))";
2860 case ValidTextureOverload::kLoadStorageRO1dArrayRgba32float:
2861 return R"(textureLoad(texture, coords, array_index))";
2862 case ValidTextureOverload::kLoadStorageRO2dRgba8unorm:
2863 case ValidTextureOverload::kLoadStorageRO2dRgba8snorm:
2864 case ValidTextureOverload::kLoadStorageRO2dRgba8uint:
2865 case ValidTextureOverload::kLoadStorageRO2dRgba8sint:
2866 case ValidTextureOverload::kLoadStorageRO2dRgba16uint:
2867 case ValidTextureOverload::kLoadStorageRO2dRgba16sint:
2868 case ValidTextureOverload::kLoadStorageRO2dRgba16float:
2869 case ValidTextureOverload::kLoadStorageRO2dR32uint:
2870 case ValidTextureOverload::kLoadStorageRO2dR32sint:
2871 case ValidTextureOverload::kLoadStorageRO2dR32float:
2872 case ValidTextureOverload::kLoadStorageRO2dRg32uint:
2873 case ValidTextureOverload::kLoadStorageRO2dRg32sint:
2874 case ValidTextureOverload::kLoadStorageRO2dRg32float:
2875 case ValidTextureOverload::kLoadStorageRO2dRgba32uint:
2876 case ValidTextureOverload::kLoadStorageRO2dRgba32sint:
2877 case ValidTextureOverload::kLoadStorageRO2dRgba32float:
2878 return R"(textureLoad(texture, coords))";
2879 case ValidTextureOverload::kLoadStorageRO2dArrayRgba32float:
2880 return R"(textureLoad(texture, coords, array_index))";
2881 case ValidTextureOverload::kLoadStorageRO3dRgba32float:
2882 return R"(textureLoad(texture, coords))";
Ben Clayton591268d2020-12-10 18:39:41 +00002883 case ValidTextureOverload::kStoreWO1dRgba32float:
2884 return R"(textureStore(texture, coords, value))";
2885 case ValidTextureOverload::kStoreWO1dArrayRgba32float:
2886 return R"(textureStore(texture, coords, array_index, value))";
2887 case ValidTextureOverload::kStoreWO2dRgba32float:
2888 return R"(textureStore(texture, coords, value))";
2889 case ValidTextureOverload::kStoreWO2dArrayRgba32float:
2890 return R"(textureStore(texture, coords, array_index, value))";
2891 case ValidTextureOverload::kStoreWO3dRgba32float:
2892 return R"(textureStore(texture, coords, value))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002893 }
2894 return "<unmatched texture overload>";
2895}
2896
2897TEST_P(TypeDeterminerTextureIntrinsicTest, Call) {
2898 auto param = GetParam();
2899
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002900 param.buildTextureVariable(this);
2901 param.buildSamplerVariable(this);
Ben Clayton3ea3c992020-11-18 21:19:22 +00002902
Ben Claytona51aa1f2021-02-08 21:10:11 +00002903 auto* call = Call(param.function, param.args(this));
Ben Clayton401b96b2021-02-03 17:19:59 +00002904 WrapInFunction(call);
Ben Clayton3ea3c992020-11-18 21:19:22 +00002905
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002906 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton3ea3c992020-11-18 21:19:22 +00002907
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002908 if (std::string(param.function) == "textureDimensions") {
2909 switch (param.texture_dimension) {
2910 default:
2911 FAIL() << "invalid texture dimensions: " << param.texture_dimension;
Ben Clayton207b5e22021-01-21 15:42:10 +00002912 case type::TextureDimension::k1d:
2913 case type::TextureDimension::k1dArray:
Ben Clayton33352542021-01-29 16:43:41 +00002914 EXPECT_EQ(TypeOf(call)->type_name(), ty.i32()->type_name());
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002915 break;
Ben Clayton207b5e22021-01-21 15:42:10 +00002916 case type::TextureDimension::k2d:
2917 case type::TextureDimension::k2dArray:
Ben Clayton33352542021-01-29 16:43:41 +00002918 EXPECT_EQ(TypeOf(call)->type_name(), ty.vec2<i32>()->type_name());
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002919 break;
Ben Clayton207b5e22021-01-21 15:42:10 +00002920 case type::TextureDimension::k3d:
2921 case type::TextureDimension::kCube:
2922 case type::TextureDimension::kCubeArray:
Ben Clayton33352542021-01-29 16:43:41 +00002923 EXPECT_EQ(TypeOf(call)->type_name(), ty.vec3<i32>()->type_name());
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002924 break;
2925 }
Ben Claytonc21f1f92021-01-14 16:50:07 +00002926 } else if (std::string(param.function) == "textureNumLayers") {
Ben Clayton33352542021-01-29 16:43:41 +00002927 EXPECT_EQ(TypeOf(call), ty.i32());
Ben Claytond9713202021-01-14 18:06:57 +00002928 } else if (std::string(param.function) == "textureNumLevels") {
Ben Clayton33352542021-01-29 16:43:41 +00002929 EXPECT_EQ(TypeOf(call), ty.i32());
Ben Clayton0a68b362021-01-14 18:11:17 +00002930 } else if (std::string(param.function) == "textureNumSamples") {
Ben Clayton33352542021-01-29 16:43:41 +00002931 EXPECT_EQ(TypeOf(call), ty.i32());
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002932 } else if (std::string(param.function) == "textureStore") {
Ben Clayton33352542021-01-29 16:43:41 +00002933 EXPECT_EQ(TypeOf(call), ty.void_());
Ben Clayton591268d2020-12-10 18:39:41 +00002934 } else {
2935 switch (param.texture_kind) {
2936 case ast::intrinsic::test::TextureKind::kRegular:
2937 case ast::intrinsic::test::TextureKind::kMultisampled:
2938 case ast::intrinsic::test::TextureKind::kStorage: {
2939 auto* datatype = param.resultVectorComponentType(this);
Ben Clayton33352542021-01-29 16:43:41 +00002940 ASSERT_TRUE(TypeOf(call)->Is<type::Vector>());
2941 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->type(), datatype);
Ben Clayton591268d2020-12-10 18:39:41 +00002942 break;
2943 }
2944 case ast::intrinsic::test::TextureKind::kDepth: {
Ben Clayton33352542021-01-29 16:43:41 +00002945 EXPECT_EQ(TypeOf(call), ty.f32());
Ben Clayton591268d2020-12-10 18:39:41 +00002946 break;
2947 }
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002948 }
Ben Clayton3ea3c992020-11-18 21:19:22 +00002949 }
2950
Ben Clayton316f9f62021-02-08 22:31:44 +00002951 auto* call_sem = Sem().Get(call);
2952 ASSERT_NE(call_sem, nullptr);
2953 auto* target = call_sem->Target();
2954 ASSERT_NE(target, nullptr);
Ben Clayton3ea3c992020-11-18 21:19:22 +00002955
Ben Clayton316f9f62021-02-08 22:31:44 +00002956 auto got = ::tint::to_str(param.function, target->Parameters());
Ben Clayton3ea3c992020-11-18 21:19:22 +00002957 auto* expected = expected_texture_overload(param.overload);
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002958 EXPECT_EQ(got, expected);
Ben Clayton3ea3c992020-11-18 21:19:22 +00002959}
2960
dan sinclairb7edc4c2020-04-07 12:46:30 +00002961} // namespace
2962} // namespace tint