blob: 27a43790d91eb15daf6b7d3094b18cf6444dd3ee [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"
Ben Clayton3ea3c992020-11-18 21:19:22 +000030#include "src/ast/builder.h"
dan sinclair3ca87462020-04-07 16:41:10 +000031#include "src/ast/call_expression.h"
dan sinclair50080b72020-07-21 13:42:13 +000032#include "src/ast/call_statement.h"
dan sinclair6010b292020-04-07 12:54:20 +000033#include "src/ast/case_statement.h"
dan sinclairaec965e2020-04-07 12:54:29 +000034#include "src/ast/continue_statement.h"
dan sinclair0cf685f2020-04-07 12:54:37 +000035#include "src/ast/else_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000036#include "src/ast/float_literal.h"
dan sinclaircab0e732020-04-07 12:57:27 +000037#include "src/ast/identifier_expression.h"
dan sinclair91c44a52020-04-07 12:55:25 +000038#include "src/ast/if_statement.h"
Ben Clayton3ea3c992020-11-18 21:19:22 +000039#include "src/ast/intrinsic_texture_helper_test.h"
dan sinclairbc71eda2020-04-07 12:55:51 +000040#include "src/ast/loop_statement.h"
dan sinclair8ee1d222020-04-07 16:41:33 +000041#include "src/ast/member_accessor_expression.h"
dan sinclair05926432020-09-21 17:51:31 +000042#include "src/ast/pipeline_stage.h"
dan sinclairbf0fff82020-04-07 12:56:24 +000043#include "src/ast/return_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000044#include "src/ast/scalar_constructor_expression.h"
dan sinclairc6f29472020-06-02 20:11:44 +000045#include "src/ast/sint_literal.h"
dan sinclair05926432020-09-21 17:51:31 +000046#include "src/ast/stage_decoration.h"
dan sinclair8ee1d222020-04-07 16:41:33 +000047#include "src/ast/struct.h"
48#include "src/ast/struct_member.h"
dan sinclair18b32852020-04-07 12:56:45 +000049#include "src/ast/switch_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000050#include "src/ast/type_constructor_expression.h"
dan sinclair92bb5572020-06-08 23:48:07 +000051#include "src/ast/uint_literal.h"
dan sinclair327ed1b2020-04-07 19:27:21 +000052#include "src/ast/unary_op_expression.h"
dan sinclairca893e32020-04-07 12:57:12 +000053#include "src/ast/variable_decl_statement.h"
Ben Clayton207b5e22021-01-21 15:42:10 +000054#include "src/type/alias_type.h"
55#include "src/type/array_type.h"
56#include "src/type/bool_type.h"
57#include "src/type/depth_texture_type.h"
58#include "src/type/f32_type.h"
59#include "src/type/i32_type.h"
60#include "src/type/matrix_type.h"
61#include "src/type/multisampled_texture_type.h"
62#include "src/type/pointer_type.h"
63#include "src/type/sampled_texture_type.h"
64#include "src/type/sampler_type.h"
65#include "src/type/storage_texture_type.h"
66#include "src/type/struct_type.h"
67#include "src/type/texture_type.h"
68#include "src/type/u32_type.h"
69#include "src/type/vector_type.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000070
71namespace tint {
72namespace {
73
dan sinclair7456f422020-04-08 19:58:35 +000074class FakeStmt : public ast::Statement {
75 public:
Ben Clayton604bc722020-12-12 01:24:53 +000076 explicit FakeStmt(Source source) : ast::Statement(source) {}
Ben Clayton1e29f4b2021-01-21 16:20:40 +000077 FakeStmt* Clone(CloneContext*) const override { return nullptr; }
dan sinclair7456f422020-04-08 19:58:35 +000078 bool IsValid() const override { return true; }
dan sinclair0975dd52020-07-27 15:25:00 +000079 void to_str(std::ostream& out, size_t) const override { out << "Fake"; }
dan sinclair7456f422020-04-08 19:58:35 +000080};
81
82class FakeExpr : public ast::Expression {
83 public:
Ben Clayton604bc722020-12-12 01:24:53 +000084 explicit FakeExpr(Source source) : ast::Expression(source) {}
Ben Clayton1e29f4b2021-01-21 16:20:40 +000085 FakeExpr* Clone(CloneContext*) const override { return nullptr; }
dan sinclair7456f422020-04-08 19:58:35 +000086 bool IsValid() const override { return true; }
87 void to_str(std::ostream&, size_t) const override {}
88};
89
dan sinclair685cb022020-12-02 21:17:58 +000090class TypeDeterminerHelper : public ast::BuilderWithModule {
dan sinclairb7edc4c2020-04-07 12:46:30 +000091 public:
dan sinclair685cb022020-12-02 21:17:58 +000092 TypeDeterminerHelper() : td_(std::make_unique<TypeDeterminer>(mod)) {}
dan sinclairb7edc4c2020-04-07 12:46:30 +000093
94 TypeDeterminer* td() const { return td_.get(); }
Ben Clayton62625922020-11-13 22:09:38 +000095
dan sinclairb7edc4c2020-04-07 12:46:30 +000096 private:
Ben Clayton3ea3c992020-11-18 21:19:22 +000097 void OnVariableBuilt(ast::Variable* var) override {
98 td_->RegisterVariableForTesting(var);
99 }
100
dan sinclairb7edc4c2020-04-07 12:46:30 +0000101 std::unique_ptr<TypeDeterminer> td_;
102};
103
dan sinclaircd077b02020-04-20 14:19:04 +0000104class TypeDeterminerTest : public TypeDeterminerHelper, public testing::Test {};
105
106template <typename T>
107class TypeDeterminerTestWithParam : public TypeDeterminerHelper,
108 public testing::TestWithParam<T> {};
109
dan sinclair7456f422020-04-08 19:58:35 +0000110TEST_F(TypeDeterminerTest, Error_WithEmptySource) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000111 auto* s = create<FakeStmt>();
dan sinclair7456f422020-04-08 19:58:35 +0000112
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000113 EXPECT_FALSE(td()->DetermineResultType(s));
dan sinclair0975dd52020-07-27 15:25:00 +0000114 EXPECT_EQ(td()->error(),
115 "unknown statement type for type determination: Fake");
dan sinclair7456f422020-04-08 19:58:35 +0000116}
117
118TEST_F(TypeDeterminerTest, Stmt_Error_Unknown) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000119 auto* s = create<FakeStmt>(Source{Source::Location{2, 30}});
dan sinclair7456f422020-04-08 19:58:35 +0000120
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000121 EXPECT_FALSE(td()->DetermineResultType(s));
dan sinclair7456f422020-04-08 19:58:35 +0000122 EXPECT_EQ(td()->error(),
dan sinclair0975dd52020-07-27 15:25:00 +0000123 "2:30: unknown statement type for type determination: Fake");
dan sinclair7456f422020-04-08 19:58:35 +0000124}
125
dan sinclair6c498fc2020-04-07 12:47:23 +0000126TEST_F(TypeDeterminerTest, Stmt_Assign) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000127 auto* lhs = Expr(2);
128 auto* rhs = Expr(2.3f);
dan sinclair6c498fc2020-04-07 12:47:23 +0000129
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000130 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
dan sinclair6c498fc2020-04-07 12:47:23 +0000131
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000132 EXPECT_TRUE(td()->DetermineResultType(assign));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000133 ASSERT_NE(lhs->result_type(), nullptr);
134 ASSERT_NE(rhs->result_type(), nullptr);
dan sinclair6c498fc2020-04-07 12:47:23 +0000135
Ben Clayton207b5e22021-01-21 15:42:10 +0000136 EXPECT_TRUE(lhs->result_type()->Is<type::I32>());
137 EXPECT_TRUE(rhs->result_type()->Is<type::F32>());
dan sinclair6c498fc2020-04-07 12:47:23 +0000138}
139
dan sinclair6010b292020-04-07 12:54:20 +0000140TEST_F(TypeDeterminerTest, Stmt_Case) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000141 auto* lhs = Expr(2);
142 auto* rhs = Expr(2.3f);
dan sinclair6010b292020-04-07 12:54:20 +0000143
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000144 auto* body = create<ast::BlockStatement>(ast::StatementList{
145 create<ast::AssignmentStatement>(lhs, rhs),
146 });
dan sinclair1aadbd42020-06-01 16:56:46 +0000147 ast::CaseSelectorList lit;
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000148 lit.push_back(create<ast::SintLiteral>(ty.i32, 3));
149 auto* cse = create<ast::CaseStatement>(lit, body);
dan sinclair6010b292020-04-07 12:54:20 +0000150
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000151 EXPECT_TRUE(td()->DetermineResultType(cse));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000152 ASSERT_NE(lhs->result_type(), nullptr);
153 ASSERT_NE(rhs->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000154 EXPECT_TRUE(lhs->result_type()->Is<type::I32>());
155 EXPECT_TRUE(rhs->result_type()->Is<type::F32>());
dan sinclair6010b292020-04-07 12:54:20 +0000156}
157
dan sinclair0975dd52020-07-27 15:25:00 +0000158TEST_F(TypeDeterminerTest, Stmt_Block) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000159 auto* lhs = Expr(2);
160 auto* rhs = Expr(2.3f);
dan sinclair0975dd52020-07-27 15:25:00 +0000161
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000162 auto* block = create<ast::BlockStatement>(ast::StatementList{
163 create<ast::AssignmentStatement>(lhs, rhs),
164 });
dan sinclair0975dd52020-07-27 15:25:00 +0000165
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000166 EXPECT_TRUE(td()->DetermineResultType(block));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000167 ASSERT_NE(lhs->result_type(), nullptr);
168 ASSERT_NE(rhs->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000169 EXPECT_TRUE(lhs->result_type()->Is<type::I32>());
170 EXPECT_TRUE(rhs->result_type()->Is<type::F32>());
dan sinclair0975dd52020-07-27 15:25:00 +0000171}
172
dan sinclair0cf685f2020-04-07 12:54:37 +0000173TEST_F(TypeDeterminerTest, Stmt_Else) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000174 auto* lhs = Expr(2);
175 auto* rhs = Expr(2.3f);
dan sinclair0cf685f2020-04-07 12:54:37 +0000176
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000177 auto* body = create<ast::BlockStatement>(ast::StatementList{
178 create<ast::AssignmentStatement>(lhs, rhs),
179 });
180 auto* stmt = create<ast::ElseStatement>(Expr(3), body);
dan sinclair0cf685f2020-04-07 12:54:37 +0000181
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000182 EXPECT_TRUE(td()->DetermineResultType(stmt));
183 ASSERT_NE(stmt->condition()->result_type(), nullptr);
Ben Clayton4bfe4612020-11-16 16:41:47 +0000184 ASSERT_NE(lhs->result_type(), nullptr);
185 ASSERT_NE(rhs->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000186 EXPECT_TRUE(stmt->condition()->result_type()->Is<type::I32>());
187 EXPECT_TRUE(lhs->result_type()->Is<type::I32>());
188 EXPECT_TRUE(rhs->result_type()->Is<type::F32>());
dan sinclair0cf685f2020-04-07 12:54:37 +0000189}
190
dan sinclair91c44a52020-04-07 12:55:25 +0000191TEST_F(TypeDeterminerTest, Stmt_If) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000192 auto* else_lhs = Expr(2);
193 auto* else_rhs = Expr(2.3f);
dan sinclair91c44a52020-04-07 12:55:25 +0000194
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000195 auto* else_body = create<ast::BlockStatement>(ast::StatementList{
196 create<ast::AssignmentStatement>(else_lhs, else_rhs),
197 });
dan sinclair91c44a52020-04-07 12:55:25 +0000198
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000199 auto* else_stmt = create<ast::ElseStatement>(Expr(3), else_body);
dan sinclair91c44a52020-04-07 12:55:25 +0000200
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000201 auto* lhs = Expr(2);
202 auto* rhs = Expr(2.3f);
dan sinclair91c44a52020-04-07 12:55:25 +0000203
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000204 auto* body = create<ast::BlockStatement>(ast::StatementList{
205 create<ast::AssignmentStatement>(lhs, rhs),
206 });
207 auto* stmt = create<ast::IfStatement>(Expr(3), body,
208 ast::ElseStatementList{else_stmt});
dan sinclair91c44a52020-04-07 12:55:25 +0000209
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000210 EXPECT_TRUE(td()->DetermineResultType(stmt));
211 ASSERT_NE(stmt->condition()->result_type(), nullptr);
Ben Clayton4bfe4612020-11-16 16:41:47 +0000212 ASSERT_NE(else_lhs->result_type(), nullptr);
213 ASSERT_NE(else_rhs->result_type(), nullptr);
214 ASSERT_NE(lhs->result_type(), nullptr);
215 ASSERT_NE(rhs->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000216 EXPECT_TRUE(stmt->condition()->result_type()->Is<type::I32>());
217 EXPECT_TRUE(else_lhs->result_type()->Is<type::I32>());
218 EXPECT_TRUE(else_rhs->result_type()->Is<type::F32>());
219 EXPECT_TRUE(lhs->result_type()->Is<type::I32>());
220 EXPECT_TRUE(rhs->result_type()->Is<type::F32>());
dan sinclair91c44a52020-04-07 12:55:25 +0000221}
222
dan sinclairbc71eda2020-04-07 12:55:51 +0000223TEST_F(TypeDeterminerTest, Stmt_Loop) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000224 auto* body_lhs = Expr(2);
225 auto* body_rhs = Expr(2.3f);
dan sinclairbc71eda2020-04-07 12:55:51 +0000226
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000227 auto* body = create<ast::BlockStatement>(ast::StatementList{
228 create<ast::AssignmentStatement>(body_lhs, body_rhs),
229 });
230 auto* continuing_lhs = Expr(2);
231 auto* continuing_rhs = Expr(2.3f);
dan sinclairbc71eda2020-04-07 12:55:51 +0000232
Ben Claytondb5ce652020-12-14 20:25:27 +0000233 auto* continuing = create<ast::BlockStatement>(
dan sinclairbc71eda2020-04-07 12:55:51 +0000234
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000235 ast::StatementList{
236 create<ast::AssignmentStatement>(continuing_lhs, continuing_rhs),
237 });
238 auto* stmt = create<ast::LoopStatement>(body, continuing);
239
240 EXPECT_TRUE(td()->DetermineResultType(stmt));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000241 ASSERT_NE(body_lhs->result_type(), nullptr);
242 ASSERT_NE(body_rhs->result_type(), nullptr);
243 ASSERT_NE(continuing_lhs->result_type(), nullptr);
244 ASSERT_NE(continuing_rhs->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000245 EXPECT_TRUE(body_lhs->result_type()->Is<type::I32>());
246 EXPECT_TRUE(body_rhs->result_type()->Is<type::F32>());
247 EXPECT_TRUE(continuing_lhs->result_type()->Is<type::I32>());
248 EXPECT_TRUE(continuing_rhs->result_type()->Is<type::F32>());
dan sinclairbc71eda2020-04-07 12:55:51 +0000249}
250
dan sinclairbf0fff82020-04-07 12:56:24 +0000251TEST_F(TypeDeterminerTest, Stmt_Return) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000252 auto* cond = Expr(2);
dan sinclairbf0fff82020-04-07 12:56:24 +0000253
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000254 auto* ret = create<ast::ReturnStatement>(cond);
dan sinclairbf0fff82020-04-07 12:56:24 +0000255
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000256 EXPECT_TRUE(td()->DetermineResultType(ret));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000257 ASSERT_NE(cond->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000258 EXPECT_TRUE(cond->result_type()->Is<type::I32>());
dan sinclairbf0fff82020-04-07 12:56:24 +0000259}
260
dan sinclair327ed1b2020-04-07 19:27:21 +0000261TEST_F(TypeDeterminerTest, Stmt_Return_WithoutValue) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000262 auto* ret = create<ast::ReturnStatement>();
263 EXPECT_TRUE(td()->DetermineResultType(ret));
dan sinclair327ed1b2020-04-07 19:27:21 +0000264}
265
dan sinclair18b32852020-04-07 12:56:45 +0000266TEST_F(TypeDeterminerTest, Stmt_Switch) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000267 auto* lhs = Expr(2);
268 auto* rhs = Expr(2.3f);
dan sinclair18b32852020-04-07 12:56:45 +0000269
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000270 auto* body = create<ast::BlockStatement>(ast::StatementList{
271 create<ast::AssignmentStatement>(lhs, rhs),
272 });
dan sinclair1aadbd42020-06-01 16:56:46 +0000273 ast::CaseSelectorList lit;
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000274 lit.push_back(create<ast::SintLiteral>(ty.i32, 3));
dan sinclair1aadbd42020-06-01 16:56:46 +0000275
dan sinclair18b32852020-04-07 12:56:45 +0000276 ast::CaseStatementList cases;
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000277 cases.push_back(create<ast::CaseStatement>(lit, body));
dan sinclair18b32852020-04-07 12:56:45 +0000278
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000279 auto* stmt = create<ast::SwitchStatement>(Expr(2), cases);
dan sinclair18b32852020-04-07 12:56:45 +0000280
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000281 EXPECT_TRUE(td()->DetermineResultType(stmt)) << td()->error();
282 ASSERT_NE(stmt->condition()->result_type(), nullptr);
Ben Clayton4bfe4612020-11-16 16:41:47 +0000283 ASSERT_NE(lhs->result_type(), nullptr);
284 ASSERT_NE(rhs->result_type(), nullptr);
dan sinclair18b32852020-04-07 12:56:45 +0000285
Ben Clayton207b5e22021-01-21 15:42:10 +0000286 EXPECT_TRUE(stmt->condition()->result_type()->Is<type::I32>());
287 EXPECT_TRUE(lhs->result_type()->Is<type::I32>());
288 EXPECT_TRUE(rhs->result_type()->Is<type::F32>());
dan sinclair18b32852020-04-07 12:56:45 +0000289}
290
dan sinclair50080b72020-07-21 13:42:13 +0000291TEST_F(TypeDeterminerTest, Stmt_Call) {
dan sinclair50080b72020-07-21 13:42:13 +0000292 ast::VariableList params;
dan sinclair181d8ba2020-12-16 15:15:40 +0000293 auto* func = Func("my_func", params, ty.f32, ast::StatementList{},
294 ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000295 mod->AddFunction(func);
dan sinclair50080b72020-07-21 13:42:13 +0000296
297 // Register the function
298 EXPECT_TRUE(td()->Determine());
299
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000300 auto* expr = Call("my_func");
dan sinclair50080b72020-07-21 13:42:13 +0000301
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000302 auto* call = create<ast::CallStatement>(expr);
303 EXPECT_TRUE(td()->DetermineResultType(call));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000304 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000305 EXPECT_TRUE(expr->result_type()->Is<type::F32>());
dan sinclair50080b72020-07-21 13:42:13 +0000306}
307
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000308TEST_F(TypeDeterminerTest, Stmt_Call_undeclared) {
309 // fn main() -> void {func(); return; }
310 // fn func() -> void { return; }
Ben Claytondb5ce652020-12-14 20:25:27 +0000311
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000312 SetSource(Source::Location{12, 34});
313 auto* call_expr = Call("func");
314 ast::VariableList params0;
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000315
dan sinclair181d8ba2020-12-16 15:15:40 +0000316 auto* func_main = Func("main", params0, ty.f32,
317 ast::StatementList{
318 create<ast::CallStatement>(call_expr),
319 create<ast::ReturnStatement>(),
320 },
321 ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000322 mod->AddFunction(func_main);
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000323
dan sinclair181d8ba2020-12-16 15:15:40 +0000324 auto* func = Func("func", params0, ty.f32,
325 ast::StatementList{
326 create<ast::ReturnStatement>(),
327 },
328 ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000329 mod->AddFunction(func);
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000330
331 EXPECT_FALSE(td()->Determine()) << td()->error();
332 EXPECT_EQ(td()->error(),
dan sinclairff267ca2020-10-14 18:26:31 +0000333 "12:34: v-0006: identifier must be declared before use: func");
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000334}
335
dan sinclairca893e32020-04-07 12:57:12 +0000336TEST_F(TypeDeterminerTest, Stmt_VariableDecl) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000337 auto* var = Var("my_var", ast::StorageClass::kNone, ty.i32, Expr(2),
338 ast::VariableDecorationList{});
Ben Clayton4bfe4612020-11-16 16:41:47 +0000339 auto* init = var->constructor();
dan sinclairca893e32020-04-07 12:57:12 +0000340
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000341 auto* decl = create<ast::VariableDeclStatement>(var);
dan sinclairca893e32020-04-07 12:57:12 +0000342
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000343 EXPECT_TRUE(td()->DetermineResultType(decl));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000344 ASSERT_NE(init->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000345 EXPECT_TRUE(init->result_type()->Is<type::I32>());
dan sinclairca893e32020-04-07 12:57:12 +0000346}
347
dan sinclair7be237a2020-06-15 20:55:09 +0000348TEST_F(TypeDeterminerTest, Stmt_VariableDecl_ModuleScope) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000349 auto* var = Var("my_var", ast::StorageClass::kNone, ty.i32, Expr(2),
350 ast::VariableDecorationList{});
Ben Clayton4bfe4612020-11-16 16:41:47 +0000351 auto* init = var->constructor();
dan sinclair7be237a2020-06-15 20:55:09 +0000352
Ben Clayton3ea3c992020-11-18 21:19:22 +0000353 mod->AddGlobalVariable(var);
dan sinclair7be237a2020-06-15 20:55:09 +0000354
355 EXPECT_TRUE(td()->Determine());
Ben Clayton4bfe4612020-11-16 16:41:47 +0000356 ASSERT_NE(init->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000357 EXPECT_TRUE(init->result_type()->Is<type::I32>());
dan sinclair7be237a2020-06-15 20:55:09 +0000358}
359
dan sinclair7456f422020-04-08 19:58:35 +0000360TEST_F(TypeDeterminerTest, Expr_Error_Unknown) {
Ben Clayton604bc722020-12-12 01:24:53 +0000361 FakeExpr e(Source{Source::Location{2, 30}});
dan sinclair7456f422020-04-08 19:58:35 +0000362
363 EXPECT_FALSE(td()->DetermineResultType(&e));
364 EXPECT_EQ(td()->error(), "2:30: unknown expression for type determination");
365}
366
dan sinclair973bd6a2020-04-07 12:57:42 +0000367TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000368 auto* idx = Expr(2);
Ben Clayton1637cbb2021-01-05 15:44:39 +0000369 auto* var = Var("my_var", ast::StorageClass::kFunction, ty.array<f32, 3>());
Ben Clayton3ea3c992020-11-18 21:19:22 +0000370 mod->AddGlobalVariable(var);
dan sinclair8eddb782020-04-23 22:26:52 +0000371
dan sinclair8eddb782020-04-23 22:26:52 +0000372 EXPECT_TRUE(td()->Determine());
373
dan sinclair8b40a672020-12-16 11:49:10 +0000374 auto* acc = IndexAccessor("my_var", idx);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000375 EXPECT_TRUE(td()->DetermineResultType(acc));
376 ASSERT_NE(acc->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000377 ASSERT_TRUE(acc->result_type()->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000378
Ben Clayton207b5e22021-01-21 15:42:10 +0000379 auto* ptr = acc->result_type()->As<type::Pointer>();
380 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000381}
382
David Neto9c88ea52020-06-22 20:33:12 +0000383TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Alias_Array) {
Ben Clayton1637cbb2021-01-05 15:44:39 +0000384 auto* aary = ty.alias("myarrty", ty.array<f32, 3>());
David Neto9c88ea52020-06-22 20:33:12 +0000385
dan sinclairb5839932020-12-16 21:38:40 +0000386 mod->AddGlobalVariable(Var("my_var", ast::StorageClass::kFunction, aary));
David Neto9c88ea52020-06-22 20:33:12 +0000387
David Neto9c88ea52020-06-22 20:33:12 +0000388 EXPECT_TRUE(td()->Determine());
389
dan sinclair8b40a672020-12-16 11:49:10 +0000390 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000391 EXPECT_TRUE(td()->DetermineResultType(acc));
392 ASSERT_NE(acc->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000393 ASSERT_TRUE(acc->result_type()->Is<type::Pointer>());
David Neto9c88ea52020-06-22 20:33:12 +0000394
Ben Clayton207b5e22021-01-21 15:42:10 +0000395 auto* ptr = acc->result_type()->As<type::Pointer>();
396 EXPECT_TRUE(ptr->type()->Is<type::F32>());
David Neto9c88ea52020-06-22 20:33:12 +0000397}
398
dan sinclair8eddb782020-04-23 22:26:52 +0000399TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array_Constant) {
Ben Clayton1637cbb2021-01-05 15:44:39 +0000400 auto* var = Const("my_var", ast::StorageClass::kFunction, ty.array<f32, 3>());
Ben Clayton3ea3c992020-11-18 21:19:22 +0000401 mod->AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000402
dan sinclairb950e802020-04-20 14:20:01 +0000403 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000404
dan sinclair8b40a672020-12-16 11:49:10 +0000405 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000406 EXPECT_TRUE(td()->DetermineResultType(acc));
407 ASSERT_NE(acc->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000408 EXPECT_TRUE(acc->result_type()->Is<type::F32>())
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000409 << acc->result_type()->type_name();
dan sinclair973bd6a2020-04-07 12:57:42 +0000410}
411
412TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix) {
Ben Clayton1637cbb2021-01-05 15:44:39 +0000413 auto* var = Var("my_var", ast::StorageClass::kNone, ty.mat2x3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +0000414 mod->AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000415
dan sinclairb950e802020-04-20 14:20:01 +0000416 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000417
dan sinclair8b40a672020-12-16 11:49:10 +0000418 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000419 EXPECT_TRUE(td()->DetermineResultType(acc));
420 ASSERT_NE(acc->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000421 ASSERT_TRUE(acc->result_type()->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000422
Ben Clayton207b5e22021-01-21 15:42:10 +0000423 auto* ptr = acc->result_type()->As<type::Pointer>();
424 ASSERT_TRUE(ptr->type()->Is<type::Vector>());
425 EXPECT_EQ(ptr->type()->As<type::Vector>()->size(), 3u);
dan sinclair973bd6a2020-04-07 12:57:42 +0000426}
427
428TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix_BothDimensions) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000429 auto* var = Var("my_var", ast::StorageClass::kNone, ty.mat2x3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +0000430 mod->AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000431
dan sinclairb950e802020-04-20 14:20:01 +0000432 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000433
dan sinclair8b40a672020-12-16 11:49:10 +0000434 auto* acc = IndexAccessor(IndexAccessor("my_var", 2), 1);
dan sinclair973bd6a2020-04-07 12:57:42 +0000435
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000436 EXPECT_TRUE(td()->DetermineResultType(acc));
437 ASSERT_NE(acc->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000438 ASSERT_TRUE(acc->result_type()->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000439
Ben Clayton207b5e22021-01-21 15:42:10 +0000440 auto* ptr = acc->result_type()->As<type::Pointer>();
441 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000442}
443
444TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Vector) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000445 auto* var = Var("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +0000446 mod->AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000447
dan sinclairb950e802020-04-20 14:20:01 +0000448 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000449
dan sinclair8b40a672020-12-16 11:49:10 +0000450 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000451 EXPECT_TRUE(td()->DetermineResultType(acc));
452 ASSERT_NE(acc->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000453 ASSERT_TRUE(acc->result_type()->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000454
Ben Clayton207b5e22021-01-21 15:42:10 +0000455 auto* ptr = acc->result_type()->As<type::Pointer>();
456 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000457}
458
dan sinclaira7d498e2020-09-22 22:07:13 +0000459TEST_F(TypeDeterminerTest, Expr_Bitcast) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000460 auto* bitcast = create<ast::BitcastExpression>(ty.f32, Expr("name"));
dan sinclaira01777c2020-04-07 12:57:52 +0000461
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000462 auto* v = Var("name", ast::StorageClass::kPrivate, ty.f32);
463 td()->RegisterVariableForTesting(v);
dan sinclairff267ca2020-10-14 18:26:31 +0000464
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000465 EXPECT_TRUE(td()->DetermineResultType(bitcast));
466 ASSERT_NE(bitcast->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000467 EXPECT_TRUE(bitcast->result_type()->Is<type::F32>());
dan sinclaira01777c2020-04-07 12:57:52 +0000468}
469
dan sinclair3ca87462020-04-07 16:41:10 +0000470TEST_F(TypeDeterminerTest, Expr_Call) {
dan sinclair3ca87462020-04-07 16:41:10 +0000471 ast::VariableList params;
dan sinclair181d8ba2020-12-16 15:15:40 +0000472 auto* func = Func("my_func", params, ty.f32, ast::StatementList{},
473 ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000474 mod->AddFunction(func);
dan sinclair3ca87462020-04-07 16:41:10 +0000475
476 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000477 EXPECT_TRUE(td()->Determine());
dan sinclair3ca87462020-04-07 16:41:10 +0000478
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000479 auto* call = Call("my_func");
480 EXPECT_TRUE(td()->DetermineResultType(call));
481 ASSERT_NE(call->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000482 EXPECT_TRUE(call->result_type()->Is<type::F32>());
dan sinclair3ca87462020-04-07 16:41:10 +0000483}
484
dan sinclairccb52dc2020-04-20 14:18:54 +0000485TEST_F(TypeDeterminerTest, Expr_Call_WithParams) {
dan sinclairccb52dc2020-04-20 14:18:54 +0000486 ast::VariableList params;
dan sinclair181d8ba2020-12-16 15:15:40 +0000487 auto* func = Func("my_func", params, ty.f32, ast::StatementList{},
488 ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000489 mod->AddFunction(func);
dan sinclairccb52dc2020-04-20 14:18:54 +0000490
491 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000492 EXPECT_TRUE(td()->Determine());
dan sinclairccb52dc2020-04-20 14:18:54 +0000493
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000494 auto* param = Expr(2.4f);
dan sinclairccb52dc2020-04-20 14:18:54 +0000495
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000496 auto* call = Call("my_func", param);
497 EXPECT_TRUE(td()->DetermineResultType(call));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000498 ASSERT_NE(param->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000499 EXPECT_TRUE(param->result_type()->Is<type::F32>());
dan sinclairccb52dc2020-04-20 14:18:54 +0000500}
501
dan sinclairb4fee2f2020-09-22 19:42:13 +0000502TEST_F(TypeDeterminerTest, Expr_Call_Intrinsic) {
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000503 // Register the function
504 EXPECT_TRUE(td()->Determine());
505
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000506 auto* call = Call("round", 2.4f);
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000507
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000508 EXPECT_TRUE(td()->DetermineResultType(call));
509 ASSERT_NE(call->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000510 EXPECT_TRUE(call->result_type()->Is<type::F32>());
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000511}
512
dan sinclair4e807952020-04-07 16:41:23 +0000513TEST_F(TypeDeterminerTest, Expr_Cast) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000514 auto* cast = Construct(ty.f32, "name");
dan sinclair3c025922020-09-24 14:38:44 +0000515
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000516 auto* v = Var("name", ast::StorageClass::kPrivate, ty.f32);
517 td()->RegisterVariableForTesting(v);
dan sinclair4e807952020-04-07 16:41:23 +0000518
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000519 EXPECT_TRUE(td()->DetermineResultType(cast));
520 ASSERT_NE(cast->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000521 EXPECT_TRUE(cast->result_type()->Is<type::F32>());
dan sinclair4e807952020-04-07 16:41:23 +0000522}
523
dan sinclairb7edc4c2020-04-07 12:46:30 +0000524TEST_F(TypeDeterminerTest, Expr_Constructor_Scalar) {
Ben Clayton1637cbb2021-01-05 15:44:39 +0000525 auto* s = Expr(1.0f);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000526 EXPECT_TRUE(td()->DetermineResultType(s));
527 ASSERT_NE(s->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000528 EXPECT_TRUE(s->result_type()->Is<type::F32>());
dan sinclairb7edc4c2020-04-07 12:46:30 +0000529}
530
531TEST_F(TypeDeterminerTest, Expr_Constructor_Type) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000532 auto* tc = vec3<f32>(1.0f, 1.0f, 3.0f);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000533
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000534 EXPECT_TRUE(td()->DetermineResultType(tc));
535 ASSERT_NE(tc->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000536 ASSERT_TRUE(tc->result_type()->Is<type::Vector>());
537 EXPECT_TRUE(tc->result_type()->As<type::Vector>()->type()->Is<type::F32>());
538 EXPECT_EQ(tc->result_type()->As<type::Vector>()->size(), 3u);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000539}
540
dan sinclaircab0e732020-04-07 12:57:27 +0000541TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalVariable) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000542 auto* var = Var("my_var", ast::StorageClass::kNone, ty.f32);
Ben Clayton3ea3c992020-11-18 21:19:22 +0000543 mod->AddGlobalVariable(var);
dan sinclaircab0e732020-04-07 12:57:27 +0000544
dan sinclairb950e802020-04-20 14:20:01 +0000545 EXPECT_TRUE(td()->Determine());
dan sinclaircab0e732020-04-07 12:57:27 +0000546
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000547 auto* ident = Expr("my_var");
548 EXPECT_TRUE(td()->DetermineResultType(ident));
549 ASSERT_NE(ident->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000550 EXPECT_TRUE(ident->result_type()->Is<type::Pointer>());
551 EXPECT_TRUE(
552 ident->result_type()->As<type::Pointer>()->type()->Is<type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000553}
554
555TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalConstant) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000556 mod->AddGlobalVariable(Const("my_var", ast::StorageClass::kNone, ty.f32));
dan sinclair8eddb782020-04-23 22:26:52 +0000557
dan sinclair8eddb782020-04-23 22:26:52 +0000558 EXPECT_TRUE(td()->Determine());
559
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000560 auto* ident = Expr("my_var");
561 EXPECT_TRUE(td()->DetermineResultType(ident));
562 ASSERT_NE(ident->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000563 EXPECT_TRUE(ident->result_type()->Is<type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000564}
565
dan sinclair8eddb782020-04-23 22:26:52 +0000566TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable_Const) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000567 auto* my_var = Expr("my_var");
dan sinclair8eddb782020-04-23 22:26:52 +0000568
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000569 auto* var = Const("my_var", ast::StorageClass::kNone, ty.f32);
dan sinclair8eddb782020-04-23 22:26:52 +0000570
dan sinclair181d8ba2020-12-16 15:15:40 +0000571 auto* f = Func("my_func", ast::VariableList{}, ty.f32,
572 ast::StatementList{
573 create<ast::VariableDeclStatement>(var),
574 create<ast::AssignmentStatement>(my_var, Expr("my_var")),
575 },
576 ast::FunctionDecorationList{});
dan sinclair8eddb782020-04-23 22:26:52 +0000577
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000578 EXPECT_TRUE(td()->DetermineFunction(f));
dan sinclair8eddb782020-04-23 22:26:52 +0000579
Ben Clayton4bfe4612020-11-16 16:41:47 +0000580 ASSERT_NE(my_var->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000581 EXPECT_TRUE(my_var->result_type()->Is<type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000582}
583
dan sinclaircab0e732020-04-07 12:57:27 +0000584TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000585 auto* my_var = Expr("my_var");
dan sinclaircab0e732020-04-07 12:57:27 +0000586
dan sinclair181d8ba2020-12-16 15:15:40 +0000587 auto* f = Func("my_func", ast::VariableList{}, ty.f32,
588 ast::StatementList{
589 create<ast::VariableDeclStatement>(
590 Var("my_var", ast::StorageClass::kNone, ty.f32)),
591 create<ast::AssignmentStatement>(my_var, Expr("my_var")),
592 },
593 ast::FunctionDecorationList{});
dan sinclaircab0e732020-04-07 12:57:27 +0000594
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000595 EXPECT_TRUE(td()->DetermineFunction(f));
dan sinclaircab0e732020-04-07 12:57:27 +0000596
Ben Clayton4bfe4612020-11-16 16:41:47 +0000597 ASSERT_NE(my_var->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000598 EXPECT_TRUE(my_var->result_type()->Is<type::Pointer>());
599 EXPECT_TRUE(
600 my_var->result_type()->As<type::Pointer>()->type()->Is<type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000601}
602
dan sinclair5e989302020-09-16 21:20:36 +0000603TEST_F(TypeDeterminerTest, Expr_Identifier_Function_Ptr) {
Ben Clayton207b5e22021-01-21 15:42:10 +0000604 type::Pointer ptr(ty.f32, ast::StorageClass::kFunction);
dan sinclair5e989302020-09-16 21:20:36 +0000605
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000606 auto* my_var = Expr("my_var");
dan sinclair5e989302020-09-16 21:20:36 +0000607
dan sinclair181d8ba2020-12-16 15:15:40 +0000608 auto* f = Func("my_func", ast::VariableList{}, ty.f32,
609 ast::StatementList{
610 create<ast::VariableDeclStatement>(
611 Var("my_var", ast::StorageClass::kNone, &ptr)),
612 create<ast::AssignmentStatement>(my_var, Expr("my_var")),
613 },
614 ast::FunctionDecorationList{});
dan sinclair5e989302020-09-16 21:20:36 +0000615
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000616 EXPECT_TRUE(td()->DetermineFunction(f));
dan sinclair5e989302020-09-16 21:20:36 +0000617
Ben Clayton4bfe4612020-11-16 16:41:47 +0000618 ASSERT_NE(my_var->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000619 EXPECT_TRUE(my_var->result_type()->Is<type::Pointer>());
620 EXPECT_TRUE(
621 my_var->result_type()->As<type::Pointer>()->type()->Is<type::F32>());
dan sinclair5e989302020-09-16 21:20:36 +0000622}
623
dan sinclaircab0e732020-04-07 12:57:27 +0000624TEST_F(TypeDeterminerTest, Expr_Identifier_Function) {
dan sinclair181d8ba2020-12-16 15:15:40 +0000625 auto* func = Func("my_func", ast::VariableList{}, ty.f32,
626 ast::StatementList{}, ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000627 mod->AddFunction(func);
dan sinclaircab0e732020-04-07 12:57:27 +0000628
629 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000630 EXPECT_TRUE(td()->Determine());
dan sinclaircab0e732020-04-07 12:57:27 +0000631
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000632 auto* ident = Expr("my_func");
633 EXPECT_TRUE(td()->DetermineResultType(ident));
634 ASSERT_NE(ident->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000635 EXPECT_TRUE(ident->result_type()->Is<type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000636}
637
dan sinclairff267ca2020-10-14 18:26:31 +0000638TEST_F(TypeDeterminerTest, Expr_Identifier_Unknown) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000639 auto* a = Expr("a");
640 EXPECT_FALSE(td()->DetermineResultType(a));
dan sinclairff267ca2020-10-14 18:26:31 +0000641}
642
dan sinclair13d2a3b2020-06-22 20:52:24 +0000643TEST_F(TypeDeterminerTest, Function_RegisterInputOutputVariables) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000644 auto* in_var = Var("in_var", ast::StorageClass::kInput, ty.f32);
645 auto* out_var = Var("out_var", ast::StorageClass::kOutput, ty.f32);
dan sinclair336bb0b2021-01-18 21:06:34 +0000646 auto* sb_var = Var("sb_var", ast::StorageClass::kStorage, ty.f32);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000647 auto* wg_var = Var("wg_var", ast::StorageClass::kWorkgroup, ty.f32);
648 auto* priv_var = Var("priv_var", ast::StorageClass::kPrivate, ty.f32);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000649
Ben Clayton3ea3c992020-11-18 21:19:22 +0000650 mod->AddGlobalVariable(in_var);
651 mod->AddGlobalVariable(out_var);
652 mod->AddGlobalVariable(sb_var);
653 mod->AddGlobalVariable(wg_var);
654 mod->AddGlobalVariable(priv_var);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000655
dan sinclair181d8ba2020-12-16 15:15:40 +0000656 auto* func = Func(
657 "my_func", ast::VariableList{}, ty.f32,
658 ast::StatementList{
659 create<ast::AssignmentStatement>(Expr("out_var"), Expr("in_var")),
660 create<ast::AssignmentStatement>(Expr("wg_var"), Expr("wg_var")),
661 create<ast::AssignmentStatement>(Expr("sb_var"), Expr("sb_var")),
662 create<ast::AssignmentStatement>(Expr("priv_var"), Expr("priv_var")),
663 },
664 ast::FunctionDecorationList{});
dan sinclair13d2a3b2020-06-22 20:52:24 +0000665
Ben Clayton3ea3c992020-11-18 21:19:22 +0000666 mod->AddFunction(func);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000667
668 // Register the function
669 EXPECT_TRUE(td()->Determine());
670
Ben Clayton4bfe4612020-11-16 16:41:47 +0000671 const auto& vars = func->referenced_module_variables();
Ryan Harrison9a452c12020-06-23 16:38:47 +0000672 ASSERT_EQ(vars.size(), 5u);
Ben Clayton4bfe4612020-11-16 16:41:47 +0000673 EXPECT_EQ(vars[0], out_var);
674 EXPECT_EQ(vars[1], in_var);
675 EXPECT_EQ(vars[2], wg_var);
676 EXPECT_EQ(vars[3], sb_var);
677 EXPECT_EQ(vars[4], priv_var);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000678}
679
dan sinclairde2dd682020-07-14 20:37:28 +0000680TEST_F(TypeDeterminerTest, Function_RegisterInputOutputVariables_SubFunction) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000681 auto* in_var = Var("in_var", ast::StorageClass::kInput, ty.f32);
682 auto* out_var = Var("out_var", ast::StorageClass::kOutput, ty.f32);
dan sinclair336bb0b2021-01-18 21:06:34 +0000683 auto* sb_var = Var("sb_var", ast::StorageClass::kStorage, ty.f32);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000684 auto* wg_var = Var("wg_var", ast::StorageClass::kWorkgroup, ty.f32);
685 auto* priv_var = Var("priv_var", ast::StorageClass::kPrivate, ty.f32);
dan sinclairde2dd682020-07-14 20:37:28 +0000686
Ben Clayton3ea3c992020-11-18 21:19:22 +0000687 mod->AddGlobalVariable(in_var);
688 mod->AddGlobalVariable(out_var);
689 mod->AddGlobalVariable(sb_var);
690 mod->AddGlobalVariable(wg_var);
691 mod->AddGlobalVariable(priv_var);
dan sinclairde2dd682020-07-14 20:37:28 +0000692
dan sinclair181d8ba2020-12-16 15:15:40 +0000693 auto* func = Func(
694 "my_func", ast::VariableList{}, ty.f32,
695 ast::StatementList{
696 create<ast::AssignmentStatement>(Expr("out_var"), Expr("in_var")),
697 create<ast::AssignmentStatement>(Expr("wg_var"), Expr("wg_var")),
698 create<ast::AssignmentStatement>(Expr("sb_var"), Expr("sb_var")),
699 create<ast::AssignmentStatement>(Expr("priv_var"), Expr("priv_var")),
700 },
701 ast::FunctionDecorationList{});
dan sinclairde2dd682020-07-14 20:37:28 +0000702
Ben Clayton3ea3c992020-11-18 21:19:22 +0000703 mod->AddFunction(func);
dan sinclairde2dd682020-07-14 20:37:28 +0000704
dan sinclair181d8ba2020-12-16 15:15:40 +0000705 auto* func2 = Func(
706 "func", ast::VariableList{}, ty.f32,
707 ast::StatementList{
708 create<ast::AssignmentStatement>(Expr("out_var"), Call("my_func")),
709 },
710 ast::FunctionDecorationList{});
dan sinclairde2dd682020-07-14 20:37:28 +0000711
Ben Clayton3ea3c992020-11-18 21:19:22 +0000712 mod->AddFunction(func2);
dan sinclairde2dd682020-07-14 20:37:28 +0000713
714 // Register the function
715 EXPECT_TRUE(td()->Determine());
716
Ben Clayton4bfe4612020-11-16 16:41:47 +0000717 const auto& vars = func2->referenced_module_variables();
dan sinclairde2dd682020-07-14 20:37:28 +0000718 ASSERT_EQ(vars.size(), 5u);
Ben Clayton4bfe4612020-11-16 16:41:47 +0000719 EXPECT_EQ(vars[0], out_var);
720 EXPECT_EQ(vars[1], in_var);
721 EXPECT_EQ(vars[2], wg_var);
722 EXPECT_EQ(vars[3], sb_var);
723 EXPECT_EQ(vars[4], priv_var);
dan sinclairde2dd682020-07-14 20:37:28 +0000724}
725
dan sinclair13d2a3b2020-06-22 20:52:24 +0000726TEST_F(TypeDeterminerTest, Function_NotRegisterFunctionVariable) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000727 auto* var = Var("in_var", ast::StorageClass::kFunction, ty.f32);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000728
dan sinclair181d8ba2020-12-16 15:15:40 +0000729 auto* func =
730 Func("my_func", ast::VariableList{}, ty.f32,
731 ast::StatementList{
732 create<ast::VariableDeclStatement>(var),
Ben Clayton1637cbb2021-01-05 15:44:39 +0000733 create<ast::AssignmentStatement>(Expr("var"), Expr(1.f)),
dan sinclair181d8ba2020-12-16 15:15:40 +0000734 },
735 ast::FunctionDecorationList{});
dan sinclair13d2a3b2020-06-22 20:52:24 +0000736
Ben Clayton3ea3c992020-11-18 21:19:22 +0000737 mod->AddFunction(func);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000738
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000739 auto* v = Var("var", ast::StorageClass::kFunction, ty.f32);
740 td()->RegisterVariableForTesting(v);
dan sinclairff267ca2020-10-14 18:26:31 +0000741
dan sinclair13d2a3b2020-06-22 20:52:24 +0000742 // Register the function
dan sinclairff267ca2020-10-14 18:26:31 +0000743 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair13d2a3b2020-06-22 20:52:24 +0000744
Ben Clayton4bfe4612020-11-16 16:41:47 +0000745 EXPECT_EQ(func->referenced_module_variables().size(), 0u);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000746}
747
dan sinclair8ee1d222020-04-07 16:41:33 +0000748TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct) {
dan sinclair5e5e36e2020-12-16 14:41:00 +0000749 auto* strct = create<ast::Struct>(
750 ast::StructMemberList{Member("first_member", ty.i32),
751 Member("second_member", ty.f32)},
752 ast::StructDecorationList{});
dan sinclair8ee1d222020-04-07 16:41:33 +0000753
dan sinclairb5839932020-12-16 21:38:40 +0000754 auto* st = ty.struct_("S", strct);
755 auto* var = Var("my_struct", ast::StorageClass::kNone, st);
dan sinclair8ee1d222020-04-07 16:41:33 +0000756
Ben Clayton3ea3c992020-11-18 21:19:22 +0000757 mod->AddGlobalVariable(var);
dan sinclair8ee1d222020-04-07 16:41:33 +0000758
dan sinclairb950e802020-04-20 14:20:01 +0000759 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +0000760
dan sinclair8b40a672020-12-16 11:49:10 +0000761 auto* mem = MemberAccessor("my_struct", "second_member");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000762 EXPECT_TRUE(td()->DetermineResultType(mem));
763 ASSERT_NE(mem->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000764 ASSERT_TRUE(mem->result_type()->Is<type::Pointer>());
dan sinclair8ee1d222020-04-07 16:41:33 +0000765
Ben Clayton207b5e22021-01-21 15:42:10 +0000766 auto* ptr = mem->result_type()->As<type::Pointer>();
767 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair8ee1d222020-04-07 16:41:33 +0000768}
769
dan sinclairb445a9b2020-04-24 00:40:45 +0000770TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct_Alias) {
dan sinclair5e5e36e2020-12-16 14:41:00 +0000771 auto* strct = create<ast::Struct>(
772 ast::StructMemberList{Member("first_member", ty.i32),
773 Member("second_member", ty.f32)},
774 ast::StructDecorationList{});
dan sinclairb445a9b2020-04-24 00:40:45 +0000775
dan sinclairb5839932020-12-16 21:38:40 +0000776 auto* st = ty.struct_("alias", strct);
777 auto* alias = ty.alias("alias", st);
778 auto* var = Var("my_struct", ast::StorageClass::kNone, alias);
dan sinclairb445a9b2020-04-24 00:40:45 +0000779
Ben Clayton3ea3c992020-11-18 21:19:22 +0000780 mod->AddGlobalVariable(var);
dan sinclairb445a9b2020-04-24 00:40:45 +0000781
dan sinclairb445a9b2020-04-24 00:40:45 +0000782 EXPECT_TRUE(td()->Determine());
783
dan sinclair8b40a672020-12-16 11:49:10 +0000784 auto* mem = MemberAccessor("my_struct", "second_member");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000785 EXPECT_TRUE(td()->DetermineResultType(mem));
786 ASSERT_NE(mem->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000787 ASSERT_TRUE(mem->result_type()->Is<type::Pointer>());
dan sinclairb445a9b2020-04-24 00:40:45 +0000788
Ben Clayton207b5e22021-01-21 15:42:10 +0000789 auto* ptr = mem->result_type()->As<type::Pointer>();
790 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclairb445a9b2020-04-24 00:40:45 +0000791}
792
dan sinclair8ee1d222020-04-07 16:41:33 +0000793TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000794 auto* var = Var("my_vec", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +0000795 mod->AddGlobalVariable(var);
dan sinclair8ee1d222020-04-07 16:41:33 +0000796
dan sinclairb950e802020-04-20 14:20:01 +0000797 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +0000798
dan sinclair8b40a672020-12-16 11:49:10 +0000799 auto* mem = MemberAccessor("my_vec", "xy");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000800 EXPECT_TRUE(td()->DetermineResultType(mem)) << td()->error();
801 ASSERT_NE(mem->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000802 ASSERT_TRUE(mem->result_type()->Is<type::Vector>());
803 EXPECT_TRUE(mem->result_type()->As<type::Vector>()->type()->Is<type::F32>());
804 EXPECT_EQ(mem->result_type()->As<type::Vector>()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +0000805}
806
dan sinclairaac58652020-04-21 13:05:34 +0000807TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle_SingleElement) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000808 auto* var = Var("my_vec", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +0000809 mod->AddGlobalVariable(var);
dan sinclairaac58652020-04-21 13:05:34 +0000810
dan sinclairaac58652020-04-21 13:05:34 +0000811 EXPECT_TRUE(td()->Determine());
812
dan sinclair8b40a672020-12-16 11:49:10 +0000813 auto* mem = MemberAccessor("my_vec", "x");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000814 EXPECT_TRUE(td()->DetermineResultType(mem)) << td()->error();
815 ASSERT_NE(mem->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000816 ASSERT_TRUE(mem->result_type()->Is<type::Pointer>());
dan sinclairaac58652020-04-21 13:05:34 +0000817
Ben Clayton207b5e22021-01-21 15:42:10 +0000818 auto* ptr = mem->result_type()->As<type::Pointer>();
819 ASSERT_TRUE(ptr->type()->Is<type::F32>());
dan sinclairaac58652020-04-21 13:05:34 +0000820}
821
dan sinclair8eddb782020-04-23 22:26:52 +0000822TEST_F(TypeDeterminerTest, Expr_Accessor_MultiLevel) {
dan sinclair8ee1d222020-04-07 16:41:33 +0000823 // struct b {
824 // vec4<f32> foo
825 // }
826 // struct A {
827 // vec3<struct b> mem
828 // }
829 // var c : A
830 // c.mem[0].foo.yx
831 // -> vec2<f32>
832 //
833 // MemberAccessor{
834 // MemberAccessor{
835 // ArrayAccessor{
836 // MemberAccessor{
837 // Identifier{c}
838 // Identifier{mem}
839 // }
840 // ScalarConstructor{0}
841 // }
842 // Identifier{foo}
843 // }
844 // Identifier{yx}
845 // }
846 //
dan sinclair8ee1d222020-04-07 16:41:33 +0000847
dan sinclair5e5e36e2020-12-16 14:41:00 +0000848 auto* strctB =
849 create<ast::Struct>(ast::StructMemberList{Member("foo", ty.vec4<f32>())},
850 ast::StructDecorationList{});
dan sinclairb5839932020-12-16 21:38:40 +0000851 auto* stB = ty.struct_("B", strctB);
dan sinclair8ee1d222020-04-07 16:41:33 +0000852
Ben Clayton207b5e22021-01-21 15:42:10 +0000853 type::Vector vecB(stB, 3);
dan sinclair5e5e36e2020-12-16 14:41:00 +0000854 auto* strctA = create<ast::Struct>(
855 ast::StructMemberList{Member("mem", &vecB)}, ast::StructDecorationList{});
dan sinclair8ee1d222020-04-07 16:41:33 +0000856
dan sinclairb5839932020-12-16 21:38:40 +0000857 auto* stA = ty.struct_("A", strctA);
858 auto* var = Var("c", ast::StorageClass::kNone, stA);
Ben Clayton3ea3c992020-11-18 21:19:22 +0000859 mod->AddGlobalVariable(var);
dan sinclairb950e802020-04-20 14:20:01 +0000860 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +0000861
dan sinclair8b40a672020-12-16 11:49:10 +0000862 auto* mem = MemberAccessor(
863 MemberAccessor(IndexAccessor(MemberAccessor("c", "mem"), 0), "foo"),
864 "yx");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000865 EXPECT_TRUE(td()->DetermineResultType(mem)) << td()->error();
dan sinclair8ee1d222020-04-07 16:41:33 +0000866
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000867 ASSERT_NE(mem->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000868 ASSERT_TRUE(mem->result_type()->Is<type::Vector>());
869 EXPECT_TRUE(mem->result_type()->As<type::Vector>()->type()->Is<type::F32>());
870 EXPECT_EQ(mem->result_type()->As<type::Vector>()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +0000871}
872
dan sinclaircd077b02020-04-20 14:19:04 +0000873using Expr_Binary_BitwiseTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +0000874TEST_P(Expr_Binary_BitwiseTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +0000875 auto op = GetParam();
876
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000877 auto* var = Var("val", ast::StorageClass::kNone, ty.i32);
dan sinclair9b978022020-04-07 19:26:39 +0000878
Ben Clayton3ea3c992020-11-18 21:19:22 +0000879 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +0000880
dan sinclairb950e802020-04-20 14:20:01 +0000881 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000882
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000883 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +0000884
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000885 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
886 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000887 EXPECT_TRUE(expr->result_type()->Is<type::I32>());
dan sinclair9b978022020-04-07 19:26:39 +0000888}
889
dan sinclair1c9b4862020-04-07 19:27:41 +0000890TEST_P(Expr_Binary_BitwiseTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +0000891 auto op = GetParam();
892
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000893 auto* var = Var("val", ast::StorageClass::kNone, ty.vec3<i32>());
dan sinclair9b978022020-04-07 19:26:39 +0000894
Ben Clayton3ea3c992020-11-18 21:19:22 +0000895 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +0000896
dan sinclairb950e802020-04-20 14:20:01 +0000897 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000898
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000899 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +0000900
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000901 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
902 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000903 ASSERT_TRUE(expr->result_type()->Is<type::Vector>());
904 EXPECT_TRUE(expr->result_type()->As<type::Vector>()->type()->Is<type::I32>());
905 EXPECT_EQ(expr->result_type()->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +0000906}
907INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +0000908 Expr_Binary_BitwiseTest,
909 testing::Values(ast::BinaryOp::kAnd,
910 ast::BinaryOp::kOr,
911 ast::BinaryOp::kXor,
912 ast::BinaryOp::kShiftLeft,
913 ast::BinaryOp::kShiftRight,
dan sinclair1c9b4862020-04-07 19:27:41 +0000914 ast::BinaryOp::kAdd,
915 ast::BinaryOp::kSubtract,
916 ast::BinaryOp::kDivide,
917 ast::BinaryOp::kModulo));
dan sinclair9b978022020-04-07 19:26:39 +0000918
dan sinclaircd077b02020-04-20 14:19:04 +0000919using Expr_Binary_LogicalTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +0000920TEST_P(Expr_Binary_LogicalTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +0000921 auto op = GetParam();
922
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000923 auto* var = Var("val", ast::StorageClass::kNone, ty.bool_);
dan sinclair9b978022020-04-07 19:26:39 +0000924
Ben Clayton3ea3c992020-11-18 21:19:22 +0000925 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +0000926
dan sinclairb950e802020-04-20 14:20:01 +0000927 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000928
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000929 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +0000930
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000931 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
932 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000933 EXPECT_TRUE(expr->result_type()->Is<type::Bool>());
dan sinclair9b978022020-04-07 19:26:39 +0000934}
935
dan sinclair1c9b4862020-04-07 19:27:41 +0000936TEST_P(Expr_Binary_LogicalTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +0000937 auto op = GetParam();
938
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000939 auto* var = Var("val", ast::StorageClass::kNone, ty.vec3<bool>());
dan sinclair9b978022020-04-07 19:26:39 +0000940
Ben Clayton3ea3c992020-11-18 21:19:22 +0000941 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +0000942
dan sinclairb950e802020-04-20 14:20:01 +0000943 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000944
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000945 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +0000946
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000947 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
948 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000949 ASSERT_TRUE(expr->result_type()->Is<type::Vector>());
950 EXPECT_TRUE(
951 expr->result_type()->As<type::Vector>()->type()->Is<type::Bool>());
952 EXPECT_EQ(expr->result_type()->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +0000953}
954INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +0000955 Expr_Binary_LogicalTest,
956 testing::Values(ast::BinaryOp::kLogicalAnd,
957 ast::BinaryOp::kLogicalOr));
dan sinclair9b978022020-04-07 19:26:39 +0000958
dan sinclaircd077b02020-04-20 14:19:04 +0000959using Expr_Binary_CompareTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +0000960TEST_P(Expr_Binary_CompareTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +0000961 auto op = GetParam();
962
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000963 auto* var = Var("val", ast::StorageClass::kNone, ty.i32);
dan sinclair9b978022020-04-07 19:26:39 +0000964
Ben Clayton3ea3c992020-11-18 21:19:22 +0000965 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +0000966
dan sinclairb950e802020-04-20 14:20:01 +0000967 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000968
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000969 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +0000970
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000971 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
972 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000973 EXPECT_TRUE(expr->result_type()->Is<type::Bool>());
dan sinclair9b978022020-04-07 19:26:39 +0000974}
975
dan sinclair1c9b4862020-04-07 19:27:41 +0000976TEST_P(Expr_Binary_CompareTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +0000977 auto op = GetParam();
978
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000979 auto* var = Var("val", ast::StorageClass::kNone, ty.vec3<i32>());
dan sinclair9b978022020-04-07 19:26:39 +0000980
Ben Clayton3ea3c992020-11-18 21:19:22 +0000981 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +0000982
dan sinclairb950e802020-04-20 14:20:01 +0000983 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000984
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000985 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +0000986
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000987 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
988 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +0000989 ASSERT_TRUE(expr->result_type()->Is<type::Vector>());
990 EXPECT_TRUE(
991 expr->result_type()->As<type::Vector>()->type()->Is<type::Bool>());
992 EXPECT_EQ(expr->result_type()->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +0000993}
994INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +0000995 Expr_Binary_CompareTest,
996 testing::Values(ast::BinaryOp::kEqual,
997 ast::BinaryOp::kNotEqual,
998 ast::BinaryOp::kLessThan,
999 ast::BinaryOp::kGreaterThan,
1000 ast::BinaryOp::kLessThanEqual,
1001 ast::BinaryOp::kGreaterThanEqual));
dan sinclair9b978022020-04-07 19:26:39 +00001002
dan sinclair1c9b4862020-04-07 19:27:41 +00001003TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Scalar) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001004 auto* var = Var("val", ast::StorageClass::kNone, ty.i32);
dan sinclair9b978022020-04-07 19:26:39 +00001005
Ben Clayton3ea3c992020-11-18 21:19:22 +00001006 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001007
dan sinclairb950e802020-04-20 14:20:01 +00001008 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001009
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001010 auto* expr = Mul("val", "val");
dan sinclair9b978022020-04-07 19:26:39 +00001011
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001012 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1013 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001014 EXPECT_TRUE(expr->result_type()->Is<type::I32>());
dan sinclair9b978022020-04-07 19:26:39 +00001015}
1016
dan sinclair1c9b4862020-04-07 19:27:41 +00001017TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Scalar) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001018 auto* scalar = Var("scalar", ast::StorageClass::kNone, ty.f32);
1019 auto* vector = Var("vector", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001020 mod->AddGlobalVariable(scalar);
1021 mod->AddGlobalVariable(vector);
dan sinclair9b978022020-04-07 19:26:39 +00001022
dan sinclairb950e802020-04-20 14:20:01 +00001023 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001024
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001025 auto* expr = Mul("vector", "scalar");
dan sinclair9b978022020-04-07 19:26:39 +00001026
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001027 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1028 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001029 ASSERT_TRUE(expr->result_type()->Is<type::Vector>());
1030 EXPECT_TRUE(expr->result_type()->As<type::Vector>()->type()->Is<type::F32>());
1031 EXPECT_EQ(expr->result_type()->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001032}
1033
dan sinclair1c9b4862020-04-07 19:27:41 +00001034TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Vector) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001035 auto* scalar = Var("scalar", ast::StorageClass::kNone, ty.f32);
1036 auto* vector = Var("vector", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001037 mod->AddGlobalVariable(scalar);
1038 mod->AddGlobalVariable(vector);
dan sinclair9b978022020-04-07 19:26:39 +00001039
dan sinclairb950e802020-04-20 14:20:01 +00001040 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001041
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001042 auto* expr = Mul("scalar", "vector");
dan sinclair9b978022020-04-07 19:26:39 +00001043
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001044 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1045 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001046 ASSERT_TRUE(expr->result_type()->Is<type::Vector>());
1047 EXPECT_TRUE(expr->result_type()->As<type::Vector>()->type()->Is<type::F32>());
1048 EXPECT_EQ(expr->result_type()->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001049}
1050
dan sinclair1c9b4862020-04-07 19:27:41 +00001051TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Vector) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001052 auto* vector = Var("vector", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001053 mod->AddGlobalVariable(vector);
dan sinclair9b978022020-04-07 19:26:39 +00001054
dan sinclairb950e802020-04-20 14:20:01 +00001055 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001056
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001057 auto* expr = Mul("vector", "vector");
dan sinclair9b978022020-04-07 19:26:39 +00001058
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001059 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1060 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001061 ASSERT_TRUE(expr->result_type()->Is<type::Vector>());
1062 EXPECT_TRUE(expr->result_type()->As<type::Vector>()->type()->Is<type::F32>());
1063 EXPECT_EQ(expr->result_type()->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001064}
1065
dan sinclair1c9b4862020-04-07 19:27:41 +00001066TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Scalar) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001067 auto* scalar = Var("scalar", ast::StorageClass::kNone, ty.f32);
Ben Clayton1637cbb2021-01-05 15:44:39 +00001068 auto* matrix = Var("matrix", ast::StorageClass::kNone, ty.mat2x3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001069 mod->AddGlobalVariable(scalar);
1070 mod->AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001071
dan sinclairb950e802020-04-20 14:20:01 +00001072 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001073
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001074 auto* expr = Mul("matrix", "scalar");
dan sinclair9b978022020-04-07 19:26:39 +00001075
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001076 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1077 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001078 ASSERT_TRUE(expr->result_type()->Is<type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001079
Ben Clayton207b5e22021-01-21 15:42:10 +00001080 auto* mat = expr->result_type()->As<type::Matrix>();
1081 EXPECT_TRUE(mat->type()->Is<type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001082 EXPECT_EQ(mat->rows(), 3u);
1083 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001084}
1085
dan sinclair1c9b4862020-04-07 19:27:41 +00001086TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Matrix) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001087 auto* scalar = Var("scalar", ast::StorageClass::kNone, ty.f32);
Ben Clayton1637cbb2021-01-05 15:44:39 +00001088 auto* matrix = Var("matrix", ast::StorageClass::kNone, ty.mat2x3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001089 mod->AddGlobalVariable(scalar);
1090 mod->AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001091
dan sinclairb950e802020-04-20 14:20:01 +00001092 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001093
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001094 auto* expr = Mul("scalar", "matrix");
dan sinclair9b978022020-04-07 19:26:39 +00001095
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001096 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1097 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001098 ASSERT_TRUE(expr->result_type()->Is<type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001099
Ben Clayton207b5e22021-01-21 15:42:10 +00001100 auto* mat = expr->result_type()->As<type::Matrix>();
1101 EXPECT_TRUE(mat->type()->Is<type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001102 EXPECT_EQ(mat->rows(), 3u);
1103 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001104}
1105
dan sinclair1c9b4862020-04-07 19:27:41 +00001106TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Vector) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001107 auto* vector = Var("vector", ast::StorageClass::kNone, ty.vec3<f32>());
1108 auto* matrix = Var("matrix", ast::StorageClass::kNone, ty.mat2x3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001109 mod->AddGlobalVariable(vector);
1110 mod->AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001111
dan sinclairb950e802020-04-20 14:20:01 +00001112 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001113
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001114 auto* expr = Mul("matrix", "vector");
dan sinclair9b978022020-04-07 19:26:39 +00001115
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001116 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1117 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001118 ASSERT_TRUE(expr->result_type()->Is<type::Vector>());
1119 EXPECT_TRUE(expr->result_type()->As<type::Vector>()->type()->Is<type::F32>());
1120 EXPECT_EQ(expr->result_type()->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001121}
1122
dan sinclair1c9b4862020-04-07 19:27:41 +00001123TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Matrix) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001124 auto* vector = Var("vector", ast::StorageClass::kNone, ty.vec3<f32>());
1125 auto* matrix = Var("matrix", ast::StorageClass::kNone, ty.mat2x3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001126 mod->AddGlobalVariable(vector);
1127 mod->AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001128
dan sinclairb950e802020-04-20 14:20:01 +00001129 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001130
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001131 auto* expr = Mul("vector", "matrix");
dan sinclair9b978022020-04-07 19:26:39 +00001132
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001133 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1134 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001135 ASSERT_TRUE(expr->result_type()->Is<type::Vector>());
1136 EXPECT_TRUE(expr->result_type()->As<type::Vector>()->type()->Is<type::F32>());
1137 EXPECT_EQ(expr->result_type()->As<type::Vector>()->size(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001138}
1139
dan sinclair1c9b4862020-04-07 19:27:41 +00001140TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Matrix) {
Ben Clayton1637cbb2021-01-05 15:44:39 +00001141 auto* matrix1 = Var("mat3x4", ast::StorageClass::kNone, ty.mat3x4<f32>());
1142 auto* matrix2 = Var("mat4x3", ast::StorageClass::kNone, ty.mat4x3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001143 mod->AddGlobalVariable(matrix1);
1144 mod->AddGlobalVariable(matrix2);
dan sinclair9b978022020-04-07 19:26:39 +00001145
dan sinclairb950e802020-04-20 14:20:01 +00001146 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001147
Ben Clayton1637cbb2021-01-05 15:44:39 +00001148 auto* expr = Mul("mat3x4", "mat4x3");
dan sinclair9b978022020-04-07 19:26:39 +00001149
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001150 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1151 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001152 ASSERT_TRUE(expr->result_type()->Is<type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001153
Ben Clayton207b5e22021-01-21 15:42:10 +00001154 auto* mat = expr->result_type()->As<type::Matrix>();
1155 EXPECT_TRUE(mat->type()->Is<type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001156 EXPECT_EQ(mat->rows(), 4u);
1157 EXPECT_EQ(mat->columns(), 4u);
dan sinclair9b978022020-04-07 19:26:39 +00001158}
1159
dan sinclair46e959d2020-06-01 13:43:22 +00001160using IntrinsicDerivativeTest = TypeDeterminerTestWithParam<std::string>;
1161TEST_P(IntrinsicDerivativeTest, Scalar) {
1162 auto name = GetParam();
dan sinclairb1730562020-04-07 19:26:49 +00001163
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001164 auto* var = Var("ident", ast::StorageClass::kNone, ty.f32);
dan sinclairb1730562020-04-07 19:26:49 +00001165
Ben Clayton3ea3c992020-11-18 21:19:22 +00001166 mod->AddGlobalVariable(var);
dan sinclair46e959d2020-06-01 13:43:22 +00001167
dan sinclair46e959d2020-06-01 13:43:22 +00001168 EXPECT_TRUE(td()->Determine());
1169
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001170 auto* expr = Call(name, "ident");
1171 EXPECT_TRUE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001172
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001173 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001174 ASSERT_TRUE(expr->result_type()->Is<type::F32>());
dan sinclair46e959d2020-06-01 13:43:22 +00001175}
1176
1177TEST_P(IntrinsicDerivativeTest, Vector) {
1178 auto name = GetParam();
1179
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001180 auto* var = Var("ident", ast::StorageClass::kNone, ty.vec4<f32>());
dan sinclairb1730562020-04-07 19:26:49 +00001181
Ben Clayton3ea3c992020-11-18 21:19:22 +00001182 mod->AddGlobalVariable(var);
dan sinclairb1730562020-04-07 19:26:49 +00001183
dan sinclairb950e802020-04-20 14:20:01 +00001184 EXPECT_TRUE(td()->Determine());
dan sinclairb1730562020-04-07 19:26:49 +00001185
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001186 auto* expr = Call(name, "ident");
1187 EXPECT_TRUE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001188
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001189 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001190 ASSERT_TRUE(expr->result_type()->Is<type::Vector>());
1191 EXPECT_TRUE(expr->result_type()->As<type::Vector>()->type()->Is<type::F32>());
1192 EXPECT_EQ(expr->result_type()->As<type::Vector>()->size(), 4u);
dan sinclair46e959d2020-06-01 13:43:22 +00001193}
1194
1195TEST_P(IntrinsicDerivativeTest, MissingParam) {
1196 auto name = GetParam();
1197
dan sinclair46e959d2020-06-01 13:43:22 +00001198 EXPECT_TRUE(td()->Determine());
1199
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001200 auto* expr = Call(name);
1201 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001202 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
1203}
1204
1205TEST_P(IntrinsicDerivativeTest, ToomManyParams) {
1206 auto name = GetParam();
1207
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001208 auto* var1 = Var("ident1", ast::StorageClass::kNone, ty.vec4<f32>());
1209 auto* var2 = Var("ident2", ast::StorageClass::kNone, ty.vec4<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001210 mod->AddGlobalVariable(var1);
1211 mod->AddGlobalVariable(var2);
dan sinclair46e959d2020-06-01 13:43:22 +00001212
dan sinclair46e959d2020-06-01 13:43:22 +00001213 EXPECT_TRUE(td()->Determine());
1214
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001215 auto* expr = Call(name, "ident1", "ident2");
1216 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001217 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
dan sinclairb1730562020-04-07 19:26:49 +00001218}
1219INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair46e959d2020-06-01 13:43:22 +00001220 IntrinsicDerivativeTest,
1221 testing::Values("dpdx",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001222 "dpdxCoarse",
1223 "dpdxFine",
dan sinclair46e959d2020-06-01 13:43:22 +00001224 "dpdy",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001225 "dpdyCoarse",
1226 "dpdyFine",
dan sinclair46e959d2020-06-01 13:43:22 +00001227 "fwidth",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001228 "fwidthCoarse",
1229 "fwidthFine"));
dan sinclairb1730562020-04-07 19:26:49 +00001230
dan sinclair46e959d2020-06-01 13:43:22 +00001231using Intrinsic = TypeDeterminerTestWithParam<std::string>;
1232TEST_P(Intrinsic, Test) {
1233 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00001234
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001235 auto* var = Var("my_var", ast::StorageClass::kNone, ty.vec3<bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001236
Ben Clayton3ea3c992020-11-18 21:19:22 +00001237 mod->AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00001238
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001239 auto* expr = Call(name, "my_var");
dan sinclair8dcfd102020-04-07 19:27:00 +00001240
dan sinclair8dcfd102020-04-07 19:27:00 +00001241 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001242 EXPECT_TRUE(td()->Determine());
dan sinclair8dcfd102020-04-07 19:27:00 +00001243
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001244 EXPECT_TRUE(td()->DetermineResultType(expr));
1245 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001246 EXPECT_TRUE(expr->result_type()->Is<type::Bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001247}
1248INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair46e959d2020-06-01 13:43:22 +00001249 Intrinsic,
1250 testing::Values("any", "all"));
dan sinclair8dcfd102020-04-07 19:27:00 +00001251
dan sinclair46e959d2020-06-01 13:43:22 +00001252using Intrinsic_FloatMethod = TypeDeterminerTestWithParam<std::string>;
1253TEST_P(Intrinsic_FloatMethod, Vector) {
1254 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00001255
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001256 auto* var = Var("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001257
Ben Clayton3ea3c992020-11-18 21:19:22 +00001258 mod->AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00001259
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001260 auto* expr = Call(name, "my_var");
dan sinclair8dcfd102020-04-07 19:27:00 +00001261
dan sinclair8dcfd102020-04-07 19:27:00 +00001262 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001263 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001264 EXPECT_TRUE(td()->DetermineResultType(expr));
dan sinclair8dcfd102020-04-07 19:27:00 +00001265
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001266 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001267 ASSERT_TRUE(expr->result_type()->Is<type::Vector>());
1268 EXPECT_TRUE(
1269 expr->result_type()->As<type::Vector>()->type()->Is<type::Bool>());
1270 EXPECT_EQ(expr->result_type()->As<type::Vector>()->size(), 3u);
dan sinclair8dcfd102020-04-07 19:27:00 +00001271}
dan sinclair46e959d2020-06-01 13:43:22 +00001272
1273TEST_P(Intrinsic_FloatMethod, Scalar) {
1274 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00001275
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001276 auto* var = Var("my_var", ast::StorageClass::kNone, ty.f32);
dan sinclair8dcfd102020-04-07 19:27:00 +00001277
Ben Clayton3ea3c992020-11-18 21:19:22 +00001278 mod->AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00001279
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001280 auto* expr = Call(name, "my_var");
dan sinclair8dcfd102020-04-07 19:27:00 +00001281
dan sinclair8dcfd102020-04-07 19:27:00 +00001282 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001283 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001284 EXPECT_TRUE(td()->DetermineResultType(expr));
1285 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001286 EXPECT_TRUE(expr->result_type()->Is<type::Bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001287}
dan sinclair8dcfd102020-04-07 19:27:00 +00001288
dan sinclair46e959d2020-06-01 13:43:22 +00001289TEST_P(Intrinsic_FloatMethod, MissingParam) {
1290 auto name = GetParam();
1291
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001292 auto* var = Var("my_var", ast::StorageClass::kNone, ty.f32);
dan sinclair46e959d2020-06-01 13:43:22 +00001293
Ben Clayton3ea3c992020-11-18 21:19:22 +00001294 mod->AddGlobalVariable(var);
dan sinclair46e959d2020-06-01 13:43:22 +00001295
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001296 auto* expr = Call(name);
dan sinclair46e959d2020-06-01 13:43:22 +00001297
1298 // Register the variable
1299 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001300 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001301 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
1302}
1303
1304TEST_P(Intrinsic_FloatMethod, TooManyParams) {
1305 auto name = GetParam();
1306
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001307 auto* var = Var("my_var", ast::StorageClass::kNone, ty.f32);
dan sinclair46e959d2020-06-01 13:43:22 +00001308
Ben Clayton3ea3c992020-11-18 21:19:22 +00001309 mod->AddGlobalVariable(var);
dan sinclair46e959d2020-06-01 13:43:22 +00001310
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001311 auto* expr = Call(name, "my_var", "my_var");
dan sinclair46e959d2020-06-01 13:43:22 +00001312
1313 // Register the variable
1314 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001315 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001316 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
1317}
1318INSTANTIATE_TEST_SUITE_P(
1319 TypeDeterminerTest,
1320 Intrinsic_FloatMethod,
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001321 testing::Values("isInf", "isNan", "isFinite", "isNormal"));
dan sinclair46e959d2020-06-01 13:43:22 +00001322
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001323enum class Texture { kF32, kI32, kU32 };
1324inline std::ostream& operator<<(std::ostream& out, Texture data) {
1325 if (data == Texture::kF32) {
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001326 out << "f32";
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001327 } else if (data == Texture::kI32) {
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001328 out << "i32";
1329 } else {
1330 out << "u32";
1331 }
1332 return out;
1333}
1334
1335struct TextureTestParams {
Ben Clayton207b5e22021-01-21 15:42:10 +00001336 type::TextureDimension dim;
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001337 Texture type = Texture::kF32;
Ben Clayton207b5e22021-01-21 15:42:10 +00001338 type::ImageFormat format = type::ImageFormat::kR16Float;
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001339};
1340inline std::ostream& operator<<(std::ostream& out, TextureTestParams data) {
1341 out << data.dim << "_" << data.type;
1342 return out;
1343}
1344
1345class Intrinsic_TextureOperation
1346 : public TypeDeterminerTestWithParam<TextureTestParams> {
1347 public:
Ben Clayton207b5e22021-01-21 15:42:10 +00001348 std::unique_ptr<type::Type> get_coords_type(type::TextureDimension dim,
1349 type::Type* type) {
1350 if (dim == type::TextureDimension::k1d) {
1351 if (type->Is<type::I32>()) {
1352 return std::make_unique<type::I32>();
1353 } else if (type->Is<type::U32>()) {
1354 return std::make_unique<type::U32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001355 } else {
Ben Clayton207b5e22021-01-21 15:42:10 +00001356 return std::make_unique<type::F32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001357 }
Ben Clayton207b5e22021-01-21 15:42:10 +00001358 } else if (dim == type::TextureDimension::k1dArray ||
1359 dim == type::TextureDimension::k2d) {
1360 return std::make_unique<type::Vector>(type, 2);
1361 } else if (dim == type::TextureDimension::kCubeArray) {
1362 return std::make_unique<type::Vector>(type, 4);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001363 } else {
Ben Clayton207b5e22021-01-21 15:42:10 +00001364 return std::make_unique<type::Vector>(type, 3);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001365 }
1366 }
1367
1368 void add_call_param(std::string name,
Ben Clayton207b5e22021-01-21 15:42:10 +00001369 type::Type* type,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001370 ast::ExpressionList* call_params) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001371 auto* var = Var(name, ast::StorageClass::kNone, type);
Ben Clayton3ea3c992020-11-18 21:19:22 +00001372 mod->AddGlobalVariable(var);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001373 call_params->push_back(Expr(name));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001374 }
1375
Ben Clayton207b5e22021-01-21 15:42:10 +00001376 std::unique_ptr<type::Type> subtype(Texture type) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001377 if (type == Texture::kF32) {
Ben Clayton207b5e22021-01-21 15:42:10 +00001378 return std::make_unique<type::F32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001379 }
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001380 if (type == Texture::kI32) {
Ben Clayton207b5e22021-01-21 15:42:10 +00001381 return std::make_unique<type::I32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001382 }
Ben Clayton207b5e22021-01-21 15:42:10 +00001383 return std::make_unique<type::U32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001384 }
1385};
1386
1387using Intrinsic_StorageTextureOperation = Intrinsic_TextureOperation;
1388TEST_P(Intrinsic_StorageTextureOperation, TextureLoadRo) {
1389 auto dim = GetParam().dim;
1390 auto type = GetParam().type;
1391 auto format = GetParam().format;
1392
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001393 auto coords_type = get_coords_type(dim, ty.i32);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001394
Ben Clayton207b5e22021-01-21 15:42:10 +00001395 type::Type* texture_type = mod->create<type::StorageTexture>(dim, format);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001396
1397 ast::ExpressionList call_params;
1398
1399 add_call_param("texture", texture_type, &call_params);
1400 add_call_param("coords", coords_type.get(), &call_params);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001401 add_call_param("lod", ty.i32, &call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001402
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001403 auto* expr = Call("textureLoad", call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001404
1405 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001406 EXPECT_TRUE(td()->DetermineResultType(expr));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001407
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001408 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001409 ASSERT_TRUE(expr->result_type()->Is<type::Vector>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001410 if (type == Texture::kF32) {
Ben Clayton207b5e22021-01-21 15:42:10 +00001411 EXPECT_TRUE(
1412 expr->result_type()->As<type::Vector>()->type()->Is<type::F32>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001413 } else if (type == Texture::kI32) {
Ben Clayton207b5e22021-01-21 15:42:10 +00001414 EXPECT_TRUE(
1415 expr->result_type()->As<type::Vector>()->type()->Is<type::I32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001416 } else {
Ben Clayton207b5e22021-01-21 15:42:10 +00001417 EXPECT_TRUE(
1418 expr->result_type()->As<type::Vector>()->type()->Is<type::U32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001419 }
Ben Clayton207b5e22021-01-21 15:42:10 +00001420 EXPECT_EQ(expr->result_type()->As<type::Vector>()->size(), 4u);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001421}
1422
1423INSTANTIATE_TEST_SUITE_P(
1424 TypeDeterminerTest,
1425 Intrinsic_StorageTextureOperation,
1426 testing::Values(
Ben Clayton207b5e22021-01-21 15:42:10 +00001427 TextureTestParams{type::TextureDimension::k1d, Texture::kF32,
1428 type::ImageFormat::kR16Float},
1429 TextureTestParams{type::TextureDimension::k1d, Texture::kI32,
1430 type::ImageFormat::kR16Sint},
1431 TextureTestParams{type::TextureDimension::k1d, Texture::kF32,
1432 type::ImageFormat::kR8Unorm},
1433 TextureTestParams{type::TextureDimension::k1dArray, Texture::kF32,
1434 type::ImageFormat::kR16Float},
1435 TextureTestParams{type::TextureDimension::k1dArray, Texture::kI32,
1436 type::ImageFormat::kR16Sint},
1437 TextureTestParams{type::TextureDimension::k1dArray, Texture::kF32,
1438 type::ImageFormat::kR8Unorm},
1439 TextureTestParams{type::TextureDimension::k2d, Texture::kF32,
1440 type::ImageFormat::kR16Float},
1441 TextureTestParams{type::TextureDimension::k2d, Texture::kI32,
1442 type::ImageFormat::kR16Sint},
1443 TextureTestParams{type::TextureDimension::k2d, Texture::kF32,
1444 type::ImageFormat::kR8Unorm},
1445 TextureTestParams{type::TextureDimension::k2dArray, Texture::kF32,
1446 type::ImageFormat::kR16Float},
1447 TextureTestParams{type::TextureDimension::k2dArray, Texture::kI32,
1448 type::ImageFormat::kR16Sint},
1449 TextureTestParams{type::TextureDimension::k2dArray, Texture::kF32,
1450 type::ImageFormat::kR8Unorm},
1451 TextureTestParams{type::TextureDimension::k3d, Texture::kF32,
1452 type::ImageFormat::kR16Float},
1453 TextureTestParams{type::TextureDimension::k3d, Texture::kI32,
1454 type::ImageFormat::kR16Sint},
1455 TextureTestParams{type::TextureDimension::k3d, Texture::kF32,
1456 type::ImageFormat::kR8Unorm}));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001457
1458using Intrinsic_SampledTextureOperation = Intrinsic_TextureOperation;
1459TEST_P(Intrinsic_SampledTextureOperation, TextureLoadSampled) {
1460 auto dim = GetParam().dim;
1461 auto type = GetParam().type;
1462
Ben Clayton207b5e22021-01-21 15:42:10 +00001463 std::unique_ptr<type::Type> s = subtype(type);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001464 auto coords_type = get_coords_type(dim, ty.i32);
Ben Clayton207b5e22021-01-21 15:42:10 +00001465 auto texture_type = std::make_unique<type::SampledTexture>(dim, s.get());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001466
1467 ast::ExpressionList call_params;
1468
1469 add_call_param("texture", texture_type.get(), &call_params);
1470 add_call_param("coords", coords_type.get(), &call_params);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001471 add_call_param("lod", ty.i32, &call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001472
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001473 auto* expr = Call("textureLoad", call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001474
1475 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001476 EXPECT_TRUE(td()->DetermineResultType(expr));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001477
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001478 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001479 ASSERT_TRUE(expr->result_type()->Is<type::Vector>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001480 if (type == Texture::kF32) {
Ben Clayton207b5e22021-01-21 15:42:10 +00001481 EXPECT_TRUE(
1482 expr->result_type()->As<type::Vector>()->type()->Is<type::F32>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001483 } else if (type == Texture::kI32) {
Ben Clayton207b5e22021-01-21 15:42:10 +00001484 EXPECT_TRUE(
1485 expr->result_type()->As<type::Vector>()->type()->Is<type::I32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001486 } else {
Ben Clayton207b5e22021-01-21 15:42:10 +00001487 EXPECT_TRUE(
1488 expr->result_type()->As<type::Vector>()->type()->Is<type::U32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001489 }
Ben Clayton207b5e22021-01-21 15:42:10 +00001490 EXPECT_EQ(expr->result_type()->As<type::Vector>()->size(), 4u);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001491}
1492
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001493INSTANTIATE_TEST_SUITE_P(
1494 TypeDeterminerTest,
1495 Intrinsic_SampledTextureOperation,
Ben Clayton207b5e22021-01-21 15:42:10 +00001496 testing::Values(TextureTestParams{type::TextureDimension::k2d},
1497 TextureTestParams{type::TextureDimension::k2dArray},
1498 TextureTestParams{type::TextureDimension::kCube},
1499 TextureTestParams{type::TextureDimension::kCubeArray}));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001500
dan sinclair46e959d2020-06-01 13:43:22 +00001501TEST_F(TypeDeterminerTest, Intrinsic_Dot) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001502 auto* var = Var("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001503
Ben Clayton3ea3c992020-11-18 21:19:22 +00001504 mod->AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00001505
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001506 auto* expr = Call("dot", "my_var", "my_var");
dan sinclair8dcfd102020-04-07 19:27:00 +00001507
dan sinclair8dcfd102020-04-07 19:27:00 +00001508 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001509 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001510 EXPECT_TRUE(td()->DetermineResultType(expr));
1511 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001512 EXPECT_TRUE(expr->result_type()->Is<type::F32>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001513}
1514
dan sinclair16a2ea12020-07-21 17:44:44 +00001515TEST_F(TypeDeterminerTest, Intrinsic_Select) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001516 auto* var = Var("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00001517
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001518 auto* bool_var = Var( // source
1519 "bool_var", ast::StorageClass::kNone, ty.vec3<bool>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001520 mod->AddGlobalVariable(var);
1521 mod->AddGlobalVariable(bool_var);
dan sinclair16a2ea12020-07-21 17:44:44 +00001522
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001523 auto* expr = Call("select", "my_var", "my_var", "bool_var");
dan sinclair16a2ea12020-07-21 17:44:44 +00001524
1525 // Register the variable
1526 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001527 EXPECT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1528 ASSERT_NE(expr->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001529 EXPECT_TRUE(expr->result_type()->Is<type::Vector>());
1530 EXPECT_EQ(expr->result_type()->As<type::Vector>()->size(), 3u);
1531 EXPECT_TRUE(expr->result_type()->As<type::Vector>()->type()->Is<type::F32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00001532}
1533
1534TEST_F(TypeDeterminerTest, Intrinsic_Select_TooFewParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001535 auto* var = Var("v", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00001536
Ben Clayton3ea3c992020-11-18 21:19:22 +00001537 mod->AddGlobalVariable(var);
dan sinclair16a2ea12020-07-21 17:44:44 +00001538
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001539 auto* expr = Call("select", "v");
dan sinclair16a2ea12020-07-21 17:44:44 +00001540
1541 // Register the variable
1542 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001543 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair16a2ea12020-07-21 17:44:44 +00001544 EXPECT_EQ(td()->error(),
1545 "incorrect number of parameters for select expected 3 got 1");
1546}
1547
1548TEST_F(TypeDeterminerTest, Intrinsic_Select_TooManyParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001549 auto* var = Var("v", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00001550
Ben Clayton3ea3c992020-11-18 21:19:22 +00001551 mod->AddGlobalVariable(var);
dan sinclair16a2ea12020-07-21 17:44:44 +00001552
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001553 auto* expr = Call("select", "v", "v", "v", "v");
dan sinclair16a2ea12020-07-21 17:44:44 +00001554
1555 // Register the variable
1556 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001557 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair16a2ea12020-07-21 17:44:44 +00001558 EXPECT_EQ(td()->error(),
1559 "incorrect number of parameters for select expected 3 got 4");
1560}
1561
dan sinclaircd077b02020-04-20 14:19:04 +00001562using UnaryOpExpressionTest = TypeDeterminerTestWithParam<ast::UnaryOp>;
dan sinclair0e257622020-04-07 19:27:11 +00001563TEST_P(UnaryOpExpressionTest, Expr_UnaryOp) {
1564 auto op = GetParam();
1565
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001566 auto* var = Var("ident", ast::StorageClass::kNone, ty.vec4<f32>());
dan sinclair0e257622020-04-07 19:27:11 +00001567
Ben Clayton3ea3c992020-11-18 21:19:22 +00001568 mod->AddGlobalVariable(var);
dan sinclair0e257622020-04-07 19:27:11 +00001569
dan sinclairb950e802020-04-20 14:20:01 +00001570 EXPECT_TRUE(td()->Determine());
dan sinclair0e257622020-04-07 19:27:11 +00001571
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001572 auto* der = create<ast::UnaryOpExpression>(op, Expr("ident"));
1573 EXPECT_TRUE(td()->DetermineResultType(der));
1574 ASSERT_NE(der->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001575 ASSERT_TRUE(der->result_type()->Is<type::Vector>());
1576 EXPECT_TRUE(der->result_type()->As<type::Vector>()->type()->Is<type::F32>());
1577 EXPECT_EQ(der->result_type()->As<type::Vector>()->size(), 4u);
dan sinclair0e257622020-04-07 19:27:11 +00001578}
1579INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
1580 UnaryOpExpressionTest,
1581 testing::Values(ast::UnaryOp::kNegation,
1582 ast::UnaryOp::kNot));
1583
dan sinclairee8ae042020-04-08 19:58:20 +00001584TEST_F(TypeDeterminerTest, StorageClass_SetsIfMissing) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001585 auto* var = Var("var", ast::StorageClass::kNone, ty.i32);
dan sinclairee8ae042020-04-08 19:58:20 +00001586
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001587 auto* stmt = create<ast::VariableDeclStatement>(var);
dan sinclair181d8ba2020-12-16 15:15:40 +00001588 auto* func = Func("func", ast::VariableList{}, ty.i32,
1589 ast::StatementList{stmt}, ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001590
Ben Clayton3ea3c992020-11-18 21:19:22 +00001591 mod->AddFunction(func);
dan sinclairee8ae042020-04-08 19:58:20 +00001592
dan sinclairb950e802020-04-20 14:20:01 +00001593 EXPECT_TRUE(td()->Determine()) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001594 EXPECT_EQ(var->storage_class(), ast::StorageClass::kFunction);
dan sinclairee8ae042020-04-08 19:58:20 +00001595}
1596
1597TEST_F(TypeDeterminerTest, StorageClass_DoesNotSetOnConst) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001598 auto* var = Const("var", ast::StorageClass::kNone, ty.i32);
1599 auto* stmt = create<ast::VariableDeclStatement>(var);
dan sinclair181d8ba2020-12-16 15:15:40 +00001600 auto* func = Func("func", ast::VariableList{}, ty.i32,
1601 ast::StatementList{stmt}, ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001602
Ben Clayton3ea3c992020-11-18 21:19:22 +00001603 mod->AddFunction(func);
dan sinclairee8ae042020-04-08 19:58:20 +00001604
dan sinclairb950e802020-04-20 14:20:01 +00001605 EXPECT_TRUE(td()->Determine()) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001606 EXPECT_EQ(var->storage_class(), ast::StorageClass::kNone);
dan sinclairee8ae042020-04-08 19:58:20 +00001607}
1608
1609TEST_F(TypeDeterminerTest, StorageClass_NonFunctionClassError) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001610 auto* var = Var("var", ast::StorageClass::kWorkgroup, ty.i32);
dan sinclairee8ae042020-04-08 19:58:20 +00001611
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001612 auto* stmt = create<ast::VariableDeclStatement>(var);
dan sinclair181d8ba2020-12-16 15:15:40 +00001613 auto* func = Func("func", ast::VariableList{}, ty.i32,
1614 ast::StatementList{stmt}, ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001615
Ben Clayton3ea3c992020-11-18 21:19:22 +00001616 mod->AddFunction(func);
dan sinclairee8ae042020-04-08 19:58:20 +00001617
dan sinclairb950e802020-04-20 14:20:01 +00001618 EXPECT_FALSE(td()->Determine());
dan sinclairee8ae042020-04-08 19:58:20 +00001619 EXPECT_EQ(td()->error(),
1620 "function variable has a non-function storage class");
1621}
1622
dan sinclairb4fee2f2020-09-22 19:42:13 +00001623struct IntrinsicData {
dan sinclairca1723e2020-04-20 15:47:55 +00001624 const char* name;
dan sinclairb4fee2f2020-09-22 19:42:13 +00001625 ast::Intrinsic intrinsic;
dan sinclairca1723e2020-04-20 15:47:55 +00001626};
dan sinclairb4fee2f2020-09-22 19:42:13 +00001627inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
dan sinclairca1723e2020-04-20 15:47:55 +00001628 out << data.name;
1629 return out;
1630}
dan sinclairb4fee2f2020-09-22 19:42:13 +00001631using IntrinsicDataTest = TypeDeterminerTestWithParam<IntrinsicData>;
1632TEST_P(IntrinsicDataTest, Lookup) {
1633 auto param = GetParam();
dan sinclairca1723e2020-04-20 15:47:55 +00001634
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001635 auto* ident = Expr(param.name);
1636 EXPECT_TRUE(td()->SetIntrinsicIfNeeded(ident));
1637 EXPECT_EQ(ident->intrinsic(), param.intrinsic);
1638 EXPECT_TRUE(ident->IsIntrinsic());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001639}
1640INSTANTIATE_TEST_SUITE_P(
1641 TypeDeterminerTest,
1642 IntrinsicDataTest,
1643 testing::Values(
1644 IntrinsicData{"abs", ast::Intrinsic::kAbs},
1645 IntrinsicData{"acos", ast::Intrinsic::kAcos},
1646 IntrinsicData{"all", ast::Intrinsic::kAll},
1647 IntrinsicData{"any", ast::Intrinsic::kAny},
dan sinclair007dc422020-10-08 17:01:55 +00001648 IntrinsicData{"arrayLength", ast::Intrinsic::kArrayLength},
dan sinclairb4fee2f2020-09-22 19:42:13 +00001649 IntrinsicData{"asin", ast::Intrinsic::kAsin},
1650 IntrinsicData{"atan", ast::Intrinsic::kAtan},
1651 IntrinsicData{"atan2", ast::Intrinsic::kAtan2},
1652 IntrinsicData{"ceil", ast::Intrinsic::kCeil},
1653 IntrinsicData{"clamp", ast::Intrinsic::kClamp},
1654 IntrinsicData{"cos", ast::Intrinsic::kCos},
1655 IntrinsicData{"cosh", ast::Intrinsic::kCosh},
1656 IntrinsicData{"countOneBits", ast::Intrinsic::kCountOneBits},
1657 IntrinsicData{"cross", ast::Intrinsic::kCross},
1658 IntrinsicData{"determinant", ast::Intrinsic::kDeterminant},
1659 IntrinsicData{"distance", ast::Intrinsic::kDistance},
1660 IntrinsicData{"dot", ast::Intrinsic::kDot},
1661 IntrinsicData{"dpdx", ast::Intrinsic::kDpdx},
1662 IntrinsicData{"dpdxCoarse", ast::Intrinsic::kDpdxCoarse},
1663 IntrinsicData{"dpdxFine", ast::Intrinsic::kDpdxFine},
1664 IntrinsicData{"dpdy", ast::Intrinsic::kDpdy},
1665 IntrinsicData{"dpdyCoarse", ast::Intrinsic::kDpdyCoarse},
1666 IntrinsicData{"dpdyFine", ast::Intrinsic::kDpdyFine},
1667 IntrinsicData{"exp", ast::Intrinsic::kExp},
1668 IntrinsicData{"exp2", ast::Intrinsic::kExp2},
1669 IntrinsicData{"faceForward", ast::Intrinsic::kFaceForward},
1670 IntrinsicData{"floor", ast::Intrinsic::kFloor},
1671 IntrinsicData{"fma", ast::Intrinsic::kFma},
1672 IntrinsicData{"fract", ast::Intrinsic::kFract},
1673 IntrinsicData{"frexp", ast::Intrinsic::kFrexp},
1674 IntrinsicData{"fwidth", ast::Intrinsic::kFwidth},
1675 IntrinsicData{"fwidthCoarse", ast::Intrinsic::kFwidthCoarse},
1676 IntrinsicData{"fwidthFine", ast::Intrinsic::kFwidthFine},
1677 IntrinsicData{"inverseSqrt", ast::Intrinsic::kInverseSqrt},
1678 IntrinsicData{"isFinite", ast::Intrinsic::kIsFinite},
1679 IntrinsicData{"isInf", ast::Intrinsic::kIsInf},
1680 IntrinsicData{"isNan", ast::Intrinsic::kIsNan},
1681 IntrinsicData{"isNormal", ast::Intrinsic::kIsNormal},
1682 IntrinsicData{"ldexp", ast::Intrinsic::kLdexp},
1683 IntrinsicData{"length", ast::Intrinsic::kLength},
1684 IntrinsicData{"log", ast::Intrinsic::kLog},
1685 IntrinsicData{"log2", ast::Intrinsic::kLog2},
1686 IntrinsicData{"max", ast::Intrinsic::kMax},
1687 IntrinsicData{"min", ast::Intrinsic::kMin},
1688 IntrinsicData{"mix", ast::Intrinsic::kMix},
1689 IntrinsicData{"modf", ast::Intrinsic::kModf},
1690 IntrinsicData{"normalize", ast::Intrinsic::kNormalize},
dan sinclairb4fee2f2020-09-22 19:42:13 +00001691 IntrinsicData{"pow", ast::Intrinsic::kPow},
1692 IntrinsicData{"reflect", ast::Intrinsic::kReflect},
1693 IntrinsicData{"reverseBits", ast::Intrinsic::kReverseBits},
1694 IntrinsicData{"round", ast::Intrinsic::kRound},
1695 IntrinsicData{"select", ast::Intrinsic::kSelect},
1696 IntrinsicData{"sign", ast::Intrinsic::kSign},
1697 IntrinsicData{"sin", ast::Intrinsic::kSin},
1698 IntrinsicData{"sinh", ast::Intrinsic::kSinh},
1699 IntrinsicData{"smoothStep", ast::Intrinsic::kSmoothStep},
1700 IntrinsicData{"sqrt", ast::Intrinsic::kSqrt},
1701 IntrinsicData{"step", ast::Intrinsic::kStep},
1702 IntrinsicData{"tan", ast::Intrinsic::kTan},
1703 IntrinsicData{"tanh", ast::Intrinsic::kTanh},
Ben Clayton4a0b9f72021-01-11 21:07:32 +00001704 IntrinsicData{"textureDimensions", ast::Intrinsic::kTextureDimensions},
dan sinclairb4fee2f2020-09-22 19:42:13 +00001705 IntrinsicData{"textureLoad", ast::Intrinsic::kTextureLoad},
Ben Claytonc21f1f92021-01-14 16:50:07 +00001706 IntrinsicData{"textureNumLayers", ast::Intrinsic::kTextureNumLayers},
Ben Claytond9713202021-01-14 18:06:57 +00001707 IntrinsicData{"textureNumLevels", ast::Intrinsic::kTextureNumLevels},
Ben Clayton0a68b362021-01-14 18:11:17 +00001708 IntrinsicData{"textureNumSamples", ast::Intrinsic::kTextureNumSamples},
dan sinclairb4fee2f2020-09-22 19:42:13 +00001709 IntrinsicData{"textureSample", ast::Intrinsic::kTextureSample},
1710 IntrinsicData{"textureSampleBias", ast::Intrinsic::kTextureSampleBias},
1711 IntrinsicData{"textureSampleCompare",
1712 ast::Intrinsic::kTextureSampleCompare},
Ben Clayton3ea3c992020-11-18 21:19:22 +00001713 IntrinsicData{"textureSampleGrad", ast::Intrinsic::kTextureSampleGrad},
dan sinclairb4fee2f2020-09-22 19:42:13 +00001714 IntrinsicData{"textureSampleLevel",
1715 ast::Intrinsic::kTextureSampleLevel},
1716 IntrinsicData{"trunc", ast::Intrinsic::kTrunc}));
1717
1718TEST_F(TypeDeterminerTest, IntrinsicNotSetIfNotMatched) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001719 auto* ident = Expr("not_intrinsic");
1720 EXPECT_FALSE(td()->SetIntrinsicIfNeeded(ident));
1721 EXPECT_EQ(ident->intrinsic(), ast::Intrinsic::kNone);
1722 EXPECT_FALSE(ident->IsIntrinsic());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001723}
1724
1725using ImportData_SingleParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair37d62c92020-04-21 12:55:06 +00001726TEST_P(ImportData_SingleParamTest, Scalar) {
dan sinclairca1723e2020-04-20 15:47:55 +00001727 auto param = GetParam();
1728
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001729 auto* ident = Expr(param.name);
1730 auto* call = Call(ident, 1.f);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001731
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001732 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001733 ASSERT_NE(ident->result_type(), nullptr);
1734 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001735}
1736
dan sinclair37d62c92020-04-21 12:55:06 +00001737TEST_P(ImportData_SingleParamTest, Vector) {
dan sinclairca1723e2020-04-20 15:47:55 +00001738 auto param = GetParam();
1739
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001740 auto* ident = Expr(param.name);
1741 auto* call = Call(ident, vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001742
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001743 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001744 ASSERT_NE(ident->result_type(), nullptr);
1745 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Clayton207b5e22021-01-21 15:42:10 +00001746 EXPECT_EQ(ident->result_type()->As<type::Vector>()->size(), 3u);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001747}
1748
dan sinclair37d62c92020-04-21 12:55:06 +00001749TEST_P(ImportData_SingleParamTest, Error_Integer) {
dan sinclairca1723e2020-04-20 15:47:55 +00001750 auto param = GetParam();
1751
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001752 auto* call = Call(param.name, 1);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001753
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001754 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair53352042020-06-08 18:49:31 +00001755 EXPECT_EQ(td()->error(),
1756 std::string("incorrect type for ") + param.name +
1757 ". Requires float scalar or float vector values");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001758}
1759
dan sinclair37d62c92020-04-21 12:55:06 +00001760TEST_P(ImportData_SingleParamTest, Error_NoParams) {
dan sinclairca1723e2020-04-20 15:47:55 +00001761 auto param = GetParam();
1762
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001763 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001764
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001765 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairca1723e2020-04-20 15:47:55 +00001766 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
1767 param.name + ". Expected 1 got 0");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001768}
1769
dan sinclair37d62c92020-04-21 12:55:06 +00001770TEST_P(ImportData_SingleParamTest, Error_MultipleParams) {
dan sinclairca1723e2020-04-20 15:47:55 +00001771 auto param = GetParam();
1772
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001773 auto* call = Call(param.name, 1.f, 1.f, 1.f);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001774
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001775 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairca1723e2020-04-20 15:47:55 +00001776 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
1777 param.name + ". Expected 1 got 3");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001778}
1779
dan sinclaira49328f2020-04-20 15:49:50 +00001780INSTANTIATE_TEST_SUITE_P(
1781 TypeDeterminerTest,
dan sinclair37d62c92020-04-21 12:55:06 +00001782 ImportData_SingleParamTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00001783 testing::Values(IntrinsicData{"acos", ast::Intrinsic::kAcos},
1784 IntrinsicData{"asin", ast::Intrinsic::kAsin},
1785 IntrinsicData{"atan", ast::Intrinsic::kAtan},
1786 IntrinsicData{"ceil", ast::Intrinsic::kCeil},
1787 IntrinsicData{"cos", ast::Intrinsic::kCos},
1788 IntrinsicData{"cosh", ast::Intrinsic::kCosh},
1789 IntrinsicData{"exp", ast::Intrinsic::kExp},
1790 IntrinsicData{"exp2", ast::Intrinsic::kExp2},
1791 IntrinsicData{"floor", ast::Intrinsic::kFloor},
1792 IntrinsicData{"fract", ast::Intrinsic::kFract},
1793 IntrinsicData{"inverseSqrt", ast::Intrinsic::kInverseSqrt},
1794 IntrinsicData{"log", ast::Intrinsic::kLog},
1795 IntrinsicData{"log2", ast::Intrinsic::kLog2},
1796 IntrinsicData{"normalize", ast::Intrinsic::kNormalize},
1797 IntrinsicData{"round", ast::Intrinsic::kRound},
1798 IntrinsicData{"sign", ast::Intrinsic::kSign},
1799 IntrinsicData{"sin", ast::Intrinsic::kSin},
1800 IntrinsicData{"sinh", ast::Intrinsic::kSinh},
1801 IntrinsicData{"sqrt", ast::Intrinsic::kSqrt},
1802 IntrinsicData{"tan", ast::Intrinsic::kTan},
1803 IntrinsicData{"tanh", ast::Intrinsic::kTanh},
1804 IntrinsicData{"trunc", ast::Intrinsic::kTrunc}));
1805
1806using ImportData_SingleParam_FloatOrInt_Test =
1807 TypeDeterminerTestWithParam<IntrinsicData>;
1808TEST_P(ImportData_SingleParam_FloatOrInt_Test, Float_Scalar) {
1809 auto param = GetParam();
1810
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001811 auto* ident = Expr(param.name);
1812 auto* call = Call(ident, 1.f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001813
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001814 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001815 ASSERT_NE(ident->result_type(), nullptr);
1816 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001817}
1818
1819TEST_P(ImportData_SingleParam_FloatOrInt_Test, Float_Vector) {
1820 auto param = GetParam();
1821
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001822 auto* ident = Expr(param.name);
1823 auto* call = Call(ident, vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001824
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001825 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001826 ASSERT_NE(ident->result_type(), nullptr);
1827 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Clayton207b5e22021-01-21 15:42:10 +00001828 EXPECT_EQ(ident->result_type()->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001829}
1830
1831TEST_P(ImportData_SingleParam_FloatOrInt_Test, Sint_Scalar) {
1832 auto param = GetParam();
1833
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001834 auto* ident = Expr(param.name);
1835 auto* call = Call(ident, -1);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001836
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001837 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001838 ASSERT_NE(ident->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001839 EXPECT_TRUE(ident->result_type()->Is<type::I32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001840}
1841
1842TEST_P(ImportData_SingleParam_FloatOrInt_Test, Sint_Vector) {
1843 auto param = GetParam();
1844
dan sinclairb4fee2f2020-09-22 19:42:13 +00001845 ast::ExpressionList vals;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001846 vals.push_back(Expr(1));
1847 vals.push_back(Expr(1));
1848 vals.push_back(Expr(3));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001849
1850 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001851 params.push_back(vec3<i32>(vals));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001852
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001853 auto* ident = Expr(param.name);
1854 auto* call = Call(ident, params);
Ben Clayton4bfe4612020-11-16 16:41:47 +00001855
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001856 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001857 ASSERT_NE(ident->result_type(), nullptr);
1858 EXPECT_TRUE(ident->result_type()->is_signed_integer_vector());
Ben Clayton207b5e22021-01-21 15:42:10 +00001859 EXPECT_EQ(ident->result_type()->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001860}
1861
1862TEST_P(ImportData_SingleParam_FloatOrInt_Test, Uint_Scalar) {
1863 auto param = GetParam();
1864
dan sinclairb4fee2f2020-09-22 19:42:13 +00001865 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001866 params.push_back(Expr(1u));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001867
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001868 auto* ident = Expr(param.name);
1869 auto* call = Call(ident, params);
Ben Clayton4bfe4612020-11-16 16:41:47 +00001870
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001871 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001872 ASSERT_NE(ident->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00001873 EXPECT_TRUE(ident->result_type()->Is<type::U32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001874}
1875
1876TEST_P(ImportData_SingleParam_FloatOrInt_Test, Uint_Vector) {
1877 auto param = GetParam();
1878
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001879 auto* ident = Expr(param.name);
1880 auto* call = Call(ident, vec3<u32>(1u, 1u, 3u));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001881
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001882 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001883 ASSERT_NE(ident->result_type(), nullptr);
1884 EXPECT_TRUE(ident->result_type()->is_unsigned_integer_vector());
Ben Clayton207b5e22021-01-21 15:42:10 +00001885 EXPECT_EQ(ident->result_type()->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001886}
1887
1888TEST_P(ImportData_SingleParam_FloatOrInt_Test, Error_Bool) {
1889 auto param = GetParam();
1890
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001891 auto* call = Call(param.name, false);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001892
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001893 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001894 EXPECT_EQ(td()->error(),
1895 std::string("incorrect type for ") + param.name +
1896 ". Requires float or int, scalar or vector values");
1897}
1898
1899TEST_P(ImportData_SingleParam_FloatOrInt_Test, Error_NoParams) {
1900 auto param = GetParam();
1901
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001902 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001903
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001904 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001905 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
1906 param.name + ". Expected 1 got 0");
1907}
1908
1909TEST_P(ImportData_SingleParam_FloatOrInt_Test, Error_MultipleParams) {
1910 auto param = GetParam();
1911
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001912 auto* call = Call(param.name, 1.f, 1.f, 1.f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001913
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001914 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001915 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
1916 param.name + ". Expected 1 got 3");
1917}
1918
1919INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
1920 ImportData_SingleParam_FloatOrInt_Test,
1921 testing::Values(IntrinsicData{"abs",
1922 ast::Intrinsic::kAbs}));
dan sinclairca1723e2020-04-20 15:47:55 +00001923
dan sinclair652a4b92020-04-20 21:09:14 +00001924TEST_F(TypeDeterminerTest, ImportData_Length_Scalar) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001925 auto* ident = Expr("length");
dan sinclair652a4b92020-04-20 21:09:14 +00001926
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001927 auto* call = Call(ident, 1.f);
dan sinclair652a4b92020-04-20 21:09:14 +00001928
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001929 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001930 ASSERT_NE(ident->result_type(), nullptr);
1931 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair652a4b92020-04-20 21:09:14 +00001932}
1933
1934TEST_F(TypeDeterminerTest, ImportData_Length_FloatVector) {
dan sinclair652a4b92020-04-20 21:09:14 +00001935 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001936 params.push_back(vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair652a4b92020-04-20 21:09:14 +00001937
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001938 auto* ident = Expr("length");
Ben Clayton4bfe4612020-11-16 16:41:47 +00001939
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001940 auto* call = Call(ident, params);
dan sinclair652a4b92020-04-20 21:09:14 +00001941
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001942 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001943 ASSERT_NE(ident->result_type(), nullptr);
1944 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair652a4b92020-04-20 21:09:14 +00001945}
1946
1947TEST_F(TypeDeterminerTest, ImportData_Length_Error_Integer) {
dan sinclair652a4b92020-04-20 21:09:14 +00001948 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001949 params.push_back(Expr(1));
dan sinclair652a4b92020-04-20 21:09:14 +00001950
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001951 auto* call = Call("length", params);
dan sinclair652a4b92020-04-20 21:09:14 +00001952
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001953 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair53352042020-06-08 18:49:31 +00001954 EXPECT_EQ(td()->error(),
1955 "incorrect type for length. Requires float scalar or float vector "
1956 "values");
dan sinclair652a4b92020-04-20 21:09:14 +00001957}
1958
1959TEST_F(TypeDeterminerTest, ImportData_Length_Error_NoParams) {
1960 ast::ExpressionList params;
dan sinclairb4fee2f2020-09-22 19:42:13 +00001961
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001962 auto* call = Call("length");
dan sinclairb4fee2f2020-09-22 19:42:13 +00001963
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001964 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair652a4b92020-04-20 21:09:14 +00001965 EXPECT_EQ(td()->error(),
1966 "incorrect number of parameters for length. Expected 1 got 0");
1967}
1968
1969TEST_F(TypeDeterminerTest, ImportData_Length_Error_MultipleParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001970 auto* call = Call("length", 1.f, 1.f, 1.f);
dan sinclair652a4b92020-04-20 21:09:14 +00001971
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001972 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair652a4b92020-04-20 21:09:14 +00001973 EXPECT_EQ(td()->error(),
1974 "incorrect number of parameters for length. Expected 1 got 3");
1975}
1976
dan sinclairb4fee2f2020-09-22 19:42:13 +00001977using ImportData_TwoParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair37d62c92020-04-21 12:55:06 +00001978TEST_P(ImportData_TwoParamTest, Scalar) {
1979 auto param = GetParam();
1980
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001981 auto* ident = Expr(param.name);
1982 auto* call = Call(ident, 1.f, 1.f);
dan sinclair37d62c92020-04-21 12:55:06 +00001983
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001984 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001985 ASSERT_NE(ident->result_type(), nullptr);
1986 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair37d62c92020-04-21 12:55:06 +00001987}
1988
1989TEST_P(ImportData_TwoParamTest, Vector) {
1990 auto param = GetParam();
1991
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001992 auto* ident = Expr(param.name);
1993 auto* call =
1994 Call(ident, vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair37d62c92020-04-21 12:55:06 +00001995
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001996 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001997 ASSERT_NE(ident->result_type(), nullptr);
1998 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Clayton207b5e22021-01-21 15:42:10 +00001999 EXPECT_EQ(ident->result_type()->As<type::Vector>()->size(), 3u);
dan sinclair37d62c92020-04-21 12:55:06 +00002000}
2001
2002TEST_P(ImportData_TwoParamTest, Error_Integer) {
2003 auto param = GetParam();
2004
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002005 auto* call = Call(param.name, 1, 2);
dan sinclair37d62c92020-04-21 12:55:06 +00002006
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002007 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair37d62c92020-04-21 12:55:06 +00002008 EXPECT_EQ(td()->error(),
2009 std::string("incorrect type for ") + param.name +
dan sinclair53352042020-06-08 18:49:31 +00002010 ". Requires float scalar or float vector values");
dan sinclair37d62c92020-04-21 12:55:06 +00002011}
2012
2013TEST_P(ImportData_TwoParamTest, Error_NoParams) {
2014 auto param = GetParam();
2015
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002016 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002017
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002018 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair37d62c92020-04-21 12:55:06 +00002019 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2020 param.name + ". Expected 2 got 0");
2021}
2022
2023TEST_P(ImportData_TwoParamTest, Error_OneParam) {
2024 auto param = GetParam();
2025
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002026 auto* call = Call(param.name, 1.f);
dan sinclair37d62c92020-04-21 12:55:06 +00002027
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002028 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair37d62c92020-04-21 12:55:06 +00002029 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2030 param.name + ". Expected 2 got 1");
2031}
2032
2033TEST_P(ImportData_TwoParamTest, Error_MismatchedParamCount) {
2034 auto param = GetParam();
2035
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002036 auto* call =
2037 Call(param.name, vec2<f32>(1.0f, 1.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair37d62c92020-04-21 12:55:06 +00002038
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002039 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair37d62c92020-04-21 12:55:06 +00002040 EXPECT_EQ(td()->error(),
2041 std::string("mismatched parameter types for ") + param.name);
2042}
2043
2044TEST_P(ImportData_TwoParamTest, Error_MismatchedParamType) {
2045 auto param = GetParam();
2046
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002047 auto* call = Call(param.name, 1.0f, vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair37d62c92020-04-21 12:55:06 +00002048
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002049 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair37d62c92020-04-21 12:55:06 +00002050 EXPECT_EQ(td()->error(),
2051 std::string("mismatched parameter types for ") + param.name);
2052}
2053
2054TEST_P(ImportData_TwoParamTest, Error_TooManyParams) {
2055 auto param = GetParam();
2056
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002057 auto* call = Call(param.name, 1.f, 1.f, 1.f);
dan sinclair37d62c92020-04-21 12:55:06 +00002058
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002059 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair37d62c92020-04-21 12:55:06 +00002060 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2061 param.name + ". Expected 2 got 3");
2062}
2063
dan sinclairb4fee2f2020-09-22 19:42:13 +00002064INSTANTIATE_TEST_SUITE_P(
2065 TypeDeterminerTest,
2066 ImportData_TwoParamTest,
2067 testing::Values(IntrinsicData{"atan2", ast::Intrinsic::kAtan2},
2068 IntrinsicData{"pow", ast::Intrinsic::kPow},
2069 IntrinsicData{"step", ast::Intrinsic::kStep},
2070 IntrinsicData{"reflect", ast::Intrinsic::kReflect}));
dan sinclair37d62c92020-04-21 12:55:06 +00002071
dan sinclair54444382020-04-21 13:04:15 +00002072TEST_F(TypeDeterminerTest, ImportData_Distance_Scalar) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002073 auto* ident = Expr("distance");
dan sinclair54444382020-04-21 13:04:15 +00002074
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002075 auto* call = Call(ident, 1.f, 1.f);
dan sinclair54444382020-04-21 13:04:15 +00002076
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002077 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002078 ASSERT_NE(ident->result_type(), nullptr);
2079 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair54444382020-04-21 13:04:15 +00002080}
2081
2082TEST_F(TypeDeterminerTest, ImportData_Distance_Vector) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002083 auto* ident = Expr("distance");
dan sinclair54444382020-04-21 13:04:15 +00002084
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002085 auto* call =
2086 Call(ident, vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair54444382020-04-21 13:04:15 +00002087
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002088 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002089 ASSERT_NE(ident->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00002090 EXPECT_TRUE(ident->result_type()->Is<type::F32>());
dan sinclair54444382020-04-21 13:04:15 +00002091}
2092
2093TEST_F(TypeDeterminerTest, ImportData_Distance_Error_Integer) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002094 auto* call = Call("distance", 1, 2);
dan sinclair54444382020-04-21 13:04:15 +00002095
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002096 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair54444382020-04-21 13:04:15 +00002097 EXPECT_EQ(td()->error(),
dan sinclair53352042020-06-08 18:49:31 +00002098 "incorrect type for distance. Requires float scalar or float "
dan sinclair54444382020-04-21 13:04:15 +00002099 "vector values");
2100}
2101
2102TEST_F(TypeDeterminerTest, ImportData_Distance_Error_NoParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002103 auto* call = Call("distance");
dan sinclairb4fee2f2020-09-22 19:42:13 +00002104
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002105 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair54444382020-04-21 13:04:15 +00002106 EXPECT_EQ(td()->error(),
2107 "incorrect number of parameters for distance. Expected 2 got 0");
2108}
2109
2110TEST_F(TypeDeterminerTest, ImportData_Distance_Error_OneParam) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002111 auto* call = Call("distance", 1.f);
dan sinclair54444382020-04-21 13:04:15 +00002112
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002113 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair54444382020-04-21 13:04:15 +00002114 EXPECT_EQ(td()->error(),
2115 "incorrect number of parameters for distance. Expected 2 got 1");
2116}
2117
2118TEST_F(TypeDeterminerTest, ImportData_Distance_Error_MismatchedParamCount) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002119 auto* call =
2120 Call("distance", vec2<f32>(1.0f, 1.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair54444382020-04-21 13:04:15 +00002121
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002122 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair54444382020-04-21 13:04:15 +00002123 EXPECT_EQ(td()->error(), "mismatched parameter types for distance");
2124}
2125
2126TEST_F(TypeDeterminerTest, ImportData_Distance_Error_MismatchedParamType) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002127 auto* call = Call("distance", Expr(1.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair54444382020-04-21 13:04:15 +00002128
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002129 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair54444382020-04-21 13:04:15 +00002130 EXPECT_EQ(td()->error(), "mismatched parameter types for distance");
2131}
2132
2133TEST_F(TypeDeterminerTest, ImportData_Distance_Error_TooManyParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002134 auto* call = Call("distance", Expr(1.f), Expr(1.f), Expr(1.f));
dan sinclair54444382020-04-21 13:04:15 +00002135
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002136 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair54444382020-04-21 13:04:15 +00002137 EXPECT_EQ(td()->error(),
2138 "incorrect number of parameters for distance. Expected 2 got 3");
2139}
2140
dan sinclairee392252020-06-08 23:48:15 +00002141TEST_F(TypeDeterminerTest, ImportData_Cross) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002142 auto* ident = Expr("cross");
dan sinclair2287d012020-04-22 00:23:57 +00002143
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002144 auto* call =
2145 Call(ident, vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairee392252020-06-08 23:48:15 +00002146
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002147 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002148 ASSERT_NE(ident->result_type(), nullptr);
2149 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Clayton207b5e22021-01-21 15:42:10 +00002150 EXPECT_EQ(ident->result_type()->As<type::Vector>()->size(), 3u);
dan sinclairee392252020-06-08 23:48:15 +00002151}
2152
2153TEST_F(TypeDeterminerTest, ImportData_Cross_Error_Scalar) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002154 auto* call = Call("cross", 1.0f, 1.0f);
dan sinclairee392252020-06-08 23:48:15 +00002155
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002156 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairee392252020-06-08 23:48:15 +00002157 EXPECT_EQ(td()->error(),
2158 "incorrect type for cross. Requires float vector values");
2159}
2160
2161TEST_F(TypeDeterminerTest, ImportData_Cross_Error_IntType) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002162 auto* call = Call("cross", vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3));
dan sinclairee392252020-06-08 23:48:15 +00002163
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002164 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairee392252020-06-08 23:48:15 +00002165 EXPECT_EQ(td()->error(),
2166 "incorrect type for cross. Requires float vector values");
2167}
2168
2169TEST_F(TypeDeterminerTest, ImportData_Cross_Error_MissingParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002170 auto* call = Call("cross");
dan sinclairee392252020-06-08 23:48:15 +00002171
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002172 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairee392252020-06-08 23:48:15 +00002173 EXPECT_EQ(td()->error(),
2174 "incorrect number of parameters for cross. Expected 2 got 0");
2175}
2176
2177TEST_F(TypeDeterminerTest, ImportData_Cross_Error_TooFewParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002178 auto* call = Call("cross", vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairee392252020-06-08 23:48:15 +00002179
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002180 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairee392252020-06-08 23:48:15 +00002181 EXPECT_EQ(td()->error(),
2182 "incorrect number of parameters for cross. Expected 2 got 1");
2183}
2184
2185TEST_F(TypeDeterminerTest, ImportData_Cross_Error_TooManyParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002186 auto* call = Call("cross", vec3<f32>(1.0f, 1.0f, 3.0f),
2187 vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairee392252020-06-08 23:48:15 +00002188
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002189 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairee392252020-06-08 23:48:15 +00002190 EXPECT_EQ(td()->error(),
2191 "incorrect number of parameters for cross. Expected 2 got 3");
2192}
2193
dan sinclairb4fee2f2020-09-22 19:42:13 +00002194using ImportData_ThreeParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair2287d012020-04-22 00:23:57 +00002195TEST_P(ImportData_ThreeParamTest, Scalar) {
2196 auto param = GetParam();
2197
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002198 auto* ident = Expr(param.name);
2199 auto* call = Call(ident, 1.f, 1.f, 1.f);
dan sinclair2287d012020-04-22 00:23:57 +00002200
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002201 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002202 ASSERT_NE(ident->result_type(), nullptr);
2203 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair2287d012020-04-22 00:23:57 +00002204}
2205
2206TEST_P(ImportData_ThreeParamTest, Vector) {
2207 auto param = GetParam();
2208
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002209 auto* ident = Expr(param.name);
2210 auto* call = Call(ident, vec3<f32>(1.0f, 1.0f, 3.0f),
2211 vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair2287d012020-04-22 00:23:57 +00002212
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002213 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002214 ASSERT_NE(ident->result_type(), nullptr);
2215 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Clayton207b5e22021-01-21 15:42:10 +00002216 EXPECT_EQ(ident->result_type()->As<type::Vector>()->size(), 3u);
dan sinclair2287d012020-04-22 00:23:57 +00002217}
2218
2219TEST_P(ImportData_ThreeParamTest, Error_Integer) {
2220 auto param = GetParam();
2221
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002222 auto* call = Call(param.name, 1, 2, 3);
dan sinclair2287d012020-04-22 00:23:57 +00002223
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002224 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair2287d012020-04-22 00:23:57 +00002225 EXPECT_EQ(td()->error(),
2226 std::string("incorrect type for ") + param.name +
dan sinclair53352042020-06-08 18:49:31 +00002227 ". Requires float scalar or float vector values");
dan sinclair2287d012020-04-22 00:23:57 +00002228}
2229
2230TEST_P(ImportData_ThreeParamTest, Error_NoParams) {
2231 auto param = GetParam();
2232
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002233 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002234
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002235 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair2287d012020-04-22 00:23:57 +00002236 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2237 param.name + ". Expected 3 got 0");
2238}
2239
2240TEST_P(ImportData_ThreeParamTest, Error_OneParam) {
2241 auto param = GetParam();
2242
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002243 auto* call = Call(param.name, 1.f);
dan sinclair2287d012020-04-22 00:23:57 +00002244
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002245 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair2287d012020-04-22 00:23:57 +00002246 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2247 param.name + ". Expected 3 got 1");
2248}
2249
2250TEST_P(ImportData_ThreeParamTest, Error_TwoParams) {
2251 auto param = GetParam();
2252
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002253 auto* call = Call(param.name, 1.f, 1.f);
dan sinclair2287d012020-04-22 00:23:57 +00002254
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002255 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair2287d012020-04-22 00:23:57 +00002256 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2257 param.name + ". Expected 3 got 2");
2258}
2259
2260TEST_P(ImportData_ThreeParamTest, Error_MismatchedParamCount) {
2261 auto param = GetParam();
2262
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002263 auto* call = Call(param.name, vec2<f32>(1.0f, 1.0f),
2264 vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair2287d012020-04-22 00:23:57 +00002265
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002266 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair2287d012020-04-22 00:23:57 +00002267 EXPECT_EQ(td()->error(),
2268 std::string("mismatched parameter types for ") + param.name);
2269}
2270
2271TEST_P(ImportData_ThreeParamTest, Error_MismatchedParamType) {
2272 auto param = GetParam();
2273
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002274 auto* call = Call(param.name, 1.0f, 1.0f, vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair2287d012020-04-22 00:23:57 +00002275
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002276 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair2287d012020-04-22 00:23:57 +00002277 EXPECT_EQ(td()->error(),
2278 std::string("mismatched parameter types for ") + param.name);
2279}
2280
2281TEST_P(ImportData_ThreeParamTest, Error_TooManyParams) {
2282 auto param = GetParam();
2283
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002284 auto* call = Call(param.name, 1.f, 1.f, 1.f, 1.f);
dan sinclair2287d012020-04-22 00:23:57 +00002285
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002286 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair2287d012020-04-22 00:23:57 +00002287 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2288 param.name + ". Expected 3 got 4");
2289}
2290
2291INSTANTIATE_TEST_SUITE_P(
2292 TypeDeterminerTest,
2293 ImportData_ThreeParamTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00002294 testing::Values(IntrinsicData{"mix", ast::Intrinsic::kMix},
2295 IntrinsicData{"smoothStep", ast::Intrinsic::kSmoothStep},
2296 IntrinsicData{"fma", ast::Intrinsic::kFma},
2297 IntrinsicData{"faceForward",
2298 ast::Intrinsic::kFaceForward}));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002299
dan sinclairb4fee2f2020-09-22 19:42:13 +00002300using ImportData_ThreeParam_FloatOrInt_Test =
2301 TypeDeterminerTestWithParam<IntrinsicData>;
2302TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Float_Scalar) {
2303 auto param = GetParam();
2304
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002305 auto* ident = Expr(param.name);
2306 auto* call = Call(ident, 1.f, 1.f, 1.f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002307
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002308 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002309 ASSERT_NE(ident->result_type(), nullptr);
2310 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002311}
2312
2313TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Float_Vector) {
2314 auto param = GetParam();
2315
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002316 auto* ident = Expr(param.name);
2317 auto* call = Call(ident, vec3<f32>(1.0f, 1.0f, 3.0f),
2318 vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002319
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002320 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002321 ASSERT_NE(ident->result_type(), nullptr);
2322 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Clayton207b5e22021-01-21 15:42:10 +00002323 EXPECT_EQ(ident->result_type()->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002324}
2325
2326TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Sint_Scalar) {
2327 auto param = GetParam();
2328
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002329 auto* ident = Expr(param.name);
2330 auto* call = Call(ident, 1, 1, 1);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002331
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002332 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002333 ASSERT_NE(ident->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00002334 EXPECT_TRUE(ident->result_type()->Is<type::I32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002335}
2336
2337TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Sint_Vector) {
2338 auto param = GetParam();
2339
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002340 auto* ident = Expr(param.name);
2341 auto* call =
2342 Call(ident, vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002343
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002344 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002345 ASSERT_NE(ident->result_type(), nullptr);
2346 EXPECT_TRUE(ident->result_type()->is_signed_integer_vector());
Ben Clayton207b5e22021-01-21 15:42:10 +00002347 EXPECT_EQ(ident->result_type()->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002348}
2349
2350TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Uint_Scalar) {
2351 auto param = GetParam();
2352
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002353 auto* ident = Expr(param.name);
2354 auto* call = Call(ident, 1u, 1u, 1u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002355
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002356 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002357 ASSERT_NE(ident->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00002358 EXPECT_TRUE(ident->result_type()->Is<type::U32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002359}
2360
2361TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Uint_Vector) {
2362 auto param = GetParam();
2363
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002364 auto* ident = Expr(param.name);
2365 auto* call = Call(ident, vec3<u32>(1u, 1u, 3u), vec3<u32>(1u, 1u, 3u),
2366 vec3<u32>(1u, 1u, 3u));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002367
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002368 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002369 ASSERT_NE(ident->result_type(), nullptr);
2370 EXPECT_TRUE(ident->result_type()->is_unsigned_integer_vector());
Ben Clayton207b5e22021-01-21 15:42:10 +00002371 EXPECT_EQ(ident->result_type()->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002372}
2373
2374TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_Bool) {
2375 auto param = GetParam();
2376
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002377 auto* call = Call(param.name, true, false, true);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002378
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002379 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002380 EXPECT_EQ(td()->error(),
2381 std::string("incorrect type for ") + param.name +
2382 ". Requires float or int, scalar or vector values");
2383}
2384
2385TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_NoParams) {
2386 auto param = GetParam();
2387
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002388 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002389
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002390 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002391 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2392 param.name + ". Expected 3 got 0");
2393}
2394
2395TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_OneParam) {
2396 auto param = GetParam();
2397
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002398 auto* call = Call(param.name, 1.f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002399
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002400 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002401 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2402 param.name + ". Expected 3 got 1");
2403}
2404
2405TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_TwoParams) {
2406 auto param = GetParam();
2407
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002408 auto* call = Call(param.name, 1.f, 1.f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002409
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002410 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002411 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2412 param.name + ". Expected 3 got 2");
2413}
2414
2415TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_MismatchedParamCount) {
2416 auto param = GetParam();
2417
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002418 auto* call = Call(param.name, vec2<f32>(1.0f, 1.0f),
2419 vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002420
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002421 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002422 EXPECT_EQ(td()->error(),
2423 std::string("mismatched parameter types for ") + param.name);
2424}
2425
2426TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_MismatchedParamType) {
2427 auto param = GetParam();
2428
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002429 auto* call = Call(param.name, 1.0f, 1.0f, vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002430
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002431 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002432 EXPECT_EQ(td()->error(),
2433 std::string("mismatched parameter types for ") + param.name);
2434}
2435
2436TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_TooManyParams) {
2437 auto param = GetParam();
2438
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002439 auto* call = Call(param.name, 1.f, 1.f, 1.f, 1.f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002440
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002441 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002442 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2443 param.name + ". Expected 3 got 4");
2444}
2445
2446INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
2447 ImportData_ThreeParam_FloatOrInt_Test,
2448 testing::Values(IntrinsicData{
2449 "clamp", ast::Intrinsic::kClamp}));
2450
2451using ImportData_Int_SingleParamTest =
2452 TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002453TEST_P(ImportData_Int_SingleParamTest, Scalar) {
2454 auto param = GetParam();
2455
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002456 auto* ident = Expr(param.name);
2457 auto* call = Call(ident, 1);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002458
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002459 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002460 ASSERT_NE(ident->result_type(), nullptr);
2461 EXPECT_TRUE(ident->result_type()->is_integer_scalar());
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002462}
2463
2464TEST_P(ImportData_Int_SingleParamTest, Vector) {
2465 auto param = GetParam();
2466
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002467 auto* ident = Expr(param.name);
2468 auto* call = Call(ident, vec3<i32>(1, 1, 3));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002469
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002470 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002471 ASSERT_NE(ident->result_type(), nullptr);
2472 EXPECT_TRUE(ident->result_type()->is_signed_integer_vector());
Ben Clayton207b5e22021-01-21 15:42:10 +00002473 EXPECT_EQ(ident->result_type()->As<type::Vector>()->size(), 3u);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002474}
2475
2476TEST_P(ImportData_Int_SingleParamTest, Error_Float) {
2477 auto param = GetParam();
2478
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002479 auto* call = Call(param.name, 1.f);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002480
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002481 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002482 EXPECT_EQ(td()->error(),
2483 std::string("incorrect type for ") + param.name +
2484 ". Requires integer scalar or integer vector values");
2485}
2486
2487TEST_P(ImportData_Int_SingleParamTest, Error_NoParams) {
2488 auto param = GetParam();
2489
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002490 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002491
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002492 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002493 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2494 param.name + ". Expected 1 got 0");
2495}
2496
2497TEST_P(ImportData_Int_SingleParamTest, Error_MultipleParams) {
2498 auto param = GetParam();
2499
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002500 auto* call = Call(param.name, 1, 1, 1);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002501
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002502 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002503 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2504 param.name + ". Expected 1 got 3");
2505}
2506
dan sinclairaf5df702020-06-08 23:48:26 +00002507INSTANTIATE_TEST_SUITE_P(
2508 TypeDeterminerTest,
2509 ImportData_Int_SingleParamTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00002510 testing::Values(
2511 IntrinsicData{"countOneBits", ast::Intrinsic::kCountOneBits},
2512 IntrinsicData{"reverseBits", ast::Intrinsic::kReverseBits}));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002513
dan sinclairb4fee2f2020-09-22 19:42:13 +00002514using ImportData_FloatOrInt_TwoParamTest =
2515 TypeDeterminerTestWithParam<IntrinsicData>;
2516TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Signed) {
dan sinclair92bb5572020-06-08 23:48:07 +00002517 auto param = GetParam();
2518
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002519 auto* ident = Expr(param.name);
2520 auto* call = Call(ident, 1, 1);
dan sinclair92bb5572020-06-08 23:48:07 +00002521
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002522 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002523 ASSERT_NE(ident->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00002524 EXPECT_TRUE(ident->result_type()->Is<type::I32>());
dan sinclair92bb5572020-06-08 23:48:07 +00002525}
2526
dan sinclairb4fee2f2020-09-22 19:42:13 +00002527TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Unsigned) {
dan sinclair92bb5572020-06-08 23:48:07 +00002528 auto param = GetParam();
2529
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002530 auto* ident = Expr(param.name);
2531 auto* call = Call(ident, 1u, 1u);
dan sinclair92bb5572020-06-08 23:48:07 +00002532
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002533 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002534 ASSERT_NE(ident->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00002535 EXPECT_TRUE(ident->result_type()->Is<type::U32>());
dan sinclair92bb5572020-06-08 23:48:07 +00002536}
2537
dan sinclairb4fee2f2020-09-22 19:42:13 +00002538TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Float) {
2539 auto param = GetParam();
2540
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002541 auto* ident = Expr(param.name);
2542 auto* call = Call(ident, 1.0f, 1.0f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002543
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002544 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002545 ASSERT_NE(ident->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00002546 EXPECT_TRUE(ident->result_type()->Is<type::F32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002547}
2548
2549TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Signed) {
dan sinclair92bb5572020-06-08 23:48:07 +00002550 auto param = GetParam();
2551
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002552 auto* ident = Expr(param.name);
2553 auto* call = Call(ident, vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3));
dan sinclair92bb5572020-06-08 23:48:07 +00002554
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002555 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002556 ASSERT_NE(ident->result_type(), nullptr);
2557 EXPECT_TRUE(ident->result_type()->is_signed_integer_vector());
Ben Clayton207b5e22021-01-21 15:42:10 +00002558 EXPECT_EQ(ident->result_type()->As<type::Vector>()->size(), 3u);
dan sinclair92bb5572020-06-08 23:48:07 +00002559}
2560
dan sinclairb4fee2f2020-09-22 19:42:13 +00002561TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Unsigned) {
dan sinclair92bb5572020-06-08 23:48:07 +00002562 auto param = GetParam();
2563
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002564 auto* ident = Expr(param.name);
2565 auto* call = Call(ident, vec3<u32>(1u, 1u, 3u), vec3<u32>(1u, 1u, 3u));
dan sinclair92bb5572020-06-08 23:48:07 +00002566
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002567 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002568 ASSERT_NE(ident->result_type(), nullptr);
2569 EXPECT_TRUE(ident->result_type()->is_unsigned_integer_vector());
Ben Clayton207b5e22021-01-21 15:42:10 +00002570 EXPECT_EQ(ident->result_type()->As<type::Vector>()->size(), 3u);
dan sinclair92bb5572020-06-08 23:48:07 +00002571}
2572
dan sinclairb4fee2f2020-09-22 19:42:13 +00002573TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Float) {
dan sinclair92bb5572020-06-08 23:48:07 +00002574 auto param = GetParam();
2575
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002576 auto* ident = Expr(param.name);
2577 auto* call = Call(ident, vec3<f32>(1.f, 1.f, 3.f), vec3<f32>(1.f, 1.f, 3.f));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002578
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002579 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002580 ASSERT_NE(ident->result_type(), nullptr);
2581 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Clayton207b5e22021-01-21 15:42:10 +00002582 EXPECT_EQ(ident->result_type()->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002583}
2584
2585TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_Bool) {
2586 auto param = GetParam();
2587
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002588 auto* call = Call(param.name, true, false);
dan sinclair92bb5572020-06-08 23:48:07 +00002589
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002590 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair92bb5572020-06-08 23:48:07 +00002591 EXPECT_EQ(td()->error(),
2592 std::string("incorrect type for ") + param.name +
dan sinclairb4fee2f2020-09-22 19:42:13 +00002593 ". Requires float or int, scalar or vector values");
dan sinclair92bb5572020-06-08 23:48:07 +00002594}
2595
dan sinclairb4fee2f2020-09-22 19:42:13 +00002596TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_NoParams) {
dan sinclair92bb5572020-06-08 23:48:07 +00002597 auto param = GetParam();
2598
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002599 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002600
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002601 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair92bb5572020-06-08 23:48:07 +00002602 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2603 param.name + ". Expected 2 got 0");
2604}
2605
dan sinclairb4fee2f2020-09-22 19:42:13 +00002606TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_OneParam) {
dan sinclair92bb5572020-06-08 23:48:07 +00002607 auto param = GetParam();
2608
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002609 auto* call = Call(param.name, 1);
dan sinclair92bb5572020-06-08 23:48:07 +00002610
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002611 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair92bb5572020-06-08 23:48:07 +00002612 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2613 param.name + ". Expected 2 got 1");
2614}
2615
dan sinclairb4fee2f2020-09-22 19:42:13 +00002616TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_MismatchedParamCount) {
dan sinclair92bb5572020-06-08 23:48:07 +00002617 auto param = GetParam();
2618
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002619 auto* call = Call(param.name, vec2<i32>(1, 1), vec3<i32>(1, 1, 3));
dan sinclair92bb5572020-06-08 23:48:07 +00002620
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002621 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair92bb5572020-06-08 23:48:07 +00002622 EXPECT_EQ(td()->error(),
2623 std::string("mismatched parameter types for ") + param.name);
2624}
2625
dan sinclairb4fee2f2020-09-22 19:42:13 +00002626TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_MismatchedParamType) {
dan sinclair92bb5572020-06-08 23:48:07 +00002627 auto param = GetParam();
2628
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002629 auto* call = Call(param.name, Expr(1), vec3<i32>(1, 1, 3));
dan sinclair92bb5572020-06-08 23:48:07 +00002630
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002631 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair92bb5572020-06-08 23:48:07 +00002632 EXPECT_EQ(td()->error(),
2633 std::string("mismatched parameter types for ") + param.name);
2634}
2635
dan sinclairb4fee2f2020-09-22 19:42:13 +00002636TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_TooManyParams) {
dan sinclair92bb5572020-06-08 23:48:07 +00002637 auto param = GetParam();
2638
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002639 auto* call = Call(param.name, 1, 1, 1);
dan sinclair92bb5572020-06-08 23:48:07 +00002640
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002641 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair92bb5572020-06-08 23:48:07 +00002642 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2643 param.name + ". Expected 2 got 3");
2644}
2645
dan sinclairb4fee2f2020-09-22 19:42:13 +00002646INSTANTIATE_TEST_SUITE_P(
2647 TypeDeterminerTest,
2648 ImportData_FloatOrInt_TwoParamTest,
2649 testing::Values(IntrinsicData{"min", ast::Intrinsic::kMin},
2650 IntrinsicData{"max", ast::Intrinsic::kMax}));
dan sinclair92bb5572020-06-08 23:48:07 +00002651
dan sinclair3238eaa2020-06-17 20:22:08 +00002652TEST_F(TypeDeterminerTest, ImportData_GLSL_Determinant) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002653 auto* var = Var("var", ast::StorageClass::kFunction, ty.mat3x3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00002654 mod->AddGlobalVariable(var);
dan sinclair3819c262020-06-17 18:39:17 +00002655
dan sinclair3819c262020-06-17 18:39:17 +00002656 ASSERT_TRUE(td()->Determine()) << td()->error();
2657
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002658 auto* ident = Expr("determinant");
dan sinclair3819c262020-06-17 18:39:17 +00002659
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002660 auto* call = Call(ident, "var");
Ben Clayton4bfe4612020-11-16 16:41:47 +00002661
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002662 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002663 ASSERT_NE(ident->result_type(), nullptr);
Ben Clayton207b5e22021-01-21 15:42:10 +00002664 EXPECT_TRUE(ident->result_type()->Is<type::F32>());
dan sinclair3819c262020-06-17 18:39:17 +00002665}
2666
dan sinclairb4fee2f2020-09-22 19:42:13 +00002667using ImportData_Matrix_OneParam_Test =
2668 TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair3238eaa2020-06-17 20:22:08 +00002669TEST_P(ImportData_Matrix_OneParam_Test, Error_Float) {
2670 auto param = GetParam();
2671
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002672 auto* var = Var("var", ast::StorageClass::kFunction, ty.f32);
Ben Clayton3ea3c992020-11-18 21:19:22 +00002673 mod->AddGlobalVariable(var);
dan sinclair3819c262020-06-17 18:39:17 +00002674
dan sinclair3819c262020-06-17 18:39:17 +00002675 ASSERT_TRUE(td()->Determine()) << td()->error();
2676
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002677 auto* call = Call(param.name, "var");
dan sinclair3819c262020-06-17 18:39:17 +00002678
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002679 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair3238eaa2020-06-17 20:22:08 +00002680 EXPECT_EQ(td()->error(), std::string("incorrect type for ") + param.name +
2681 ". Requires matrix value");
dan sinclair3819c262020-06-17 18:39:17 +00002682}
2683
dan sinclair3238eaa2020-06-17 20:22:08 +00002684TEST_P(ImportData_Matrix_OneParam_Test, NoParams) {
2685 auto param = GetParam();
2686
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002687 auto* call = Call(param.name);
dan sinclair3819c262020-06-17 18:39:17 +00002688
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002689 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair3238eaa2020-06-17 20:22:08 +00002690 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2691 param.name + ". Expected 1 got 0");
dan sinclair3819c262020-06-17 18:39:17 +00002692}
2693
dan sinclair3238eaa2020-06-17 20:22:08 +00002694TEST_P(ImportData_Matrix_OneParam_Test, TooManyParams) {
2695 auto param = GetParam();
2696
Ben Clayton1637cbb2021-01-05 15:44:39 +00002697 auto* var = Var("var", ast::StorageClass::kFunction, ty.mat3x3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00002698 mod->AddGlobalVariable(var);
dan sinclair3819c262020-06-17 18:39:17 +00002699
dan sinclair3819c262020-06-17 18:39:17 +00002700 ASSERT_TRUE(td()->Determine()) << td()->error();
2701
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002702 auto* call = Call(param.name, "var", "var");
dan sinclair3819c262020-06-17 18:39:17 +00002703
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002704 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair3238eaa2020-06-17 20:22:08 +00002705 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2706 param.name + ". Expected 1 got 2");
dan sinclair3819c262020-06-17 18:39:17 +00002707}
dan sinclaire9598d62020-06-18 18:03:00 +00002708INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00002709 ImportData_Matrix_OneParam_Test,
2710 testing::Values(IntrinsicData{
2711 "determinant", ast::Intrinsic::kDeterminant}));
dan sinclaire9598d62020-06-18 18:03:00 +00002712
dan sinclair05926432020-09-21 17:51:31 +00002713TEST_F(TypeDeterminerTest, Function_EntryPoints_StageDecoration) {
dan sinclair05926432020-09-21 17:51:31 +00002714 // fn b() {}
2715 // fn c() { b(); }
2716 // fn a() { c(); }
2717 // fn ep_1() { a(); b(); }
2718 // fn ep_2() { c();}
2719 //
2720 // c -> {ep_1, ep_2}
2721 // a -> {ep_1}
2722 // b -> {ep_1, ep_2}
2723 // ep_1 -> {}
2724 // ep_2 -> {}
2725
2726 ast::VariableList params;
dan sinclair181d8ba2020-12-16 15:15:40 +00002727 auto* func_b = Func("b", params, ty.f32, ast::StatementList{},
2728 ast::FunctionDecorationList{});
dan sinclaira41132f2020-12-11 18:24:53 +00002729 auto* func_c =
dan sinclair181d8ba2020-12-16 15:15:40 +00002730 Func("c", params, ty.f32,
2731 ast::StatementList{
2732 create<ast::AssignmentStatement>(Expr("second"), Call("b")),
2733 },
2734 ast::FunctionDecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00002735
dan sinclaira41132f2020-12-11 18:24:53 +00002736 auto* func_a =
dan sinclair181d8ba2020-12-16 15:15:40 +00002737 Func("a", params, ty.f32,
2738 ast::StatementList{
2739 create<ast::AssignmentStatement>(Expr("first"), Call("c")),
2740 },
2741 ast::FunctionDecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00002742
dan sinclair181d8ba2020-12-16 15:15:40 +00002743 auto* ep_1 =
2744 Func("ep_1", params, ty.f32,
2745 ast::StatementList{
2746 create<ast::AssignmentStatement>(Expr("call_a"), Call("a")),
2747 create<ast::AssignmentStatement>(Expr("call_b"), Call("b")),
2748 },
2749 ast::FunctionDecorationList{
2750 create<ast::StageDecoration>(ast::PipelineStage::kVertex),
2751 });
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002752
dan sinclair181d8ba2020-12-16 15:15:40 +00002753 auto* ep_2 =
2754 Func("ep_2", params, ty.f32,
2755 ast::StatementList{
2756 create<ast::AssignmentStatement>(Expr("call_c"), Call("c")),
2757 },
2758 ast::FunctionDecorationList{
2759 create<ast::StageDecoration>(ast::PipelineStage::kVertex),
2760 });
dan sinclair05926432020-09-21 17:51:31 +00002761
Ben Clayton3ea3c992020-11-18 21:19:22 +00002762 mod->AddFunction(func_b);
2763 mod->AddFunction(func_c);
2764 mod->AddFunction(func_a);
2765 mod->AddFunction(ep_1);
2766 mod->AddFunction(ep_2);
dan sinclair05926432020-09-21 17:51:31 +00002767
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002768 mod->AddGlobalVariable(Var("first", ast::StorageClass::kPrivate, ty.f32));
2769 mod->AddGlobalVariable(Var("second", ast::StorageClass::kPrivate, ty.f32));
2770 mod->AddGlobalVariable(Var("call_a", ast::StorageClass::kPrivate, ty.f32));
2771 mod->AddGlobalVariable(Var("call_b", ast::StorageClass::kPrivate, ty.f32));
2772 mod->AddGlobalVariable(Var("call_c", ast::StorageClass::kPrivate, ty.f32));
dan sinclairff267ca2020-10-14 18:26:31 +00002773
dan sinclair05926432020-09-21 17:51:31 +00002774 // Register the functions and calculate the callers
2775 ASSERT_TRUE(td()->Determine()) << td()->error();
2776
Ben Clayton4bfe4612020-11-16 16:41:47 +00002777 const auto& b_eps = func_b->ancestor_entry_points();
dan sinclair05926432020-09-21 17:51:31 +00002778 ASSERT_EQ(2u, b_eps.size());
dan sinclaira41132f2020-12-11 18:24:53 +00002779 EXPECT_EQ(mod->RegisterSymbol("ep_1"), b_eps[0]);
2780 EXPECT_EQ(mod->RegisterSymbol("ep_2"), b_eps[1]);
dan sinclair05926432020-09-21 17:51:31 +00002781
Ben Clayton4bfe4612020-11-16 16:41:47 +00002782 const auto& a_eps = func_a->ancestor_entry_points();
dan sinclair05926432020-09-21 17:51:31 +00002783 ASSERT_EQ(1u, a_eps.size());
dan sinclaira41132f2020-12-11 18:24:53 +00002784 EXPECT_EQ(mod->RegisterSymbol("ep_1"), a_eps[0]);
dan sinclair05926432020-09-21 17:51:31 +00002785
Ben Clayton4bfe4612020-11-16 16:41:47 +00002786 const auto& c_eps = func_c->ancestor_entry_points();
dan sinclair05926432020-09-21 17:51:31 +00002787 ASSERT_EQ(2u, c_eps.size());
dan sinclaira41132f2020-12-11 18:24:53 +00002788 EXPECT_EQ(mod->RegisterSymbol("ep_1"), c_eps[0]);
2789 EXPECT_EQ(mod->RegisterSymbol("ep_2"), c_eps[1]);
dan sinclair05926432020-09-21 17:51:31 +00002790
Ben Clayton4bfe4612020-11-16 16:41:47 +00002791 EXPECT_TRUE(ep_1->ancestor_entry_points().empty());
2792 EXPECT_TRUE(ep_2->ancestor_entry_points().empty());
dan sinclair05926432020-09-21 17:51:31 +00002793}
2794
Ben Clayton3ea3c992020-11-18 21:19:22 +00002795using TypeDeterminerTextureIntrinsicTest =
2796 TypeDeterminerTestWithParam<ast::intrinsic::test::TextureOverloadCase>;
2797
2798INSTANTIATE_TEST_SUITE_P(
2799 TypeDeterminerTest,
2800 TypeDeterminerTextureIntrinsicTest,
2801 testing::ValuesIn(ast::intrinsic::test::TextureOverloadCase::ValidCases()));
2802
2803std::string to_str(const std::string& function,
2804 const ast::intrinsic::TextureSignature* sig) {
2805 struct Parameter {
2806 size_t idx;
2807 std::string name;
2808 };
2809 std::vector<Parameter> params;
2810 auto maybe_add_param = [&params](size_t idx, const char* name) {
2811 if (idx != ast::intrinsic::TextureSignature::Parameters::kNotUsed) {
2812 params.emplace_back(Parameter{idx, name});
2813 }
2814 };
2815 maybe_add_param(sig->params.idx.array_index, "array_index");
2816 maybe_add_param(sig->params.idx.bias, "bias");
2817 maybe_add_param(sig->params.idx.coords, "coords");
2818 maybe_add_param(sig->params.idx.depth_ref, "depth_ref");
2819 maybe_add_param(sig->params.idx.ddx, "ddx");
2820 maybe_add_param(sig->params.idx.ddy, "ddy");
2821 maybe_add_param(sig->params.idx.level, "level");
2822 maybe_add_param(sig->params.idx.offset, "offset");
2823 maybe_add_param(sig->params.idx.sampler, "sampler");
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002824 maybe_add_param(sig->params.idx.sample_index, "sample_index");
Ben Clayton3ea3c992020-11-18 21:19:22 +00002825 maybe_add_param(sig->params.idx.texture, "texture");
Ben Clayton591268d2020-12-10 18:39:41 +00002826 maybe_add_param(sig->params.idx.value, "value");
Ben Clayton3ea3c992020-11-18 21:19:22 +00002827 std::sort(
2828 params.begin(), params.end(),
2829 [](const Parameter& a, const Parameter& b) { return a.idx < b.idx; });
2830
2831 std::stringstream out;
2832 out << function << "(";
2833 bool first = true;
2834 for (auto& param : params) {
2835 if (!first) {
2836 out << ", ";
2837 }
2838 out << param.name;
2839 first = false;
2840 }
2841 out << ")";
2842 return out.str();
2843}
2844
2845const char* expected_texture_overload(
2846 ast::intrinsic::test::ValidTextureOverload overload) {
2847 using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
2848 switch (overload) {
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002849 case ValidTextureOverload::kDimensions1d:
2850 case ValidTextureOverload::kDimensions1dArray:
2851 case ValidTextureOverload::kDimensions2d:
2852 case ValidTextureOverload::kDimensions2dArray:
2853 case ValidTextureOverload::kDimensions3d:
2854 case ValidTextureOverload::kDimensionsCube:
2855 case ValidTextureOverload::kDimensionsCubeArray:
Ben Clayton6e5b5ec2021-01-14 18:09:07 +00002856 case ValidTextureOverload::kDimensionsMultisampled2d:
2857 case ValidTextureOverload::kDimensionsMultisampled2dArray:
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002858 case ValidTextureOverload::kDimensionsDepth2d:
2859 case ValidTextureOverload::kDimensionsDepth2dArray:
2860 case ValidTextureOverload::kDimensionsDepthCube:
2861 case ValidTextureOverload::kDimensionsDepthCubeArray:
2862 case ValidTextureOverload::kDimensionsStorageRO1d:
2863 case ValidTextureOverload::kDimensionsStorageRO1dArray:
2864 case ValidTextureOverload::kDimensionsStorageRO2d:
2865 case ValidTextureOverload::kDimensionsStorageRO2dArray:
2866 case ValidTextureOverload::kDimensionsStorageRO3d:
2867 case ValidTextureOverload::kDimensionsStorageWO1d:
2868 case ValidTextureOverload::kDimensionsStorageWO1dArray:
2869 case ValidTextureOverload::kDimensionsStorageWO2d:
2870 case ValidTextureOverload::kDimensionsStorageWO2dArray:
2871 case ValidTextureOverload::kDimensionsStorageWO3d:
2872 return R"(textureDimensions(texture))";
Ben Claytonc21f1f92021-01-14 16:50:07 +00002873 case ValidTextureOverload::kNumLayers1dArray:
2874 case ValidTextureOverload::kNumLayers2dArray:
2875 case ValidTextureOverload::kNumLayersCubeArray:
Ben Clayton6e5b5ec2021-01-14 18:09:07 +00002876 case ValidTextureOverload::kNumLayersMultisampled2dArray:
Ben Claytonc21f1f92021-01-14 16:50:07 +00002877 case ValidTextureOverload::kNumLayersDepth2dArray:
2878 case ValidTextureOverload::kNumLayersDepthCubeArray:
2879 case ValidTextureOverload::kNumLayersStorageWO1dArray:
2880 case ValidTextureOverload::kNumLayersStorageWO2dArray:
2881 return R"(textureNumLayers(texture))";
Ben Claytond9713202021-01-14 18:06:57 +00002882 case ValidTextureOverload::kNumLevels2d:
2883 case ValidTextureOverload::kNumLevels2dArray:
2884 case ValidTextureOverload::kNumLevels3d:
2885 case ValidTextureOverload::kNumLevelsCube:
2886 case ValidTextureOverload::kNumLevelsCubeArray:
2887 case ValidTextureOverload::kNumLevelsDepth2d:
2888 case ValidTextureOverload::kNumLevelsDepth2dArray:
2889 case ValidTextureOverload::kNumLevelsDepthCube:
2890 case ValidTextureOverload::kNumLevelsDepthCubeArray:
2891 return R"(textureNumLevels(texture))";
Ben Clayton0a68b362021-01-14 18:11:17 +00002892 case ValidTextureOverload::kNumSamplesMultisampled2d:
2893 case ValidTextureOverload::kNumSamplesMultisampled2dArray:
2894 return R"(textureNumSamples(texture))";
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002895 case ValidTextureOverload::kDimensions2dLevel:
2896 case ValidTextureOverload::kDimensions2dArrayLevel:
2897 case ValidTextureOverload::kDimensions3dLevel:
2898 case ValidTextureOverload::kDimensionsCubeLevel:
2899 case ValidTextureOverload::kDimensionsCubeArrayLevel:
2900 case ValidTextureOverload::kDimensionsDepth2dLevel:
2901 case ValidTextureOverload::kDimensionsDepth2dArrayLevel:
2902 case ValidTextureOverload::kDimensionsDepthCubeLevel:
2903 case ValidTextureOverload::kDimensionsDepthCubeArrayLevel:
2904 return R"(textureDimensions(texture, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002905 case ValidTextureOverload::kSample1dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002906 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002907 case ValidTextureOverload::kSample1dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002908 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002909 case ValidTextureOverload::kSample2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002910 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002911 case ValidTextureOverload::kSample2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002912 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002913 case ValidTextureOverload::kSample2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002914 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002915 case ValidTextureOverload::kSample2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002916 return R"(textureSample(texture, sampler, coords, array_index, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002917 case ValidTextureOverload::kSample3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002918 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002919 case ValidTextureOverload::kSample3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002920 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002921 case ValidTextureOverload::kSampleCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002922 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002923 case ValidTextureOverload::kSampleCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002924 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002925 case ValidTextureOverload::kSampleDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002926 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002927 case ValidTextureOverload::kSampleDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002928 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002929 case ValidTextureOverload::kSampleDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002930 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002931 case ValidTextureOverload::kSampleDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002932 return R"(textureSample(texture, sampler, coords, array_index, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002933 case ValidTextureOverload::kSampleDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002934 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002935 case ValidTextureOverload::kSampleDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002936 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002937 case ValidTextureOverload::kSampleBias2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002938 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002939 case ValidTextureOverload::kSampleBias2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002940 return R"(textureSampleBias(texture, sampler, coords, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002941 case ValidTextureOverload::kSampleBias2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002942 return R"(textureSampleBias(texture, sampler, coords, array_index, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002943 case ValidTextureOverload::kSampleBias2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002944 return R"(textureSampleBias(texture, sampler, coords, array_index, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002945 case ValidTextureOverload::kSampleBias3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002946 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002947 case ValidTextureOverload::kSampleBias3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002948 return R"(textureSampleBias(texture, sampler, coords, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002949 case ValidTextureOverload::kSampleBiasCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002950 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002951 case ValidTextureOverload::kSampleBiasCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002952 return R"(textureSampleBias(texture, sampler, coords, array_index, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002953 case ValidTextureOverload::kSampleLevel2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002954 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002955 case ValidTextureOverload::kSampleLevel2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002956 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002957 case ValidTextureOverload::kSampleLevel2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002958 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002959 case ValidTextureOverload::kSampleLevel2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002960 return R"(textureSampleLevel(texture, sampler, coords, array_index, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002961 case ValidTextureOverload::kSampleLevel3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002962 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002963 case ValidTextureOverload::kSampleLevel3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002964 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002965 case ValidTextureOverload::kSampleLevelCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002966 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002967 case ValidTextureOverload::kSampleLevelCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002968 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002969 case ValidTextureOverload::kSampleLevelDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002970 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002971 case ValidTextureOverload::kSampleLevelDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002972 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002973 case ValidTextureOverload::kSampleLevelDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002974 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002975 case ValidTextureOverload::kSampleLevelDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002976 return R"(textureSampleLevel(texture, sampler, coords, array_index, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002977 case ValidTextureOverload::kSampleLevelDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002978 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002979 case ValidTextureOverload::kSampleLevelDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002980 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002981 case ValidTextureOverload::kSampleGrad2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002982 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002983 case ValidTextureOverload::kSampleGrad2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002984 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002985 case ValidTextureOverload::kSampleGrad2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002986 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002987 case ValidTextureOverload::kSampleGrad2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002988 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002989 case ValidTextureOverload::kSampleGrad3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002990 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002991 case ValidTextureOverload::kSampleGrad3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002992 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002993 case ValidTextureOverload::kSampleGradCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002994 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002995 case ValidTextureOverload::kSampleGradCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002996 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy))";
Ben Clayton57166262021-01-13 16:36:51 +00002997 case ValidTextureOverload::kSampleCompareDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002998 return R"(textureSampleCompare(texture, sampler, coords, depth_ref))";
Ben Clayton57166262021-01-13 16:36:51 +00002999 case ValidTextureOverload::kSampleCompareDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003000 return R"(textureSampleCompare(texture, sampler, coords, depth_ref, offset))";
Ben Clayton57166262021-01-13 16:36:51 +00003001 case ValidTextureOverload::kSampleCompareDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003002 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref))";
Ben Clayton57166262021-01-13 16:36:51 +00003003 case ValidTextureOverload::kSampleCompareDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003004 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref, offset))";
Ben Clayton57166262021-01-13 16:36:51 +00003005 case ValidTextureOverload::kSampleCompareDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003006 return R"(textureSampleCompare(texture, sampler, coords, depth_ref))";
Ben Clayton57166262021-01-13 16:36:51 +00003007 case ValidTextureOverload::kSampleCompareDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003008 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref))";
3009 case ValidTextureOverload::kLoad1dF32:
3010 return R"(textureLoad(texture, coords))";
3011 case ValidTextureOverload::kLoad1dU32:
3012 return R"(textureLoad(texture, coords))";
3013 case ValidTextureOverload::kLoad1dI32:
3014 return R"(textureLoad(texture, coords))";
3015 case ValidTextureOverload::kLoad1dArrayF32:
3016 return R"(textureLoad(texture, coords, array_index))";
3017 case ValidTextureOverload::kLoad1dArrayU32:
3018 return R"(textureLoad(texture, coords, array_index))";
3019 case ValidTextureOverload::kLoad1dArrayI32:
3020 return R"(textureLoad(texture, coords, array_index))";
3021 case ValidTextureOverload::kLoad2dF32:
3022 return R"(textureLoad(texture, coords))";
3023 case ValidTextureOverload::kLoad2dU32:
3024 return R"(textureLoad(texture, coords))";
3025 case ValidTextureOverload::kLoad2dI32:
3026 return R"(textureLoad(texture, coords))";
3027 case ValidTextureOverload::kLoad2dLevelF32:
3028 return R"(textureLoad(texture, coords, level))";
3029 case ValidTextureOverload::kLoad2dLevelU32:
3030 return R"(textureLoad(texture, coords, level))";
3031 case ValidTextureOverload::kLoad2dLevelI32:
3032 return R"(textureLoad(texture, coords, level))";
3033 case ValidTextureOverload::kLoad2dArrayF32:
3034 return R"(textureLoad(texture, coords, array_index))";
3035 case ValidTextureOverload::kLoad2dArrayU32:
3036 return R"(textureLoad(texture, coords, array_index))";
3037 case ValidTextureOverload::kLoad2dArrayI32:
3038 return R"(textureLoad(texture, coords, array_index))";
3039 case ValidTextureOverload::kLoad2dArrayLevelF32:
3040 return R"(textureLoad(texture, coords, array_index, level))";
3041 case ValidTextureOverload::kLoad2dArrayLevelU32:
3042 return R"(textureLoad(texture, coords, array_index, level))";
3043 case ValidTextureOverload::kLoad2dArrayLevelI32:
3044 return R"(textureLoad(texture, coords, array_index, level))";
3045 case ValidTextureOverload::kLoad3dF32:
3046 return R"(textureLoad(texture, coords))";
3047 case ValidTextureOverload::kLoad3dU32:
3048 return R"(textureLoad(texture, coords))";
3049 case ValidTextureOverload::kLoad3dI32:
3050 return R"(textureLoad(texture, coords))";
3051 case ValidTextureOverload::kLoad3dLevelF32:
3052 return R"(textureLoad(texture, coords, level))";
3053 case ValidTextureOverload::kLoad3dLevelU32:
3054 return R"(textureLoad(texture, coords, level))";
3055 case ValidTextureOverload::kLoad3dLevelI32:
3056 return R"(textureLoad(texture, coords, level))";
3057 case ValidTextureOverload::kLoadMultisampled2dF32:
3058 return R"(textureLoad(texture, coords, sample_index))";
3059 case ValidTextureOverload::kLoadMultisampled2dU32:
3060 return R"(textureLoad(texture, coords, sample_index))";
3061 case ValidTextureOverload::kLoadMultisampled2dI32:
3062 return R"(textureLoad(texture, coords, sample_index))";
3063 case ValidTextureOverload::kLoadMultisampled2dArrayF32:
3064 return R"(textureLoad(texture, coords, array_index, sample_index))";
3065 case ValidTextureOverload::kLoadMultisampled2dArrayU32:
3066 return R"(textureLoad(texture, coords, array_index, sample_index))";
3067 case ValidTextureOverload::kLoadMultisampled2dArrayI32:
3068 return R"(textureLoad(texture, coords, array_index, sample_index))";
3069 case ValidTextureOverload::kLoadDepth2dF32:
3070 return R"(textureLoad(texture, coords))";
3071 case ValidTextureOverload::kLoadDepth2dLevelF32:
3072 return R"(textureLoad(texture, coords, level))";
3073 case ValidTextureOverload::kLoadDepth2dArrayF32:
3074 return R"(textureLoad(texture, coords, array_index))";
3075 case ValidTextureOverload::kLoadDepth2dArrayLevelF32:
3076 return R"(textureLoad(texture, coords, array_index, level))";
3077 case ValidTextureOverload::kLoadStorageRO1dRgba32float:
3078 return R"(textureLoad(texture, coords))";
3079 case ValidTextureOverload::kLoadStorageRO1dArrayRgba32float:
3080 return R"(textureLoad(texture, coords, array_index))";
3081 case ValidTextureOverload::kLoadStorageRO2dRgba8unorm:
3082 case ValidTextureOverload::kLoadStorageRO2dRgba8snorm:
3083 case ValidTextureOverload::kLoadStorageRO2dRgba8uint:
3084 case ValidTextureOverload::kLoadStorageRO2dRgba8sint:
3085 case ValidTextureOverload::kLoadStorageRO2dRgba16uint:
3086 case ValidTextureOverload::kLoadStorageRO2dRgba16sint:
3087 case ValidTextureOverload::kLoadStorageRO2dRgba16float:
3088 case ValidTextureOverload::kLoadStorageRO2dR32uint:
3089 case ValidTextureOverload::kLoadStorageRO2dR32sint:
3090 case ValidTextureOverload::kLoadStorageRO2dR32float:
3091 case ValidTextureOverload::kLoadStorageRO2dRg32uint:
3092 case ValidTextureOverload::kLoadStorageRO2dRg32sint:
3093 case ValidTextureOverload::kLoadStorageRO2dRg32float:
3094 case ValidTextureOverload::kLoadStorageRO2dRgba32uint:
3095 case ValidTextureOverload::kLoadStorageRO2dRgba32sint:
3096 case ValidTextureOverload::kLoadStorageRO2dRgba32float:
3097 return R"(textureLoad(texture, coords))";
3098 case ValidTextureOverload::kLoadStorageRO2dArrayRgba32float:
3099 return R"(textureLoad(texture, coords, array_index))";
3100 case ValidTextureOverload::kLoadStorageRO3dRgba32float:
3101 return R"(textureLoad(texture, coords))";
Ben Clayton591268d2020-12-10 18:39:41 +00003102 case ValidTextureOverload::kStoreWO1dRgba32float:
3103 return R"(textureStore(texture, coords, value))";
3104 case ValidTextureOverload::kStoreWO1dArrayRgba32float:
3105 return R"(textureStore(texture, coords, array_index, value))";
3106 case ValidTextureOverload::kStoreWO2dRgba32float:
3107 return R"(textureStore(texture, coords, value))";
3108 case ValidTextureOverload::kStoreWO2dArrayRgba32float:
3109 return R"(textureStore(texture, coords, array_index, value))";
3110 case ValidTextureOverload::kStoreWO3dRgba32float:
3111 return R"(textureStore(texture, coords, value))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003112 }
3113 return "<unmatched texture overload>";
3114}
3115
3116TEST_P(TypeDeterminerTextureIntrinsicTest, Call) {
3117 auto param = GetParam();
3118
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003119 param.buildTextureVariable(this);
3120 param.buildSamplerVariable(this);
Ben Clayton3ea3c992020-11-18 21:19:22 +00003121
3122 auto* ident = Expr(param.function);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00003123 auto* call = Call(ident, param.args(this));
Ben Clayton3ea3c992020-11-18 21:19:22 +00003124
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003125 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton7eaf4b52020-12-14 22:08:27 +00003126 ASSERT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton3ea3c992020-11-18 21:19:22 +00003127
Ben Clayton4a0b9f72021-01-11 21:07:32 +00003128 if (std::string(param.function) == "textureDimensions") {
3129 switch (param.texture_dimension) {
3130 default:
3131 FAIL() << "invalid texture dimensions: " << param.texture_dimension;
Ben Clayton207b5e22021-01-21 15:42:10 +00003132 case type::TextureDimension::k1d:
3133 case type::TextureDimension::k1dArray:
Ben Clayton4a0b9f72021-01-11 21:07:32 +00003134 EXPECT_EQ(call->result_type()->type_name(), ty.i32->type_name());
3135 break;
Ben Clayton207b5e22021-01-21 15:42:10 +00003136 case type::TextureDimension::k2d:
3137 case type::TextureDimension::k2dArray:
Ben Clayton4a0b9f72021-01-11 21:07:32 +00003138 EXPECT_EQ(call->result_type()->type_name(),
3139 ty.vec2<i32>()->type_name());
3140 break;
Ben Clayton207b5e22021-01-21 15:42:10 +00003141 case type::TextureDimension::k3d:
3142 case type::TextureDimension::kCube:
3143 case type::TextureDimension::kCubeArray:
Ben Clayton4a0b9f72021-01-11 21:07:32 +00003144 EXPECT_EQ(call->result_type()->type_name(),
3145 ty.vec3<i32>()->type_name());
3146 break;
3147 }
Ben Claytonc21f1f92021-01-14 16:50:07 +00003148 } else if (std::string(param.function) == "textureNumLayers") {
3149 EXPECT_EQ(call->result_type(), ty.i32);
Ben Claytond9713202021-01-14 18:06:57 +00003150 } else if (std::string(param.function) == "textureNumLevels") {
3151 EXPECT_EQ(call->result_type(), ty.i32);
Ben Clayton0a68b362021-01-14 18:11:17 +00003152 } else if (std::string(param.function) == "textureNumSamples") {
3153 EXPECT_EQ(call->result_type(), ty.i32);
Ben Clayton4a0b9f72021-01-11 21:07:32 +00003154 } else if (std::string(param.function) == "textureStore") {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00003155 EXPECT_EQ(call->result_type(), ty.void_);
Ben Clayton591268d2020-12-10 18:39:41 +00003156 } else {
3157 switch (param.texture_kind) {
3158 case ast::intrinsic::test::TextureKind::kRegular:
3159 case ast::intrinsic::test::TextureKind::kMultisampled:
3160 case ast::intrinsic::test::TextureKind::kStorage: {
3161 auto* datatype = param.resultVectorComponentType(this);
Ben Clayton207b5e22021-01-21 15:42:10 +00003162 ASSERT_TRUE(call->result_type()->Is<type::Vector>());
3163 EXPECT_EQ(call->result_type()->As<type::Vector>()->type(), datatype);
Ben Clayton591268d2020-12-10 18:39:41 +00003164 break;
3165 }
3166 case ast::intrinsic::test::TextureKind::kDepth: {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00003167 EXPECT_EQ(call->result_type(), ty.f32);
Ben Clayton591268d2020-12-10 18:39:41 +00003168 break;
3169 }
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003170 }
Ben Clayton3ea3c992020-11-18 21:19:22 +00003171 }
3172
3173 auto* sig = static_cast<const ast::intrinsic::TextureSignature*>(
3174 ident->intrinsic_signature());
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003175 ASSERT_NE(sig, nullptr);
Ben Clayton3ea3c992020-11-18 21:19:22 +00003176
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003177 auto got = to_str(param.function, sig);
Ben Clayton3ea3c992020-11-18 21:19:22 +00003178 auto* expected = expected_texture_overload(param.overload);
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003179 EXPECT_EQ(got, expected);
Ben Clayton3ea3c992020-11-18 21:19:22 +00003180}
3181
dan sinclairb7edc4c2020-04-07 12:46:30 +00003182} // namespace
3183} // namespace tint