blob: f35214040f0cc2b33246e1a743e94afa1942c0e6 [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 sinclairb445a9b2020-04-24 00:40:45 +000050#include "src/ast/type/alias_type.h"
dan sinclair973bd6a2020-04-07 12:57:42 +000051#include "src/ast/type/array_type.h"
dan sinclair9b978022020-04-07 19:26:39 +000052#include "src/ast/type/bool_type.h"
Tomek Ponitka1a61fc42020-08-31 15:24:54 +000053#include "src/ast/type/depth_texture_type.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000054#include "src/ast/type/f32_type.h"
dan sinclair6c498fc2020-04-07 12:47:23 +000055#include "src/ast/type/i32_type.h"
dan sinclair973bd6a2020-04-07 12:57:42 +000056#include "src/ast/type/matrix_type.h"
Ben Clayton7f04e5c2020-12-09 15:57:00 +000057#include "src/ast/type/multisampled_texture_type.h"
dan sinclair8eddb782020-04-23 22:26:52 +000058#include "src/ast/type/pointer_type.h"
Tomek Ponitka1a61fc42020-08-31 15:24:54 +000059#include "src/ast/type/sampled_texture_type.h"
60#include "src/ast/type/sampler_type.h"
61#include "src/ast/type/storage_texture_type.h"
dan sinclair8ee1d222020-04-07 16:41:33 +000062#include "src/ast/type/struct_type.h"
Tomek Ponitka1a61fc42020-08-31 15:24:54 +000063#include "src/ast/type/texture_type.h"
dan sinclair92bb5572020-06-08 23:48:07 +000064#include "src/ast/type/u32_type.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000065#include "src/ast/type/vector_type.h"
66#include "src/ast/type_constructor_expression.h"
dan sinclair92bb5572020-06-08 23:48:07 +000067#include "src/ast/uint_literal.h"
dan sinclair327ed1b2020-04-07 19:27:21 +000068#include "src/ast/unary_op_expression.h"
dan sinclairca893e32020-04-07 12:57:12 +000069#include "src/ast/variable_decl_statement.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 Claytoned2b9782020-12-01 18:04:17 +000077 FakeStmt* Clone(ast::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 Claytoned2b9782020-12-01 18:04:17 +000085 FakeExpr* Clone(ast::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 Claytonf1b0e1e2020-11-30 23:30:58 +0000136 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
137 EXPECT_TRUE(rhs->result_type()->Is<ast::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 Claytonf1b0e1e2020-11-30 23:30:58 +0000154 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
155 EXPECT_TRUE(rhs->result_type()->Is<ast::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 Claytonf1b0e1e2020-11-30 23:30:58 +0000169 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
170 EXPECT_TRUE(rhs->result_type()->Is<ast::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 Clayton7eaf4b52020-12-14 22:08:27 +0000186 EXPECT_TRUE(stmt->condition()->result_type()->Is<ast::type::I32>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000187 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
188 EXPECT_TRUE(rhs->result_type()->Is<ast::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 Clayton7eaf4b52020-12-14 22:08:27 +0000216 EXPECT_TRUE(stmt->condition()->result_type()->Is<ast::type::I32>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000217 EXPECT_TRUE(else_lhs->result_type()->Is<ast::type::I32>());
218 EXPECT_TRUE(else_rhs->result_type()->Is<ast::type::F32>());
219 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
220 EXPECT_TRUE(rhs->result_type()->Is<ast::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 Claytonf1b0e1e2020-11-30 23:30:58 +0000245 EXPECT_TRUE(body_lhs->result_type()->Is<ast::type::I32>());
246 EXPECT_TRUE(body_rhs->result_type()->Is<ast::type::F32>());
247 EXPECT_TRUE(continuing_lhs->result_type()->Is<ast::type::I32>());
248 EXPECT_TRUE(continuing_rhs->result_type()->Is<ast::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 Claytonf1b0e1e2020-11-30 23:30:58 +0000258 EXPECT_TRUE(cond->result_type()->Is<ast::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 Clayton7eaf4b52020-12-14 22:08:27 +0000286 EXPECT_TRUE(stmt->condition()->result_type()->Is<ast::type::I32>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000287 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
288 EXPECT_TRUE(rhs->result_type()->Is<ast::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 Claytonf1b0e1e2020-11-30 23:30:58 +0000305 EXPECT_TRUE(expr->result_type()->Is<ast::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 Claytonf1b0e1e2020-11-30 23:30:58 +0000345 EXPECT_TRUE(init->result_type()->Is<ast::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 Claytonf1b0e1e2020-11-30 23:30:58 +0000357 EXPECT_TRUE(init->result_type()->Is<ast::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 ast::type::Array ary(ty.f32, 3, ast::ArrayDecorationList{});
dan sinclair973bd6a2020-04-07 12:57:42 +0000369
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000370 auto* idx = Expr(2);
371 auto* var = Var("my_var", ast::StorageClass::kFunction, &ary);
Ben Clayton3ea3c992020-11-18 21:19:22 +0000372 mod->AddGlobalVariable(var);
dan sinclair8eddb782020-04-23 22:26:52 +0000373
dan sinclair8eddb782020-04-23 22:26:52 +0000374 EXPECT_TRUE(td()->Determine());
375
dan sinclair8b40a672020-12-16 11:49:10 +0000376 auto* acc = IndexAccessor("my_var", idx);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000377 EXPECT_TRUE(td()->DetermineResultType(acc));
378 ASSERT_NE(acc->result_type(), nullptr);
379 ASSERT_TRUE(acc->result_type()->Is<ast::type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000380
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000381 auto* ptr = acc->result_type()->As<ast::type::Pointer>();
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000382 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000383}
384
David Neto9c88ea52020-06-22 20:33:12 +0000385TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Alias_Array) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000386 ast::type::Array ary(ty.f32, 3, ast::ArrayDecorationList{});
dan sinclair4226b6a2020-12-11 19:35:03 +0000387 ast::type::Alias aary(mod->RegisterSymbol("myarrty"), "myarrty", &ary);
David Neto9c88ea52020-06-22 20:33:12 +0000388
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000389 auto* var = Var("my_var", ast::StorageClass::kFunction, &aary);
Ben Clayton3ea3c992020-11-18 21:19:22 +0000390 mod->AddGlobalVariable(var);
David Neto9c88ea52020-06-22 20:33:12 +0000391
David Neto9c88ea52020-06-22 20:33:12 +0000392 EXPECT_TRUE(td()->Determine());
393
dan sinclair8b40a672020-12-16 11:49:10 +0000394 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000395 EXPECT_TRUE(td()->DetermineResultType(acc));
396 ASSERT_NE(acc->result_type(), nullptr);
397 ASSERT_TRUE(acc->result_type()->Is<ast::type::Pointer>());
David Neto9c88ea52020-06-22 20:33:12 +0000398
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000399 auto* ptr = acc->result_type()->As<ast::type::Pointer>();
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000400 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
David Neto9c88ea52020-06-22 20:33:12 +0000401}
402
dan sinclair8eddb782020-04-23 22:26:52 +0000403TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array_Constant) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000404 ast::type::Array ary(ty.f32, 3, ast::ArrayDecorationList{});
dan sinclair8eddb782020-04-23 22:26:52 +0000405
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000406 auto* var = Const("my_var", ast::StorageClass::kFunction, &ary);
Ben Clayton3ea3c992020-11-18 21:19:22 +0000407 mod->AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000408
dan sinclairb950e802020-04-20 14:20:01 +0000409 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000410
dan sinclair8b40a672020-12-16 11:49:10 +0000411 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000412 EXPECT_TRUE(td()->DetermineResultType(acc));
413 ASSERT_NE(acc->result_type(), nullptr);
414 EXPECT_TRUE(acc->result_type()->Is<ast::type::F32>())
415 << acc->result_type()->type_name();
dan sinclair973bd6a2020-04-07 12:57:42 +0000416}
417
418TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000419 ast::type::Matrix mat(ty.f32, 3, 2);
dan sinclair973bd6a2020-04-07 12:57:42 +0000420
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000421 auto* var = Var("my_var", ast::StorageClass::kNone, &mat);
Ben Clayton3ea3c992020-11-18 21:19:22 +0000422 mod->AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000423
dan sinclairb950e802020-04-20 14:20:01 +0000424 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000425
dan sinclair8b40a672020-12-16 11:49:10 +0000426 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000427 EXPECT_TRUE(td()->DetermineResultType(acc));
428 ASSERT_NE(acc->result_type(), nullptr);
429 ASSERT_TRUE(acc->result_type()->Is<ast::type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000430
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000431 auto* ptr = acc->result_type()->As<ast::type::Pointer>();
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000432 ASSERT_TRUE(ptr->type()->Is<ast::type::Vector>());
433 EXPECT_EQ(ptr->type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair973bd6a2020-04-07 12:57:42 +0000434}
435
436TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix_BothDimensions) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000437 auto* var = Var("my_var", ast::StorageClass::kNone, ty.mat2x3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +0000438 mod->AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000439
dan sinclairb950e802020-04-20 14:20:01 +0000440 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000441
dan sinclair8b40a672020-12-16 11:49:10 +0000442 auto* acc = IndexAccessor(IndexAccessor("my_var", 2), 1);
dan sinclair973bd6a2020-04-07 12:57:42 +0000443
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000444 EXPECT_TRUE(td()->DetermineResultType(acc));
445 ASSERT_NE(acc->result_type(), nullptr);
446 ASSERT_TRUE(acc->result_type()->Is<ast::type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000447
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000448 auto* ptr = acc->result_type()->As<ast::type::Pointer>();
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000449 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000450}
451
452TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Vector) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000453 auto* var = Var("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +0000454 mod->AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000455
dan sinclairb950e802020-04-20 14:20:01 +0000456 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000457
dan sinclair8b40a672020-12-16 11:49:10 +0000458 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000459 EXPECT_TRUE(td()->DetermineResultType(acc));
460 ASSERT_NE(acc->result_type(), nullptr);
461 ASSERT_TRUE(acc->result_type()->Is<ast::type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000462
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000463 auto* ptr = acc->result_type()->As<ast::type::Pointer>();
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000464 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000465}
466
dan sinclaira7d498e2020-09-22 22:07:13 +0000467TEST_F(TypeDeterminerTest, Expr_Bitcast) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000468 auto* bitcast = create<ast::BitcastExpression>(ty.f32, Expr("name"));
dan sinclaira01777c2020-04-07 12:57:52 +0000469
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000470 auto* v = Var("name", ast::StorageClass::kPrivate, ty.f32);
471 td()->RegisterVariableForTesting(v);
dan sinclairff267ca2020-10-14 18:26:31 +0000472
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000473 EXPECT_TRUE(td()->DetermineResultType(bitcast));
474 ASSERT_NE(bitcast->result_type(), nullptr);
475 EXPECT_TRUE(bitcast->result_type()->Is<ast::type::F32>());
dan sinclaira01777c2020-04-07 12:57:52 +0000476}
477
dan sinclair3ca87462020-04-07 16:41:10 +0000478TEST_F(TypeDeterminerTest, Expr_Call) {
dan sinclair3ca87462020-04-07 16:41:10 +0000479 ast::VariableList params;
dan sinclair181d8ba2020-12-16 15:15:40 +0000480 auto* func = Func("my_func", params, ty.f32, ast::StatementList{},
481 ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000482 mod->AddFunction(func);
dan sinclair3ca87462020-04-07 16:41:10 +0000483
484 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000485 EXPECT_TRUE(td()->Determine());
dan sinclair3ca87462020-04-07 16:41:10 +0000486
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000487 auto* call = Call("my_func");
488 EXPECT_TRUE(td()->DetermineResultType(call));
489 ASSERT_NE(call->result_type(), nullptr);
490 EXPECT_TRUE(call->result_type()->Is<ast::type::F32>());
dan sinclair3ca87462020-04-07 16:41:10 +0000491}
492
dan sinclairccb52dc2020-04-20 14:18:54 +0000493TEST_F(TypeDeterminerTest, Expr_Call_WithParams) {
dan sinclairccb52dc2020-04-20 14:18:54 +0000494 ast::VariableList params;
dan sinclair181d8ba2020-12-16 15:15:40 +0000495 auto* func = Func("my_func", params, ty.f32, ast::StatementList{},
496 ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000497 mod->AddFunction(func);
dan sinclairccb52dc2020-04-20 14:18:54 +0000498
499 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000500 EXPECT_TRUE(td()->Determine());
dan sinclairccb52dc2020-04-20 14:18:54 +0000501
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000502 auto* param = Expr(2.4f);
dan sinclairccb52dc2020-04-20 14:18:54 +0000503
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000504 auto* call = Call("my_func", param);
505 EXPECT_TRUE(td()->DetermineResultType(call));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000506 ASSERT_NE(param->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000507 EXPECT_TRUE(param->result_type()->Is<ast::type::F32>());
dan sinclairccb52dc2020-04-20 14:18:54 +0000508}
509
dan sinclairb4fee2f2020-09-22 19:42:13 +0000510TEST_F(TypeDeterminerTest, Expr_Call_Intrinsic) {
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000511 // Register the function
512 EXPECT_TRUE(td()->Determine());
513
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000514 auto* call = Call("round", 2.4f);
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000515
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000516 EXPECT_TRUE(td()->DetermineResultType(call));
517 ASSERT_NE(call->result_type(), nullptr);
518 EXPECT_TRUE(call->result_type()->Is<ast::type::F32>());
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000519}
520
dan sinclair4e807952020-04-07 16:41:23 +0000521TEST_F(TypeDeterminerTest, Expr_Cast) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000522 auto* cast = Construct(ty.f32, "name");
dan sinclair3c025922020-09-24 14:38:44 +0000523
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000524 auto* v = Var("name", ast::StorageClass::kPrivate, ty.f32);
525 td()->RegisterVariableForTesting(v);
dan sinclair4e807952020-04-07 16:41:23 +0000526
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000527 EXPECT_TRUE(td()->DetermineResultType(cast));
528 ASSERT_NE(cast->result_type(), nullptr);
529 EXPECT_TRUE(cast->result_type()->Is<ast::type::F32>());
dan sinclair4e807952020-04-07 16:41:23 +0000530}
531
dan sinclairb7edc4c2020-04-07 12:46:30 +0000532TEST_F(TypeDeterminerTest, Expr_Constructor_Scalar) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000533 auto* s = create<ast::ScalarConstructorExpression>(
534 create<ast::FloatLiteral>(ty.f32, 1.0f));
dan sinclairb7edc4c2020-04-07 12:46:30 +0000535
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000536 EXPECT_TRUE(td()->DetermineResultType(s));
537 ASSERT_NE(s->result_type(), nullptr);
538 EXPECT_TRUE(s->result_type()->Is<ast::type::F32>());
dan sinclairb7edc4c2020-04-07 12:46:30 +0000539}
540
541TEST_F(TypeDeterminerTest, Expr_Constructor_Type) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000542 auto* tc = vec3<f32>(1.0f, 1.0f, 3.0f);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000543
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000544 EXPECT_TRUE(td()->DetermineResultType(tc));
545 ASSERT_NE(tc->result_type(), nullptr);
546 ASSERT_TRUE(tc->result_type()->Is<ast::type::Vector>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000547 EXPECT_TRUE(
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000548 tc->result_type()->As<ast::type::Vector>()->type()->Is<ast::type::F32>());
549 EXPECT_EQ(tc->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000550}
551
dan sinclaircab0e732020-04-07 12:57:27 +0000552TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalVariable) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000553 auto* var = Var("my_var", ast::StorageClass::kNone, ty.f32);
Ben Clayton3ea3c992020-11-18 21:19:22 +0000554 mod->AddGlobalVariable(var);
dan sinclaircab0e732020-04-07 12:57:27 +0000555
dan sinclairb950e802020-04-20 14:20:01 +0000556 EXPECT_TRUE(td()->Determine());
dan sinclaircab0e732020-04-07 12:57:27 +0000557
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000558 auto* ident = Expr("my_var");
559 EXPECT_TRUE(td()->DetermineResultType(ident));
560 ASSERT_NE(ident->result_type(), nullptr);
561 EXPECT_TRUE(ident->result_type()->Is<ast::type::Pointer>());
562 EXPECT_TRUE(ident->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000563 ->As<ast::type::Pointer>()
Ben Claytonc52f4212020-11-30 23:30:58 +0000564 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000565 ->Is<ast::type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000566}
567
568TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalConstant) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000569 mod->AddGlobalVariable(Const("my_var", ast::StorageClass::kNone, ty.f32));
dan sinclair8eddb782020-04-23 22:26:52 +0000570
dan sinclair8eddb782020-04-23 22:26:52 +0000571 EXPECT_TRUE(td()->Determine());
572
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000573 auto* ident = Expr("my_var");
574 EXPECT_TRUE(td()->DetermineResultType(ident));
575 ASSERT_NE(ident->result_type(), nullptr);
576 EXPECT_TRUE(ident->result_type()->Is<ast::type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000577}
578
dan sinclair8eddb782020-04-23 22:26:52 +0000579TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable_Const) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000580 auto* my_var = Expr("my_var");
dan sinclair8eddb782020-04-23 22:26:52 +0000581
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000582 auto* var = Const("my_var", ast::StorageClass::kNone, ty.f32);
dan sinclair8eddb782020-04-23 22:26:52 +0000583
dan sinclair181d8ba2020-12-16 15:15:40 +0000584 auto* f = Func("my_func", ast::VariableList{}, ty.f32,
585 ast::StatementList{
586 create<ast::VariableDeclStatement>(var),
587 create<ast::AssignmentStatement>(my_var, Expr("my_var")),
588 },
589 ast::FunctionDecorationList{});
dan sinclair8eddb782020-04-23 22:26:52 +0000590
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000591 EXPECT_TRUE(td()->DetermineFunction(f));
dan sinclair8eddb782020-04-23 22:26:52 +0000592
Ben Clayton4bfe4612020-11-16 16:41:47 +0000593 ASSERT_NE(my_var->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000594 EXPECT_TRUE(my_var->result_type()->Is<ast::type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000595}
596
dan sinclaircab0e732020-04-07 12:57:27 +0000597TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000598 auto* my_var = Expr("my_var");
dan sinclaircab0e732020-04-07 12:57:27 +0000599
dan sinclair181d8ba2020-12-16 15:15:40 +0000600 auto* f = Func("my_func", ast::VariableList{}, ty.f32,
601 ast::StatementList{
602 create<ast::VariableDeclStatement>(
603 Var("my_var", ast::StorageClass::kNone, ty.f32)),
604 create<ast::AssignmentStatement>(my_var, Expr("my_var")),
605 },
606 ast::FunctionDecorationList{});
dan sinclaircab0e732020-04-07 12:57:27 +0000607
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000608 EXPECT_TRUE(td()->DetermineFunction(f));
dan sinclaircab0e732020-04-07 12:57:27 +0000609
Ben Clayton4bfe4612020-11-16 16:41:47 +0000610 ASSERT_NE(my_var->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000611 EXPECT_TRUE(my_var->result_type()->Is<ast::type::Pointer>());
Ben Claytonc52f4212020-11-30 23:30:58 +0000612 EXPECT_TRUE(my_var->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000613 ->As<ast::type::Pointer>()
Ben Claytonc52f4212020-11-30 23:30:58 +0000614 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000615 ->Is<ast::type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000616}
617
dan sinclair5e989302020-09-16 21:20:36 +0000618TEST_F(TypeDeterminerTest, Expr_Identifier_Function_Ptr) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000619 ast::type::Pointer ptr(ty.f32, ast::StorageClass::kFunction);
dan sinclair5e989302020-09-16 21:20:36 +0000620
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000621 auto* my_var = Expr("my_var");
dan sinclair5e989302020-09-16 21:20:36 +0000622
dan sinclair181d8ba2020-12-16 15:15:40 +0000623 auto* f = Func("my_func", ast::VariableList{}, ty.f32,
624 ast::StatementList{
625 create<ast::VariableDeclStatement>(
626 Var("my_var", ast::StorageClass::kNone, &ptr)),
627 create<ast::AssignmentStatement>(my_var, Expr("my_var")),
628 },
629 ast::FunctionDecorationList{});
dan sinclair5e989302020-09-16 21:20:36 +0000630
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000631 EXPECT_TRUE(td()->DetermineFunction(f));
dan sinclair5e989302020-09-16 21:20:36 +0000632
Ben Clayton4bfe4612020-11-16 16:41:47 +0000633 ASSERT_NE(my_var->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000634 EXPECT_TRUE(my_var->result_type()->Is<ast::type::Pointer>());
Ben Claytonc52f4212020-11-30 23:30:58 +0000635 EXPECT_TRUE(my_var->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000636 ->As<ast::type::Pointer>()
Ben Claytonc52f4212020-11-30 23:30:58 +0000637 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000638 ->Is<ast::type::F32>());
dan sinclair5e989302020-09-16 21:20:36 +0000639}
640
dan sinclaircab0e732020-04-07 12:57:27 +0000641TEST_F(TypeDeterminerTest, Expr_Identifier_Function) {
dan sinclair181d8ba2020-12-16 15:15:40 +0000642 auto* func = Func("my_func", ast::VariableList{}, ty.f32,
643 ast::StatementList{}, ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000644 mod->AddFunction(func);
dan sinclaircab0e732020-04-07 12:57:27 +0000645
646 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000647 EXPECT_TRUE(td()->Determine());
dan sinclaircab0e732020-04-07 12:57:27 +0000648
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000649 auto* ident = Expr("my_func");
650 EXPECT_TRUE(td()->DetermineResultType(ident));
651 ASSERT_NE(ident->result_type(), nullptr);
652 EXPECT_TRUE(ident->result_type()->Is<ast::type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000653}
654
dan sinclairff267ca2020-10-14 18:26:31 +0000655TEST_F(TypeDeterminerTest, Expr_Identifier_Unknown) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000656 auto* a = Expr("a");
657 EXPECT_FALSE(td()->DetermineResultType(a));
dan sinclairff267ca2020-10-14 18:26:31 +0000658}
659
dan sinclair13d2a3b2020-06-22 20:52:24 +0000660TEST_F(TypeDeterminerTest, Function_RegisterInputOutputVariables) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000661 auto* in_var = Var("in_var", ast::StorageClass::kInput, ty.f32);
662 auto* out_var = Var("out_var", ast::StorageClass::kOutput, ty.f32);
663 auto* sb_var = Var("sb_var", ast::StorageClass::kStorageBuffer, ty.f32);
664 auto* wg_var = Var("wg_var", ast::StorageClass::kWorkgroup, ty.f32);
665 auto* priv_var = Var("priv_var", ast::StorageClass::kPrivate, ty.f32);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000666
Ben Clayton3ea3c992020-11-18 21:19:22 +0000667 mod->AddGlobalVariable(in_var);
668 mod->AddGlobalVariable(out_var);
669 mod->AddGlobalVariable(sb_var);
670 mod->AddGlobalVariable(wg_var);
671 mod->AddGlobalVariable(priv_var);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000672
dan sinclair181d8ba2020-12-16 15:15:40 +0000673 auto* func = Func(
674 "my_func", ast::VariableList{}, ty.f32,
675 ast::StatementList{
676 create<ast::AssignmentStatement>(Expr("out_var"), Expr("in_var")),
677 create<ast::AssignmentStatement>(Expr("wg_var"), Expr("wg_var")),
678 create<ast::AssignmentStatement>(Expr("sb_var"), Expr("sb_var")),
679 create<ast::AssignmentStatement>(Expr("priv_var"), Expr("priv_var")),
680 },
681 ast::FunctionDecorationList{});
dan sinclair13d2a3b2020-06-22 20:52:24 +0000682
Ben Clayton3ea3c992020-11-18 21:19:22 +0000683 mod->AddFunction(func);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000684
685 // Register the function
686 EXPECT_TRUE(td()->Determine());
687
Ben Clayton4bfe4612020-11-16 16:41:47 +0000688 const auto& vars = func->referenced_module_variables();
Ryan Harrison9a452c12020-06-23 16:38:47 +0000689 ASSERT_EQ(vars.size(), 5u);
Ben Clayton4bfe4612020-11-16 16:41:47 +0000690 EXPECT_EQ(vars[0], out_var);
691 EXPECT_EQ(vars[1], in_var);
692 EXPECT_EQ(vars[2], wg_var);
693 EXPECT_EQ(vars[3], sb_var);
694 EXPECT_EQ(vars[4], priv_var);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000695}
696
dan sinclairde2dd682020-07-14 20:37:28 +0000697TEST_F(TypeDeterminerTest, Function_RegisterInputOutputVariables_SubFunction) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000698 auto* in_var = Var("in_var", ast::StorageClass::kInput, ty.f32);
699 auto* out_var = Var("out_var", ast::StorageClass::kOutput, ty.f32);
700 auto* sb_var = Var("sb_var", ast::StorageClass::kStorageBuffer, ty.f32);
701 auto* wg_var = Var("wg_var", ast::StorageClass::kWorkgroup, ty.f32);
702 auto* priv_var = Var("priv_var", ast::StorageClass::kPrivate, ty.f32);
dan sinclairde2dd682020-07-14 20:37:28 +0000703
Ben Clayton3ea3c992020-11-18 21:19:22 +0000704 mod->AddGlobalVariable(in_var);
705 mod->AddGlobalVariable(out_var);
706 mod->AddGlobalVariable(sb_var);
707 mod->AddGlobalVariable(wg_var);
708 mod->AddGlobalVariable(priv_var);
dan sinclairde2dd682020-07-14 20:37:28 +0000709
dan sinclair181d8ba2020-12-16 15:15:40 +0000710 auto* func = Func(
711 "my_func", ast::VariableList{}, ty.f32,
712 ast::StatementList{
713 create<ast::AssignmentStatement>(Expr("out_var"), Expr("in_var")),
714 create<ast::AssignmentStatement>(Expr("wg_var"), Expr("wg_var")),
715 create<ast::AssignmentStatement>(Expr("sb_var"), Expr("sb_var")),
716 create<ast::AssignmentStatement>(Expr("priv_var"), Expr("priv_var")),
717 },
718 ast::FunctionDecorationList{});
dan sinclairde2dd682020-07-14 20:37:28 +0000719
Ben Clayton3ea3c992020-11-18 21:19:22 +0000720 mod->AddFunction(func);
dan sinclairde2dd682020-07-14 20:37:28 +0000721
dan sinclair181d8ba2020-12-16 15:15:40 +0000722 auto* func2 = Func(
723 "func", ast::VariableList{}, ty.f32,
724 ast::StatementList{
725 create<ast::AssignmentStatement>(Expr("out_var"), Call("my_func")),
726 },
727 ast::FunctionDecorationList{});
dan sinclairde2dd682020-07-14 20:37:28 +0000728
Ben Clayton3ea3c992020-11-18 21:19:22 +0000729 mod->AddFunction(func2);
dan sinclairde2dd682020-07-14 20:37:28 +0000730
731 // Register the function
732 EXPECT_TRUE(td()->Determine());
733
Ben Clayton4bfe4612020-11-16 16:41:47 +0000734 const auto& vars = func2->referenced_module_variables();
dan sinclairde2dd682020-07-14 20:37:28 +0000735 ASSERT_EQ(vars.size(), 5u);
Ben Clayton4bfe4612020-11-16 16:41:47 +0000736 EXPECT_EQ(vars[0], out_var);
737 EXPECT_EQ(vars[1], in_var);
738 EXPECT_EQ(vars[2], wg_var);
739 EXPECT_EQ(vars[3], sb_var);
740 EXPECT_EQ(vars[4], priv_var);
dan sinclairde2dd682020-07-14 20:37:28 +0000741}
742
dan sinclair13d2a3b2020-06-22 20:52:24 +0000743TEST_F(TypeDeterminerTest, Function_NotRegisterFunctionVariable) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000744 auto* var = Var("in_var", ast::StorageClass::kFunction, ty.f32);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000745
dan sinclair181d8ba2020-12-16 15:15:40 +0000746 auto* func =
747 Func("my_func", ast::VariableList{}, ty.f32,
748 ast::StatementList{
749 create<ast::VariableDeclStatement>(var),
750 create<ast::AssignmentStatement>(
751 Expr("var"), create<ast::ScalarConstructorExpression>(
752 create<ast::FloatLiteral>(ty.f32, 1.f))),
753 },
754 ast::FunctionDecorationList{});
dan sinclair13d2a3b2020-06-22 20:52:24 +0000755
Ben Clayton3ea3c992020-11-18 21:19:22 +0000756 mod->AddFunction(func);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000757
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000758 auto* v = Var("var", ast::StorageClass::kFunction, ty.f32);
759 td()->RegisterVariableForTesting(v);
dan sinclairff267ca2020-10-14 18:26:31 +0000760
dan sinclair13d2a3b2020-06-22 20:52:24 +0000761 // Register the function
dan sinclairff267ca2020-10-14 18:26:31 +0000762 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair13d2a3b2020-06-22 20:52:24 +0000763
Ben Clayton4bfe4612020-11-16 16:41:47 +0000764 EXPECT_EQ(func->referenced_module_variables().size(), 0u);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000765}
766
dan sinclair8ee1d222020-04-07 16:41:33 +0000767TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct) {
dan sinclair5e5e36e2020-12-16 14:41:00 +0000768 auto* strct = create<ast::Struct>(
769 ast::StructMemberList{Member("first_member", ty.i32),
770 Member("second_member", ty.f32)},
771 ast::StructDecorationList{});
dan sinclair8ee1d222020-04-07 16:41:33 +0000772
dan sinclair24bbbbb2020-12-14 16:01:37 +0000773 ast::type::Struct st(mod->RegisterSymbol("S"), "S", strct);
dan sinclair8ee1d222020-04-07 16:41:33 +0000774
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000775 auto* var = Var("my_struct", ast::StorageClass::kNone, &st);
dan sinclair8ee1d222020-04-07 16:41:33 +0000776
Ben Clayton3ea3c992020-11-18 21:19:22 +0000777 mod->AddGlobalVariable(var);
dan sinclair8ee1d222020-04-07 16:41:33 +0000778
dan sinclairb950e802020-04-20 14:20:01 +0000779 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +0000780
dan sinclair8b40a672020-12-16 11:49:10 +0000781 auto* mem = MemberAccessor("my_struct", "second_member");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000782 EXPECT_TRUE(td()->DetermineResultType(mem));
783 ASSERT_NE(mem->result_type(), nullptr);
784 ASSERT_TRUE(mem->result_type()->Is<ast::type::Pointer>());
dan sinclair8ee1d222020-04-07 16:41:33 +0000785
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000786 auto* ptr = mem->result_type()->As<ast::type::Pointer>();
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000787 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclair8ee1d222020-04-07 16:41:33 +0000788}
789
dan sinclairb445a9b2020-04-24 00:40:45 +0000790TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct_Alias) {
dan sinclair5e5e36e2020-12-16 14:41:00 +0000791 auto* strct = create<ast::Struct>(
792 ast::StructMemberList{Member("first_member", ty.i32),
793 Member("second_member", ty.f32)},
794 ast::StructDecorationList{});
dan sinclairb445a9b2020-04-24 00:40:45 +0000795
dan sinclair24bbbbb2020-12-14 16:01:37 +0000796 auto st = std::make_unique<ast::type::Struct>(mod->RegisterSymbol("alias"),
797 "alias", strct);
dan sinclair4226b6a2020-12-11 19:35:03 +0000798 ast::type::Alias alias(mod->RegisterSymbol("alias"), "alias", st.get());
dan sinclairb445a9b2020-04-24 00:40:45 +0000799
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000800 auto* var = Var("my_struct", ast::StorageClass::kNone, &alias);
dan sinclairb445a9b2020-04-24 00:40:45 +0000801
Ben Clayton3ea3c992020-11-18 21:19:22 +0000802 mod->AddGlobalVariable(var);
dan sinclairb445a9b2020-04-24 00:40:45 +0000803
dan sinclairb445a9b2020-04-24 00:40:45 +0000804 EXPECT_TRUE(td()->Determine());
805
dan sinclair8b40a672020-12-16 11:49:10 +0000806 auto* mem = MemberAccessor("my_struct", "second_member");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000807 EXPECT_TRUE(td()->DetermineResultType(mem));
808 ASSERT_NE(mem->result_type(), nullptr);
809 ASSERT_TRUE(mem->result_type()->Is<ast::type::Pointer>());
dan sinclairb445a9b2020-04-24 00:40:45 +0000810
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000811 auto* ptr = mem->result_type()->As<ast::type::Pointer>();
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000812 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclairb445a9b2020-04-24 00:40:45 +0000813}
814
dan sinclair8ee1d222020-04-07 16:41:33 +0000815TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000816 auto* var = Var("my_vec", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +0000817 mod->AddGlobalVariable(var);
dan sinclair8ee1d222020-04-07 16:41:33 +0000818
dan sinclairb950e802020-04-20 14:20:01 +0000819 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +0000820
dan sinclair8b40a672020-12-16 11:49:10 +0000821 auto* mem = MemberAccessor("my_vec", "xy");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000822 EXPECT_TRUE(td()->DetermineResultType(mem)) << td()->error();
823 ASSERT_NE(mem->result_type(), nullptr);
824 ASSERT_TRUE(mem->result_type()->Is<ast::type::Vector>());
825 EXPECT_TRUE(mem->result_type()
826 ->As<ast::type::Vector>()
827 ->type()
828 ->Is<ast::type::F32>());
829 EXPECT_EQ(mem->result_type()->As<ast::type::Vector>()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +0000830}
831
dan sinclairaac58652020-04-21 13:05:34 +0000832TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle_SingleElement) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000833 auto* var = Var("my_vec", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +0000834 mod->AddGlobalVariable(var);
dan sinclairaac58652020-04-21 13:05:34 +0000835
dan sinclairaac58652020-04-21 13:05:34 +0000836 EXPECT_TRUE(td()->Determine());
837
dan sinclair8b40a672020-12-16 11:49:10 +0000838 auto* mem = MemberAccessor("my_vec", "x");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000839 EXPECT_TRUE(td()->DetermineResultType(mem)) << td()->error();
840 ASSERT_NE(mem->result_type(), nullptr);
841 ASSERT_TRUE(mem->result_type()->Is<ast::type::Pointer>());
dan sinclairaac58652020-04-21 13:05:34 +0000842
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000843 auto* ptr = mem->result_type()->As<ast::type::Pointer>();
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000844 ASSERT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclairaac58652020-04-21 13:05:34 +0000845}
846
dan sinclair8eddb782020-04-23 22:26:52 +0000847TEST_F(TypeDeterminerTest, Expr_Accessor_MultiLevel) {
dan sinclair8ee1d222020-04-07 16:41:33 +0000848 // struct b {
849 // vec4<f32> foo
850 // }
851 // struct A {
852 // vec3<struct b> mem
853 // }
854 // var c : A
855 // c.mem[0].foo.yx
856 // -> vec2<f32>
857 //
858 // MemberAccessor{
859 // MemberAccessor{
860 // ArrayAccessor{
861 // MemberAccessor{
862 // Identifier{c}
863 // Identifier{mem}
864 // }
865 // ScalarConstructor{0}
866 // }
867 // Identifier{foo}
868 // }
869 // Identifier{yx}
870 // }
871 //
dan sinclair8ee1d222020-04-07 16:41:33 +0000872
dan sinclair5e5e36e2020-12-16 14:41:00 +0000873 auto* strctB =
874 create<ast::Struct>(ast::StructMemberList{Member("foo", ty.vec4<f32>())},
875 ast::StructDecorationList{});
dan sinclair24bbbbb2020-12-14 16:01:37 +0000876 ast::type::Struct stB(mod->RegisterSymbol("B"), "B", strctB);
dan sinclair8ee1d222020-04-07 16:41:33 +0000877
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000878 ast::type::Vector vecB(&stB, 3);
dan sinclair5e5e36e2020-12-16 14:41:00 +0000879 auto* strctA = create<ast::Struct>(
880 ast::StructMemberList{Member("mem", &vecB)}, ast::StructDecorationList{});
dan sinclair8ee1d222020-04-07 16:41:33 +0000881
dan sinclair24bbbbb2020-12-14 16:01:37 +0000882 ast::type::Struct stA(mod->RegisterSymbol("A"), "A", strctA);
dan sinclair8ee1d222020-04-07 16:41:33 +0000883
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000884 auto* var = Var("c", ast::StorageClass::kNone, &stA);
885
Ben Clayton3ea3c992020-11-18 21:19:22 +0000886 mod->AddGlobalVariable(var);
dan sinclair8ee1d222020-04-07 16:41:33 +0000887
dan sinclairb950e802020-04-20 14:20:01 +0000888 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +0000889
dan sinclair8b40a672020-12-16 11:49:10 +0000890 auto* mem = MemberAccessor(
891 MemberAccessor(IndexAccessor(MemberAccessor("c", "mem"), 0), "foo"),
892 "yx");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000893 EXPECT_TRUE(td()->DetermineResultType(mem)) << td()->error();
dan sinclair8ee1d222020-04-07 16:41:33 +0000894
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000895 ASSERT_NE(mem->result_type(), nullptr);
896 ASSERT_TRUE(mem->result_type()->Is<ast::type::Vector>());
897 EXPECT_TRUE(mem->result_type()
898 ->As<ast::type::Vector>()
899 ->type()
900 ->Is<ast::type::F32>());
901 EXPECT_EQ(mem->result_type()->As<ast::type::Vector>()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +0000902}
903
dan sinclaircd077b02020-04-20 14:19:04 +0000904using Expr_Binary_BitwiseTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +0000905TEST_P(Expr_Binary_BitwiseTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +0000906 auto op = GetParam();
907
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000908 auto* var = Var("val", ast::StorageClass::kNone, ty.i32);
dan sinclair9b978022020-04-07 19:26:39 +0000909
Ben Clayton3ea3c992020-11-18 21:19:22 +0000910 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +0000911
dan sinclairb950e802020-04-20 14:20:01 +0000912 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000913
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000914 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +0000915
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000916 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
917 ASSERT_NE(expr->result_type(), nullptr);
918 EXPECT_TRUE(expr->result_type()->Is<ast::type::I32>());
dan sinclair9b978022020-04-07 19:26:39 +0000919}
920
dan sinclair1c9b4862020-04-07 19:27:41 +0000921TEST_P(Expr_Binary_BitwiseTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +0000922 auto op = GetParam();
923
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000924 auto* var = Var("val", ast::StorageClass::kNone, ty.vec3<i32>());
dan sinclair9b978022020-04-07 19:26:39 +0000925
Ben Clayton3ea3c992020-11-18 21:19:22 +0000926 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +0000927
dan sinclairb950e802020-04-20 14:20:01 +0000928 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000929
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000930 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +0000931
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000932 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
933 ASSERT_NE(expr->result_type(), nullptr);
934 ASSERT_TRUE(expr->result_type()->Is<ast::type::Vector>());
935 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000936 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +0000937 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000938 ->Is<ast::type::I32>());
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000939 EXPECT_EQ(expr->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +0000940}
941INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +0000942 Expr_Binary_BitwiseTest,
943 testing::Values(ast::BinaryOp::kAnd,
944 ast::BinaryOp::kOr,
945 ast::BinaryOp::kXor,
946 ast::BinaryOp::kShiftLeft,
947 ast::BinaryOp::kShiftRight,
dan sinclair1c9b4862020-04-07 19:27:41 +0000948 ast::BinaryOp::kAdd,
949 ast::BinaryOp::kSubtract,
950 ast::BinaryOp::kDivide,
951 ast::BinaryOp::kModulo));
dan sinclair9b978022020-04-07 19:26:39 +0000952
dan sinclaircd077b02020-04-20 14:19:04 +0000953using Expr_Binary_LogicalTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +0000954TEST_P(Expr_Binary_LogicalTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +0000955 auto op = GetParam();
956
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000957 auto* var = Var("val", ast::StorageClass::kNone, ty.bool_);
dan sinclair9b978022020-04-07 19:26:39 +0000958
Ben Clayton3ea3c992020-11-18 21:19:22 +0000959 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +0000960
dan sinclairb950e802020-04-20 14:20:01 +0000961 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000962
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000963 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +0000964
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000965 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
966 ASSERT_NE(expr->result_type(), nullptr);
967 EXPECT_TRUE(expr->result_type()->Is<ast::type::Bool>());
dan sinclair9b978022020-04-07 19:26:39 +0000968}
969
dan sinclair1c9b4862020-04-07 19:27:41 +0000970TEST_P(Expr_Binary_LogicalTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +0000971 auto op = GetParam();
972
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000973 auto* var = Var("val", ast::StorageClass::kNone, ty.vec3<bool>());
dan sinclair9b978022020-04-07 19:26:39 +0000974
Ben Clayton3ea3c992020-11-18 21:19:22 +0000975 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +0000976
dan sinclairb950e802020-04-20 14:20:01 +0000977 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000978
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000979 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +0000980
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000981 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
982 ASSERT_NE(expr->result_type(), nullptr);
983 ASSERT_TRUE(expr->result_type()->Is<ast::type::Vector>());
984 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000985 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +0000986 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000987 ->Is<ast::type::Bool>());
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000988 EXPECT_EQ(expr->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +0000989}
990INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +0000991 Expr_Binary_LogicalTest,
992 testing::Values(ast::BinaryOp::kLogicalAnd,
993 ast::BinaryOp::kLogicalOr));
dan sinclair9b978022020-04-07 19:26:39 +0000994
dan sinclaircd077b02020-04-20 14:19:04 +0000995using Expr_Binary_CompareTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +0000996TEST_P(Expr_Binary_CompareTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +0000997 auto op = GetParam();
998
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000999 auto* var = Var("val", ast::StorageClass::kNone, ty.i32);
dan sinclair9b978022020-04-07 19:26:39 +00001000
Ben Clayton3ea3c992020-11-18 21:19:22 +00001001 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001002
dan sinclairb950e802020-04-20 14:20:01 +00001003 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001004
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001005 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +00001006
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001007 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1008 ASSERT_NE(expr->result_type(), nullptr);
1009 EXPECT_TRUE(expr->result_type()->Is<ast::type::Bool>());
dan sinclair9b978022020-04-07 19:26:39 +00001010}
1011
dan sinclair1c9b4862020-04-07 19:27:41 +00001012TEST_P(Expr_Binary_CompareTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001013 auto op = GetParam();
1014
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001015 auto* var = Var("val", ast::StorageClass::kNone, ty.vec3<i32>());
dan sinclair9b978022020-04-07 19:26:39 +00001016
Ben Clayton3ea3c992020-11-18 21:19:22 +00001017 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001018
dan sinclairb950e802020-04-20 14:20:01 +00001019 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001020
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001021 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +00001022
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001023 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1024 ASSERT_NE(expr->result_type(), nullptr);
1025 ASSERT_TRUE(expr->result_type()->Is<ast::type::Vector>());
1026 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001027 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001028 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001029 ->Is<ast::type::Bool>());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001030 EXPECT_EQ(expr->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001031}
1032INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +00001033 Expr_Binary_CompareTest,
1034 testing::Values(ast::BinaryOp::kEqual,
1035 ast::BinaryOp::kNotEqual,
1036 ast::BinaryOp::kLessThan,
1037 ast::BinaryOp::kGreaterThan,
1038 ast::BinaryOp::kLessThanEqual,
1039 ast::BinaryOp::kGreaterThanEqual));
dan sinclair9b978022020-04-07 19:26:39 +00001040
dan sinclair1c9b4862020-04-07 19:27:41 +00001041TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Scalar) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001042 auto* var = Var("val", ast::StorageClass::kNone, ty.i32);
dan sinclair9b978022020-04-07 19:26:39 +00001043
Ben Clayton3ea3c992020-11-18 21:19:22 +00001044 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001045
dan sinclairb950e802020-04-20 14:20:01 +00001046 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001047
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001048 auto* expr = Mul("val", "val");
dan sinclair9b978022020-04-07 19:26:39 +00001049
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001050 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1051 ASSERT_NE(expr->result_type(), nullptr);
1052 EXPECT_TRUE(expr->result_type()->Is<ast::type::I32>());
dan sinclair9b978022020-04-07 19:26:39 +00001053}
1054
dan sinclair1c9b4862020-04-07 19:27:41 +00001055TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Scalar) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001056 auto* scalar = Var("scalar", ast::StorageClass::kNone, ty.f32);
1057 auto* vector = Var("vector", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001058 mod->AddGlobalVariable(scalar);
1059 mod->AddGlobalVariable(vector);
dan sinclair9b978022020-04-07 19:26:39 +00001060
dan sinclairb950e802020-04-20 14:20:01 +00001061 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001062
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001063 auto* expr = Mul("vector", "scalar");
dan sinclair9b978022020-04-07 19:26:39 +00001064
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001065 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1066 ASSERT_NE(expr->result_type(), nullptr);
1067 ASSERT_TRUE(expr->result_type()->Is<ast::type::Vector>());
1068 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001069 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001070 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001071 ->Is<ast::type::F32>());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001072 EXPECT_EQ(expr->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001073}
1074
dan sinclair1c9b4862020-04-07 19:27:41 +00001075TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Vector) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001076 auto* scalar = Var("scalar", ast::StorageClass::kNone, ty.f32);
1077 auto* vector = Var("vector", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001078 mod->AddGlobalVariable(scalar);
1079 mod->AddGlobalVariable(vector);
dan sinclair9b978022020-04-07 19:26:39 +00001080
dan sinclairb950e802020-04-20 14:20:01 +00001081 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001082
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001083 auto* expr = Mul("scalar", "vector");
dan sinclair9b978022020-04-07 19:26:39 +00001084
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001085 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1086 ASSERT_NE(expr->result_type(), nullptr);
1087 ASSERT_TRUE(expr->result_type()->Is<ast::type::Vector>());
1088 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001089 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001090 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001091 ->Is<ast::type::F32>());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001092 EXPECT_EQ(expr->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001093}
1094
dan sinclair1c9b4862020-04-07 19:27:41 +00001095TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Vector) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001096 auto* vector = Var("vector", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001097 mod->AddGlobalVariable(vector);
dan sinclair9b978022020-04-07 19:26:39 +00001098
dan sinclairb950e802020-04-20 14:20:01 +00001099 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001100
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001101 auto* expr = Mul("vector", "vector");
dan sinclair9b978022020-04-07 19:26:39 +00001102
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001103 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1104 ASSERT_NE(expr->result_type(), nullptr);
1105 ASSERT_TRUE(expr->result_type()->Is<ast::type::Vector>());
1106 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001107 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001108 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001109 ->Is<ast::type::F32>());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001110 EXPECT_EQ(expr->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001111}
1112
dan sinclair1c9b4862020-04-07 19:27:41 +00001113TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Scalar) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001114 ast::type::Matrix mat3x2(ty.f32, 3, 2);
dan sinclair9b978022020-04-07 19:26:39 +00001115
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001116 auto* scalar = Var("scalar", ast::StorageClass::kNone, ty.f32);
1117 auto* matrix = Var("matrix", ast::StorageClass::kNone, &mat3x2);
Ben Clayton3ea3c992020-11-18 21:19:22 +00001118 mod->AddGlobalVariable(scalar);
1119 mod->AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001120
dan sinclairb950e802020-04-20 14:20:01 +00001121 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001122
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001123 auto* expr = Mul("matrix", "scalar");
dan sinclair9b978022020-04-07 19:26:39 +00001124
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001125 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1126 ASSERT_NE(expr->result_type(), nullptr);
1127 ASSERT_TRUE(expr->result_type()->Is<ast::type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001128
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001129 auto* mat = expr->result_type()->As<ast::type::Matrix>();
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001130 EXPECT_TRUE(mat->type()->Is<ast::type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001131 EXPECT_EQ(mat->rows(), 3u);
1132 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001133}
1134
dan sinclair1c9b4862020-04-07 19:27:41 +00001135TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Matrix) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001136 ast::type::Matrix mat3x2(ty.f32, 3, 2);
dan sinclair9b978022020-04-07 19:26:39 +00001137
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001138 auto* scalar = Var("scalar", ast::StorageClass::kNone, ty.f32);
1139 auto* matrix = Var("matrix", ast::StorageClass::kNone, &mat3x2);
Ben Clayton3ea3c992020-11-18 21:19:22 +00001140 mod->AddGlobalVariable(scalar);
1141 mod->AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001142
dan sinclairb950e802020-04-20 14:20:01 +00001143 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001144
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001145 auto* expr = Mul("scalar", "matrix");
dan sinclair9b978022020-04-07 19:26:39 +00001146
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001147 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1148 ASSERT_NE(expr->result_type(), nullptr);
1149 ASSERT_TRUE(expr->result_type()->Is<ast::type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001150
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001151 auto* mat = expr->result_type()->As<ast::type::Matrix>();
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001152 EXPECT_TRUE(mat->type()->Is<ast::type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001153 EXPECT_EQ(mat->rows(), 3u);
1154 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001155}
1156
dan sinclair1c9b4862020-04-07 19:27:41 +00001157TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Vector) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001158 auto* vector = Var("vector", ast::StorageClass::kNone, ty.vec3<f32>());
1159 auto* matrix = Var("matrix", ast::StorageClass::kNone, ty.mat2x3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001160 mod->AddGlobalVariable(vector);
1161 mod->AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001162
dan sinclairb950e802020-04-20 14:20:01 +00001163 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001164
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001165 auto* expr = Mul("matrix", "vector");
dan sinclair9b978022020-04-07 19:26:39 +00001166
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001167 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1168 ASSERT_NE(expr->result_type(), nullptr);
1169 ASSERT_TRUE(expr->result_type()->Is<ast::type::Vector>());
1170 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001171 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001172 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001173 ->Is<ast::type::F32>());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001174 EXPECT_EQ(expr->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001175}
1176
dan sinclair1c9b4862020-04-07 19:27:41 +00001177TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Matrix) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001178 auto* vector = Var("vector", ast::StorageClass::kNone, ty.vec3<f32>());
1179 auto* matrix = Var("matrix", ast::StorageClass::kNone, ty.mat2x3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001180 mod->AddGlobalVariable(vector);
1181 mod->AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001182
dan sinclairb950e802020-04-20 14:20:01 +00001183 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001184
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001185 auto* expr = Mul("vector", "matrix");
dan sinclair9b978022020-04-07 19:26:39 +00001186
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001187 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1188 ASSERT_NE(expr->result_type(), nullptr);
1189 ASSERT_TRUE(expr->result_type()->Is<ast::type::Vector>());
1190 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001191 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001192 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001193 ->Is<ast::type::F32>());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001194 EXPECT_EQ(expr->result_type()->As<ast::type::Vector>()->size(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001195}
1196
dan sinclair1c9b4862020-04-07 19:27:41 +00001197TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Matrix) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001198 ast::type::Matrix mat4x3(ty.f32, 4, 3);
1199 ast::type::Matrix mat3x4(ty.f32, 3, 4);
dan sinclair9b978022020-04-07 19:26:39 +00001200
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001201 auto* matrix1 = Var( // source
1202 "mat4x3", ast::StorageClass::kNone, &mat4x3);
1203 auto* matrix2 = Var( // source
1204 "mat3x4", ast::StorageClass::kNone, &mat3x4);
Ben Clayton3ea3c992020-11-18 21:19:22 +00001205 mod->AddGlobalVariable(matrix1);
1206 mod->AddGlobalVariable(matrix2);
dan sinclair9b978022020-04-07 19:26:39 +00001207
dan sinclairb950e802020-04-20 14:20:01 +00001208 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001209
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001210 auto* expr = Mul("mat4x3", "mat3x4");
dan sinclair9b978022020-04-07 19:26:39 +00001211
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001212 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1213 ASSERT_NE(expr->result_type(), nullptr);
1214 ASSERT_TRUE(expr->result_type()->Is<ast::type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001215
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001216 auto* mat = expr->result_type()->As<ast::type::Matrix>();
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001217 EXPECT_TRUE(mat->type()->Is<ast::type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001218 EXPECT_EQ(mat->rows(), 4u);
1219 EXPECT_EQ(mat->columns(), 4u);
dan sinclair9b978022020-04-07 19:26:39 +00001220}
1221
dan sinclair46e959d2020-06-01 13:43:22 +00001222using IntrinsicDerivativeTest = TypeDeterminerTestWithParam<std::string>;
1223TEST_P(IntrinsicDerivativeTest, Scalar) {
1224 auto name = GetParam();
dan sinclairb1730562020-04-07 19:26:49 +00001225
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001226 auto* var = Var("ident", ast::StorageClass::kNone, ty.f32);
dan sinclairb1730562020-04-07 19:26:49 +00001227
Ben Clayton3ea3c992020-11-18 21:19:22 +00001228 mod->AddGlobalVariable(var);
dan sinclair46e959d2020-06-01 13:43:22 +00001229
dan sinclair46e959d2020-06-01 13:43:22 +00001230 EXPECT_TRUE(td()->Determine());
1231
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001232 auto* expr = Call(name, "ident");
1233 EXPECT_TRUE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001234
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001235 ASSERT_NE(expr->result_type(), nullptr);
1236 ASSERT_TRUE(expr->result_type()->Is<ast::type::F32>());
dan sinclair46e959d2020-06-01 13:43:22 +00001237}
1238
1239TEST_P(IntrinsicDerivativeTest, Vector) {
1240 auto name = GetParam();
1241
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001242 auto* var = Var("ident", ast::StorageClass::kNone, ty.vec4<f32>());
dan sinclairb1730562020-04-07 19:26:49 +00001243
Ben Clayton3ea3c992020-11-18 21:19:22 +00001244 mod->AddGlobalVariable(var);
dan sinclairb1730562020-04-07 19:26:49 +00001245
dan sinclairb950e802020-04-20 14:20:01 +00001246 EXPECT_TRUE(td()->Determine());
dan sinclairb1730562020-04-07 19:26:49 +00001247
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001248 auto* expr = Call(name, "ident");
1249 EXPECT_TRUE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001250
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001251 ASSERT_NE(expr->result_type(), nullptr);
1252 ASSERT_TRUE(expr->result_type()->Is<ast::type::Vector>());
1253 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001254 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001255 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001256 ->Is<ast::type::F32>());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001257 EXPECT_EQ(expr->result_type()->As<ast::type::Vector>()->size(), 4u);
dan sinclair46e959d2020-06-01 13:43:22 +00001258}
1259
1260TEST_P(IntrinsicDerivativeTest, MissingParam) {
1261 auto name = GetParam();
1262
dan sinclair46e959d2020-06-01 13:43:22 +00001263 EXPECT_TRUE(td()->Determine());
1264
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001265 auto* expr = Call(name);
1266 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001267 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
1268}
1269
1270TEST_P(IntrinsicDerivativeTest, ToomManyParams) {
1271 auto name = GetParam();
1272
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001273 auto* var1 = Var("ident1", ast::StorageClass::kNone, ty.vec4<f32>());
1274 auto* var2 = Var("ident2", ast::StorageClass::kNone, ty.vec4<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001275 mod->AddGlobalVariable(var1);
1276 mod->AddGlobalVariable(var2);
dan sinclair46e959d2020-06-01 13:43:22 +00001277
dan sinclair46e959d2020-06-01 13:43:22 +00001278 EXPECT_TRUE(td()->Determine());
1279
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001280 auto* expr = Call(name, "ident1", "ident2");
1281 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001282 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
dan sinclairb1730562020-04-07 19:26:49 +00001283}
1284INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair46e959d2020-06-01 13:43:22 +00001285 IntrinsicDerivativeTest,
1286 testing::Values("dpdx",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001287 "dpdxCoarse",
1288 "dpdxFine",
dan sinclair46e959d2020-06-01 13:43:22 +00001289 "dpdy",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001290 "dpdyCoarse",
1291 "dpdyFine",
dan sinclair46e959d2020-06-01 13:43:22 +00001292 "fwidth",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001293 "fwidthCoarse",
1294 "fwidthFine"));
dan sinclairb1730562020-04-07 19:26:49 +00001295
dan sinclair46e959d2020-06-01 13:43:22 +00001296using Intrinsic = TypeDeterminerTestWithParam<std::string>;
1297TEST_P(Intrinsic, Test) {
1298 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00001299
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001300 auto* var = Var("my_var", ast::StorageClass::kNone, ty.vec3<bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001301
Ben Clayton3ea3c992020-11-18 21:19:22 +00001302 mod->AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00001303
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001304 auto* expr = Call(name, "my_var");
dan sinclair8dcfd102020-04-07 19:27:00 +00001305
dan sinclair8dcfd102020-04-07 19:27:00 +00001306 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001307 EXPECT_TRUE(td()->Determine());
dan sinclair8dcfd102020-04-07 19:27:00 +00001308
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001309 EXPECT_TRUE(td()->DetermineResultType(expr));
1310 ASSERT_NE(expr->result_type(), nullptr);
1311 EXPECT_TRUE(expr->result_type()->Is<ast::type::Bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001312}
1313INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair46e959d2020-06-01 13:43:22 +00001314 Intrinsic,
1315 testing::Values("any", "all"));
dan sinclair8dcfd102020-04-07 19:27:00 +00001316
dan sinclair46e959d2020-06-01 13:43:22 +00001317using Intrinsic_FloatMethod = TypeDeterminerTestWithParam<std::string>;
1318TEST_P(Intrinsic_FloatMethod, Vector) {
1319 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00001320
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001321 auto* var = Var("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001322
Ben Clayton3ea3c992020-11-18 21:19:22 +00001323 mod->AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00001324
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001325 auto* expr = Call(name, "my_var");
dan sinclair8dcfd102020-04-07 19:27:00 +00001326
dan sinclair8dcfd102020-04-07 19:27:00 +00001327 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001328 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001329 EXPECT_TRUE(td()->DetermineResultType(expr));
dan sinclair8dcfd102020-04-07 19:27:00 +00001330
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001331 ASSERT_NE(expr->result_type(), nullptr);
1332 ASSERT_TRUE(expr->result_type()->Is<ast::type::Vector>());
1333 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001334 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001335 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001336 ->Is<ast::type::Bool>());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001337 EXPECT_EQ(expr->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair8dcfd102020-04-07 19:27:00 +00001338}
dan sinclair46e959d2020-06-01 13:43:22 +00001339
1340TEST_P(Intrinsic_FloatMethod, Scalar) {
1341 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00001342
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001343 auto* var = Var("my_var", ast::StorageClass::kNone, ty.f32);
dan sinclair8dcfd102020-04-07 19:27:00 +00001344
Ben Clayton3ea3c992020-11-18 21:19:22 +00001345 mod->AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00001346
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001347 auto* expr = Call(name, "my_var");
dan sinclair8dcfd102020-04-07 19:27:00 +00001348
dan sinclair8dcfd102020-04-07 19:27:00 +00001349 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001350 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001351 EXPECT_TRUE(td()->DetermineResultType(expr));
1352 ASSERT_NE(expr->result_type(), nullptr);
1353 EXPECT_TRUE(expr->result_type()->Is<ast::type::Bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001354}
dan sinclair8dcfd102020-04-07 19:27:00 +00001355
dan sinclair46e959d2020-06-01 13:43:22 +00001356TEST_P(Intrinsic_FloatMethod, MissingParam) {
1357 auto name = GetParam();
1358
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001359 auto* var = Var("my_var", ast::StorageClass::kNone, ty.f32);
dan sinclair46e959d2020-06-01 13:43:22 +00001360
Ben Clayton3ea3c992020-11-18 21:19:22 +00001361 mod->AddGlobalVariable(var);
dan sinclair46e959d2020-06-01 13:43:22 +00001362
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001363 auto* expr = Call(name);
dan sinclair46e959d2020-06-01 13:43:22 +00001364
1365 // Register the variable
1366 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001367 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001368 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
1369}
1370
1371TEST_P(Intrinsic_FloatMethod, TooManyParams) {
1372 auto name = GetParam();
1373
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001374 auto* var = Var("my_var", ast::StorageClass::kNone, ty.f32);
dan sinclair46e959d2020-06-01 13:43:22 +00001375
Ben Clayton3ea3c992020-11-18 21:19:22 +00001376 mod->AddGlobalVariable(var);
dan sinclair46e959d2020-06-01 13:43:22 +00001377
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001378 auto* expr = Call(name, "my_var", "my_var");
dan sinclair46e959d2020-06-01 13:43:22 +00001379
1380 // Register the variable
1381 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001382 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001383 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
1384}
1385INSTANTIATE_TEST_SUITE_P(
1386 TypeDeterminerTest,
1387 Intrinsic_FloatMethod,
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001388 testing::Values("isInf", "isNan", "isFinite", "isNormal"));
dan sinclair46e959d2020-06-01 13:43:22 +00001389
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001390enum class Texture { kF32, kI32, kU32 };
1391inline std::ostream& operator<<(std::ostream& out, Texture data) {
1392 if (data == Texture::kF32) {
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001393 out << "f32";
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001394 } else if (data == Texture::kI32) {
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001395 out << "i32";
1396 } else {
1397 out << "u32";
1398 }
1399 return out;
1400}
1401
1402struct TextureTestParams {
1403 ast::type::TextureDimension dim;
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001404 Texture type = Texture::kF32;
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001405 ast::type::ImageFormat format = ast::type::ImageFormat::kR16Float;
1406};
1407inline std::ostream& operator<<(std::ostream& out, TextureTestParams data) {
1408 out << data.dim << "_" << data.type;
1409 return out;
1410}
1411
1412class Intrinsic_TextureOperation
1413 : public TypeDeterminerTestWithParam<TextureTestParams> {
1414 public:
1415 std::unique_ptr<ast::type::Type> get_coords_type(
1416 ast::type::TextureDimension dim,
1417 ast::type::Type* type) {
1418 if (dim == ast::type::TextureDimension::k1d) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001419 if (type->Is<ast::type::I32>()) {
1420 return std::make_unique<ast::type::I32>();
1421 } else if (type->Is<ast::type::U32>()) {
1422 return std::make_unique<ast::type::U32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001423 } else {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001424 return std::make_unique<ast::type::F32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001425 }
1426 } else if (dim == ast::type::TextureDimension::k1dArray ||
dan sinclaird3f75ca2020-09-17 03:53:04 +00001427 dim == ast::type::TextureDimension::k2d) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001428 return std::make_unique<ast::type::Vector>(type, 2);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001429 } else if (dim == ast::type::TextureDimension::kCubeArray) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001430 return std::make_unique<ast::type::Vector>(type, 4);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001431 } else {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001432 return std::make_unique<ast::type::Vector>(type, 3);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001433 }
1434 }
1435
1436 void add_call_param(std::string name,
1437 ast::type::Type* type,
1438 ast::ExpressionList* call_params) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001439 auto* var = Var(name, ast::StorageClass::kNone, type);
Ben Clayton3ea3c992020-11-18 21:19:22 +00001440 mod->AddGlobalVariable(var);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001441 call_params->push_back(Expr(name));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001442 }
1443
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001444 std::unique_ptr<ast::type::Type> subtype(Texture type) {
1445 if (type == Texture::kF32) {
1446 return std::make_unique<ast::type::F32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001447 }
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001448 if (type == Texture::kI32) {
1449 return std::make_unique<ast::type::I32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001450 }
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001451 return std::make_unique<ast::type::U32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001452 }
1453};
1454
1455using Intrinsic_StorageTextureOperation = Intrinsic_TextureOperation;
1456TEST_P(Intrinsic_StorageTextureOperation, TextureLoadRo) {
1457 auto dim = GetParam().dim;
1458 auto type = GetParam().type;
1459 auto format = GetParam().format;
1460
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001461 auto coords_type = get_coords_type(dim, ty.i32);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001462
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001463 ast::type::Type* texture_type = mod->create<ast::type::StorageTexture>(
Ben Clayton7e4ffa02020-11-23 19:58:55 +00001464 dim, ast::AccessControl::kReadOnly, format);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001465
1466 ast::ExpressionList call_params;
1467
1468 add_call_param("texture", texture_type, &call_params);
1469 add_call_param("coords", coords_type.get(), &call_params);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001470 add_call_param("lod", ty.i32, &call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001471
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001472 auto* expr = Call("textureLoad", call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001473
1474 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001475 EXPECT_TRUE(td()->DetermineResultType(expr));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001476
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001477 ASSERT_NE(expr->result_type(), nullptr);
1478 ASSERT_TRUE(expr->result_type()->Is<ast::type::Vector>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001479 if (type == Texture::kF32) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001480 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001481 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001482 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001483 ->Is<ast::type::F32>());
1484 } else if (type == Texture::kI32) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001485 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001486 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001487 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001488 ->Is<ast::type::I32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001489 } else {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001490 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001491 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001492 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001493 ->Is<ast::type::U32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001494 }
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001495 EXPECT_EQ(expr->result_type()->As<ast::type::Vector>()->size(), 4u);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001496}
1497
1498INSTANTIATE_TEST_SUITE_P(
1499 TypeDeterminerTest,
1500 Intrinsic_StorageTextureOperation,
1501 testing::Values(
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001502 TextureTestParams{ast::type::TextureDimension::k1d, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001503 ast::type::ImageFormat::kR16Float},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001504 TextureTestParams{ast::type::TextureDimension::k1d, Texture::kI32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001505 ast::type::ImageFormat::kR16Sint},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001506 TextureTestParams{ast::type::TextureDimension::k1d, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001507 ast::type::ImageFormat::kR8Unorm},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001508 TextureTestParams{ast::type::TextureDimension::k1dArray, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001509 ast::type::ImageFormat::kR16Float},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001510 TextureTestParams{ast::type::TextureDimension::k1dArray, Texture::kI32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001511 ast::type::ImageFormat::kR16Sint},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001512 TextureTestParams{ast::type::TextureDimension::k1dArray, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001513 ast::type::ImageFormat::kR8Unorm},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001514 TextureTestParams{ast::type::TextureDimension::k2d, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001515 ast::type::ImageFormat::kR16Float},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001516 TextureTestParams{ast::type::TextureDimension::k2d, Texture::kI32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001517 ast::type::ImageFormat::kR16Sint},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001518 TextureTestParams{ast::type::TextureDimension::k2d, Texture::kF32,
1519 ast::type::ImageFormat::kR8Unorm},
1520 TextureTestParams{ast::type::TextureDimension::k2dArray, Texture::kF32,
1521 ast::type::ImageFormat::kR16Float},
1522 TextureTestParams{ast::type::TextureDimension::k2dArray, Texture::kI32,
1523 ast::type::ImageFormat::kR16Sint},
1524 TextureTestParams{ast::type::TextureDimension::k2dArray, Texture::kF32,
1525 ast::type::ImageFormat::kR8Unorm},
1526 TextureTestParams{ast::type::TextureDimension::k3d, Texture::kF32,
1527 ast::type::ImageFormat::kR16Float},
1528 TextureTestParams{ast::type::TextureDimension::k3d, Texture::kI32,
1529 ast::type::ImageFormat::kR16Sint},
1530 TextureTestParams{ast::type::TextureDimension::k3d, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001531 ast::type::ImageFormat::kR8Unorm}));
1532
1533using Intrinsic_SampledTextureOperation = Intrinsic_TextureOperation;
1534TEST_P(Intrinsic_SampledTextureOperation, TextureLoadSampled) {
1535 auto dim = GetParam().dim;
1536 auto type = GetParam().type;
1537
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001538 std::unique_ptr<ast::type::Type> s = subtype(type);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001539 auto coords_type = get_coords_type(dim, ty.i32);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001540 auto texture_type = std::make_unique<ast::type::SampledTexture>(dim, s.get());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001541
1542 ast::ExpressionList call_params;
1543
1544 add_call_param("texture", texture_type.get(), &call_params);
1545 add_call_param("coords", coords_type.get(), &call_params);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001546 add_call_param("lod", ty.i32, &call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001547
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001548 auto* expr = Call("textureLoad", call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001549
1550 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001551 EXPECT_TRUE(td()->DetermineResultType(expr));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001552
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001553 ASSERT_NE(expr->result_type(), nullptr);
1554 ASSERT_TRUE(expr->result_type()->Is<ast::type::Vector>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001555 if (type == Texture::kF32) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001556 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001557 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001558 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001559 ->Is<ast::type::F32>());
1560 } else if (type == Texture::kI32) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001561 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001562 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001563 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001564 ->Is<ast::type::I32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001565 } else {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001566 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001567 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001568 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001569 ->Is<ast::type::U32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001570 }
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001571 EXPECT_EQ(expr->result_type()->As<ast::type::Vector>()->size(), 4u);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001572}
1573
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001574INSTANTIATE_TEST_SUITE_P(
1575 TypeDeterminerTest,
1576 Intrinsic_SampledTextureOperation,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001577 testing::Values(TextureTestParams{ast::type::TextureDimension::k2d},
1578 TextureTestParams{ast::type::TextureDimension::k2dArray},
1579 TextureTestParams{ast::type::TextureDimension::kCube},
1580 TextureTestParams{
1581 ast::type::TextureDimension::kCubeArray}));
1582
dan sinclair46e959d2020-06-01 13:43:22 +00001583TEST_F(TypeDeterminerTest, Intrinsic_Dot) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001584 auto* var = Var("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001585
Ben Clayton3ea3c992020-11-18 21:19:22 +00001586 mod->AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00001587
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001588 auto* expr = Call("dot", "my_var", "my_var");
dan sinclair8dcfd102020-04-07 19:27:00 +00001589
dan sinclair8dcfd102020-04-07 19:27:00 +00001590 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001591 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001592 EXPECT_TRUE(td()->DetermineResultType(expr));
1593 ASSERT_NE(expr->result_type(), nullptr);
1594 EXPECT_TRUE(expr->result_type()->Is<ast::type::F32>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001595}
1596
dan sinclair16a2ea12020-07-21 17:44:44 +00001597TEST_F(TypeDeterminerTest, Intrinsic_Select) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001598 auto* var = Var("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00001599
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001600 auto* bool_var = Var( // source
1601 "bool_var", ast::StorageClass::kNone, ty.vec3<bool>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001602 mod->AddGlobalVariable(var);
1603 mod->AddGlobalVariable(bool_var);
dan sinclair16a2ea12020-07-21 17:44:44 +00001604
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001605 auto* expr = Call("select", "my_var", "my_var", "bool_var");
dan sinclair16a2ea12020-07-21 17:44:44 +00001606
1607 // Register the variable
1608 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001609 EXPECT_TRUE(td()->DetermineResultType(expr)) << td()->error();
1610 ASSERT_NE(expr->result_type(), nullptr);
1611 EXPECT_TRUE(expr->result_type()->Is<ast::type::Vector>());
1612 EXPECT_EQ(expr->result_type()->As<ast::type::Vector>()->size(), 3u);
1613 EXPECT_TRUE(expr->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001614 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001615 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001616 ->Is<ast::type::F32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00001617}
1618
1619TEST_F(TypeDeterminerTest, Intrinsic_Select_TooFewParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001620 auto* var = Var("v", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00001621
Ben Clayton3ea3c992020-11-18 21:19:22 +00001622 mod->AddGlobalVariable(var);
dan sinclair16a2ea12020-07-21 17:44:44 +00001623
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001624 auto* expr = Call("select", "v");
dan sinclair16a2ea12020-07-21 17:44:44 +00001625
1626 // Register the variable
1627 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001628 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair16a2ea12020-07-21 17:44:44 +00001629 EXPECT_EQ(td()->error(),
1630 "incorrect number of parameters for select expected 3 got 1");
1631}
1632
1633TEST_F(TypeDeterminerTest, Intrinsic_Select_TooManyParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001634 auto* var = Var("v", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00001635
Ben Clayton3ea3c992020-11-18 21:19:22 +00001636 mod->AddGlobalVariable(var);
dan sinclair16a2ea12020-07-21 17:44:44 +00001637
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001638 auto* expr = Call("select", "v", "v", "v", "v");
dan sinclair16a2ea12020-07-21 17:44:44 +00001639
1640 // Register the variable
1641 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001642 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair16a2ea12020-07-21 17:44:44 +00001643 EXPECT_EQ(td()->error(),
1644 "incorrect number of parameters for select expected 3 got 4");
1645}
1646
dan sinclair46e959d2020-06-01 13:43:22 +00001647TEST_F(TypeDeterminerTest, Intrinsic_OuterProduct) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001648 auto* var1 = Var( // source
1649 "v3", ast::StorageClass::kNone, ty.vec3<f32>());
1650 auto* var2 = Var( // source
1651 "v2", ast::StorageClass::kNone, ty.vec2<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001652 mod->AddGlobalVariable(var1);
1653 mod->AddGlobalVariable(var2);
dan sinclair8dcfd102020-04-07 19:27:00 +00001654
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001655 auto* expr = Call("outerProduct", "v3", "v2");
dan sinclair8dcfd102020-04-07 19:27:00 +00001656
dan sinclair8dcfd102020-04-07 19:27:00 +00001657 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001658 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001659 EXPECT_TRUE(td()->DetermineResultType(expr));
dan sinclair8dcfd102020-04-07 19:27:00 +00001660
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001661 ASSERT_NE(expr->result_type(), nullptr);
1662 ASSERT_TRUE(expr->result_type()->Is<ast::type::Matrix>());
dan sinclair46e959d2020-06-01 13:43:22 +00001663
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001664 auto* mat = expr->result_type()->As<ast::type::Matrix>();
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001665 EXPECT_TRUE(mat->type()->Is<ast::type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001666 EXPECT_EQ(mat->rows(), 3u);
1667 EXPECT_EQ(mat->columns(), 2u);
dan sinclair8dcfd102020-04-07 19:27:00 +00001668}
1669
dan sinclair46e959d2020-06-01 13:43:22 +00001670TEST_F(TypeDeterminerTest, Intrinsic_OuterProduct_TooFewParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001671 auto* var2 = Var( // source
1672 "v2", ast::StorageClass::kNone, ty.vec2<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001673 mod->AddGlobalVariable(var2);
dan sinclair46e959d2020-06-01 13:43:22 +00001674
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001675 auto* expr = Call("outerProduct", "v2");
dan sinclair46e959d2020-06-01 13:43:22 +00001676
1677 // Register the variable
1678 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001679 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001680 EXPECT_EQ(td()->error(), "incorrect number of parameters for outerProduct");
dan sinclair46e959d2020-06-01 13:43:22 +00001681}
1682
1683TEST_F(TypeDeterminerTest, Intrinsic_OuterProduct_TooManyParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001684 auto* var2 = Var( // source
1685 "v2", ast::StorageClass::kNone, ty.vec2<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00001686 mod->AddGlobalVariable(var2);
dan sinclair46e959d2020-06-01 13:43:22 +00001687
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001688 auto* expr = Call("outerProduct", "v2", "v2", "v2");
dan sinclair46e959d2020-06-01 13:43:22 +00001689
1690 // Register the variable
1691 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001692 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001693 EXPECT_EQ(td()->error(), "incorrect number of parameters for outerProduct");
dan sinclair46e959d2020-06-01 13:43:22 +00001694}
1695
dan sinclaircd077b02020-04-20 14:19:04 +00001696using UnaryOpExpressionTest = TypeDeterminerTestWithParam<ast::UnaryOp>;
dan sinclair0e257622020-04-07 19:27:11 +00001697TEST_P(UnaryOpExpressionTest, Expr_UnaryOp) {
1698 auto op = GetParam();
1699
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001700 auto* var = Var("ident", ast::StorageClass::kNone, ty.vec4<f32>());
dan sinclair0e257622020-04-07 19:27:11 +00001701
Ben Clayton3ea3c992020-11-18 21:19:22 +00001702 mod->AddGlobalVariable(var);
dan sinclair0e257622020-04-07 19:27:11 +00001703
dan sinclairb950e802020-04-20 14:20:01 +00001704 EXPECT_TRUE(td()->Determine());
dan sinclair0e257622020-04-07 19:27:11 +00001705
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001706 auto* der = create<ast::UnaryOpExpression>(op, Expr("ident"));
1707 EXPECT_TRUE(td()->DetermineResultType(der));
1708 ASSERT_NE(der->result_type(), nullptr);
1709 ASSERT_TRUE(der->result_type()->Is<ast::type::Vector>());
1710 EXPECT_TRUE(der->result_type()
1711 ->As<ast::type::Vector>()
1712 ->type()
1713 ->Is<ast::type::F32>());
1714 EXPECT_EQ(der->result_type()->As<ast::type::Vector>()->size(), 4u);
dan sinclair0e257622020-04-07 19:27:11 +00001715}
1716INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
1717 UnaryOpExpressionTest,
1718 testing::Values(ast::UnaryOp::kNegation,
1719 ast::UnaryOp::kNot));
1720
dan sinclairee8ae042020-04-08 19:58:20 +00001721TEST_F(TypeDeterminerTest, StorageClass_SetsIfMissing) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001722 auto* var = Var("var", ast::StorageClass::kNone, ty.i32);
dan sinclairee8ae042020-04-08 19:58:20 +00001723
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001724 auto* stmt = create<ast::VariableDeclStatement>(var);
dan sinclair181d8ba2020-12-16 15:15:40 +00001725 auto* func = Func("func", ast::VariableList{}, ty.i32,
1726 ast::StatementList{stmt}, ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001727
Ben Clayton3ea3c992020-11-18 21:19:22 +00001728 mod->AddFunction(func);
dan sinclairee8ae042020-04-08 19:58:20 +00001729
dan sinclairb950e802020-04-20 14:20:01 +00001730 EXPECT_TRUE(td()->Determine()) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001731 EXPECT_EQ(var->storage_class(), ast::StorageClass::kFunction);
dan sinclairee8ae042020-04-08 19:58:20 +00001732}
1733
1734TEST_F(TypeDeterminerTest, StorageClass_DoesNotSetOnConst) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001735 auto* var = Const("var", ast::StorageClass::kNone, ty.i32);
1736 auto* stmt = create<ast::VariableDeclStatement>(var);
dan sinclair181d8ba2020-12-16 15:15:40 +00001737 auto* func = Func("func", ast::VariableList{}, ty.i32,
1738 ast::StatementList{stmt}, ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001739
Ben Clayton3ea3c992020-11-18 21:19:22 +00001740 mod->AddFunction(func);
dan sinclairee8ae042020-04-08 19:58:20 +00001741
dan sinclairb950e802020-04-20 14:20:01 +00001742 EXPECT_TRUE(td()->Determine()) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001743 EXPECT_EQ(var->storage_class(), ast::StorageClass::kNone);
dan sinclairee8ae042020-04-08 19:58:20 +00001744}
1745
1746TEST_F(TypeDeterminerTest, StorageClass_NonFunctionClassError) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001747 auto* var = Var("var", ast::StorageClass::kWorkgroup, ty.i32);
dan sinclairee8ae042020-04-08 19:58:20 +00001748
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001749 auto* stmt = create<ast::VariableDeclStatement>(var);
dan sinclair181d8ba2020-12-16 15:15:40 +00001750 auto* func = Func("func", ast::VariableList{}, ty.i32,
1751 ast::StatementList{stmt}, ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001752
Ben Clayton3ea3c992020-11-18 21:19:22 +00001753 mod->AddFunction(func);
dan sinclairee8ae042020-04-08 19:58:20 +00001754
dan sinclairb950e802020-04-20 14:20:01 +00001755 EXPECT_FALSE(td()->Determine());
dan sinclairee8ae042020-04-08 19:58:20 +00001756 EXPECT_EQ(td()->error(),
1757 "function variable has a non-function storage class");
1758}
1759
dan sinclairb4fee2f2020-09-22 19:42:13 +00001760struct IntrinsicData {
dan sinclairca1723e2020-04-20 15:47:55 +00001761 const char* name;
dan sinclairb4fee2f2020-09-22 19:42:13 +00001762 ast::Intrinsic intrinsic;
dan sinclairca1723e2020-04-20 15:47:55 +00001763};
dan sinclairb4fee2f2020-09-22 19:42:13 +00001764inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
dan sinclairca1723e2020-04-20 15:47:55 +00001765 out << data.name;
1766 return out;
1767}
dan sinclairb4fee2f2020-09-22 19:42:13 +00001768using IntrinsicDataTest = TypeDeterminerTestWithParam<IntrinsicData>;
1769TEST_P(IntrinsicDataTest, Lookup) {
1770 auto param = GetParam();
dan sinclairca1723e2020-04-20 15:47:55 +00001771
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001772 auto* ident = Expr(param.name);
1773 EXPECT_TRUE(td()->SetIntrinsicIfNeeded(ident));
1774 EXPECT_EQ(ident->intrinsic(), param.intrinsic);
1775 EXPECT_TRUE(ident->IsIntrinsic());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001776}
1777INSTANTIATE_TEST_SUITE_P(
1778 TypeDeterminerTest,
1779 IntrinsicDataTest,
1780 testing::Values(
1781 IntrinsicData{"abs", ast::Intrinsic::kAbs},
1782 IntrinsicData{"acos", ast::Intrinsic::kAcos},
1783 IntrinsicData{"all", ast::Intrinsic::kAll},
1784 IntrinsicData{"any", ast::Intrinsic::kAny},
dan sinclair007dc422020-10-08 17:01:55 +00001785 IntrinsicData{"arrayLength", ast::Intrinsic::kArrayLength},
dan sinclairb4fee2f2020-09-22 19:42:13 +00001786 IntrinsicData{"asin", ast::Intrinsic::kAsin},
1787 IntrinsicData{"atan", ast::Intrinsic::kAtan},
1788 IntrinsicData{"atan2", ast::Intrinsic::kAtan2},
1789 IntrinsicData{"ceil", ast::Intrinsic::kCeil},
1790 IntrinsicData{"clamp", ast::Intrinsic::kClamp},
1791 IntrinsicData{"cos", ast::Intrinsic::kCos},
1792 IntrinsicData{"cosh", ast::Intrinsic::kCosh},
1793 IntrinsicData{"countOneBits", ast::Intrinsic::kCountOneBits},
1794 IntrinsicData{"cross", ast::Intrinsic::kCross},
1795 IntrinsicData{"determinant", ast::Intrinsic::kDeterminant},
1796 IntrinsicData{"distance", ast::Intrinsic::kDistance},
1797 IntrinsicData{"dot", ast::Intrinsic::kDot},
1798 IntrinsicData{"dpdx", ast::Intrinsic::kDpdx},
1799 IntrinsicData{"dpdxCoarse", ast::Intrinsic::kDpdxCoarse},
1800 IntrinsicData{"dpdxFine", ast::Intrinsic::kDpdxFine},
1801 IntrinsicData{"dpdy", ast::Intrinsic::kDpdy},
1802 IntrinsicData{"dpdyCoarse", ast::Intrinsic::kDpdyCoarse},
1803 IntrinsicData{"dpdyFine", ast::Intrinsic::kDpdyFine},
1804 IntrinsicData{"exp", ast::Intrinsic::kExp},
1805 IntrinsicData{"exp2", ast::Intrinsic::kExp2},
1806 IntrinsicData{"faceForward", ast::Intrinsic::kFaceForward},
1807 IntrinsicData{"floor", ast::Intrinsic::kFloor},
1808 IntrinsicData{"fma", ast::Intrinsic::kFma},
1809 IntrinsicData{"fract", ast::Intrinsic::kFract},
1810 IntrinsicData{"frexp", ast::Intrinsic::kFrexp},
1811 IntrinsicData{"fwidth", ast::Intrinsic::kFwidth},
1812 IntrinsicData{"fwidthCoarse", ast::Intrinsic::kFwidthCoarse},
1813 IntrinsicData{"fwidthFine", ast::Intrinsic::kFwidthFine},
1814 IntrinsicData{"inverseSqrt", ast::Intrinsic::kInverseSqrt},
1815 IntrinsicData{"isFinite", ast::Intrinsic::kIsFinite},
1816 IntrinsicData{"isInf", ast::Intrinsic::kIsInf},
1817 IntrinsicData{"isNan", ast::Intrinsic::kIsNan},
1818 IntrinsicData{"isNormal", ast::Intrinsic::kIsNormal},
1819 IntrinsicData{"ldexp", ast::Intrinsic::kLdexp},
1820 IntrinsicData{"length", ast::Intrinsic::kLength},
1821 IntrinsicData{"log", ast::Intrinsic::kLog},
1822 IntrinsicData{"log2", ast::Intrinsic::kLog2},
1823 IntrinsicData{"max", ast::Intrinsic::kMax},
1824 IntrinsicData{"min", ast::Intrinsic::kMin},
1825 IntrinsicData{"mix", ast::Intrinsic::kMix},
1826 IntrinsicData{"modf", ast::Intrinsic::kModf},
1827 IntrinsicData{"normalize", ast::Intrinsic::kNormalize},
1828 IntrinsicData{"outerProduct", ast::Intrinsic::kOuterProduct},
1829 IntrinsicData{"pow", ast::Intrinsic::kPow},
1830 IntrinsicData{"reflect", ast::Intrinsic::kReflect},
1831 IntrinsicData{"reverseBits", ast::Intrinsic::kReverseBits},
1832 IntrinsicData{"round", ast::Intrinsic::kRound},
1833 IntrinsicData{"select", ast::Intrinsic::kSelect},
1834 IntrinsicData{"sign", ast::Intrinsic::kSign},
1835 IntrinsicData{"sin", ast::Intrinsic::kSin},
1836 IntrinsicData{"sinh", ast::Intrinsic::kSinh},
1837 IntrinsicData{"smoothStep", ast::Intrinsic::kSmoothStep},
1838 IntrinsicData{"sqrt", ast::Intrinsic::kSqrt},
1839 IntrinsicData{"step", ast::Intrinsic::kStep},
1840 IntrinsicData{"tan", ast::Intrinsic::kTan},
1841 IntrinsicData{"tanh", ast::Intrinsic::kTanh},
1842 IntrinsicData{"textureLoad", ast::Intrinsic::kTextureLoad},
1843 IntrinsicData{"textureSample", ast::Intrinsic::kTextureSample},
1844 IntrinsicData{"textureSampleBias", ast::Intrinsic::kTextureSampleBias},
1845 IntrinsicData{"textureSampleCompare",
1846 ast::Intrinsic::kTextureSampleCompare},
Ben Clayton3ea3c992020-11-18 21:19:22 +00001847 IntrinsicData{"textureSampleGrad", ast::Intrinsic::kTextureSampleGrad},
dan sinclairb4fee2f2020-09-22 19:42:13 +00001848 IntrinsicData{"textureSampleLevel",
1849 ast::Intrinsic::kTextureSampleLevel},
1850 IntrinsicData{"trunc", ast::Intrinsic::kTrunc}));
1851
1852TEST_F(TypeDeterminerTest, IntrinsicNotSetIfNotMatched) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001853 auto* ident = Expr("not_intrinsic");
1854 EXPECT_FALSE(td()->SetIntrinsicIfNeeded(ident));
1855 EXPECT_EQ(ident->intrinsic(), ast::Intrinsic::kNone);
1856 EXPECT_FALSE(ident->IsIntrinsic());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001857}
1858
1859using ImportData_SingleParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair37d62c92020-04-21 12:55:06 +00001860TEST_P(ImportData_SingleParamTest, Scalar) {
dan sinclairca1723e2020-04-20 15:47:55 +00001861 auto param = GetParam();
1862
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001863 auto* ident = Expr(param.name);
1864 auto* call = Call(ident, 1.f);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001865
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001866 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001867 ASSERT_NE(ident->result_type(), nullptr);
1868 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001869}
1870
dan sinclair37d62c92020-04-21 12:55:06 +00001871TEST_P(ImportData_SingleParamTest, Vector) {
dan sinclairca1723e2020-04-20 15:47:55 +00001872 auto param = GetParam();
1873
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001874 auto* ident = Expr(param.name);
1875 auto* call = Call(ident, vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001876
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001877 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001878 ASSERT_NE(ident->result_type(), nullptr);
1879 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001880 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001881}
1882
dan sinclair37d62c92020-04-21 12:55:06 +00001883TEST_P(ImportData_SingleParamTest, Error_Integer) {
dan sinclairca1723e2020-04-20 15:47:55 +00001884 auto param = GetParam();
1885
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001886 auto* call = Call(param.name, 1);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001887
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001888 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair53352042020-06-08 18:49:31 +00001889 EXPECT_EQ(td()->error(),
1890 std::string("incorrect type for ") + param.name +
1891 ". Requires float scalar or float vector values");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001892}
1893
dan sinclair37d62c92020-04-21 12:55:06 +00001894TEST_P(ImportData_SingleParamTest, Error_NoParams) {
dan sinclairca1723e2020-04-20 15:47:55 +00001895 auto param = GetParam();
1896
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001897 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001898
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001899 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairca1723e2020-04-20 15:47:55 +00001900 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
1901 param.name + ". Expected 1 got 0");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001902}
1903
dan sinclair37d62c92020-04-21 12:55:06 +00001904TEST_P(ImportData_SingleParamTest, Error_MultipleParams) {
dan sinclairca1723e2020-04-20 15:47:55 +00001905 auto param = GetParam();
1906
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001907 auto* call = Call(param.name, 1.f, 1.f, 1.f);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001908
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001909 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairca1723e2020-04-20 15:47:55 +00001910 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
1911 param.name + ". Expected 1 got 3");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001912}
1913
dan sinclaira49328f2020-04-20 15:49:50 +00001914INSTANTIATE_TEST_SUITE_P(
1915 TypeDeterminerTest,
dan sinclair37d62c92020-04-21 12:55:06 +00001916 ImportData_SingleParamTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00001917 testing::Values(IntrinsicData{"acos", ast::Intrinsic::kAcos},
1918 IntrinsicData{"asin", ast::Intrinsic::kAsin},
1919 IntrinsicData{"atan", ast::Intrinsic::kAtan},
1920 IntrinsicData{"ceil", ast::Intrinsic::kCeil},
1921 IntrinsicData{"cos", ast::Intrinsic::kCos},
1922 IntrinsicData{"cosh", ast::Intrinsic::kCosh},
1923 IntrinsicData{"exp", ast::Intrinsic::kExp},
1924 IntrinsicData{"exp2", ast::Intrinsic::kExp2},
1925 IntrinsicData{"floor", ast::Intrinsic::kFloor},
1926 IntrinsicData{"fract", ast::Intrinsic::kFract},
1927 IntrinsicData{"inverseSqrt", ast::Intrinsic::kInverseSqrt},
1928 IntrinsicData{"log", ast::Intrinsic::kLog},
1929 IntrinsicData{"log2", ast::Intrinsic::kLog2},
1930 IntrinsicData{"normalize", ast::Intrinsic::kNormalize},
1931 IntrinsicData{"round", ast::Intrinsic::kRound},
1932 IntrinsicData{"sign", ast::Intrinsic::kSign},
1933 IntrinsicData{"sin", ast::Intrinsic::kSin},
1934 IntrinsicData{"sinh", ast::Intrinsic::kSinh},
1935 IntrinsicData{"sqrt", ast::Intrinsic::kSqrt},
1936 IntrinsicData{"tan", ast::Intrinsic::kTan},
1937 IntrinsicData{"tanh", ast::Intrinsic::kTanh},
1938 IntrinsicData{"trunc", ast::Intrinsic::kTrunc}));
1939
1940using ImportData_SingleParam_FloatOrInt_Test =
1941 TypeDeterminerTestWithParam<IntrinsicData>;
1942TEST_P(ImportData_SingleParam_FloatOrInt_Test, Float_Scalar) {
1943 auto param = GetParam();
1944
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001945 auto* ident = Expr(param.name);
1946 auto* call = Call(ident, 1.f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001947
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001948 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001949 ASSERT_NE(ident->result_type(), nullptr);
1950 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001951}
1952
1953TEST_P(ImportData_SingleParam_FloatOrInt_Test, Float_Vector) {
1954 auto param = GetParam();
1955
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001956 auto* ident = Expr(param.name);
1957 auto* call = Call(ident, vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001958
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001959 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001960 ASSERT_NE(ident->result_type(), nullptr);
1961 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001962 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001963}
1964
1965TEST_P(ImportData_SingleParam_FloatOrInt_Test, Sint_Scalar) {
1966 auto param = GetParam();
1967
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001968 auto* ident = Expr(param.name);
1969 auto* call = Call(ident, -1);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001970
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001971 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001972 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001973 EXPECT_TRUE(ident->result_type()->Is<ast::type::I32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001974}
1975
1976TEST_P(ImportData_SingleParam_FloatOrInt_Test, Sint_Vector) {
1977 auto param = GetParam();
1978
dan sinclairb4fee2f2020-09-22 19:42:13 +00001979 ast::ExpressionList vals;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001980 vals.push_back(Expr(1));
1981 vals.push_back(Expr(1));
1982 vals.push_back(Expr(3));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001983
1984 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001985 params.push_back(vec3<i32>(vals));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001986
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001987 auto* ident = Expr(param.name);
1988 auto* call = Call(ident, params);
Ben Clayton4bfe4612020-11-16 16:41:47 +00001989
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001990 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001991 ASSERT_NE(ident->result_type(), nullptr);
1992 EXPECT_TRUE(ident->result_type()->is_signed_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001993 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001994}
1995
1996TEST_P(ImportData_SingleParam_FloatOrInt_Test, Uint_Scalar) {
1997 auto param = GetParam();
1998
dan sinclairb4fee2f2020-09-22 19:42:13 +00001999 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002000 params.push_back(Expr(1u));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002001
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002002 auto* ident = Expr(param.name);
2003 auto* call = Call(ident, params);
Ben Clayton4bfe4612020-11-16 16:41:47 +00002004
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002005 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002006 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002007 EXPECT_TRUE(ident->result_type()->Is<ast::type::U32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002008}
2009
2010TEST_P(ImportData_SingleParam_FloatOrInt_Test, Uint_Vector) {
2011 auto param = GetParam();
2012
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002013 auto* ident = Expr(param.name);
2014 auto* call = Call(ident, vec3<u32>(1u, 1u, 3u));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002015
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002016 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002017 ASSERT_NE(ident->result_type(), nullptr);
2018 EXPECT_TRUE(ident->result_type()->is_unsigned_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002019 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002020}
2021
2022TEST_P(ImportData_SingleParam_FloatOrInt_Test, Error_Bool) {
2023 auto param = GetParam();
2024
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002025 auto* call = Call(param.name, false);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002026
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002027 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002028 EXPECT_EQ(td()->error(),
2029 std::string("incorrect type for ") + param.name +
2030 ". Requires float or int, scalar or vector values");
2031}
2032
2033TEST_P(ImportData_SingleParam_FloatOrInt_Test, Error_NoParams) {
2034 auto param = GetParam();
2035
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002036 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002037
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002038 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002039 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2040 param.name + ". Expected 1 got 0");
2041}
2042
2043TEST_P(ImportData_SingleParam_FloatOrInt_Test, Error_MultipleParams) {
2044 auto param = GetParam();
2045
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002046 auto* call = Call(param.name, 1.f, 1.f, 1.f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002047
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002048 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002049 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2050 param.name + ". Expected 1 got 3");
2051}
2052
2053INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
2054 ImportData_SingleParam_FloatOrInt_Test,
2055 testing::Values(IntrinsicData{"abs",
2056 ast::Intrinsic::kAbs}));
dan sinclairca1723e2020-04-20 15:47:55 +00002057
dan sinclair652a4b92020-04-20 21:09:14 +00002058TEST_F(TypeDeterminerTest, ImportData_Length_Scalar) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002059 auto* ident = Expr("length");
dan sinclair652a4b92020-04-20 21:09:14 +00002060
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002061 auto* call = Call(ident, 1.f);
dan sinclair652a4b92020-04-20 21:09:14 +00002062
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002063 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002064 ASSERT_NE(ident->result_type(), nullptr);
2065 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair652a4b92020-04-20 21:09:14 +00002066}
2067
2068TEST_F(TypeDeterminerTest, ImportData_Length_FloatVector) {
dan sinclair652a4b92020-04-20 21:09:14 +00002069 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002070 params.push_back(vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair652a4b92020-04-20 21:09:14 +00002071
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002072 auto* ident = Expr("length");
Ben Clayton4bfe4612020-11-16 16:41:47 +00002073
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002074 auto* call = Call(ident, params);
dan sinclair652a4b92020-04-20 21:09:14 +00002075
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002076 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002077 ASSERT_NE(ident->result_type(), nullptr);
2078 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair652a4b92020-04-20 21:09:14 +00002079}
2080
2081TEST_F(TypeDeterminerTest, ImportData_Length_Error_Integer) {
dan sinclair652a4b92020-04-20 21:09:14 +00002082 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002083 params.push_back(Expr(1));
dan sinclair652a4b92020-04-20 21:09:14 +00002084
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002085 auto* call = Call("length", params);
dan sinclair652a4b92020-04-20 21:09:14 +00002086
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002087 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair53352042020-06-08 18:49:31 +00002088 EXPECT_EQ(td()->error(),
2089 "incorrect type for length. Requires float scalar or float vector "
2090 "values");
dan sinclair652a4b92020-04-20 21:09:14 +00002091}
2092
2093TEST_F(TypeDeterminerTest, ImportData_Length_Error_NoParams) {
2094 ast::ExpressionList params;
dan sinclairb4fee2f2020-09-22 19:42:13 +00002095
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002096 auto* call = Call("length");
dan sinclairb4fee2f2020-09-22 19:42:13 +00002097
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002098 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair652a4b92020-04-20 21:09:14 +00002099 EXPECT_EQ(td()->error(),
2100 "incorrect number of parameters for length. Expected 1 got 0");
2101}
2102
2103TEST_F(TypeDeterminerTest, ImportData_Length_Error_MultipleParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002104 auto* call = Call("length", 1.f, 1.f, 1.f);
dan sinclair652a4b92020-04-20 21:09:14 +00002105
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002106 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair652a4b92020-04-20 21:09:14 +00002107 EXPECT_EQ(td()->error(),
2108 "incorrect number of parameters for length. Expected 1 got 3");
2109}
2110
dan sinclairb4fee2f2020-09-22 19:42:13 +00002111using ImportData_TwoParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair37d62c92020-04-21 12:55:06 +00002112TEST_P(ImportData_TwoParamTest, Scalar) {
2113 auto param = GetParam();
2114
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002115 auto* ident = Expr(param.name);
2116 auto* call = Call(ident, 1.f, 1.f);
dan sinclair37d62c92020-04-21 12:55:06 +00002117
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002118 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002119 ASSERT_NE(ident->result_type(), nullptr);
2120 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair37d62c92020-04-21 12:55:06 +00002121}
2122
2123TEST_P(ImportData_TwoParamTest, Vector) {
2124 auto param = GetParam();
2125
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002126 auto* ident = Expr(param.name);
2127 auto* call =
2128 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 +00002129
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002130 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002131 ASSERT_NE(ident->result_type(), nullptr);
2132 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002133 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair37d62c92020-04-21 12:55:06 +00002134}
2135
2136TEST_P(ImportData_TwoParamTest, Error_Integer) {
2137 auto param = GetParam();
2138
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002139 auto* call = Call(param.name, 1, 2);
dan sinclair37d62c92020-04-21 12:55:06 +00002140
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002141 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair37d62c92020-04-21 12:55:06 +00002142 EXPECT_EQ(td()->error(),
2143 std::string("incorrect type for ") + param.name +
dan sinclair53352042020-06-08 18:49:31 +00002144 ". Requires float scalar or float vector values");
dan sinclair37d62c92020-04-21 12:55:06 +00002145}
2146
2147TEST_P(ImportData_TwoParamTest, Error_NoParams) {
2148 auto param = GetParam();
2149
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002150 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002151
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002152 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair37d62c92020-04-21 12:55:06 +00002153 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2154 param.name + ". Expected 2 got 0");
2155}
2156
2157TEST_P(ImportData_TwoParamTest, Error_OneParam) {
2158 auto param = GetParam();
2159
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002160 auto* call = Call(param.name, 1.f);
dan sinclair37d62c92020-04-21 12:55:06 +00002161
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002162 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair37d62c92020-04-21 12:55:06 +00002163 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2164 param.name + ". Expected 2 got 1");
2165}
2166
2167TEST_P(ImportData_TwoParamTest, Error_MismatchedParamCount) {
2168 auto param = GetParam();
2169
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002170 auto* call =
2171 Call(param.name, vec2<f32>(1.0f, 1.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair37d62c92020-04-21 12:55:06 +00002172
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002173 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair37d62c92020-04-21 12:55:06 +00002174 EXPECT_EQ(td()->error(),
2175 std::string("mismatched parameter types for ") + param.name);
2176}
2177
2178TEST_P(ImportData_TwoParamTest, Error_MismatchedParamType) {
2179 auto param = GetParam();
2180
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002181 auto* call = Call(param.name, 1.0f, vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair37d62c92020-04-21 12:55:06 +00002182
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002183 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair37d62c92020-04-21 12:55:06 +00002184 EXPECT_EQ(td()->error(),
2185 std::string("mismatched parameter types for ") + param.name);
2186}
2187
2188TEST_P(ImportData_TwoParamTest, Error_TooManyParams) {
2189 auto param = GetParam();
2190
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002191 auto* call = Call(param.name, 1.f, 1.f, 1.f);
dan sinclair37d62c92020-04-21 12:55:06 +00002192
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002193 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair37d62c92020-04-21 12:55:06 +00002194 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2195 param.name + ". Expected 2 got 3");
2196}
2197
dan sinclairb4fee2f2020-09-22 19:42:13 +00002198INSTANTIATE_TEST_SUITE_P(
2199 TypeDeterminerTest,
2200 ImportData_TwoParamTest,
2201 testing::Values(IntrinsicData{"atan2", ast::Intrinsic::kAtan2},
2202 IntrinsicData{"pow", ast::Intrinsic::kPow},
2203 IntrinsicData{"step", ast::Intrinsic::kStep},
2204 IntrinsicData{"reflect", ast::Intrinsic::kReflect}));
dan sinclair37d62c92020-04-21 12:55:06 +00002205
dan sinclair54444382020-04-21 13:04:15 +00002206TEST_F(TypeDeterminerTest, ImportData_Distance_Scalar) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002207 auto* ident = Expr("distance");
dan sinclair54444382020-04-21 13:04:15 +00002208
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002209 auto* call = Call(ident, 1.f, 1.f);
dan sinclair54444382020-04-21 13:04:15 +00002210
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002211 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002212 ASSERT_NE(ident->result_type(), nullptr);
2213 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair54444382020-04-21 13:04:15 +00002214}
2215
2216TEST_F(TypeDeterminerTest, ImportData_Distance_Vector) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002217 auto* ident = Expr("distance");
dan sinclair54444382020-04-21 13:04:15 +00002218
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002219 auto* call =
2220 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 +00002221
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002222 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002223 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002224 EXPECT_TRUE(ident->result_type()->Is<ast::type::F32>());
dan sinclair54444382020-04-21 13:04:15 +00002225}
2226
2227TEST_F(TypeDeterminerTest, ImportData_Distance_Error_Integer) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002228 auto* call = Call("distance", 1, 2);
dan sinclair54444382020-04-21 13:04:15 +00002229
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002230 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair54444382020-04-21 13:04:15 +00002231 EXPECT_EQ(td()->error(),
dan sinclair53352042020-06-08 18:49:31 +00002232 "incorrect type for distance. Requires float scalar or float "
dan sinclair54444382020-04-21 13:04:15 +00002233 "vector values");
2234}
2235
2236TEST_F(TypeDeterminerTest, ImportData_Distance_Error_NoParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002237 auto* call = Call("distance");
dan sinclairb4fee2f2020-09-22 19:42:13 +00002238
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002239 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair54444382020-04-21 13:04:15 +00002240 EXPECT_EQ(td()->error(),
2241 "incorrect number of parameters for distance. Expected 2 got 0");
2242}
2243
2244TEST_F(TypeDeterminerTest, ImportData_Distance_Error_OneParam) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002245 auto* call = Call("distance", 1.f);
dan sinclair54444382020-04-21 13:04:15 +00002246
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002247 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair54444382020-04-21 13:04:15 +00002248 EXPECT_EQ(td()->error(),
2249 "incorrect number of parameters for distance. Expected 2 got 1");
2250}
2251
2252TEST_F(TypeDeterminerTest, ImportData_Distance_Error_MismatchedParamCount) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002253 auto* call =
2254 Call("distance", vec2<f32>(1.0f, 1.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair54444382020-04-21 13:04:15 +00002255
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002256 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair54444382020-04-21 13:04:15 +00002257 EXPECT_EQ(td()->error(), "mismatched parameter types for distance");
2258}
2259
2260TEST_F(TypeDeterminerTest, ImportData_Distance_Error_MismatchedParamType) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002261 auto* call = Call("distance", Expr(1.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair54444382020-04-21 13:04:15 +00002262
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002263 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair54444382020-04-21 13:04:15 +00002264 EXPECT_EQ(td()->error(), "mismatched parameter types for distance");
2265}
2266
2267TEST_F(TypeDeterminerTest, ImportData_Distance_Error_TooManyParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002268 auto* call = Call("distance", Expr(1.f), Expr(1.f), Expr(1.f));
dan sinclair54444382020-04-21 13:04:15 +00002269
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002270 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair54444382020-04-21 13:04:15 +00002271 EXPECT_EQ(td()->error(),
2272 "incorrect number of parameters for distance. Expected 2 got 3");
2273}
2274
dan sinclairee392252020-06-08 23:48:15 +00002275TEST_F(TypeDeterminerTest, ImportData_Cross) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002276 auto* ident = Expr("cross");
dan sinclair2287d012020-04-22 00:23:57 +00002277
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002278 auto* call =
2279 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 +00002280
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002281 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002282 ASSERT_NE(ident->result_type(), nullptr);
2283 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002284 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairee392252020-06-08 23:48:15 +00002285}
2286
2287TEST_F(TypeDeterminerTest, ImportData_Cross_Error_Scalar) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002288 auto* call = Call("cross", 1.0f, 1.0f);
dan sinclairee392252020-06-08 23:48:15 +00002289
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002290 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairee392252020-06-08 23:48:15 +00002291 EXPECT_EQ(td()->error(),
2292 "incorrect type for cross. Requires float vector values");
2293}
2294
2295TEST_F(TypeDeterminerTest, ImportData_Cross_Error_IntType) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002296 auto* call = Call("cross", vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3));
dan sinclairee392252020-06-08 23:48:15 +00002297
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002298 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairee392252020-06-08 23:48:15 +00002299 EXPECT_EQ(td()->error(),
2300 "incorrect type for cross. Requires float vector values");
2301}
2302
2303TEST_F(TypeDeterminerTest, ImportData_Cross_Error_MissingParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002304 auto* call = Call("cross");
dan sinclairee392252020-06-08 23:48:15 +00002305
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002306 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairee392252020-06-08 23:48:15 +00002307 EXPECT_EQ(td()->error(),
2308 "incorrect number of parameters for cross. Expected 2 got 0");
2309}
2310
2311TEST_F(TypeDeterminerTest, ImportData_Cross_Error_TooFewParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002312 auto* call = Call("cross", vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairee392252020-06-08 23:48:15 +00002313
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002314 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairee392252020-06-08 23:48:15 +00002315 EXPECT_EQ(td()->error(),
2316 "incorrect number of parameters for cross. Expected 2 got 1");
2317}
2318
2319TEST_F(TypeDeterminerTest, ImportData_Cross_Error_TooManyParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002320 auto* call = Call("cross", vec3<f32>(1.0f, 1.0f, 3.0f),
2321 vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairee392252020-06-08 23:48:15 +00002322
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002323 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairee392252020-06-08 23:48:15 +00002324 EXPECT_EQ(td()->error(),
2325 "incorrect number of parameters for cross. Expected 2 got 3");
2326}
2327
dan sinclairb4fee2f2020-09-22 19:42:13 +00002328using ImportData_ThreeParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair2287d012020-04-22 00:23:57 +00002329TEST_P(ImportData_ThreeParamTest, Scalar) {
2330 auto param = GetParam();
2331
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002332 auto* ident = Expr(param.name);
2333 auto* call = Call(ident, 1.f, 1.f, 1.f);
dan sinclair2287d012020-04-22 00:23:57 +00002334
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002335 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002336 ASSERT_NE(ident->result_type(), nullptr);
2337 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair2287d012020-04-22 00:23:57 +00002338}
2339
2340TEST_P(ImportData_ThreeParamTest, Vector) {
2341 auto param = GetParam();
2342
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002343 auto* ident = Expr(param.name);
2344 auto* call = Call(ident, vec3<f32>(1.0f, 1.0f, 3.0f),
2345 vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair2287d012020-04-22 00:23:57 +00002346
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002347 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002348 ASSERT_NE(ident->result_type(), nullptr);
2349 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002350 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair2287d012020-04-22 00:23:57 +00002351}
2352
2353TEST_P(ImportData_ThreeParamTest, Error_Integer) {
2354 auto param = GetParam();
2355
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002356 auto* call = Call(param.name, 1, 2, 3);
dan sinclair2287d012020-04-22 00:23:57 +00002357
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002358 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair2287d012020-04-22 00:23:57 +00002359 EXPECT_EQ(td()->error(),
2360 std::string("incorrect type for ") + param.name +
dan sinclair53352042020-06-08 18:49:31 +00002361 ". Requires float scalar or float vector values");
dan sinclair2287d012020-04-22 00:23:57 +00002362}
2363
2364TEST_P(ImportData_ThreeParamTest, Error_NoParams) {
2365 auto param = GetParam();
2366
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002367 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002368
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002369 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair2287d012020-04-22 00:23:57 +00002370 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2371 param.name + ". Expected 3 got 0");
2372}
2373
2374TEST_P(ImportData_ThreeParamTest, Error_OneParam) {
2375 auto param = GetParam();
2376
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002377 auto* call = Call(param.name, 1.f);
dan sinclair2287d012020-04-22 00:23:57 +00002378
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002379 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair2287d012020-04-22 00:23:57 +00002380 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2381 param.name + ". Expected 3 got 1");
2382}
2383
2384TEST_P(ImportData_ThreeParamTest, Error_TwoParams) {
2385 auto param = GetParam();
2386
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002387 auto* call = Call(param.name, 1.f, 1.f);
dan sinclair2287d012020-04-22 00:23:57 +00002388
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002389 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair2287d012020-04-22 00:23:57 +00002390 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2391 param.name + ". Expected 3 got 2");
2392}
2393
2394TEST_P(ImportData_ThreeParamTest, Error_MismatchedParamCount) {
2395 auto param = GetParam();
2396
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002397 auto* call = Call(param.name, vec2<f32>(1.0f, 1.0f),
2398 vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair2287d012020-04-22 00:23:57 +00002399
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002400 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair2287d012020-04-22 00:23:57 +00002401 EXPECT_EQ(td()->error(),
2402 std::string("mismatched parameter types for ") + param.name);
2403}
2404
2405TEST_P(ImportData_ThreeParamTest, Error_MismatchedParamType) {
2406 auto param = GetParam();
2407
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002408 auto* call = Call(param.name, 1.0f, 1.0f, vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair2287d012020-04-22 00:23:57 +00002409
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002410 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair2287d012020-04-22 00:23:57 +00002411 EXPECT_EQ(td()->error(),
2412 std::string("mismatched parameter types for ") + param.name);
2413}
2414
2415TEST_P(ImportData_ThreeParamTest, Error_TooManyParams) {
2416 auto param = GetParam();
2417
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002418 auto* call = Call(param.name, 1.f, 1.f, 1.f, 1.f);
dan sinclair2287d012020-04-22 00:23:57 +00002419
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002420 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair2287d012020-04-22 00:23:57 +00002421 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2422 param.name + ". Expected 3 got 4");
2423}
2424
2425INSTANTIATE_TEST_SUITE_P(
2426 TypeDeterminerTest,
2427 ImportData_ThreeParamTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00002428 testing::Values(IntrinsicData{"mix", ast::Intrinsic::kMix},
2429 IntrinsicData{"smoothStep", ast::Intrinsic::kSmoothStep},
2430 IntrinsicData{"fma", ast::Intrinsic::kFma},
2431 IntrinsicData{"faceForward",
2432 ast::Intrinsic::kFaceForward}));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002433
dan sinclairb4fee2f2020-09-22 19:42:13 +00002434using ImportData_ThreeParam_FloatOrInt_Test =
2435 TypeDeterminerTestWithParam<IntrinsicData>;
2436TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Float_Scalar) {
2437 auto param = GetParam();
2438
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002439 auto* ident = Expr(param.name);
2440 auto* call = Call(ident, 1.f, 1.f, 1.f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002441
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002442 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002443 ASSERT_NE(ident->result_type(), nullptr);
2444 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002445}
2446
2447TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Float_Vector) {
2448 auto param = GetParam();
2449
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002450 auto* ident = Expr(param.name);
2451 auto* call = Call(ident, vec3<f32>(1.0f, 1.0f, 3.0f),
2452 vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002453
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002454 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002455 ASSERT_NE(ident->result_type(), nullptr);
2456 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002457 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002458}
2459
2460TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Sint_Scalar) {
2461 auto param = GetParam();
2462
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002463 auto* ident = Expr(param.name);
2464 auto* call = Call(ident, 1, 1, 1);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002465
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002466 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002467 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002468 EXPECT_TRUE(ident->result_type()->Is<ast::type::I32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002469}
2470
2471TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Sint_Vector) {
2472 auto param = GetParam();
2473
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002474 auto* ident = Expr(param.name);
2475 auto* call =
2476 Call(ident, vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002477
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002478 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002479 ASSERT_NE(ident->result_type(), nullptr);
2480 EXPECT_TRUE(ident->result_type()->is_signed_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002481 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002482}
2483
2484TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Uint_Scalar) {
2485 auto param = GetParam();
2486
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002487 auto* ident = Expr(param.name);
2488 auto* call = Call(ident, 1u, 1u, 1u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002489
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002490 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002491 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002492 EXPECT_TRUE(ident->result_type()->Is<ast::type::U32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002493}
2494
2495TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Uint_Vector) {
2496 auto param = GetParam();
2497
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002498 auto* ident = Expr(param.name);
2499 auto* call = Call(ident, vec3<u32>(1u, 1u, 3u), vec3<u32>(1u, 1u, 3u),
2500 vec3<u32>(1u, 1u, 3u));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002501
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002502 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002503 ASSERT_NE(ident->result_type(), nullptr);
2504 EXPECT_TRUE(ident->result_type()->is_unsigned_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002505 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002506}
2507
2508TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_Bool) {
2509 auto param = GetParam();
2510
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002511 auto* call = Call(param.name, true, false, true);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002512
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002513 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002514 EXPECT_EQ(td()->error(),
2515 std::string("incorrect type for ") + param.name +
2516 ". Requires float or int, scalar or vector values");
2517}
2518
2519TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_NoParams) {
2520 auto param = GetParam();
2521
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002522 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002523
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002524 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002525 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2526 param.name + ". Expected 3 got 0");
2527}
2528
2529TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_OneParam) {
2530 auto param = GetParam();
2531
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002532 auto* call = Call(param.name, 1.f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002533
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002534 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002535 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2536 param.name + ". Expected 3 got 1");
2537}
2538
2539TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_TwoParams) {
2540 auto param = GetParam();
2541
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002542 auto* call = Call(param.name, 1.f, 1.f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002543
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002544 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002545 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2546 param.name + ". Expected 3 got 2");
2547}
2548
2549TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_MismatchedParamCount) {
2550 auto param = GetParam();
2551
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002552 auto* call = Call(param.name, vec2<f32>(1.0f, 1.0f),
2553 vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002554
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002555 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002556 EXPECT_EQ(td()->error(),
2557 std::string("mismatched parameter types for ") + param.name);
2558}
2559
2560TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_MismatchedParamType) {
2561 auto param = GetParam();
2562
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002563 auto* call = Call(param.name, 1.0f, 1.0f, vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002564
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002565 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002566 EXPECT_EQ(td()->error(),
2567 std::string("mismatched parameter types for ") + param.name);
2568}
2569
2570TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_TooManyParams) {
2571 auto param = GetParam();
2572
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002573 auto* call = Call(param.name, 1.f, 1.f, 1.f, 1.f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002574
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002575 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002576 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2577 param.name + ". Expected 3 got 4");
2578}
2579
2580INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
2581 ImportData_ThreeParam_FloatOrInt_Test,
2582 testing::Values(IntrinsicData{
2583 "clamp", ast::Intrinsic::kClamp}));
2584
2585using ImportData_Int_SingleParamTest =
2586 TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002587TEST_P(ImportData_Int_SingleParamTest, Scalar) {
2588 auto param = GetParam();
2589
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002590 auto* ident = Expr(param.name);
2591 auto* call = Call(ident, 1);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002592
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002593 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002594 ASSERT_NE(ident->result_type(), nullptr);
2595 EXPECT_TRUE(ident->result_type()->is_integer_scalar());
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002596}
2597
2598TEST_P(ImportData_Int_SingleParamTest, Vector) {
2599 auto param = GetParam();
2600
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002601 auto* ident = Expr(param.name);
2602 auto* call = Call(ident, vec3<i32>(1, 1, 3));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002603
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002604 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002605 ASSERT_NE(ident->result_type(), nullptr);
2606 EXPECT_TRUE(ident->result_type()->is_signed_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002607 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002608}
2609
2610TEST_P(ImportData_Int_SingleParamTest, Error_Float) {
2611 auto param = GetParam();
2612
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002613 auto* call = Call(param.name, 1.f);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002614
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002615 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002616 EXPECT_EQ(td()->error(),
2617 std::string("incorrect type for ") + param.name +
2618 ". Requires integer scalar or integer vector values");
2619}
2620
2621TEST_P(ImportData_Int_SingleParamTest, Error_NoParams) {
2622 auto param = GetParam();
2623
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002624 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002625
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002626 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002627 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2628 param.name + ". Expected 1 got 0");
2629}
2630
2631TEST_P(ImportData_Int_SingleParamTest, Error_MultipleParams) {
2632 auto param = GetParam();
2633
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002634 auto* call = Call(param.name, 1, 1, 1);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002635
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002636 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002637 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2638 param.name + ". Expected 1 got 3");
2639}
2640
dan sinclairaf5df702020-06-08 23:48:26 +00002641INSTANTIATE_TEST_SUITE_P(
2642 TypeDeterminerTest,
2643 ImportData_Int_SingleParamTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00002644 testing::Values(
2645 IntrinsicData{"countOneBits", ast::Intrinsic::kCountOneBits},
2646 IntrinsicData{"reverseBits", ast::Intrinsic::kReverseBits}));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002647
dan sinclairb4fee2f2020-09-22 19:42:13 +00002648using ImportData_FloatOrInt_TwoParamTest =
2649 TypeDeterminerTestWithParam<IntrinsicData>;
2650TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Signed) {
dan sinclair92bb5572020-06-08 23:48:07 +00002651 auto param = GetParam();
2652
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002653 auto* ident = Expr(param.name);
2654 auto* call = Call(ident, 1, 1);
dan sinclair92bb5572020-06-08 23:48:07 +00002655
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002656 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002657 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002658 EXPECT_TRUE(ident->result_type()->Is<ast::type::I32>());
dan sinclair92bb5572020-06-08 23:48:07 +00002659}
2660
dan sinclairb4fee2f2020-09-22 19:42:13 +00002661TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Unsigned) {
dan sinclair92bb5572020-06-08 23:48:07 +00002662 auto param = GetParam();
2663
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002664 auto* ident = Expr(param.name);
2665 auto* call = Call(ident, 1u, 1u);
dan sinclair92bb5572020-06-08 23:48:07 +00002666
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002667 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002668 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002669 EXPECT_TRUE(ident->result_type()->Is<ast::type::U32>());
dan sinclair92bb5572020-06-08 23:48:07 +00002670}
2671
dan sinclairb4fee2f2020-09-22 19:42:13 +00002672TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Float) {
2673 auto param = GetParam();
2674
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002675 auto* ident = Expr(param.name);
2676 auto* call = Call(ident, 1.0f, 1.0f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002677
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002678 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002679 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002680 EXPECT_TRUE(ident->result_type()->Is<ast::type::F32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002681}
2682
2683TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Signed) {
dan sinclair92bb5572020-06-08 23:48:07 +00002684 auto param = GetParam();
2685
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002686 auto* ident = Expr(param.name);
2687 auto* call = Call(ident, vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3));
dan sinclair92bb5572020-06-08 23:48:07 +00002688
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002689 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002690 ASSERT_NE(ident->result_type(), nullptr);
2691 EXPECT_TRUE(ident->result_type()->is_signed_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002692 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair92bb5572020-06-08 23:48:07 +00002693}
2694
dan sinclairb4fee2f2020-09-22 19:42:13 +00002695TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Unsigned) {
dan sinclair92bb5572020-06-08 23:48:07 +00002696 auto param = GetParam();
2697
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002698 auto* ident = Expr(param.name);
2699 auto* call = Call(ident, vec3<u32>(1u, 1u, 3u), vec3<u32>(1u, 1u, 3u));
dan sinclair92bb5572020-06-08 23:48:07 +00002700
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002701 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002702 ASSERT_NE(ident->result_type(), nullptr);
2703 EXPECT_TRUE(ident->result_type()->is_unsigned_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002704 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair92bb5572020-06-08 23:48:07 +00002705}
2706
dan sinclairb4fee2f2020-09-22 19:42:13 +00002707TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Float) {
dan sinclair92bb5572020-06-08 23:48:07 +00002708 auto param = GetParam();
2709
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002710 auto* ident = Expr(param.name);
2711 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 +00002712
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002713 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002714 ASSERT_NE(ident->result_type(), nullptr);
2715 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002716 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002717}
2718
2719TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_Bool) {
2720 auto param = GetParam();
2721
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002722 auto* call = Call(param.name, true, false);
dan sinclair92bb5572020-06-08 23:48:07 +00002723
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002724 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair92bb5572020-06-08 23:48:07 +00002725 EXPECT_EQ(td()->error(),
2726 std::string("incorrect type for ") + param.name +
dan sinclairb4fee2f2020-09-22 19:42:13 +00002727 ". Requires float or int, scalar or vector values");
dan sinclair92bb5572020-06-08 23:48:07 +00002728}
2729
dan sinclairb4fee2f2020-09-22 19:42:13 +00002730TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_NoParams) {
dan sinclair92bb5572020-06-08 23:48:07 +00002731 auto param = GetParam();
2732
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002733 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002734
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002735 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair92bb5572020-06-08 23:48:07 +00002736 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2737 param.name + ". Expected 2 got 0");
2738}
2739
dan sinclairb4fee2f2020-09-22 19:42:13 +00002740TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_OneParam) {
dan sinclair92bb5572020-06-08 23:48:07 +00002741 auto param = GetParam();
2742
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002743 auto* call = Call(param.name, 1);
dan sinclair92bb5572020-06-08 23:48:07 +00002744
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002745 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair92bb5572020-06-08 23:48:07 +00002746 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2747 param.name + ". Expected 2 got 1");
2748}
2749
dan sinclairb4fee2f2020-09-22 19:42:13 +00002750TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_MismatchedParamCount) {
dan sinclair92bb5572020-06-08 23:48:07 +00002751 auto param = GetParam();
2752
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002753 auto* call = Call(param.name, vec2<i32>(1, 1), vec3<i32>(1, 1, 3));
dan sinclair92bb5572020-06-08 23:48:07 +00002754
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002755 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair92bb5572020-06-08 23:48:07 +00002756 EXPECT_EQ(td()->error(),
2757 std::string("mismatched parameter types for ") + param.name);
2758}
2759
dan sinclairb4fee2f2020-09-22 19:42:13 +00002760TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_MismatchedParamType) {
dan sinclair92bb5572020-06-08 23:48:07 +00002761 auto param = GetParam();
2762
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002763 auto* call = Call(param.name, Expr(1), vec3<i32>(1, 1, 3));
dan sinclair92bb5572020-06-08 23:48:07 +00002764
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002765 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair92bb5572020-06-08 23:48:07 +00002766 EXPECT_EQ(td()->error(),
2767 std::string("mismatched parameter types for ") + param.name);
2768}
2769
dan sinclairb4fee2f2020-09-22 19:42:13 +00002770TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_TooManyParams) {
dan sinclair92bb5572020-06-08 23:48:07 +00002771 auto param = GetParam();
2772
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002773 auto* call = Call(param.name, 1, 1, 1);
dan sinclair92bb5572020-06-08 23:48:07 +00002774
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002775 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair92bb5572020-06-08 23:48:07 +00002776 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2777 param.name + ". Expected 2 got 3");
2778}
2779
dan sinclairb4fee2f2020-09-22 19:42:13 +00002780INSTANTIATE_TEST_SUITE_P(
2781 TypeDeterminerTest,
2782 ImportData_FloatOrInt_TwoParamTest,
2783 testing::Values(IntrinsicData{"min", ast::Intrinsic::kMin},
2784 IntrinsicData{"max", ast::Intrinsic::kMax}));
dan sinclair92bb5572020-06-08 23:48:07 +00002785
dan sinclair3238eaa2020-06-17 20:22:08 +00002786TEST_F(TypeDeterminerTest, ImportData_GLSL_Determinant) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002787 auto* var = Var("var", ast::StorageClass::kFunction, ty.mat3x3<f32>());
Ben Clayton3ea3c992020-11-18 21:19:22 +00002788 mod->AddGlobalVariable(var);
dan sinclair3819c262020-06-17 18:39:17 +00002789
dan sinclair3819c262020-06-17 18:39:17 +00002790 ASSERT_TRUE(td()->Determine()) << td()->error();
2791
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002792 auto* ident = Expr("determinant");
dan sinclair3819c262020-06-17 18:39:17 +00002793
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002794 auto* call = Call(ident, "var");
Ben Clayton4bfe4612020-11-16 16:41:47 +00002795
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002796 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002797 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002798 EXPECT_TRUE(ident->result_type()->Is<ast::type::F32>());
dan sinclair3819c262020-06-17 18:39:17 +00002799}
2800
dan sinclairb4fee2f2020-09-22 19:42:13 +00002801using ImportData_Matrix_OneParam_Test =
2802 TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair3238eaa2020-06-17 20:22:08 +00002803TEST_P(ImportData_Matrix_OneParam_Test, Error_Float) {
2804 auto param = GetParam();
2805
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002806 auto* var = Var("var", ast::StorageClass::kFunction, ty.f32);
Ben Clayton3ea3c992020-11-18 21:19:22 +00002807 mod->AddGlobalVariable(var);
dan sinclair3819c262020-06-17 18:39:17 +00002808
dan sinclair3819c262020-06-17 18:39:17 +00002809 ASSERT_TRUE(td()->Determine()) << td()->error();
2810
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002811 auto* call = Call(param.name, "var");
dan sinclair3819c262020-06-17 18:39:17 +00002812
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002813 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair3238eaa2020-06-17 20:22:08 +00002814 EXPECT_EQ(td()->error(), std::string("incorrect type for ") + param.name +
2815 ". Requires matrix value");
dan sinclair3819c262020-06-17 18:39:17 +00002816}
2817
dan sinclair3238eaa2020-06-17 20:22:08 +00002818TEST_P(ImportData_Matrix_OneParam_Test, NoParams) {
2819 auto param = GetParam();
2820
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002821 auto* call = Call(param.name);
dan sinclair3819c262020-06-17 18:39:17 +00002822
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002823 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair3238eaa2020-06-17 20:22:08 +00002824 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2825 param.name + ". Expected 1 got 0");
dan sinclair3819c262020-06-17 18:39:17 +00002826}
2827
dan sinclair3238eaa2020-06-17 20:22:08 +00002828TEST_P(ImportData_Matrix_OneParam_Test, TooManyParams) {
2829 auto param = GetParam();
2830
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002831 ast::type::Matrix mat(ty.f32, 3, 3);
dan sinclair3819c262020-06-17 18:39:17 +00002832
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002833 auto* var = Var("var", ast::StorageClass::kFunction, &mat);
Ben Clayton3ea3c992020-11-18 21:19:22 +00002834 mod->AddGlobalVariable(var);
dan sinclair3819c262020-06-17 18:39:17 +00002835
dan sinclair3819c262020-06-17 18:39:17 +00002836 ASSERT_TRUE(td()->Determine()) << td()->error();
2837
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002838 auto* call = Call(param.name, "var", "var");
dan sinclair3819c262020-06-17 18:39:17 +00002839
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002840 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair3238eaa2020-06-17 20:22:08 +00002841 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2842 param.name + ". Expected 1 got 2");
dan sinclair3819c262020-06-17 18:39:17 +00002843}
dan sinclaire9598d62020-06-18 18:03:00 +00002844INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00002845 ImportData_Matrix_OneParam_Test,
2846 testing::Values(IntrinsicData{
2847 "determinant", ast::Intrinsic::kDeterminant}));
dan sinclaire9598d62020-06-18 18:03:00 +00002848
dan sinclair05926432020-09-21 17:51:31 +00002849TEST_F(TypeDeterminerTest, Function_EntryPoints_StageDecoration) {
dan sinclair05926432020-09-21 17:51:31 +00002850 // fn b() {}
2851 // fn c() { b(); }
2852 // fn a() { c(); }
2853 // fn ep_1() { a(); b(); }
2854 // fn ep_2() { c();}
2855 //
2856 // c -> {ep_1, ep_2}
2857 // a -> {ep_1}
2858 // b -> {ep_1, ep_2}
2859 // ep_1 -> {}
2860 // ep_2 -> {}
2861
2862 ast::VariableList params;
dan sinclair181d8ba2020-12-16 15:15:40 +00002863 auto* func_b = Func("b", params, ty.f32, ast::StatementList{},
2864 ast::FunctionDecorationList{});
dan sinclaira41132f2020-12-11 18:24:53 +00002865 auto* func_c =
dan sinclair181d8ba2020-12-16 15:15:40 +00002866 Func("c", params, ty.f32,
2867 ast::StatementList{
2868 create<ast::AssignmentStatement>(Expr("second"), Call("b")),
2869 },
2870 ast::FunctionDecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00002871
dan sinclaira41132f2020-12-11 18:24:53 +00002872 auto* func_a =
dan sinclair181d8ba2020-12-16 15:15:40 +00002873 Func("a", params, ty.f32,
2874 ast::StatementList{
2875 create<ast::AssignmentStatement>(Expr("first"), Call("c")),
2876 },
2877 ast::FunctionDecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00002878
dan sinclair181d8ba2020-12-16 15:15:40 +00002879 auto* ep_1 =
2880 Func("ep_1", params, ty.f32,
2881 ast::StatementList{
2882 create<ast::AssignmentStatement>(Expr("call_a"), Call("a")),
2883 create<ast::AssignmentStatement>(Expr("call_b"), Call("b")),
2884 },
2885 ast::FunctionDecorationList{
2886 create<ast::StageDecoration>(ast::PipelineStage::kVertex),
2887 });
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002888
dan sinclair181d8ba2020-12-16 15:15:40 +00002889 auto* ep_2 =
2890 Func("ep_2", params, ty.f32,
2891 ast::StatementList{
2892 create<ast::AssignmentStatement>(Expr("call_c"), Call("c")),
2893 },
2894 ast::FunctionDecorationList{
2895 create<ast::StageDecoration>(ast::PipelineStage::kVertex),
2896 });
dan sinclair05926432020-09-21 17:51:31 +00002897
Ben Clayton3ea3c992020-11-18 21:19:22 +00002898 mod->AddFunction(func_b);
2899 mod->AddFunction(func_c);
2900 mod->AddFunction(func_a);
2901 mod->AddFunction(ep_1);
2902 mod->AddFunction(ep_2);
dan sinclair05926432020-09-21 17:51:31 +00002903
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002904 mod->AddGlobalVariable(Var("first", ast::StorageClass::kPrivate, ty.f32));
2905 mod->AddGlobalVariable(Var("second", ast::StorageClass::kPrivate, ty.f32));
2906 mod->AddGlobalVariable(Var("call_a", ast::StorageClass::kPrivate, ty.f32));
2907 mod->AddGlobalVariable(Var("call_b", ast::StorageClass::kPrivate, ty.f32));
2908 mod->AddGlobalVariable(Var("call_c", ast::StorageClass::kPrivate, ty.f32));
dan sinclairff267ca2020-10-14 18:26:31 +00002909
dan sinclair05926432020-09-21 17:51:31 +00002910 // Register the functions and calculate the callers
2911 ASSERT_TRUE(td()->Determine()) << td()->error();
2912
Ben Clayton4bfe4612020-11-16 16:41:47 +00002913 const auto& b_eps = func_b->ancestor_entry_points();
dan sinclair05926432020-09-21 17:51:31 +00002914 ASSERT_EQ(2u, b_eps.size());
dan sinclaira41132f2020-12-11 18:24:53 +00002915 EXPECT_EQ(mod->RegisterSymbol("ep_1"), b_eps[0]);
2916 EXPECT_EQ(mod->RegisterSymbol("ep_2"), b_eps[1]);
dan sinclair05926432020-09-21 17:51:31 +00002917
Ben Clayton4bfe4612020-11-16 16:41:47 +00002918 const auto& a_eps = func_a->ancestor_entry_points();
dan sinclair05926432020-09-21 17:51:31 +00002919 ASSERT_EQ(1u, a_eps.size());
dan sinclaira41132f2020-12-11 18:24:53 +00002920 EXPECT_EQ(mod->RegisterSymbol("ep_1"), a_eps[0]);
dan sinclair05926432020-09-21 17:51:31 +00002921
Ben Clayton4bfe4612020-11-16 16:41:47 +00002922 const auto& c_eps = func_c->ancestor_entry_points();
dan sinclair05926432020-09-21 17:51:31 +00002923 ASSERT_EQ(2u, c_eps.size());
dan sinclaira41132f2020-12-11 18:24:53 +00002924 EXPECT_EQ(mod->RegisterSymbol("ep_1"), c_eps[0]);
2925 EXPECT_EQ(mod->RegisterSymbol("ep_2"), c_eps[1]);
dan sinclair05926432020-09-21 17:51:31 +00002926
Ben Clayton4bfe4612020-11-16 16:41:47 +00002927 EXPECT_TRUE(ep_1->ancestor_entry_points().empty());
2928 EXPECT_TRUE(ep_2->ancestor_entry_points().empty());
dan sinclair05926432020-09-21 17:51:31 +00002929}
2930
Ben Clayton3ea3c992020-11-18 21:19:22 +00002931using TypeDeterminerTextureIntrinsicTest =
2932 TypeDeterminerTestWithParam<ast::intrinsic::test::TextureOverloadCase>;
2933
2934INSTANTIATE_TEST_SUITE_P(
2935 TypeDeterminerTest,
2936 TypeDeterminerTextureIntrinsicTest,
2937 testing::ValuesIn(ast::intrinsic::test::TextureOverloadCase::ValidCases()));
2938
2939std::string to_str(const std::string& function,
2940 const ast::intrinsic::TextureSignature* sig) {
2941 struct Parameter {
2942 size_t idx;
2943 std::string name;
2944 };
2945 std::vector<Parameter> params;
2946 auto maybe_add_param = [&params](size_t idx, const char* name) {
2947 if (idx != ast::intrinsic::TextureSignature::Parameters::kNotUsed) {
2948 params.emplace_back(Parameter{idx, name});
2949 }
2950 };
2951 maybe_add_param(sig->params.idx.array_index, "array_index");
2952 maybe_add_param(sig->params.idx.bias, "bias");
2953 maybe_add_param(sig->params.idx.coords, "coords");
2954 maybe_add_param(sig->params.idx.depth_ref, "depth_ref");
2955 maybe_add_param(sig->params.idx.ddx, "ddx");
2956 maybe_add_param(sig->params.idx.ddy, "ddy");
2957 maybe_add_param(sig->params.idx.level, "level");
2958 maybe_add_param(sig->params.idx.offset, "offset");
2959 maybe_add_param(sig->params.idx.sampler, "sampler");
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002960 maybe_add_param(sig->params.idx.sample_index, "sample_index");
Ben Clayton3ea3c992020-11-18 21:19:22 +00002961 maybe_add_param(sig->params.idx.texture, "texture");
Ben Clayton591268d2020-12-10 18:39:41 +00002962 maybe_add_param(sig->params.idx.value, "value");
Ben Clayton3ea3c992020-11-18 21:19:22 +00002963 std::sort(
2964 params.begin(), params.end(),
2965 [](const Parameter& a, const Parameter& b) { return a.idx < b.idx; });
2966
2967 std::stringstream out;
2968 out << function << "(";
2969 bool first = true;
2970 for (auto& param : params) {
2971 if (!first) {
2972 out << ", ";
2973 }
2974 out << param.name;
2975 first = false;
2976 }
2977 out << ")";
2978 return out.str();
2979}
2980
2981const char* expected_texture_overload(
2982 ast::intrinsic::test::ValidTextureOverload overload) {
2983 using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
2984 switch (overload) {
2985 case ValidTextureOverload::kSample1dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002986 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002987 case ValidTextureOverload::kSample1dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002988 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002989 case ValidTextureOverload::kSample2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002990 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002991 case ValidTextureOverload::kSample2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002992 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002993 case ValidTextureOverload::kSample2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002994 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002995 case ValidTextureOverload::kSample2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002996 return R"(textureSample(texture, sampler, coords, array_index, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002997 case ValidTextureOverload::kSample3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002998 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002999 case ValidTextureOverload::kSample3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003000 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003001 case ValidTextureOverload::kSampleCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003002 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003003 case ValidTextureOverload::kSampleCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003004 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003005 case ValidTextureOverload::kSampleDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003006 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003007 case ValidTextureOverload::kSampleDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003008 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003009 case ValidTextureOverload::kSampleDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003010 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003011 case ValidTextureOverload::kSampleDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003012 return R"(textureSample(texture, sampler, coords, array_index, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003013 case ValidTextureOverload::kSampleDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003014 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003015 case ValidTextureOverload::kSampleDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003016 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003017 case ValidTextureOverload::kSampleBias2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003018 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003019 case ValidTextureOverload::kSampleBias2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003020 return R"(textureSampleBias(texture, sampler, coords, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003021 case ValidTextureOverload::kSampleBias2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003022 return R"(textureSampleBias(texture, sampler, coords, array_index, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003023 case ValidTextureOverload::kSampleBias2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003024 return R"(textureSampleBias(texture, sampler, coords, array_index, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003025 case ValidTextureOverload::kSampleBias3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003026 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003027 case ValidTextureOverload::kSampleBias3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003028 return R"(textureSampleBias(texture, sampler, coords, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003029 case ValidTextureOverload::kSampleBiasCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003030 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003031 case ValidTextureOverload::kSampleBiasCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003032 return R"(textureSampleBias(texture, sampler, coords, array_index, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003033 case ValidTextureOverload::kSampleLevel2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003034 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003035 case ValidTextureOverload::kSampleLevel2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003036 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003037 case ValidTextureOverload::kSampleLevel2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003038 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003039 case ValidTextureOverload::kSampleLevel2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003040 return R"(textureSampleLevel(texture, sampler, coords, array_index, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003041 case ValidTextureOverload::kSampleLevel3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003042 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003043 case ValidTextureOverload::kSampleLevel3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003044 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003045 case ValidTextureOverload::kSampleLevelCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003046 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003047 case ValidTextureOverload::kSampleLevelCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003048 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003049 case ValidTextureOverload::kSampleLevelDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003050 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003051 case ValidTextureOverload::kSampleLevelDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003052 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003053 case ValidTextureOverload::kSampleLevelDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003054 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003055 case ValidTextureOverload::kSampleLevelDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003056 return R"(textureSampleLevel(texture, sampler, coords, array_index, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003057 case ValidTextureOverload::kSampleLevelDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003058 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003059 case ValidTextureOverload::kSampleLevelDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003060 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003061 case ValidTextureOverload::kSampleGrad2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003062 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003063 case ValidTextureOverload::kSampleGrad2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003064 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003065 case ValidTextureOverload::kSampleGrad2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003066 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003067 case ValidTextureOverload::kSampleGrad2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003068 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003069 case ValidTextureOverload::kSampleGrad3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003070 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003071 case ValidTextureOverload::kSampleGrad3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003072 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003073 case ValidTextureOverload::kSampleGradCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003074 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003075 case ValidTextureOverload::kSampleGradCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003076 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003077 case ValidTextureOverload::kSampleGradDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003078 return R"(textureSampleCompare(texture, sampler, coords, depth_ref))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003079 case ValidTextureOverload::kSampleGradDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003080 return R"(textureSampleCompare(texture, sampler, coords, depth_ref, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003081 case ValidTextureOverload::kSampleGradDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003082 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003083 case ValidTextureOverload::kSampleGradDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003084 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003085 case ValidTextureOverload::kSampleGradDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003086 return R"(textureSampleCompare(texture, sampler, coords, depth_ref))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003087 case ValidTextureOverload::kSampleGradDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003088 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref))";
3089 case ValidTextureOverload::kLoad1dF32:
3090 return R"(textureLoad(texture, coords))";
3091 case ValidTextureOverload::kLoad1dU32:
3092 return R"(textureLoad(texture, coords))";
3093 case ValidTextureOverload::kLoad1dI32:
3094 return R"(textureLoad(texture, coords))";
3095 case ValidTextureOverload::kLoad1dArrayF32:
3096 return R"(textureLoad(texture, coords, array_index))";
3097 case ValidTextureOverload::kLoad1dArrayU32:
3098 return R"(textureLoad(texture, coords, array_index))";
3099 case ValidTextureOverload::kLoad1dArrayI32:
3100 return R"(textureLoad(texture, coords, array_index))";
3101 case ValidTextureOverload::kLoad2dF32:
3102 return R"(textureLoad(texture, coords))";
3103 case ValidTextureOverload::kLoad2dU32:
3104 return R"(textureLoad(texture, coords))";
3105 case ValidTextureOverload::kLoad2dI32:
3106 return R"(textureLoad(texture, coords))";
3107 case ValidTextureOverload::kLoad2dLevelF32:
3108 return R"(textureLoad(texture, coords, level))";
3109 case ValidTextureOverload::kLoad2dLevelU32:
3110 return R"(textureLoad(texture, coords, level))";
3111 case ValidTextureOverload::kLoad2dLevelI32:
3112 return R"(textureLoad(texture, coords, level))";
3113 case ValidTextureOverload::kLoad2dArrayF32:
3114 return R"(textureLoad(texture, coords, array_index))";
3115 case ValidTextureOverload::kLoad2dArrayU32:
3116 return R"(textureLoad(texture, coords, array_index))";
3117 case ValidTextureOverload::kLoad2dArrayI32:
3118 return R"(textureLoad(texture, coords, array_index))";
3119 case ValidTextureOverload::kLoad2dArrayLevelF32:
3120 return R"(textureLoad(texture, coords, array_index, level))";
3121 case ValidTextureOverload::kLoad2dArrayLevelU32:
3122 return R"(textureLoad(texture, coords, array_index, level))";
3123 case ValidTextureOverload::kLoad2dArrayLevelI32:
3124 return R"(textureLoad(texture, coords, array_index, level))";
3125 case ValidTextureOverload::kLoad3dF32:
3126 return R"(textureLoad(texture, coords))";
3127 case ValidTextureOverload::kLoad3dU32:
3128 return R"(textureLoad(texture, coords))";
3129 case ValidTextureOverload::kLoad3dI32:
3130 return R"(textureLoad(texture, coords))";
3131 case ValidTextureOverload::kLoad3dLevelF32:
3132 return R"(textureLoad(texture, coords, level))";
3133 case ValidTextureOverload::kLoad3dLevelU32:
3134 return R"(textureLoad(texture, coords, level))";
3135 case ValidTextureOverload::kLoad3dLevelI32:
3136 return R"(textureLoad(texture, coords, level))";
3137 case ValidTextureOverload::kLoadMultisampled2dF32:
3138 return R"(textureLoad(texture, coords, sample_index))";
3139 case ValidTextureOverload::kLoadMultisampled2dU32:
3140 return R"(textureLoad(texture, coords, sample_index))";
3141 case ValidTextureOverload::kLoadMultisampled2dI32:
3142 return R"(textureLoad(texture, coords, sample_index))";
3143 case ValidTextureOverload::kLoadMultisampled2dArrayF32:
3144 return R"(textureLoad(texture, coords, array_index, sample_index))";
3145 case ValidTextureOverload::kLoadMultisampled2dArrayU32:
3146 return R"(textureLoad(texture, coords, array_index, sample_index))";
3147 case ValidTextureOverload::kLoadMultisampled2dArrayI32:
3148 return R"(textureLoad(texture, coords, array_index, sample_index))";
3149 case ValidTextureOverload::kLoadDepth2dF32:
3150 return R"(textureLoad(texture, coords))";
3151 case ValidTextureOverload::kLoadDepth2dLevelF32:
3152 return R"(textureLoad(texture, coords, level))";
3153 case ValidTextureOverload::kLoadDepth2dArrayF32:
3154 return R"(textureLoad(texture, coords, array_index))";
3155 case ValidTextureOverload::kLoadDepth2dArrayLevelF32:
3156 return R"(textureLoad(texture, coords, array_index, level))";
3157 case ValidTextureOverload::kLoadStorageRO1dRgba32float:
3158 return R"(textureLoad(texture, coords))";
3159 case ValidTextureOverload::kLoadStorageRO1dArrayRgba32float:
3160 return R"(textureLoad(texture, coords, array_index))";
3161 case ValidTextureOverload::kLoadStorageRO2dRgba8unorm:
3162 case ValidTextureOverload::kLoadStorageRO2dRgba8snorm:
3163 case ValidTextureOverload::kLoadStorageRO2dRgba8uint:
3164 case ValidTextureOverload::kLoadStorageRO2dRgba8sint:
3165 case ValidTextureOverload::kLoadStorageRO2dRgba16uint:
3166 case ValidTextureOverload::kLoadStorageRO2dRgba16sint:
3167 case ValidTextureOverload::kLoadStorageRO2dRgba16float:
3168 case ValidTextureOverload::kLoadStorageRO2dR32uint:
3169 case ValidTextureOverload::kLoadStorageRO2dR32sint:
3170 case ValidTextureOverload::kLoadStorageRO2dR32float:
3171 case ValidTextureOverload::kLoadStorageRO2dRg32uint:
3172 case ValidTextureOverload::kLoadStorageRO2dRg32sint:
3173 case ValidTextureOverload::kLoadStorageRO2dRg32float:
3174 case ValidTextureOverload::kLoadStorageRO2dRgba32uint:
3175 case ValidTextureOverload::kLoadStorageRO2dRgba32sint:
3176 case ValidTextureOverload::kLoadStorageRO2dRgba32float:
3177 return R"(textureLoad(texture, coords))";
3178 case ValidTextureOverload::kLoadStorageRO2dArrayRgba32float:
3179 return R"(textureLoad(texture, coords, array_index))";
3180 case ValidTextureOverload::kLoadStorageRO3dRgba32float:
3181 return R"(textureLoad(texture, coords))";
Ben Clayton591268d2020-12-10 18:39:41 +00003182 case ValidTextureOverload::kStoreWO1dRgba32float:
3183 return R"(textureStore(texture, coords, value))";
3184 case ValidTextureOverload::kStoreWO1dArrayRgba32float:
3185 return R"(textureStore(texture, coords, array_index, value))";
3186 case ValidTextureOverload::kStoreWO2dRgba32float:
3187 return R"(textureStore(texture, coords, value))";
3188 case ValidTextureOverload::kStoreWO2dArrayRgba32float:
3189 return R"(textureStore(texture, coords, array_index, value))";
3190 case ValidTextureOverload::kStoreWO3dRgba32float:
3191 return R"(textureStore(texture, coords, value))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00003192 }
3193 return "<unmatched texture overload>";
3194}
3195
3196TEST_P(TypeDeterminerTextureIntrinsicTest, Call) {
3197 auto param = GetParam();
3198
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003199 param.buildTextureVariable(this);
3200 param.buildSamplerVariable(this);
Ben Clayton3ea3c992020-11-18 21:19:22 +00003201
3202 auto* ident = Expr(param.function);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00003203 auto* call = Call(ident, param.args(this));
Ben Clayton3ea3c992020-11-18 21:19:22 +00003204
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003205 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton7eaf4b52020-12-14 22:08:27 +00003206 ASSERT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton3ea3c992020-11-18 21:19:22 +00003207
Ben Clayton591268d2020-12-10 18:39:41 +00003208 if (std::string(param.function) == "textureStore") {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00003209 EXPECT_EQ(call->result_type(), ty.void_);
Ben Clayton591268d2020-12-10 18:39:41 +00003210 } else {
3211 switch (param.texture_kind) {
3212 case ast::intrinsic::test::TextureKind::kRegular:
3213 case ast::intrinsic::test::TextureKind::kMultisampled:
3214 case ast::intrinsic::test::TextureKind::kStorage: {
3215 auto* datatype = param.resultVectorComponentType(this);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00003216 ASSERT_TRUE(call->result_type()->Is<ast::type::Vector>());
3217 EXPECT_EQ(call->result_type()->As<ast::type::Vector>()->type(),
Ben Clayton591268d2020-12-10 18:39:41 +00003218 datatype);
3219 break;
3220 }
3221 case ast::intrinsic::test::TextureKind::kDepth: {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00003222 EXPECT_EQ(call->result_type(), ty.f32);
Ben Clayton591268d2020-12-10 18:39:41 +00003223 break;
3224 }
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003225 }
Ben Clayton3ea3c992020-11-18 21:19:22 +00003226 }
3227
3228 auto* sig = static_cast<const ast::intrinsic::TextureSignature*>(
3229 ident->intrinsic_signature());
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003230 ASSERT_NE(sig, nullptr);
Ben Clayton3ea3c992020-11-18 21:19:22 +00003231
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003232 auto got = to_str(param.function, sig);
Ben Clayton3ea3c992020-11-18 21:19:22 +00003233 auto* expected = expected_texture_overload(param.overload);
Ben Clayton7f04e5c2020-12-09 15:57:00 +00003234 EXPECT_EQ(got, expected);
Ben Clayton3ea3c992020-11-18 21:19:22 +00003235}
3236
dan sinclairb7edc4c2020-04-07 12:46:30 +00003237} // namespace
3238} // namespace tint