blob: 3fe802aacd92a4c55109f3235b69cdb78a1567e8 [file] [log] [blame]
dan sinclairb7edc4c2020-04-07 12:46:30 +00001// Copyright 2020 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "src/type_determiner.h"
16
Ben Clayton3ea3c992020-11-18 21:19:22 +000017#include <algorithm>
dan sinclairb7edc4c2020-04-07 12:46:30 +000018#include <memory>
19#include <utility>
dan sinclairfd5d4ca2020-04-20 15:46:18 +000020#include <vector>
dan sinclairb7edc4c2020-04-07 12:46:30 +000021
22#include "gtest/gtest.h"
dan sinclair973bd6a2020-04-07 12:57:42 +000023#include "src/ast/array_accessor_expression.h"
dan sinclair6c498fc2020-04-07 12:47:23 +000024#include "src/ast/assignment_statement.h"
dan sinclair1c9b4862020-04-07 19:27:41 +000025#include "src/ast/binary_expression.h"
dan sinclaira7d498e2020-09-22 22:07:13 +000026#include "src/ast/bitcast_expression.h"
dan sinclair0975dd52020-07-27 15:25:00 +000027#include "src/ast/block_statement.h"
dan sinclairb4fee2f2020-09-22 19:42:13 +000028#include "src/ast/bool_literal.h"
dan sinclairb7ea6e22020-04-07 12:54:10 +000029#include "src/ast/break_statement.h"
dan sinclair3ca87462020-04-07 16:41:10 +000030#include "src/ast/call_expression.h"
dan sinclair50080b72020-07-21 13:42:13 +000031#include "src/ast/call_statement.h"
dan sinclair6010b292020-04-07 12:54:20 +000032#include "src/ast/case_statement.h"
dan sinclairaec965e2020-04-07 12:54:29 +000033#include "src/ast/continue_statement.h"
dan sinclair0cf685f2020-04-07 12:54:37 +000034#include "src/ast/else_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000035#include "src/ast/float_literal.h"
dan sinclaircab0e732020-04-07 12:57:27 +000036#include "src/ast/identifier_expression.h"
dan sinclair91c44a52020-04-07 12:55:25 +000037#include "src/ast/if_statement.h"
Ben Clayton3ea3c992020-11-18 21:19:22 +000038#include "src/ast/intrinsic_texture_helper_test.h"
dan sinclairbc71eda2020-04-07 12:55:51 +000039#include "src/ast/loop_statement.h"
dan sinclair8ee1d222020-04-07 16:41:33 +000040#include "src/ast/member_accessor_expression.h"
dan sinclair05926432020-09-21 17:51:31 +000041#include "src/ast/pipeline_stage.h"
dan sinclairbf0fff82020-04-07 12:56:24 +000042#include "src/ast/return_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000043#include "src/ast/scalar_constructor_expression.h"
dan sinclairc6f29472020-06-02 20:11:44 +000044#include "src/ast/sint_literal.h"
dan sinclair05926432020-09-21 17:51:31 +000045#include "src/ast/stage_decoration.h"
dan sinclair8ee1d222020-04-07 16:41:33 +000046#include "src/ast/struct.h"
47#include "src/ast/struct_member.h"
dan sinclair18b32852020-04-07 12:56:45 +000048#include "src/ast/switch_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000049#include "src/ast/type_constructor_expression.h"
dan sinclair92bb5572020-06-08 23:48:07 +000050#include "src/ast/uint_literal.h"
dan sinclair327ed1b2020-04-07 19:27:21 +000051#include "src/ast/unary_op_expression.h"
dan sinclairca893e32020-04-07 12:57:12 +000052#include "src/ast/variable_decl_statement.h"
Ben Claytona6b9a8e2021-01-26 16:57:10 +000053#include "src/program_builder.h"
Ben Clayton33352542021-01-29 16:43:41 +000054#include "src/semantic/expression.h"
Ben Clayton207b5e22021-01-21 15:42:10 +000055#include "src/type/alias_type.h"
56#include "src/type/array_type.h"
57#include "src/type/bool_type.h"
58#include "src/type/depth_texture_type.h"
59#include "src/type/f32_type.h"
60#include "src/type/i32_type.h"
61#include "src/type/matrix_type.h"
62#include "src/type/multisampled_texture_type.h"
63#include "src/type/pointer_type.h"
64#include "src/type/sampled_texture_type.h"
65#include "src/type/sampler_type.h"
66#include "src/type/storage_texture_type.h"
67#include "src/type/struct_type.h"
68#include "src/type/texture_type.h"
69#include "src/type/u32_type.h"
70#include "src/type/vector_type.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000071
72namespace tint {
73namespace {
74
dan sinclair7456f422020-04-08 19:58:35 +000075class FakeStmt : public ast::Statement {
76 public:
Ben Clayton604bc722020-12-12 01:24:53 +000077 explicit FakeStmt(Source source) : ast::Statement(source) {}
Ben Clayton1e29f4b2021-01-21 16:20:40 +000078 FakeStmt* Clone(CloneContext*) const override { return nullptr; }
dan sinclair7456f422020-04-08 19:58:35 +000079 bool IsValid() const override { return true; }
Ben Claytondd1b6fc2021-01-29 10:55:40 +000080 void to_str(const semantic::Info&, std::ostream& out, size_t) const override {
81 out << "Fake";
82 }
dan sinclair7456f422020-04-08 19:58:35 +000083};
84
85class FakeExpr : public ast::Expression {
86 public:
Ben Clayton604bc722020-12-12 01:24:53 +000087 explicit FakeExpr(Source source) : ast::Expression(source) {}
Ben Clayton1e29f4b2021-01-21 16:20:40 +000088 FakeExpr* Clone(CloneContext*) const override { return nullptr; }
dan sinclair7456f422020-04-08 19:58:35 +000089 bool IsValid() const override { return true; }
Ben Claytondd1b6fc2021-01-29 10:55:40 +000090 void to_str(const semantic::Info&, std::ostream&, size_t) const override {}
dan sinclair7456f422020-04-08 19:58:35 +000091};
92
Ben Claytona6b9a8e2021-01-26 16:57:10 +000093class TypeDeterminerHelper : public ProgramBuilder {
dan sinclairb7edc4c2020-04-07 12:46:30 +000094 public:
Ben Claytona6b9a8e2021-01-26 16:57:10 +000095 TypeDeterminerHelper() : td_(std::make_unique<TypeDeterminer>(this)) {}
dan sinclairb7edc4c2020-04-07 12:46:30 +000096
97 TypeDeterminer* td() const { return td_.get(); }
Ben Clayton62625922020-11-13 22:09:38 +000098
dan sinclairb7edc4c2020-04-07 12:46:30 +000099 private:
Ben Clayton3ea3c992020-11-18 21:19:22 +0000100 void OnVariableBuilt(ast::Variable* var) override {
101 td_->RegisterVariableForTesting(var);
102 }
103
dan sinclairb7edc4c2020-04-07 12:46:30 +0000104 std::unique_ptr<TypeDeterminer> td_;
105};
106
dan sinclaircd077b02020-04-20 14:19:04 +0000107class TypeDeterminerTest : public TypeDeterminerHelper, public testing::Test {};
108
109template <typename T>
110class TypeDeterminerTestWithParam : public TypeDeterminerHelper,
111 public testing::TestWithParam<T> {};
112
dan sinclair7456f422020-04-08 19:58:35 +0000113TEST_F(TypeDeterminerTest, Error_WithEmptySource) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000114 auto* s = create<FakeStmt>();
dan sinclair7456f422020-04-08 19:58:35 +0000115
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000116 EXPECT_FALSE(td()->DetermineResultType(s));
dan sinclair0975dd52020-07-27 15:25:00 +0000117 EXPECT_EQ(td()->error(),
118 "unknown statement type for type determination: Fake");
dan sinclair7456f422020-04-08 19:58:35 +0000119}
120
121TEST_F(TypeDeterminerTest, Stmt_Error_Unknown) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000122 auto* s = create<FakeStmt>(Source{Source::Location{2, 30}});
dan sinclair7456f422020-04-08 19:58:35 +0000123
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000124 EXPECT_FALSE(td()->DetermineResultType(s));
dan sinclair7456f422020-04-08 19:58:35 +0000125 EXPECT_EQ(td()->error(),
dan sinclair0975dd52020-07-27 15:25:00 +0000126 "2:30: unknown statement type for type determination: Fake");
dan sinclair7456f422020-04-08 19:58:35 +0000127}
128
dan sinclair6c498fc2020-04-07 12:47:23 +0000129TEST_F(TypeDeterminerTest, Stmt_Assign) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000130 auto* lhs = Expr(2);
131 auto* rhs = Expr(2.3f);
dan sinclair6c498fc2020-04-07 12:47:23 +0000132
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000133 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
dan sinclair6c498fc2020-04-07 12:47:23 +0000134
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000135 EXPECT_TRUE(td()->DetermineResultType(assign));
Ben Clayton33352542021-01-29 16:43:41 +0000136 ASSERT_NE(TypeOf(lhs), nullptr);
137 ASSERT_NE(TypeOf(rhs), nullptr);
dan sinclair6c498fc2020-04-07 12:47:23 +0000138
Ben Clayton33352542021-01-29 16:43:41 +0000139 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
140 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
dan sinclair6c498fc2020-04-07 12:47:23 +0000141}
142
dan sinclair6010b292020-04-07 12:54:20 +0000143TEST_F(TypeDeterminerTest, Stmt_Case) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000144 auto* lhs = Expr(2);
145 auto* rhs = Expr(2.3f);
dan sinclair6010b292020-04-07 12:54:20 +0000146
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000147 auto* body = create<ast::BlockStatement>(ast::StatementList{
148 create<ast::AssignmentStatement>(lhs, rhs),
149 });
dan sinclair1aadbd42020-06-01 16:56:46 +0000150 ast::CaseSelectorList lit;
Ben Clayton8d391f72021-01-26 16:57:10 +0000151 lit.push_back(create<ast::SintLiteral>(ty.i32(), 3));
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000152 auto* cse = create<ast::CaseStatement>(lit, body);
dan sinclair6010b292020-04-07 12:54:20 +0000153
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000154 EXPECT_TRUE(td()->DetermineResultType(cse));
Ben Clayton33352542021-01-29 16:43:41 +0000155 ASSERT_NE(TypeOf(lhs), nullptr);
156 ASSERT_NE(TypeOf(rhs), nullptr);
157 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
158 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
dan sinclair6010b292020-04-07 12:54:20 +0000159}
160
dan sinclair0975dd52020-07-27 15:25:00 +0000161TEST_F(TypeDeterminerTest, Stmt_Block) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000162 auto* lhs = Expr(2);
163 auto* rhs = Expr(2.3f);
dan sinclair0975dd52020-07-27 15:25:00 +0000164
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000165 auto* block = create<ast::BlockStatement>(ast::StatementList{
166 create<ast::AssignmentStatement>(lhs, rhs),
167 });
dan sinclair0975dd52020-07-27 15:25:00 +0000168
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000169 EXPECT_TRUE(td()->DetermineResultType(block));
Ben Clayton33352542021-01-29 16:43:41 +0000170 ASSERT_NE(TypeOf(lhs), nullptr);
171 ASSERT_NE(TypeOf(rhs), nullptr);
172 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
173 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
dan sinclair0975dd52020-07-27 15:25:00 +0000174}
175
dan sinclair0cf685f2020-04-07 12:54:37 +0000176TEST_F(TypeDeterminerTest, Stmt_Else) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000177 auto* lhs = Expr(2);
178 auto* rhs = Expr(2.3f);
dan sinclair0cf685f2020-04-07 12:54:37 +0000179
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000180 auto* body = create<ast::BlockStatement>(ast::StatementList{
181 create<ast::AssignmentStatement>(lhs, rhs),
182 });
183 auto* stmt = create<ast::ElseStatement>(Expr(3), body);
dan sinclair0cf685f2020-04-07 12:54:37 +0000184
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000185 EXPECT_TRUE(td()->DetermineResultType(stmt));
Ben Clayton33352542021-01-29 16:43:41 +0000186 ASSERT_NE(TypeOf(stmt->condition()), nullptr);
187 ASSERT_NE(TypeOf(lhs), nullptr);
188 ASSERT_NE(TypeOf(rhs), nullptr);
189 EXPECT_TRUE(TypeOf(stmt->condition())->Is<type::I32>());
190 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
191 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
dan sinclair0cf685f2020-04-07 12:54:37 +0000192}
193
dan sinclair91c44a52020-04-07 12:55:25 +0000194TEST_F(TypeDeterminerTest, Stmt_If) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000195 auto* else_lhs = Expr(2);
196 auto* else_rhs = Expr(2.3f);
dan sinclair91c44a52020-04-07 12:55:25 +0000197
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000198 auto* else_body = create<ast::BlockStatement>(ast::StatementList{
199 create<ast::AssignmentStatement>(else_lhs, else_rhs),
200 });
dan sinclair91c44a52020-04-07 12:55:25 +0000201
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000202 auto* else_stmt = create<ast::ElseStatement>(Expr(3), else_body);
dan sinclair91c44a52020-04-07 12:55:25 +0000203
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000204 auto* lhs = Expr(2);
205 auto* rhs = Expr(2.3f);
dan sinclair91c44a52020-04-07 12:55:25 +0000206
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000207 auto* body = create<ast::BlockStatement>(ast::StatementList{
208 create<ast::AssignmentStatement>(lhs, rhs),
209 });
210 auto* stmt = create<ast::IfStatement>(Expr(3), body,
211 ast::ElseStatementList{else_stmt});
dan sinclair91c44a52020-04-07 12:55:25 +0000212
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000213 EXPECT_TRUE(td()->DetermineResultType(stmt));
Ben Clayton33352542021-01-29 16:43:41 +0000214 ASSERT_NE(TypeOf(stmt->condition()), nullptr);
215 ASSERT_NE(TypeOf(else_lhs), nullptr);
216 ASSERT_NE(TypeOf(else_rhs), nullptr);
217 ASSERT_NE(TypeOf(lhs), nullptr);
218 ASSERT_NE(TypeOf(rhs), nullptr);
219 EXPECT_TRUE(TypeOf(stmt->condition())->Is<type::I32>());
220 EXPECT_TRUE(TypeOf(else_lhs)->Is<type::I32>());
221 EXPECT_TRUE(TypeOf(else_rhs)->Is<type::F32>());
222 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
223 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
dan sinclair91c44a52020-04-07 12:55:25 +0000224}
225
dan sinclairbc71eda2020-04-07 12:55:51 +0000226TEST_F(TypeDeterminerTest, Stmt_Loop) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000227 auto* body_lhs = Expr(2);
228 auto* body_rhs = Expr(2.3f);
dan sinclairbc71eda2020-04-07 12:55:51 +0000229
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000230 auto* body = create<ast::BlockStatement>(ast::StatementList{
231 create<ast::AssignmentStatement>(body_lhs, body_rhs),
232 });
233 auto* continuing_lhs = Expr(2);
234 auto* continuing_rhs = Expr(2.3f);
dan sinclairbc71eda2020-04-07 12:55:51 +0000235
Ben Claytondb5ce652020-12-14 20:25:27 +0000236 auto* continuing = create<ast::BlockStatement>(
dan sinclairbc71eda2020-04-07 12:55:51 +0000237
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000238 ast::StatementList{
239 create<ast::AssignmentStatement>(continuing_lhs, continuing_rhs),
240 });
241 auto* stmt = create<ast::LoopStatement>(body, continuing);
242
243 EXPECT_TRUE(td()->DetermineResultType(stmt));
Ben Clayton33352542021-01-29 16:43:41 +0000244 ASSERT_NE(TypeOf(body_lhs), nullptr);
245 ASSERT_NE(TypeOf(body_rhs), nullptr);
246 ASSERT_NE(TypeOf(continuing_lhs), nullptr);
247 ASSERT_NE(TypeOf(continuing_rhs), nullptr);
248 EXPECT_TRUE(TypeOf(body_lhs)->Is<type::I32>());
249 EXPECT_TRUE(TypeOf(body_rhs)->Is<type::F32>());
250 EXPECT_TRUE(TypeOf(continuing_lhs)->Is<type::I32>());
251 EXPECT_TRUE(TypeOf(continuing_rhs)->Is<type::F32>());
dan sinclairbc71eda2020-04-07 12:55:51 +0000252}
253
dan sinclairbf0fff82020-04-07 12:56:24 +0000254TEST_F(TypeDeterminerTest, Stmt_Return) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000255 auto* cond = Expr(2);
dan sinclairbf0fff82020-04-07 12:56:24 +0000256
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000257 auto* ret = create<ast::ReturnStatement>(cond);
dan sinclairbf0fff82020-04-07 12:56:24 +0000258
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000259 EXPECT_TRUE(td()->DetermineResultType(ret));
Ben Clayton33352542021-01-29 16:43:41 +0000260 ASSERT_NE(TypeOf(cond), nullptr);
261 EXPECT_TRUE(TypeOf(cond)->Is<type::I32>());
dan sinclairbf0fff82020-04-07 12:56:24 +0000262}
263
dan sinclair327ed1b2020-04-07 19:27:21 +0000264TEST_F(TypeDeterminerTest, Stmt_Return_WithoutValue) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000265 auto* ret = create<ast::ReturnStatement>();
266 EXPECT_TRUE(td()->DetermineResultType(ret));
dan sinclair327ed1b2020-04-07 19:27:21 +0000267}
268
dan sinclair18b32852020-04-07 12:56:45 +0000269TEST_F(TypeDeterminerTest, Stmt_Switch) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000270 auto* lhs = Expr(2);
271 auto* rhs = Expr(2.3f);
dan sinclair18b32852020-04-07 12:56:45 +0000272
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000273 auto* body = create<ast::BlockStatement>(ast::StatementList{
274 create<ast::AssignmentStatement>(lhs, rhs),
275 });
dan sinclair1aadbd42020-06-01 16:56:46 +0000276 ast::CaseSelectorList lit;
Ben Clayton8d391f72021-01-26 16:57:10 +0000277 lit.push_back(create<ast::SintLiteral>(ty.i32(), 3));
dan sinclair1aadbd42020-06-01 16:56:46 +0000278
dan sinclair18b32852020-04-07 12:56:45 +0000279 ast::CaseStatementList cases;
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000280 cases.push_back(create<ast::CaseStatement>(lit, body));
dan sinclair18b32852020-04-07 12:56:45 +0000281
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000282 auto* stmt = create<ast::SwitchStatement>(Expr(2), cases);
dan sinclair18b32852020-04-07 12:56:45 +0000283
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000284 EXPECT_TRUE(td()->DetermineResultType(stmt)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +0000285 ASSERT_NE(TypeOf(stmt->condition()), nullptr);
286 ASSERT_NE(TypeOf(lhs), nullptr);
287 ASSERT_NE(TypeOf(rhs), nullptr);
dan sinclair18b32852020-04-07 12:56:45 +0000288
Ben Clayton33352542021-01-29 16:43:41 +0000289 EXPECT_TRUE(TypeOf(stmt->condition())->Is<type::I32>());
290 EXPECT_TRUE(TypeOf(lhs)->Is<type::I32>());
291 EXPECT_TRUE(TypeOf(rhs)->Is<type::F32>());
dan sinclair18b32852020-04-07 12:56:45 +0000292}
293
dan sinclair50080b72020-07-21 13:42:13 +0000294TEST_F(TypeDeterminerTest, Stmt_Call) {
dan sinclair50080b72020-07-21 13:42:13 +0000295 ast::VariableList params;
Ben Clayton8d391f72021-01-26 16:57:10 +0000296 auto* func = Func("my_func", params, ty.f32(), ast::StatementList{},
dan sinclair181d8ba2020-12-16 15:15:40 +0000297 ast::FunctionDecorationList{});
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000298 AST().Functions().Add(func);
dan sinclair50080b72020-07-21 13:42:13 +0000299
300 // Register the function
301 EXPECT_TRUE(td()->Determine());
302
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000303 auto* expr = Call("my_func");
dan sinclair50080b72020-07-21 13:42:13 +0000304
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000305 auto* call = create<ast::CallStatement>(expr);
306 EXPECT_TRUE(td()->DetermineResultType(call));
Ben Clayton33352542021-01-29 16:43:41 +0000307 ASSERT_NE(TypeOf(expr), nullptr);
308 EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
dan sinclair50080b72020-07-21 13:42:13 +0000309}
310
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000311TEST_F(TypeDeterminerTest, Stmt_Call_undeclared) {
312 // fn main() -> void {func(); return; }
313 // fn func() -> void { return; }
Ben Claytondb5ce652020-12-14 20:25:27 +0000314
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000315 SetSource(Source::Location{12, 34});
316 auto* call_expr = Call("func");
317 ast::VariableList params0;
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000318
Ben Clayton8d391f72021-01-26 16:57:10 +0000319 auto* func_main = Func("main", params0, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000320 ast::StatementList{
321 create<ast::CallStatement>(call_expr),
322 create<ast::ReturnStatement>(),
323 },
324 ast::FunctionDecorationList{});
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000325 AST().Functions().Add(func_main);
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000326
Ben Clayton8d391f72021-01-26 16:57:10 +0000327 auto* func = Func("func", params0, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000328 ast::StatementList{
329 create<ast::ReturnStatement>(),
330 },
331 ast::FunctionDecorationList{});
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000332 AST().Functions().Add(func);
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000333
334 EXPECT_FALSE(td()->Determine()) << td()->error();
335 EXPECT_EQ(td()->error(),
dan sinclairff267ca2020-10-14 18:26:31 +0000336 "12:34: v-0006: identifier must be declared before use: func");
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000337}
338
dan sinclairca893e32020-04-07 12:57:12 +0000339TEST_F(TypeDeterminerTest, Stmt_VariableDecl) {
Ben Clayton8d391f72021-01-26 16:57:10 +0000340 auto* var = Var("my_var", ast::StorageClass::kNone, ty.i32(), Expr(2),
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000341 ast::VariableDecorationList{});
Ben Clayton4bfe4612020-11-16 16:41:47 +0000342 auto* init = var->constructor();
dan sinclairca893e32020-04-07 12:57:12 +0000343
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000344 auto* decl = create<ast::VariableDeclStatement>(var);
dan sinclairca893e32020-04-07 12:57:12 +0000345
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000346 EXPECT_TRUE(td()->DetermineResultType(decl));
Ben Clayton33352542021-01-29 16:43:41 +0000347 ASSERT_NE(TypeOf(init), nullptr);
348 EXPECT_TRUE(TypeOf(init)->Is<type::I32>());
dan sinclairca893e32020-04-07 12:57:12 +0000349}
350
dan sinclair7be237a2020-06-15 20:55:09 +0000351TEST_F(TypeDeterminerTest, Stmt_VariableDecl_ModuleScope) {
Ben Clayton8d391f72021-01-26 16:57:10 +0000352 auto* var = Var("my_var", ast::StorageClass::kNone, ty.i32(), Expr(2),
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000353 ast::VariableDecorationList{});
Ben Clayton4bfe4612020-11-16 16:41:47 +0000354 auto* init = var->constructor();
dan sinclair7be237a2020-06-15 20:55:09 +0000355
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000356 AST().AddGlobalVariable(var);
dan sinclair7be237a2020-06-15 20:55:09 +0000357
358 EXPECT_TRUE(td()->Determine());
Ben Clayton33352542021-01-29 16:43:41 +0000359 ASSERT_NE(TypeOf(init), nullptr);
360 EXPECT_TRUE(TypeOf(init)->Is<type::I32>());
dan sinclair7be237a2020-06-15 20:55:09 +0000361}
362
dan sinclair7456f422020-04-08 19:58:35 +0000363TEST_F(TypeDeterminerTest, Expr_Error_Unknown) {
Ben Clayton604bc722020-12-12 01:24:53 +0000364 FakeExpr e(Source{Source::Location{2, 30}});
dan sinclair7456f422020-04-08 19:58:35 +0000365
366 EXPECT_FALSE(td()->DetermineResultType(&e));
367 EXPECT_EQ(td()->error(), "2:30: unknown expression for type determination");
368}
369
dan sinclair973bd6a2020-04-07 12:57:42 +0000370TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000371 auto* idx = Expr(2);
Ben Clayton1637cbb2021-01-05 15:44:39 +0000372 auto* var = Var("my_var", ast::StorageClass::kFunction, ty.array<f32, 3>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000373 AST().AddGlobalVariable(var);
dan sinclair8eddb782020-04-23 22:26:52 +0000374
dan sinclair8eddb782020-04-23 22:26:52 +0000375 EXPECT_TRUE(td()->Determine());
376
dan sinclair8b40a672020-12-16 11:49:10 +0000377 auto* acc = IndexAccessor("my_var", idx);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000378 EXPECT_TRUE(td()->DetermineResultType(acc));
Ben Clayton33352542021-01-29 16:43:41 +0000379 ASSERT_NE(TypeOf(acc), nullptr);
380 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000381
Ben Clayton33352542021-01-29 16:43:41 +0000382 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000383 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000384}
385
David Neto9c88ea52020-06-22 20:33:12 +0000386TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Alias_Array) {
Ben Clayton1637cbb2021-01-05 15:44:39 +0000387 auto* aary = ty.alias("myarrty", ty.array<f32, 3>());
David Neto9c88ea52020-06-22 20:33:12 +0000388
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000389 AST().AddGlobalVariable(Var("my_var", ast::StorageClass::kFunction, aary));
David Neto9c88ea52020-06-22 20:33:12 +0000390
David Neto9c88ea52020-06-22 20:33:12 +0000391 EXPECT_TRUE(td()->Determine());
392
dan sinclair8b40a672020-12-16 11:49:10 +0000393 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000394 EXPECT_TRUE(td()->DetermineResultType(acc));
Ben Clayton33352542021-01-29 16:43:41 +0000395 ASSERT_NE(TypeOf(acc), nullptr);
396 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
David Neto9c88ea52020-06-22 20:33:12 +0000397
Ben Clayton33352542021-01-29 16:43:41 +0000398 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000399 EXPECT_TRUE(ptr->type()->Is<type::F32>());
David Neto9c88ea52020-06-22 20:33:12 +0000400}
401
dan sinclair8eddb782020-04-23 22:26:52 +0000402TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array_Constant) {
Ben Clayton1637cbb2021-01-05 15:44:39 +0000403 auto* var = Const("my_var", ast::StorageClass::kFunction, ty.array<f32, 3>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000404 AST().AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000405
dan sinclairb950e802020-04-20 14:20:01 +0000406 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000407
dan sinclair8b40a672020-12-16 11:49:10 +0000408 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000409 EXPECT_TRUE(td()->DetermineResultType(acc));
Ben Clayton33352542021-01-29 16:43:41 +0000410 ASSERT_NE(TypeOf(acc), nullptr);
411 EXPECT_TRUE(TypeOf(acc)->Is<type::F32>()) << TypeOf(acc)->type_name();
dan sinclair973bd6a2020-04-07 12:57:42 +0000412}
413
414TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix) {
Ben Clayton1637cbb2021-01-05 15:44:39 +0000415 auto* var = Var("my_var", ast::StorageClass::kNone, ty.mat2x3<f32>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000416 AST().AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000417
dan sinclairb950e802020-04-20 14:20:01 +0000418 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000419
dan sinclair8b40a672020-12-16 11:49:10 +0000420 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000421 EXPECT_TRUE(td()->DetermineResultType(acc));
Ben Clayton33352542021-01-29 16:43:41 +0000422 ASSERT_NE(TypeOf(acc), nullptr);
423 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000424
Ben Clayton33352542021-01-29 16:43:41 +0000425 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000426 ASSERT_TRUE(ptr->type()->Is<type::Vector>());
427 EXPECT_EQ(ptr->type()->As<type::Vector>()->size(), 3u);
dan sinclair973bd6a2020-04-07 12:57:42 +0000428}
429
430TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix_BothDimensions) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000431 auto* var = Var("my_var", ast::StorageClass::kNone, ty.mat2x3<f32>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000432 AST().AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000433
dan sinclairb950e802020-04-20 14:20:01 +0000434 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000435
dan sinclair8b40a672020-12-16 11:49:10 +0000436 auto* acc = IndexAccessor(IndexAccessor("my_var", 2), 1);
dan sinclair973bd6a2020-04-07 12:57:42 +0000437
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000438 EXPECT_TRUE(td()->DetermineResultType(acc));
Ben Clayton33352542021-01-29 16:43:41 +0000439 ASSERT_NE(TypeOf(acc), nullptr);
440 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000441
Ben Clayton33352542021-01-29 16:43:41 +0000442 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000443 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000444}
445
446TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Vector) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000447 auto* var = Var("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000448 AST().AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000449
dan sinclairb950e802020-04-20 14:20:01 +0000450 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000451
dan sinclair8b40a672020-12-16 11:49:10 +0000452 auto* acc = IndexAccessor("my_var", 2);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000453 EXPECT_TRUE(td()->DetermineResultType(acc));
Ben Clayton33352542021-01-29 16:43:41 +0000454 ASSERT_NE(TypeOf(acc), nullptr);
455 ASSERT_TRUE(TypeOf(acc)->Is<type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000456
Ben Clayton33352542021-01-29 16:43:41 +0000457 auto* ptr = TypeOf(acc)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000458 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000459}
460
dan sinclaira7d498e2020-09-22 22:07:13 +0000461TEST_F(TypeDeterminerTest, Expr_Bitcast) {
Ben Clayton8d391f72021-01-26 16:57:10 +0000462 auto* bitcast = create<ast::BitcastExpression>(ty.f32(), Expr("name"));
dan sinclaira01777c2020-04-07 12:57:52 +0000463
Ben Clayton8d391f72021-01-26 16:57:10 +0000464 auto* v = Var("name", ast::StorageClass::kPrivate, ty.f32());
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000465 td()->RegisterVariableForTesting(v);
dan sinclairff267ca2020-10-14 18:26:31 +0000466
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000467 EXPECT_TRUE(td()->DetermineResultType(bitcast));
Ben Clayton33352542021-01-29 16:43:41 +0000468 ASSERT_NE(TypeOf(bitcast), nullptr);
469 EXPECT_TRUE(TypeOf(bitcast)->Is<type::F32>());
dan sinclaira01777c2020-04-07 12:57:52 +0000470}
471
dan sinclair3ca87462020-04-07 16:41:10 +0000472TEST_F(TypeDeterminerTest, Expr_Call) {
dan sinclair3ca87462020-04-07 16:41:10 +0000473 ast::VariableList params;
Ben Clayton8d391f72021-01-26 16:57:10 +0000474 auto* func = Func("my_func", params, ty.f32(), ast::StatementList{},
dan sinclair181d8ba2020-12-16 15:15:40 +0000475 ast::FunctionDecorationList{});
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000476 AST().Functions().Add(func);
dan sinclair3ca87462020-04-07 16:41:10 +0000477
478 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000479 EXPECT_TRUE(td()->Determine());
dan sinclair3ca87462020-04-07 16:41:10 +0000480
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000481 auto* call = Call("my_func");
482 EXPECT_TRUE(td()->DetermineResultType(call));
Ben Clayton33352542021-01-29 16:43:41 +0000483 ASSERT_NE(TypeOf(call), nullptr);
484 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclair3ca87462020-04-07 16:41:10 +0000485}
486
dan sinclairccb52dc2020-04-20 14:18:54 +0000487TEST_F(TypeDeterminerTest, Expr_Call_WithParams) {
dan sinclairccb52dc2020-04-20 14:18:54 +0000488 ast::VariableList params;
Ben Clayton8d391f72021-01-26 16:57:10 +0000489 auto* func = Func("my_func", params, ty.f32(), ast::StatementList{},
dan sinclair181d8ba2020-12-16 15:15:40 +0000490 ast::FunctionDecorationList{});
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000491 AST().Functions().Add(func);
dan sinclairccb52dc2020-04-20 14:18:54 +0000492
493 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000494 EXPECT_TRUE(td()->Determine());
dan sinclairccb52dc2020-04-20 14:18:54 +0000495
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000496 auto* param = Expr(2.4f);
dan sinclairccb52dc2020-04-20 14:18:54 +0000497
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000498 auto* call = Call("my_func", param);
499 EXPECT_TRUE(td()->DetermineResultType(call));
Ben Clayton33352542021-01-29 16:43:41 +0000500 ASSERT_NE(TypeOf(param), nullptr);
501 EXPECT_TRUE(TypeOf(param)->Is<type::F32>());
dan sinclairccb52dc2020-04-20 14:18:54 +0000502}
503
dan sinclairb4fee2f2020-09-22 19:42:13 +0000504TEST_F(TypeDeterminerTest, Expr_Call_Intrinsic) {
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000505 // Register the function
506 EXPECT_TRUE(td()->Determine());
507
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000508 auto* call = Call("round", 2.4f);
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000509
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000510 EXPECT_TRUE(td()->DetermineResultType(call));
Ben Clayton33352542021-01-29 16:43:41 +0000511 ASSERT_NE(TypeOf(call), nullptr);
512 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000513}
514
dan sinclair4e807952020-04-07 16:41:23 +0000515TEST_F(TypeDeterminerTest, Expr_Cast) {
Ben Clayton8d391f72021-01-26 16:57:10 +0000516 auto* cast = Construct(ty.f32(), "name");
dan sinclair3c025922020-09-24 14:38:44 +0000517
Ben Clayton8d391f72021-01-26 16:57:10 +0000518 auto* v = Var("name", ast::StorageClass::kPrivate, ty.f32());
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000519 td()->RegisterVariableForTesting(v);
dan sinclair4e807952020-04-07 16:41:23 +0000520
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000521 EXPECT_TRUE(td()->DetermineResultType(cast));
Ben Clayton33352542021-01-29 16:43:41 +0000522 ASSERT_NE(TypeOf(cast), nullptr);
523 EXPECT_TRUE(TypeOf(cast)->Is<type::F32>());
dan sinclair4e807952020-04-07 16:41:23 +0000524}
525
dan sinclairb7edc4c2020-04-07 12:46:30 +0000526TEST_F(TypeDeterminerTest, Expr_Constructor_Scalar) {
Ben Clayton1637cbb2021-01-05 15:44:39 +0000527 auto* s = Expr(1.0f);
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000528 EXPECT_TRUE(td()->DetermineResultType(s));
Ben Clayton33352542021-01-29 16:43:41 +0000529 ASSERT_NE(TypeOf(s), nullptr);
530 EXPECT_TRUE(TypeOf(s)->Is<type::F32>());
dan sinclairb7edc4c2020-04-07 12:46:30 +0000531}
532
533TEST_F(TypeDeterminerTest, Expr_Constructor_Type) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000534 auto* tc = vec3<f32>(1.0f, 1.0f, 3.0f);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000535
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000536 EXPECT_TRUE(td()->DetermineResultType(tc));
Ben Clayton33352542021-01-29 16:43:41 +0000537 ASSERT_NE(TypeOf(tc), nullptr);
538 ASSERT_TRUE(TypeOf(tc)->Is<type::Vector>());
539 EXPECT_TRUE(TypeOf(tc)->As<type::Vector>()->type()->Is<type::F32>());
540 EXPECT_EQ(TypeOf(tc)->As<type::Vector>()->size(), 3u);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000541}
542
dan sinclaircab0e732020-04-07 12:57:27 +0000543TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalVariable) {
Ben Clayton8d391f72021-01-26 16:57:10 +0000544 auto* var = Var("my_var", ast::StorageClass::kNone, ty.f32());
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000545 AST().AddGlobalVariable(var);
dan sinclaircab0e732020-04-07 12:57:27 +0000546
dan sinclairb950e802020-04-20 14:20:01 +0000547 EXPECT_TRUE(td()->Determine());
dan sinclaircab0e732020-04-07 12:57:27 +0000548
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000549 auto* ident = Expr("my_var");
550 EXPECT_TRUE(td()->DetermineResultType(ident));
Ben Clayton33352542021-01-29 16:43:41 +0000551 ASSERT_NE(TypeOf(ident), nullptr);
552 EXPECT_TRUE(TypeOf(ident)->Is<type::Pointer>());
553 EXPECT_TRUE(TypeOf(ident)->As<type::Pointer>()->type()->Is<type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000554}
555
556TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalConstant) {
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000557 AST().AddGlobalVariable(Const("my_var", ast::StorageClass::kNone, ty.f32()));
dan sinclair8eddb782020-04-23 22:26:52 +0000558
dan sinclair8eddb782020-04-23 22:26:52 +0000559 EXPECT_TRUE(td()->Determine());
560
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000561 auto* ident = Expr("my_var");
562 EXPECT_TRUE(td()->DetermineResultType(ident));
Ben Clayton33352542021-01-29 16:43:41 +0000563 ASSERT_NE(TypeOf(ident), nullptr);
564 EXPECT_TRUE(TypeOf(ident)->Is<type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000565}
566
dan sinclair8eddb782020-04-23 22:26:52 +0000567TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable_Const) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000568 auto* my_var = Expr("my_var");
dan sinclair8eddb782020-04-23 22:26:52 +0000569
Ben Clayton8d391f72021-01-26 16:57:10 +0000570 auto* var = Const("my_var", ast::StorageClass::kNone, ty.f32());
dan sinclair8eddb782020-04-23 22:26:52 +0000571
Ben Clayton8d391f72021-01-26 16:57:10 +0000572 auto* f = Func("my_func", ast::VariableList{}, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000573 ast::StatementList{
574 create<ast::VariableDeclStatement>(var),
575 create<ast::AssignmentStatement>(my_var, Expr("my_var")),
576 },
577 ast::FunctionDecorationList{});
dan sinclair8eddb782020-04-23 22:26:52 +0000578
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000579 EXPECT_TRUE(td()->DetermineFunction(f));
dan sinclair8eddb782020-04-23 22:26:52 +0000580
Ben Clayton33352542021-01-29 16:43:41 +0000581 ASSERT_NE(TypeOf(my_var), nullptr);
582 EXPECT_TRUE(TypeOf(my_var)->Is<type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000583}
584
dan sinclaircab0e732020-04-07 12:57:27 +0000585TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000586 auto* my_var = Expr("my_var");
dan sinclaircab0e732020-04-07 12:57:27 +0000587
Ben Clayton8d391f72021-01-26 16:57:10 +0000588 auto* f = Func("my_func", ast::VariableList{}, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000589 ast::StatementList{
590 create<ast::VariableDeclStatement>(
Ben Clayton8d391f72021-01-26 16:57:10 +0000591 Var("my_var", ast::StorageClass::kNone, ty.f32())),
dan sinclair181d8ba2020-12-16 15:15:40 +0000592 create<ast::AssignmentStatement>(my_var, Expr("my_var")),
593 },
594 ast::FunctionDecorationList{});
dan sinclaircab0e732020-04-07 12:57:27 +0000595
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000596 EXPECT_TRUE(td()->DetermineFunction(f));
dan sinclaircab0e732020-04-07 12:57:27 +0000597
Ben Clayton33352542021-01-29 16:43:41 +0000598 ASSERT_NE(TypeOf(my_var), nullptr);
599 EXPECT_TRUE(TypeOf(my_var)->Is<type::Pointer>());
600 EXPECT_TRUE(TypeOf(my_var)->As<type::Pointer>()->type()->Is<type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000601}
602
dan sinclair5e989302020-09-16 21:20:36 +0000603TEST_F(TypeDeterminerTest, Expr_Identifier_Function_Ptr) {
Ben Clayton8d391f72021-01-26 16:57:10 +0000604 type::Pointer ptr(ty.f32(), ast::StorageClass::kFunction);
dan sinclair5e989302020-09-16 21:20:36 +0000605
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000606 auto* my_var = Expr("my_var");
dan sinclair5e989302020-09-16 21:20:36 +0000607
Ben Clayton8d391f72021-01-26 16:57:10 +0000608 auto* f = Func("my_func", ast::VariableList{}, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000609 ast::StatementList{
610 create<ast::VariableDeclStatement>(
611 Var("my_var", ast::StorageClass::kNone, &ptr)),
612 create<ast::AssignmentStatement>(my_var, Expr("my_var")),
613 },
614 ast::FunctionDecorationList{});
dan sinclair5e989302020-09-16 21:20:36 +0000615
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000616 EXPECT_TRUE(td()->DetermineFunction(f));
dan sinclair5e989302020-09-16 21:20:36 +0000617
Ben Clayton33352542021-01-29 16:43:41 +0000618 ASSERT_NE(TypeOf(my_var), nullptr);
619 EXPECT_TRUE(TypeOf(my_var)->Is<type::Pointer>());
620 EXPECT_TRUE(TypeOf(my_var)->As<type::Pointer>()->type()->Is<type::F32>());
dan sinclair5e989302020-09-16 21:20:36 +0000621}
622
dan sinclaircab0e732020-04-07 12:57:27 +0000623TEST_F(TypeDeterminerTest, Expr_Identifier_Function) {
Ben Clayton8d391f72021-01-26 16:57:10 +0000624 auto* func = Func("my_func", ast::VariableList{}, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000625 ast::StatementList{}, ast::FunctionDecorationList{});
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000626 AST().Functions().Add(func);
dan sinclaircab0e732020-04-07 12:57:27 +0000627
628 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000629 EXPECT_TRUE(td()->Determine());
dan sinclaircab0e732020-04-07 12:57:27 +0000630
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000631 auto* ident = Expr("my_func");
632 EXPECT_TRUE(td()->DetermineResultType(ident));
Ben Clayton33352542021-01-29 16:43:41 +0000633 ASSERT_NE(TypeOf(ident), nullptr);
634 EXPECT_TRUE(TypeOf(ident)->Is<type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000635}
636
dan sinclairff267ca2020-10-14 18:26:31 +0000637TEST_F(TypeDeterminerTest, Expr_Identifier_Unknown) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000638 auto* a = Expr("a");
639 EXPECT_FALSE(td()->DetermineResultType(a));
dan sinclairff267ca2020-10-14 18:26:31 +0000640}
641
dan sinclair13d2a3b2020-06-22 20:52:24 +0000642TEST_F(TypeDeterminerTest, Function_RegisterInputOutputVariables) {
Ben Clayton8d391f72021-01-26 16:57:10 +0000643 auto* in_var = Var("in_var", ast::StorageClass::kInput, ty.f32());
644 auto* out_var = Var("out_var", ast::StorageClass::kOutput, ty.f32());
645 auto* sb_var = Var("sb_var", ast::StorageClass::kStorage, ty.f32());
646 auto* wg_var = Var("wg_var", ast::StorageClass::kWorkgroup, ty.f32());
647 auto* priv_var = Var("priv_var", ast::StorageClass::kPrivate, ty.f32());
dan sinclair13d2a3b2020-06-22 20:52:24 +0000648
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000649 AST().AddGlobalVariable(in_var);
650 AST().AddGlobalVariable(out_var);
651 AST().AddGlobalVariable(sb_var);
652 AST().AddGlobalVariable(wg_var);
653 AST().AddGlobalVariable(priv_var);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000654
dan sinclair181d8ba2020-12-16 15:15:40 +0000655 auto* func = Func(
Ben Clayton8d391f72021-01-26 16:57:10 +0000656 "my_func", ast::VariableList{}, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000657 ast::StatementList{
658 create<ast::AssignmentStatement>(Expr("out_var"), Expr("in_var")),
659 create<ast::AssignmentStatement>(Expr("wg_var"), Expr("wg_var")),
660 create<ast::AssignmentStatement>(Expr("sb_var"), Expr("sb_var")),
661 create<ast::AssignmentStatement>(Expr("priv_var"), Expr("priv_var")),
662 },
663 ast::FunctionDecorationList{});
dan sinclair13d2a3b2020-06-22 20:52:24 +0000664
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000665 AST().Functions().Add(func);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000666
667 // Register the function
668 EXPECT_TRUE(td()->Determine());
669
Ben Clayton4bfe4612020-11-16 16:41:47 +0000670 const auto& vars = func->referenced_module_variables();
Ryan Harrison9a452c12020-06-23 16:38:47 +0000671 ASSERT_EQ(vars.size(), 5u);
Ben Clayton4bfe4612020-11-16 16:41:47 +0000672 EXPECT_EQ(vars[0], out_var);
673 EXPECT_EQ(vars[1], in_var);
674 EXPECT_EQ(vars[2], wg_var);
675 EXPECT_EQ(vars[3], sb_var);
676 EXPECT_EQ(vars[4], priv_var);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000677}
678
dan sinclairde2dd682020-07-14 20:37:28 +0000679TEST_F(TypeDeterminerTest, Function_RegisterInputOutputVariables_SubFunction) {
Ben Clayton8d391f72021-01-26 16:57:10 +0000680 auto* in_var = Var("in_var", ast::StorageClass::kInput, ty.f32());
681 auto* out_var = Var("out_var", ast::StorageClass::kOutput, ty.f32());
682 auto* sb_var = Var("sb_var", ast::StorageClass::kStorage, ty.f32());
683 auto* wg_var = Var("wg_var", ast::StorageClass::kWorkgroup, ty.f32());
684 auto* priv_var = Var("priv_var", ast::StorageClass::kPrivate, ty.f32());
dan sinclairde2dd682020-07-14 20:37:28 +0000685
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000686 AST().AddGlobalVariable(in_var);
687 AST().AddGlobalVariable(out_var);
688 AST().AddGlobalVariable(sb_var);
689 AST().AddGlobalVariable(wg_var);
690 AST().AddGlobalVariable(priv_var);
dan sinclairde2dd682020-07-14 20:37:28 +0000691
dan sinclair181d8ba2020-12-16 15:15:40 +0000692 auto* func = Func(
Ben Clayton8d391f72021-01-26 16:57:10 +0000693 "my_func", ast::VariableList{}, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000694 ast::StatementList{
695 create<ast::AssignmentStatement>(Expr("out_var"), Expr("in_var")),
696 create<ast::AssignmentStatement>(Expr("wg_var"), Expr("wg_var")),
697 create<ast::AssignmentStatement>(Expr("sb_var"), Expr("sb_var")),
698 create<ast::AssignmentStatement>(Expr("priv_var"), Expr("priv_var")),
699 },
700 ast::FunctionDecorationList{});
dan sinclairde2dd682020-07-14 20:37:28 +0000701
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000702 AST().Functions().Add(func);
dan sinclairde2dd682020-07-14 20:37:28 +0000703
dan sinclair181d8ba2020-12-16 15:15:40 +0000704 auto* func2 = Func(
Ben Clayton8d391f72021-01-26 16:57:10 +0000705 "func", ast::VariableList{}, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000706 ast::StatementList{
707 create<ast::AssignmentStatement>(Expr("out_var"), Call("my_func")),
708 },
709 ast::FunctionDecorationList{});
dan sinclairde2dd682020-07-14 20:37:28 +0000710
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000711 AST().Functions().Add(func2);
dan sinclairde2dd682020-07-14 20:37:28 +0000712
713 // Register the function
714 EXPECT_TRUE(td()->Determine());
715
Ben Clayton4bfe4612020-11-16 16:41:47 +0000716 const auto& vars = func2->referenced_module_variables();
dan sinclairde2dd682020-07-14 20:37:28 +0000717 ASSERT_EQ(vars.size(), 5u);
Ben Clayton4bfe4612020-11-16 16:41:47 +0000718 EXPECT_EQ(vars[0], out_var);
719 EXPECT_EQ(vars[1], in_var);
720 EXPECT_EQ(vars[2], wg_var);
721 EXPECT_EQ(vars[3], sb_var);
722 EXPECT_EQ(vars[4], priv_var);
dan sinclairde2dd682020-07-14 20:37:28 +0000723}
724
dan sinclair13d2a3b2020-06-22 20:52:24 +0000725TEST_F(TypeDeterminerTest, Function_NotRegisterFunctionVariable) {
Ben Clayton8d391f72021-01-26 16:57:10 +0000726 auto* var = Var("in_var", ast::StorageClass::kFunction, ty.f32());
dan sinclair13d2a3b2020-06-22 20:52:24 +0000727
dan sinclair181d8ba2020-12-16 15:15:40 +0000728 auto* func =
Ben Clayton8d391f72021-01-26 16:57:10 +0000729 Func("my_func", ast::VariableList{}, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +0000730 ast::StatementList{
731 create<ast::VariableDeclStatement>(var),
Ben Clayton1637cbb2021-01-05 15:44:39 +0000732 create<ast::AssignmentStatement>(Expr("var"), Expr(1.f)),
dan sinclair181d8ba2020-12-16 15:15:40 +0000733 },
734 ast::FunctionDecorationList{});
dan sinclair13d2a3b2020-06-22 20:52:24 +0000735
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000736 AST().Functions().Add(func);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000737
Ben Clayton8d391f72021-01-26 16:57:10 +0000738 auto* v = Var("var", ast::StorageClass::kFunction, ty.f32());
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000739 td()->RegisterVariableForTesting(v);
dan sinclairff267ca2020-10-14 18:26:31 +0000740
dan sinclair13d2a3b2020-06-22 20:52:24 +0000741 // Register the function
dan sinclairff267ca2020-10-14 18:26:31 +0000742 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair13d2a3b2020-06-22 20:52:24 +0000743
Ben Clayton4bfe4612020-11-16 16:41:47 +0000744 EXPECT_EQ(func->referenced_module_variables().size(), 0u);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000745}
746
dan sinclair8ee1d222020-04-07 16:41:33 +0000747TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct) {
dan sinclair5e5e36e2020-12-16 14:41:00 +0000748 auto* strct = create<ast::Struct>(
Ben Clayton8d391f72021-01-26 16:57:10 +0000749 ast::StructMemberList{Member("first_member", ty.i32()),
750 Member("second_member", ty.f32())},
dan sinclair5e5e36e2020-12-16 14:41:00 +0000751 ast::StructDecorationList{});
dan sinclair8ee1d222020-04-07 16:41:33 +0000752
dan sinclairb5839932020-12-16 21:38:40 +0000753 auto* st = ty.struct_("S", strct);
754 auto* var = Var("my_struct", ast::StorageClass::kNone, st);
dan sinclair8ee1d222020-04-07 16:41:33 +0000755
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000756 AST().AddGlobalVariable(var);
dan sinclair8ee1d222020-04-07 16:41:33 +0000757
dan sinclairb950e802020-04-20 14:20:01 +0000758 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +0000759
dan sinclair8b40a672020-12-16 11:49:10 +0000760 auto* mem = MemberAccessor("my_struct", "second_member");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000761 EXPECT_TRUE(td()->DetermineResultType(mem));
Ben Clayton33352542021-01-29 16:43:41 +0000762 ASSERT_NE(TypeOf(mem), nullptr);
763 ASSERT_TRUE(TypeOf(mem)->Is<type::Pointer>());
dan sinclair8ee1d222020-04-07 16:41:33 +0000764
Ben Clayton33352542021-01-29 16:43:41 +0000765 auto* ptr = TypeOf(mem)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000766 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclair8ee1d222020-04-07 16:41:33 +0000767}
768
dan sinclairb445a9b2020-04-24 00:40:45 +0000769TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct_Alias) {
dan sinclair5e5e36e2020-12-16 14:41:00 +0000770 auto* strct = create<ast::Struct>(
Ben Clayton8d391f72021-01-26 16:57:10 +0000771 ast::StructMemberList{Member("first_member", ty.i32()),
772 Member("second_member", ty.f32())},
dan sinclair5e5e36e2020-12-16 14:41:00 +0000773 ast::StructDecorationList{});
dan sinclairb445a9b2020-04-24 00:40:45 +0000774
dan sinclairb5839932020-12-16 21:38:40 +0000775 auto* st = ty.struct_("alias", strct);
776 auto* alias = ty.alias("alias", st);
777 auto* var = Var("my_struct", ast::StorageClass::kNone, alias);
dan sinclairb445a9b2020-04-24 00:40:45 +0000778
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000779 AST().AddGlobalVariable(var);
dan sinclairb445a9b2020-04-24 00:40:45 +0000780
dan sinclairb445a9b2020-04-24 00:40:45 +0000781 EXPECT_TRUE(td()->Determine());
782
dan sinclair8b40a672020-12-16 11:49:10 +0000783 auto* mem = MemberAccessor("my_struct", "second_member");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000784 EXPECT_TRUE(td()->DetermineResultType(mem));
Ben Clayton33352542021-01-29 16:43:41 +0000785 ASSERT_NE(TypeOf(mem), nullptr);
786 ASSERT_TRUE(TypeOf(mem)->Is<type::Pointer>());
dan sinclairb445a9b2020-04-24 00:40:45 +0000787
Ben Clayton33352542021-01-29 16:43:41 +0000788 auto* ptr = TypeOf(mem)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000789 EXPECT_TRUE(ptr->type()->Is<type::F32>());
dan sinclairb445a9b2020-04-24 00:40:45 +0000790}
791
dan sinclair8ee1d222020-04-07 16:41:33 +0000792TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000793 auto* var = Var("my_vec", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000794 AST().AddGlobalVariable(var);
dan sinclair8ee1d222020-04-07 16:41:33 +0000795
dan sinclairb950e802020-04-20 14:20:01 +0000796 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +0000797
dan sinclair8b40a672020-12-16 11:49:10 +0000798 auto* mem = MemberAccessor("my_vec", "xy");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000799 EXPECT_TRUE(td()->DetermineResultType(mem)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +0000800 ASSERT_NE(TypeOf(mem), nullptr);
801 ASSERT_TRUE(TypeOf(mem)->Is<type::Vector>());
802 EXPECT_TRUE(TypeOf(mem)->As<type::Vector>()->type()->Is<type::F32>());
803 EXPECT_EQ(TypeOf(mem)->As<type::Vector>()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +0000804}
805
dan sinclairaac58652020-04-21 13:05:34 +0000806TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle_SingleElement) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000807 auto* var = Var("my_vec", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000808 AST().AddGlobalVariable(var);
dan sinclairaac58652020-04-21 13:05:34 +0000809
dan sinclairaac58652020-04-21 13:05:34 +0000810 EXPECT_TRUE(td()->Determine());
811
dan sinclair8b40a672020-12-16 11:49:10 +0000812 auto* mem = MemberAccessor("my_vec", "x");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000813 EXPECT_TRUE(td()->DetermineResultType(mem)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +0000814 ASSERT_NE(TypeOf(mem), nullptr);
815 ASSERT_TRUE(TypeOf(mem)->Is<type::Pointer>());
dan sinclairaac58652020-04-21 13:05:34 +0000816
Ben Clayton33352542021-01-29 16:43:41 +0000817 auto* ptr = TypeOf(mem)->As<type::Pointer>();
Ben Clayton207b5e22021-01-21 15:42:10 +0000818 ASSERT_TRUE(ptr->type()->Is<type::F32>());
dan sinclairaac58652020-04-21 13:05:34 +0000819}
820
dan sinclair8eddb782020-04-23 22:26:52 +0000821TEST_F(TypeDeterminerTest, Expr_Accessor_MultiLevel) {
dan sinclair8ee1d222020-04-07 16:41:33 +0000822 // struct b {
823 // vec4<f32> foo
824 // }
825 // struct A {
826 // vec3<struct b> mem
827 // }
828 // var c : A
829 // c.mem[0].foo.yx
830 // -> vec2<f32>
831 //
832 // MemberAccessor{
833 // MemberAccessor{
834 // ArrayAccessor{
835 // MemberAccessor{
836 // Identifier{c}
837 // Identifier{mem}
838 // }
839 // ScalarConstructor{0}
840 // }
841 // Identifier{foo}
842 // }
843 // Identifier{yx}
844 // }
845 //
dan sinclair8ee1d222020-04-07 16:41:33 +0000846
dan sinclair5e5e36e2020-12-16 14:41:00 +0000847 auto* strctB =
848 create<ast::Struct>(ast::StructMemberList{Member("foo", ty.vec4<f32>())},
849 ast::StructDecorationList{});
dan sinclairb5839932020-12-16 21:38:40 +0000850 auto* stB = ty.struct_("B", strctB);
dan sinclair8ee1d222020-04-07 16:41:33 +0000851
Ben Clayton207b5e22021-01-21 15:42:10 +0000852 type::Vector vecB(stB, 3);
dan sinclair5e5e36e2020-12-16 14:41:00 +0000853 auto* strctA = create<ast::Struct>(
854 ast::StructMemberList{Member("mem", &vecB)}, ast::StructDecorationList{});
dan sinclair8ee1d222020-04-07 16:41:33 +0000855
dan sinclairb5839932020-12-16 21:38:40 +0000856 auto* stA = ty.struct_("A", strctA);
857 auto* var = Var("c", ast::StorageClass::kNone, stA);
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000858 AST().AddGlobalVariable(var);
dan sinclairb950e802020-04-20 14:20:01 +0000859 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +0000860
dan sinclair8b40a672020-12-16 11:49:10 +0000861 auto* mem = MemberAccessor(
862 MemberAccessor(IndexAccessor(MemberAccessor("c", "mem"), 0), "foo"),
863 "yx");
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000864 EXPECT_TRUE(td()->DetermineResultType(mem)) << td()->error();
dan sinclair8ee1d222020-04-07 16:41:33 +0000865
Ben Clayton33352542021-01-29 16:43:41 +0000866 ASSERT_NE(TypeOf(mem), nullptr);
867 ASSERT_TRUE(TypeOf(mem)->Is<type::Vector>());
868 EXPECT_TRUE(TypeOf(mem)->As<type::Vector>()->type()->Is<type::F32>());
869 EXPECT_EQ(TypeOf(mem)->As<type::Vector>()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +0000870}
871
dan sinclaircd077b02020-04-20 14:19:04 +0000872using Expr_Binary_BitwiseTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +0000873TEST_P(Expr_Binary_BitwiseTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +0000874 auto op = GetParam();
875
Ben Clayton8d391f72021-01-26 16:57:10 +0000876 auto* var = Var("val", ast::StorageClass::kNone, ty.i32());
dan sinclair9b978022020-04-07 19:26:39 +0000877
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000878 AST().AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +0000879
dan sinclairb950e802020-04-20 14:20:01 +0000880 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000881
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000882 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +0000883
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000884 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +0000885 ASSERT_NE(TypeOf(expr), nullptr);
886 EXPECT_TRUE(TypeOf(expr)->Is<type::I32>());
dan sinclair9b978022020-04-07 19:26:39 +0000887}
888
dan sinclair1c9b4862020-04-07 19:27:41 +0000889TEST_P(Expr_Binary_BitwiseTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +0000890 auto op = GetParam();
891
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000892 auto* var = Var("val", ast::StorageClass::kNone, ty.vec3<i32>());
dan sinclair9b978022020-04-07 19:26:39 +0000893
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000894 AST().AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +0000895
dan sinclairb950e802020-04-20 14:20:01 +0000896 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000897
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000898 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +0000899
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000900 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +0000901 ASSERT_NE(TypeOf(expr), nullptr);
902 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
903 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::I32>());
904 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +0000905}
906INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +0000907 Expr_Binary_BitwiseTest,
908 testing::Values(ast::BinaryOp::kAnd,
909 ast::BinaryOp::kOr,
910 ast::BinaryOp::kXor,
911 ast::BinaryOp::kShiftLeft,
912 ast::BinaryOp::kShiftRight,
dan sinclair1c9b4862020-04-07 19:27:41 +0000913 ast::BinaryOp::kAdd,
914 ast::BinaryOp::kSubtract,
915 ast::BinaryOp::kDivide,
916 ast::BinaryOp::kModulo));
dan sinclair9b978022020-04-07 19:26:39 +0000917
dan sinclaircd077b02020-04-20 14:19:04 +0000918using Expr_Binary_LogicalTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +0000919TEST_P(Expr_Binary_LogicalTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +0000920 auto op = GetParam();
921
Ben Clayton8d391f72021-01-26 16:57:10 +0000922 auto* var = Var("val", ast::StorageClass::kNone, ty.bool_());
dan sinclair9b978022020-04-07 19:26:39 +0000923
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000924 AST().AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +0000925
dan sinclairb950e802020-04-20 14:20:01 +0000926 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000927
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000928 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +0000929
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000930 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +0000931 ASSERT_NE(TypeOf(expr), nullptr);
932 EXPECT_TRUE(TypeOf(expr)->Is<type::Bool>());
dan sinclair9b978022020-04-07 19:26:39 +0000933}
934
dan sinclair1c9b4862020-04-07 19:27:41 +0000935TEST_P(Expr_Binary_LogicalTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +0000936 auto op = GetParam();
937
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000938 auto* var = Var("val", ast::StorageClass::kNone, ty.vec3<bool>());
dan sinclair9b978022020-04-07 19:26:39 +0000939
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000940 AST().AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +0000941
dan sinclairb950e802020-04-20 14:20:01 +0000942 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000943
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000944 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +0000945
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000946 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +0000947 ASSERT_NE(TypeOf(expr), nullptr);
948 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
949 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::Bool>());
950 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +0000951}
952INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +0000953 Expr_Binary_LogicalTest,
954 testing::Values(ast::BinaryOp::kLogicalAnd,
955 ast::BinaryOp::kLogicalOr));
dan sinclair9b978022020-04-07 19:26:39 +0000956
dan sinclaircd077b02020-04-20 14:19:04 +0000957using Expr_Binary_CompareTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +0000958TEST_P(Expr_Binary_CompareTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +0000959 auto op = GetParam();
960
Ben Clayton8d391f72021-01-26 16:57:10 +0000961 auto* var = Var("val", ast::StorageClass::kNone, ty.i32());
dan sinclair9b978022020-04-07 19:26:39 +0000962
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000963 AST().AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +0000964
dan sinclairb950e802020-04-20 14:20:01 +0000965 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000966
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000967 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +0000968
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000969 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +0000970 ASSERT_NE(TypeOf(expr), nullptr);
971 EXPECT_TRUE(TypeOf(expr)->Is<type::Bool>());
dan sinclair9b978022020-04-07 19:26:39 +0000972}
973
dan sinclair1c9b4862020-04-07 19:27:41 +0000974TEST_P(Expr_Binary_CompareTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +0000975 auto op = GetParam();
976
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000977 auto* var = Var("val", ast::StorageClass::kNone, ty.vec3<i32>());
dan sinclair9b978022020-04-07 19:26:39 +0000978
Ben Clayton1f7e18b2021-01-26 16:57:10 +0000979 AST().AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +0000980
dan sinclairb950e802020-04-20 14:20:01 +0000981 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000982
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000983 auto* expr = create<ast::BinaryExpression>(op, Expr("val"), Expr("val"));
dan sinclair9b978022020-04-07 19:26:39 +0000984
Ben Clayton7eaf4b52020-12-14 22:08:27 +0000985 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +0000986 ASSERT_NE(TypeOf(expr), nullptr);
987 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
988 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::Bool>());
989 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +0000990}
991INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +0000992 Expr_Binary_CompareTest,
993 testing::Values(ast::BinaryOp::kEqual,
994 ast::BinaryOp::kNotEqual,
995 ast::BinaryOp::kLessThan,
996 ast::BinaryOp::kGreaterThan,
997 ast::BinaryOp::kLessThanEqual,
998 ast::BinaryOp::kGreaterThanEqual));
dan sinclair9b978022020-04-07 19:26:39 +0000999
dan sinclair1c9b4862020-04-07 19:27:41 +00001000TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Scalar) {
Ben Clayton8d391f72021-01-26 16:57:10 +00001001 auto* var = Var("val", ast::StorageClass::kNone, ty.i32());
dan sinclair9b978022020-04-07 19:26:39 +00001002
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001003 AST().AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001004
dan sinclairb950e802020-04-20 14:20:01 +00001005 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001006
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001007 auto* expr = Mul("val", "val");
dan sinclair9b978022020-04-07 19:26:39 +00001008
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001009 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001010 ASSERT_NE(TypeOf(expr), nullptr);
1011 EXPECT_TRUE(TypeOf(expr)->Is<type::I32>());
dan sinclair9b978022020-04-07 19:26:39 +00001012}
1013
dan sinclair1c9b4862020-04-07 19:27:41 +00001014TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Scalar) {
Ben Clayton8d391f72021-01-26 16:57:10 +00001015 auto* scalar = Var("scalar", ast::StorageClass::kNone, ty.f32());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001016 auto* vector = Var("vector", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001017 AST().AddGlobalVariable(scalar);
1018 AST().AddGlobalVariable(vector);
dan sinclair9b978022020-04-07 19:26:39 +00001019
dan sinclairb950e802020-04-20 14:20:01 +00001020 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001021
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001022 auto* expr = Mul("vector", "scalar");
dan sinclair9b978022020-04-07 19:26:39 +00001023
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001024 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001025 ASSERT_NE(TypeOf(expr), nullptr);
1026 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1027 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1028 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001029}
1030
dan sinclair1c9b4862020-04-07 19:27:41 +00001031TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Vector) {
Ben Clayton8d391f72021-01-26 16:57:10 +00001032 auto* scalar = Var("scalar", ast::StorageClass::kNone, ty.f32());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001033 auto* vector = Var("vector", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001034 AST().AddGlobalVariable(scalar);
1035 AST().AddGlobalVariable(vector);
dan sinclair9b978022020-04-07 19:26:39 +00001036
dan sinclairb950e802020-04-20 14:20:01 +00001037 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001038
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001039 auto* expr = Mul("scalar", "vector");
dan sinclair9b978022020-04-07 19:26:39 +00001040
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001041 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001042 ASSERT_NE(TypeOf(expr), nullptr);
1043 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1044 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1045 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001046}
1047
dan sinclair1c9b4862020-04-07 19:27:41 +00001048TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Vector) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001049 auto* vector = Var("vector", ast::StorageClass::kNone, ty.vec3<f32>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001050 AST().AddGlobalVariable(vector);
dan sinclair9b978022020-04-07 19:26:39 +00001051
dan sinclairb950e802020-04-20 14:20:01 +00001052 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001053
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001054 auto* expr = Mul("vector", "vector");
dan sinclair9b978022020-04-07 19:26:39 +00001055
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001056 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001057 ASSERT_NE(TypeOf(expr), nullptr);
1058 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1059 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1060 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001061}
1062
dan sinclair1c9b4862020-04-07 19:27:41 +00001063TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Scalar) {
Ben Clayton8d391f72021-01-26 16:57:10 +00001064 auto* scalar = Var("scalar", ast::StorageClass::kNone, ty.f32());
Ben Clayton1637cbb2021-01-05 15:44:39 +00001065 auto* matrix = Var("matrix", ast::StorageClass::kNone, ty.mat2x3<f32>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001066 AST().AddGlobalVariable(scalar);
1067 AST().AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001068
dan sinclairb950e802020-04-20 14:20:01 +00001069 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001070
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001071 auto* expr = Mul("matrix", "scalar");
dan sinclair9b978022020-04-07 19:26:39 +00001072
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001073 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001074 ASSERT_NE(TypeOf(expr), nullptr);
1075 ASSERT_TRUE(TypeOf(expr)->Is<type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001076
Ben Clayton33352542021-01-29 16:43:41 +00001077 auto* mat = TypeOf(expr)->As<type::Matrix>();
Ben Clayton207b5e22021-01-21 15:42:10 +00001078 EXPECT_TRUE(mat->type()->Is<type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001079 EXPECT_EQ(mat->rows(), 3u);
1080 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001081}
1082
dan sinclair1c9b4862020-04-07 19:27:41 +00001083TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Matrix) {
Ben Clayton8d391f72021-01-26 16:57:10 +00001084 auto* scalar = Var("scalar", ast::StorageClass::kNone, ty.f32());
Ben Clayton1637cbb2021-01-05 15:44:39 +00001085 auto* matrix = Var("matrix", ast::StorageClass::kNone, ty.mat2x3<f32>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001086 AST().AddGlobalVariable(scalar);
1087 AST().AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001088
dan sinclairb950e802020-04-20 14:20:01 +00001089 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001090
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001091 auto* expr = Mul("scalar", "matrix");
dan sinclair9b978022020-04-07 19:26:39 +00001092
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001093 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001094 ASSERT_NE(TypeOf(expr), nullptr);
1095 ASSERT_TRUE(TypeOf(expr)->Is<type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001096
Ben Clayton33352542021-01-29 16:43:41 +00001097 auto* mat = TypeOf(expr)->As<type::Matrix>();
Ben Clayton207b5e22021-01-21 15:42:10 +00001098 EXPECT_TRUE(mat->type()->Is<type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001099 EXPECT_EQ(mat->rows(), 3u);
1100 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001101}
1102
dan sinclair1c9b4862020-04-07 19:27:41 +00001103TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Vector) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001104 auto* vector = Var("vector", ast::StorageClass::kNone, ty.vec3<f32>());
1105 auto* matrix = Var("matrix", ast::StorageClass::kNone, ty.mat2x3<f32>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001106 AST().AddGlobalVariable(vector);
1107 AST().AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001108
dan sinclairb950e802020-04-20 14:20:01 +00001109 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001110
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001111 auto* expr = Mul("matrix", "vector");
dan sinclair9b978022020-04-07 19:26:39 +00001112
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001113 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001114 ASSERT_NE(TypeOf(expr), nullptr);
1115 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1116 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1117 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001118}
1119
dan sinclair1c9b4862020-04-07 19:27:41 +00001120TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Matrix) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001121 auto* vector = Var("vector", ast::StorageClass::kNone, ty.vec3<f32>());
1122 auto* matrix = Var("matrix", ast::StorageClass::kNone, ty.mat2x3<f32>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001123 AST().AddGlobalVariable(vector);
1124 AST().AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001125
dan sinclairb950e802020-04-20 14:20:01 +00001126 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001127
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001128 auto* expr = Mul("vector", "matrix");
dan sinclair9b978022020-04-07 19:26:39 +00001129
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001130 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001131 ASSERT_NE(TypeOf(expr), nullptr);
1132 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1133 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1134 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001135}
1136
dan sinclair1c9b4862020-04-07 19:27:41 +00001137TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Matrix) {
Ben Clayton1637cbb2021-01-05 15:44:39 +00001138 auto* matrix1 = Var("mat3x4", ast::StorageClass::kNone, ty.mat3x4<f32>());
1139 auto* matrix2 = Var("mat4x3", ast::StorageClass::kNone, ty.mat4x3<f32>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001140 AST().AddGlobalVariable(matrix1);
1141 AST().AddGlobalVariable(matrix2);
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 Clayton1637cbb2021-01-05 15:44:39 +00001145 auto* expr = Mul("mat3x4", "mat4x3");
dan sinclair9b978022020-04-07 19:26:39 +00001146
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001147 ASSERT_TRUE(td()->DetermineResultType(expr)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001148 ASSERT_NE(TypeOf(expr), nullptr);
1149 ASSERT_TRUE(TypeOf(expr)->Is<type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001150
Ben Clayton33352542021-01-29 16:43:41 +00001151 auto* mat = TypeOf(expr)->As<type::Matrix>();
Ben Clayton207b5e22021-01-21 15:42:10 +00001152 EXPECT_TRUE(mat->type()->Is<type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001153 EXPECT_EQ(mat->rows(), 4u);
1154 EXPECT_EQ(mat->columns(), 4u);
dan sinclair9b978022020-04-07 19:26:39 +00001155}
1156
dan sinclair46e959d2020-06-01 13:43:22 +00001157using IntrinsicDerivativeTest = TypeDeterminerTestWithParam<std::string>;
1158TEST_P(IntrinsicDerivativeTest, Scalar) {
1159 auto name = GetParam();
dan sinclairb1730562020-04-07 19:26:49 +00001160
Ben Clayton8d391f72021-01-26 16:57:10 +00001161 auto* var = Var("ident", ast::StorageClass::kNone, ty.f32());
dan sinclairb1730562020-04-07 19:26:49 +00001162
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001163 AST().AddGlobalVariable(var);
dan sinclair46e959d2020-06-01 13:43:22 +00001164
dan sinclair46e959d2020-06-01 13:43:22 +00001165 EXPECT_TRUE(td()->Determine());
1166
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001167 auto* expr = Call(name, "ident");
1168 EXPECT_TRUE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001169
Ben Clayton33352542021-01-29 16:43:41 +00001170 ASSERT_NE(TypeOf(expr), nullptr);
1171 ASSERT_TRUE(TypeOf(expr)->Is<type::F32>());
dan sinclair46e959d2020-06-01 13:43:22 +00001172}
1173
1174TEST_P(IntrinsicDerivativeTest, Vector) {
1175 auto name = GetParam();
1176
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001177 auto* var = Var("ident", ast::StorageClass::kNone, ty.vec4<f32>());
dan sinclairb1730562020-04-07 19:26:49 +00001178
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001179 AST().AddGlobalVariable(var);
dan sinclairb1730562020-04-07 19:26:49 +00001180
dan sinclairb950e802020-04-20 14:20:01 +00001181 EXPECT_TRUE(td()->Determine());
dan sinclairb1730562020-04-07 19:26:49 +00001182
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001183 auto* expr = Call(name, "ident");
1184 EXPECT_TRUE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001185
Ben Clayton33352542021-01-29 16:43:41 +00001186 ASSERT_NE(TypeOf(expr), nullptr);
1187 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1188 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
1189 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 4u);
dan sinclair46e959d2020-06-01 13:43:22 +00001190}
1191
1192TEST_P(IntrinsicDerivativeTest, MissingParam) {
1193 auto name = GetParam();
1194
dan sinclair46e959d2020-06-01 13:43:22 +00001195 EXPECT_TRUE(td()->Determine());
1196
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001197 auto* expr = Call(name);
1198 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001199 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
1200}
1201
1202TEST_P(IntrinsicDerivativeTest, ToomManyParams) {
1203 auto name = GetParam();
1204
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001205 auto* var1 = Var("ident1", ast::StorageClass::kNone, ty.vec4<f32>());
1206 auto* var2 = Var("ident2", ast::StorageClass::kNone, ty.vec4<f32>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001207 AST().AddGlobalVariable(var1);
1208 AST().AddGlobalVariable(var2);
dan sinclair46e959d2020-06-01 13:43:22 +00001209
dan sinclair46e959d2020-06-01 13:43:22 +00001210 EXPECT_TRUE(td()->Determine());
1211
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001212 auto* expr = Call(name, "ident1", "ident2");
1213 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001214 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
dan sinclairb1730562020-04-07 19:26:49 +00001215}
1216INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair46e959d2020-06-01 13:43:22 +00001217 IntrinsicDerivativeTest,
1218 testing::Values("dpdx",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001219 "dpdxCoarse",
1220 "dpdxFine",
dan sinclair46e959d2020-06-01 13:43:22 +00001221 "dpdy",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001222 "dpdyCoarse",
1223 "dpdyFine",
dan sinclair46e959d2020-06-01 13:43:22 +00001224 "fwidth",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001225 "fwidthCoarse",
1226 "fwidthFine"));
dan sinclairb1730562020-04-07 19:26:49 +00001227
dan sinclair46e959d2020-06-01 13:43:22 +00001228using Intrinsic = TypeDeterminerTestWithParam<std::string>;
1229TEST_P(Intrinsic, Test) {
1230 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00001231
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001232 auto* var = Var("my_var", ast::StorageClass::kNone, ty.vec3<bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001233
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001234 AST().AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00001235
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001236 auto* expr = Call(name, "my_var");
dan sinclair8dcfd102020-04-07 19:27:00 +00001237
dan sinclair8dcfd102020-04-07 19:27:00 +00001238 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001239 EXPECT_TRUE(td()->Determine());
dan sinclair8dcfd102020-04-07 19:27:00 +00001240
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001241 EXPECT_TRUE(td()->DetermineResultType(expr));
Ben Clayton33352542021-01-29 16:43:41 +00001242 ASSERT_NE(TypeOf(expr), nullptr);
1243 EXPECT_TRUE(TypeOf(expr)->Is<type::Bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001244}
1245INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair46e959d2020-06-01 13:43:22 +00001246 Intrinsic,
1247 testing::Values("any", "all"));
dan sinclair8dcfd102020-04-07 19:27:00 +00001248
dan sinclair46e959d2020-06-01 13:43:22 +00001249using Intrinsic_FloatMethod = TypeDeterminerTestWithParam<std::string>;
1250TEST_P(Intrinsic_FloatMethod, Vector) {
1251 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00001252
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001253 auto* var = Var("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001254
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001255 AST().AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00001256
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001257 auto* expr = Call(name, "my_var");
dan sinclair8dcfd102020-04-07 19:27:00 +00001258
dan sinclair8dcfd102020-04-07 19:27:00 +00001259 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001260 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001261 EXPECT_TRUE(td()->DetermineResultType(expr));
dan sinclair8dcfd102020-04-07 19:27:00 +00001262
Ben Clayton33352542021-01-29 16:43:41 +00001263 ASSERT_NE(TypeOf(expr), nullptr);
1264 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
1265 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::Bool>());
1266 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
dan sinclair8dcfd102020-04-07 19:27:00 +00001267}
dan sinclair46e959d2020-06-01 13:43:22 +00001268
1269TEST_P(Intrinsic_FloatMethod, Scalar) {
1270 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00001271
Ben Clayton8d391f72021-01-26 16:57:10 +00001272 auto* var = Var("my_var", ast::StorageClass::kNone, ty.f32());
dan sinclair8dcfd102020-04-07 19:27:00 +00001273
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001274 AST().AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00001275
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001276 auto* expr = Call(name, "my_var");
dan sinclair8dcfd102020-04-07 19:27:00 +00001277
dan sinclair8dcfd102020-04-07 19:27:00 +00001278 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001279 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001280 EXPECT_TRUE(td()->DetermineResultType(expr));
Ben Clayton33352542021-01-29 16:43:41 +00001281 ASSERT_NE(TypeOf(expr), nullptr);
1282 EXPECT_TRUE(TypeOf(expr)->Is<type::Bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001283}
dan sinclair8dcfd102020-04-07 19:27:00 +00001284
dan sinclair46e959d2020-06-01 13:43:22 +00001285TEST_P(Intrinsic_FloatMethod, MissingParam) {
1286 auto name = GetParam();
1287
Ben Clayton8d391f72021-01-26 16:57:10 +00001288 auto* var = Var("my_var", ast::StorageClass::kNone, ty.f32());
dan sinclair46e959d2020-06-01 13:43:22 +00001289
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001290 AST().AddGlobalVariable(var);
dan sinclair46e959d2020-06-01 13:43:22 +00001291
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001292 auto* expr = Call(name);
dan sinclair46e959d2020-06-01 13:43:22 +00001293
1294 // Register the variable
1295 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001296 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001297 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
1298}
1299
1300TEST_P(Intrinsic_FloatMethod, TooManyParams) {
1301 auto name = GetParam();
1302
Ben Clayton8d391f72021-01-26 16:57:10 +00001303 auto* var = Var("my_var", ast::StorageClass::kNone, ty.f32());
dan sinclair46e959d2020-06-01 13:43:22 +00001304
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001305 AST().AddGlobalVariable(var);
dan sinclair46e959d2020-06-01 13:43:22 +00001306
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001307 auto* expr = Call(name, "my_var", "my_var");
dan sinclair46e959d2020-06-01 13:43:22 +00001308
1309 // Register the variable
1310 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001311 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair46e959d2020-06-01 13:43:22 +00001312 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
1313}
1314INSTANTIATE_TEST_SUITE_P(
1315 TypeDeterminerTest,
1316 Intrinsic_FloatMethod,
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00001317 testing::Values("isInf", "isNan", "isFinite", "isNormal"));
dan sinclair46e959d2020-06-01 13:43:22 +00001318
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001319enum class Texture { kF32, kI32, kU32 };
1320inline std::ostream& operator<<(std::ostream& out, Texture data) {
1321 if (data == Texture::kF32) {
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001322 out << "f32";
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001323 } else if (data == Texture::kI32) {
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001324 out << "i32";
1325 } else {
1326 out << "u32";
1327 }
1328 return out;
1329}
1330
1331struct TextureTestParams {
Ben Clayton207b5e22021-01-21 15:42:10 +00001332 type::TextureDimension dim;
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001333 Texture type = Texture::kF32;
Ben Clayton207b5e22021-01-21 15:42:10 +00001334 type::ImageFormat format = type::ImageFormat::kR16Float;
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001335};
1336inline std::ostream& operator<<(std::ostream& out, TextureTestParams data) {
1337 out << data.dim << "_" << data.type;
1338 return out;
1339}
1340
1341class Intrinsic_TextureOperation
1342 : public TypeDeterminerTestWithParam<TextureTestParams> {
1343 public:
Ben Clayton281b6022021-01-21 16:35:10 +00001344 type::Type* get_coords_type(type::TextureDimension dim, type::Type* type) {
Ben Clayton207b5e22021-01-21 15:42:10 +00001345 if (dim == type::TextureDimension::k1d) {
1346 if (type->Is<type::I32>()) {
Ben Clayton281b6022021-01-21 16:35:10 +00001347 return create<type::I32>();
Ben Clayton207b5e22021-01-21 15:42:10 +00001348 } else if (type->Is<type::U32>()) {
Ben Clayton281b6022021-01-21 16:35:10 +00001349 return create<type::U32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001350 } else {
Ben Clayton281b6022021-01-21 16:35:10 +00001351 return create<type::F32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001352 }
Ben Clayton207b5e22021-01-21 15:42:10 +00001353 } else if (dim == type::TextureDimension::k1dArray ||
1354 dim == type::TextureDimension::k2d) {
Ben Clayton281b6022021-01-21 16:35:10 +00001355 return create<type::Vector>(type, 2);
Ben Clayton207b5e22021-01-21 15:42:10 +00001356 } else if (dim == type::TextureDimension::kCubeArray) {
Ben Clayton281b6022021-01-21 16:35:10 +00001357 return create<type::Vector>(type, 4);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001358 } else {
Ben Clayton281b6022021-01-21 16:35:10 +00001359 return create<type::Vector>(type, 3);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001360 }
1361 }
1362
1363 void add_call_param(std::string name,
Ben Clayton207b5e22021-01-21 15:42:10 +00001364 type::Type* type,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001365 ast::ExpressionList* call_params) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001366 auto* var = Var(name, ast::StorageClass::kNone, type);
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001367 AST().AddGlobalVariable(var);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001368 call_params->push_back(Expr(name));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001369 }
1370
Ben Clayton281b6022021-01-21 16:35:10 +00001371 type::Type* subtype(Texture type) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001372 if (type == Texture::kF32) {
Ben Clayton281b6022021-01-21 16:35:10 +00001373 return create<type::F32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001374 }
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001375 if (type == Texture::kI32) {
Ben Clayton281b6022021-01-21 16:35:10 +00001376 return create<type::I32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001377 }
Ben Clayton281b6022021-01-21 16:35:10 +00001378 return create<type::U32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001379 }
1380};
1381
1382using Intrinsic_StorageTextureOperation = Intrinsic_TextureOperation;
1383TEST_P(Intrinsic_StorageTextureOperation, TextureLoadRo) {
1384 auto dim = GetParam().dim;
1385 auto type = GetParam().type;
1386 auto format = GetParam().format;
1387
Ben Clayton8d391f72021-01-26 16:57:10 +00001388 auto* coords_type = get_coords_type(dim, ty.i32());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001389
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001390 type::Type* texture_type = create<type::StorageTexture>(dim, format);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001391
1392 ast::ExpressionList call_params;
1393
1394 add_call_param("texture", texture_type, &call_params);
Ben Clayton281b6022021-01-21 16:35:10 +00001395 add_call_param("coords", coords_type, &call_params);
Ben Clayton8d391f72021-01-26 16:57:10 +00001396 add_call_param("lod", ty.i32(), &call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001397
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001398 auto* expr = Call("textureLoad", call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001399
1400 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001401 EXPECT_TRUE(td()->DetermineResultType(expr));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001402
Ben Clayton33352542021-01-29 16:43:41 +00001403 ASSERT_NE(TypeOf(expr), nullptr);
1404 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001405 if (type == Texture::kF32) {
Ben Clayton33352542021-01-29 16:43:41 +00001406 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001407 } else if (type == Texture::kI32) {
Ben Clayton33352542021-01-29 16:43:41 +00001408 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::I32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001409 } else {
Ben Clayton33352542021-01-29 16:43:41 +00001410 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::U32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001411 }
Ben Clayton33352542021-01-29 16:43:41 +00001412 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 4u);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001413}
1414
1415INSTANTIATE_TEST_SUITE_P(
1416 TypeDeterminerTest,
1417 Intrinsic_StorageTextureOperation,
1418 testing::Values(
Ben Clayton207b5e22021-01-21 15:42:10 +00001419 TextureTestParams{type::TextureDimension::k1d, Texture::kF32,
1420 type::ImageFormat::kR16Float},
1421 TextureTestParams{type::TextureDimension::k1d, Texture::kI32,
1422 type::ImageFormat::kR16Sint},
1423 TextureTestParams{type::TextureDimension::k1d, Texture::kF32,
1424 type::ImageFormat::kR8Unorm},
1425 TextureTestParams{type::TextureDimension::k1dArray, Texture::kF32,
1426 type::ImageFormat::kR16Float},
1427 TextureTestParams{type::TextureDimension::k1dArray, Texture::kI32,
1428 type::ImageFormat::kR16Sint},
1429 TextureTestParams{type::TextureDimension::k1dArray, Texture::kF32,
1430 type::ImageFormat::kR8Unorm},
1431 TextureTestParams{type::TextureDimension::k2d, Texture::kF32,
1432 type::ImageFormat::kR16Float},
1433 TextureTestParams{type::TextureDimension::k2d, Texture::kI32,
1434 type::ImageFormat::kR16Sint},
1435 TextureTestParams{type::TextureDimension::k2d, Texture::kF32,
1436 type::ImageFormat::kR8Unorm},
1437 TextureTestParams{type::TextureDimension::k2dArray, Texture::kF32,
1438 type::ImageFormat::kR16Float},
1439 TextureTestParams{type::TextureDimension::k2dArray, Texture::kI32,
1440 type::ImageFormat::kR16Sint},
1441 TextureTestParams{type::TextureDimension::k2dArray, Texture::kF32,
1442 type::ImageFormat::kR8Unorm},
1443 TextureTestParams{type::TextureDimension::k3d, Texture::kF32,
1444 type::ImageFormat::kR16Float},
1445 TextureTestParams{type::TextureDimension::k3d, Texture::kI32,
1446 type::ImageFormat::kR16Sint},
1447 TextureTestParams{type::TextureDimension::k3d, Texture::kF32,
1448 type::ImageFormat::kR8Unorm}));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001449
1450using Intrinsic_SampledTextureOperation = Intrinsic_TextureOperation;
1451TEST_P(Intrinsic_SampledTextureOperation, TextureLoadSampled) {
1452 auto dim = GetParam().dim;
1453 auto type = GetParam().type;
1454
Ben Clayton281b6022021-01-21 16:35:10 +00001455 type::Type* s = subtype(type);
Ben Clayton8d391f72021-01-26 16:57:10 +00001456 auto* coords_type = get_coords_type(dim, ty.i32());
Ben Clayton281b6022021-01-21 16:35:10 +00001457 auto* texture_type = create<type::SampledTexture>(dim, s);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001458
1459 ast::ExpressionList call_params;
1460
Ben Clayton281b6022021-01-21 16:35:10 +00001461 add_call_param("texture", texture_type, &call_params);
1462 add_call_param("coords", coords_type, &call_params);
Ben Clayton8d391f72021-01-26 16:57:10 +00001463 add_call_param("lod", ty.i32(), &call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001464
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001465 auto* expr = Call("textureLoad", call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001466
1467 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001468 EXPECT_TRUE(td()->DetermineResultType(expr));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001469
Ben Clayton33352542021-01-29 16:43:41 +00001470 ASSERT_NE(TypeOf(expr), nullptr);
1471 ASSERT_TRUE(TypeOf(expr)->Is<type::Vector>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001472 if (type == Texture::kF32) {
Ben Clayton33352542021-01-29 16:43:41 +00001473 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001474 } else if (type == Texture::kI32) {
Ben Clayton33352542021-01-29 16:43:41 +00001475 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::I32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001476 } else {
Ben Clayton33352542021-01-29 16:43:41 +00001477 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::U32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001478 }
Ben Clayton33352542021-01-29 16:43:41 +00001479 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 4u);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001480}
1481
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001482INSTANTIATE_TEST_SUITE_P(
1483 TypeDeterminerTest,
1484 Intrinsic_SampledTextureOperation,
Ben Clayton207b5e22021-01-21 15:42:10 +00001485 testing::Values(TextureTestParams{type::TextureDimension::k2d},
1486 TextureTestParams{type::TextureDimension::k2dArray},
1487 TextureTestParams{type::TextureDimension::kCube},
1488 TextureTestParams{type::TextureDimension::kCubeArray}));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00001489
dan sinclair46e959d2020-06-01 13:43:22 +00001490TEST_F(TypeDeterminerTest, Intrinsic_Dot) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001491 auto* var = Var("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001492
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001493 AST().AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00001494
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001495 auto* expr = Call("dot", "my_var", "my_var");
dan sinclair8dcfd102020-04-07 19:27:00 +00001496
dan sinclair8dcfd102020-04-07 19:27:00 +00001497 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001498 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001499 EXPECT_TRUE(td()->DetermineResultType(expr));
Ben Clayton33352542021-01-29 16:43:41 +00001500 ASSERT_NE(TypeOf(expr), nullptr);
1501 EXPECT_TRUE(TypeOf(expr)->Is<type::F32>());
dan sinclair8dcfd102020-04-07 19:27:00 +00001502}
1503
dan sinclair16a2ea12020-07-21 17:44:44 +00001504TEST_F(TypeDeterminerTest, Intrinsic_Select) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001505 auto* var = Var("my_var", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00001506
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001507 auto* bool_var = Var( // source
1508 "bool_var", ast::StorageClass::kNone, ty.vec3<bool>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001509 AST().AddGlobalVariable(var);
1510 AST().AddGlobalVariable(bool_var);
dan sinclair16a2ea12020-07-21 17:44:44 +00001511
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001512 auto* expr = Call("select", "my_var", "my_var", "bool_var");
dan sinclair16a2ea12020-07-21 17:44:44 +00001513
1514 // Register the variable
1515 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001516 EXPECT_TRUE(td()->DetermineResultType(expr)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001517 ASSERT_NE(TypeOf(expr), nullptr);
1518 EXPECT_TRUE(TypeOf(expr)->Is<type::Vector>());
1519 EXPECT_EQ(TypeOf(expr)->As<type::Vector>()->size(), 3u);
1520 EXPECT_TRUE(TypeOf(expr)->As<type::Vector>()->type()->Is<type::F32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00001521}
1522
1523TEST_F(TypeDeterminerTest, Intrinsic_Select_TooFewParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001524 auto* var = Var("v", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00001525
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001526 AST().AddGlobalVariable(var);
dan sinclair16a2ea12020-07-21 17:44:44 +00001527
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001528 auto* expr = Call("select", "v");
dan sinclair16a2ea12020-07-21 17:44:44 +00001529
1530 // Register the variable
1531 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001532 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair16a2ea12020-07-21 17:44:44 +00001533 EXPECT_EQ(td()->error(),
1534 "incorrect number of parameters for select expected 3 got 1");
1535}
1536
1537TEST_F(TypeDeterminerTest, Intrinsic_Select_TooManyParams) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001538 auto* var = Var("v", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00001539
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001540 AST().AddGlobalVariable(var);
dan sinclair16a2ea12020-07-21 17:44:44 +00001541
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001542 auto* expr = Call("select", "v", "v", "v", "v");
dan sinclair16a2ea12020-07-21 17:44:44 +00001543
1544 // Register the variable
1545 EXPECT_TRUE(td()->Determine());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001546 EXPECT_FALSE(td()->DetermineResultType(expr));
dan sinclair16a2ea12020-07-21 17:44:44 +00001547 EXPECT_EQ(td()->error(),
1548 "incorrect number of parameters for select expected 3 got 4");
1549}
1550
dan sinclaircd077b02020-04-20 14:19:04 +00001551using UnaryOpExpressionTest = TypeDeterminerTestWithParam<ast::UnaryOp>;
dan sinclair0e257622020-04-07 19:27:11 +00001552TEST_P(UnaryOpExpressionTest, Expr_UnaryOp) {
1553 auto op = GetParam();
1554
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001555 auto* var = Var("ident", ast::StorageClass::kNone, ty.vec4<f32>());
dan sinclair0e257622020-04-07 19:27:11 +00001556
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001557 AST().AddGlobalVariable(var);
dan sinclair0e257622020-04-07 19:27:11 +00001558
dan sinclairb950e802020-04-20 14:20:01 +00001559 EXPECT_TRUE(td()->Determine());
dan sinclair0e257622020-04-07 19:27:11 +00001560
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001561 auto* der = create<ast::UnaryOpExpression>(op, Expr("ident"));
1562 EXPECT_TRUE(td()->DetermineResultType(der));
Ben Clayton33352542021-01-29 16:43:41 +00001563 ASSERT_NE(TypeOf(der), nullptr);
1564 ASSERT_TRUE(TypeOf(der)->Is<type::Vector>());
1565 EXPECT_TRUE(TypeOf(der)->As<type::Vector>()->type()->Is<type::F32>());
1566 EXPECT_EQ(TypeOf(der)->As<type::Vector>()->size(), 4u);
dan sinclair0e257622020-04-07 19:27:11 +00001567}
1568INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
1569 UnaryOpExpressionTest,
1570 testing::Values(ast::UnaryOp::kNegation,
1571 ast::UnaryOp::kNot));
1572
dan sinclairee8ae042020-04-08 19:58:20 +00001573TEST_F(TypeDeterminerTest, StorageClass_SetsIfMissing) {
Ben Clayton8d391f72021-01-26 16:57:10 +00001574 auto* var = Var("var", ast::StorageClass::kNone, ty.i32());
dan sinclairee8ae042020-04-08 19:58:20 +00001575
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001576 auto* stmt = create<ast::VariableDeclStatement>(var);
Ben Clayton8d391f72021-01-26 16:57:10 +00001577 auto* func = Func("func", ast::VariableList{}, ty.i32(),
dan sinclair181d8ba2020-12-16 15:15:40 +00001578 ast::StatementList{stmt}, ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001579
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001580 AST().Functions().Add(func);
dan sinclairee8ae042020-04-08 19:58:20 +00001581
dan sinclairb950e802020-04-20 14:20:01 +00001582 EXPECT_TRUE(td()->Determine()) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001583 EXPECT_EQ(var->storage_class(), ast::StorageClass::kFunction);
dan sinclairee8ae042020-04-08 19:58:20 +00001584}
1585
1586TEST_F(TypeDeterminerTest, StorageClass_DoesNotSetOnConst) {
Ben Clayton8d391f72021-01-26 16:57:10 +00001587 auto* var = Const("var", ast::StorageClass::kNone, ty.i32());
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001588 auto* stmt = create<ast::VariableDeclStatement>(var);
Ben Clayton8d391f72021-01-26 16:57:10 +00001589 auto* func = Func("func", ast::VariableList{}, ty.i32(),
dan sinclair181d8ba2020-12-16 15:15:40 +00001590 ast::StatementList{stmt}, ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001591
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001592 AST().Functions().Add(func);
dan sinclairee8ae042020-04-08 19:58:20 +00001593
dan sinclairb950e802020-04-20 14:20:01 +00001594 EXPECT_TRUE(td()->Determine()) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001595 EXPECT_EQ(var->storage_class(), ast::StorageClass::kNone);
dan sinclairee8ae042020-04-08 19:58:20 +00001596}
1597
1598TEST_F(TypeDeterminerTest, StorageClass_NonFunctionClassError) {
Ben Clayton8d391f72021-01-26 16:57:10 +00001599 auto* var = Var("var", ast::StorageClass::kWorkgroup, ty.i32());
dan sinclairee8ae042020-04-08 19:58:20 +00001600
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001601 auto* stmt = create<ast::VariableDeclStatement>(var);
Ben Clayton8d391f72021-01-26 16:57:10 +00001602 auto* func = Func("func", ast::VariableList{}, ty.i32(),
dan sinclair181d8ba2020-12-16 15:15:40 +00001603 ast::StatementList{stmt}, ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00001604
Ben Clayton1f7e18b2021-01-26 16:57:10 +00001605 AST().Functions().Add(func);
dan sinclairee8ae042020-04-08 19:58:20 +00001606
dan sinclairb950e802020-04-20 14:20:01 +00001607 EXPECT_FALSE(td()->Determine());
dan sinclairee8ae042020-04-08 19:58:20 +00001608 EXPECT_EQ(td()->error(),
1609 "function variable has a non-function storage class");
1610}
1611
dan sinclairb4fee2f2020-09-22 19:42:13 +00001612struct IntrinsicData {
dan sinclairca1723e2020-04-20 15:47:55 +00001613 const char* name;
dan sinclairb4fee2f2020-09-22 19:42:13 +00001614 ast::Intrinsic intrinsic;
dan sinclairca1723e2020-04-20 15:47:55 +00001615};
dan sinclairb4fee2f2020-09-22 19:42:13 +00001616inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
dan sinclairca1723e2020-04-20 15:47:55 +00001617 out << data.name;
1618 return out;
1619}
dan sinclairb4fee2f2020-09-22 19:42:13 +00001620using IntrinsicDataTest = TypeDeterminerTestWithParam<IntrinsicData>;
1621TEST_P(IntrinsicDataTest, Lookup) {
1622 auto param = GetParam();
dan sinclairca1723e2020-04-20 15:47:55 +00001623
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001624 auto* ident = Expr(param.name);
1625 EXPECT_TRUE(td()->SetIntrinsicIfNeeded(ident));
1626 EXPECT_EQ(ident->intrinsic(), param.intrinsic);
1627 EXPECT_TRUE(ident->IsIntrinsic());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001628}
1629INSTANTIATE_TEST_SUITE_P(
1630 TypeDeterminerTest,
1631 IntrinsicDataTest,
1632 testing::Values(
1633 IntrinsicData{"abs", ast::Intrinsic::kAbs},
1634 IntrinsicData{"acos", ast::Intrinsic::kAcos},
1635 IntrinsicData{"all", ast::Intrinsic::kAll},
1636 IntrinsicData{"any", ast::Intrinsic::kAny},
dan sinclair007dc422020-10-08 17:01:55 +00001637 IntrinsicData{"arrayLength", ast::Intrinsic::kArrayLength},
dan sinclairb4fee2f2020-09-22 19:42:13 +00001638 IntrinsicData{"asin", ast::Intrinsic::kAsin},
1639 IntrinsicData{"atan", ast::Intrinsic::kAtan},
1640 IntrinsicData{"atan2", ast::Intrinsic::kAtan2},
1641 IntrinsicData{"ceil", ast::Intrinsic::kCeil},
1642 IntrinsicData{"clamp", ast::Intrinsic::kClamp},
1643 IntrinsicData{"cos", ast::Intrinsic::kCos},
1644 IntrinsicData{"cosh", ast::Intrinsic::kCosh},
1645 IntrinsicData{"countOneBits", ast::Intrinsic::kCountOneBits},
1646 IntrinsicData{"cross", ast::Intrinsic::kCross},
1647 IntrinsicData{"determinant", ast::Intrinsic::kDeterminant},
1648 IntrinsicData{"distance", ast::Intrinsic::kDistance},
1649 IntrinsicData{"dot", ast::Intrinsic::kDot},
1650 IntrinsicData{"dpdx", ast::Intrinsic::kDpdx},
1651 IntrinsicData{"dpdxCoarse", ast::Intrinsic::kDpdxCoarse},
1652 IntrinsicData{"dpdxFine", ast::Intrinsic::kDpdxFine},
1653 IntrinsicData{"dpdy", ast::Intrinsic::kDpdy},
1654 IntrinsicData{"dpdyCoarse", ast::Intrinsic::kDpdyCoarse},
1655 IntrinsicData{"dpdyFine", ast::Intrinsic::kDpdyFine},
1656 IntrinsicData{"exp", ast::Intrinsic::kExp},
1657 IntrinsicData{"exp2", ast::Intrinsic::kExp2},
1658 IntrinsicData{"faceForward", ast::Intrinsic::kFaceForward},
1659 IntrinsicData{"floor", ast::Intrinsic::kFloor},
1660 IntrinsicData{"fma", ast::Intrinsic::kFma},
1661 IntrinsicData{"fract", ast::Intrinsic::kFract},
1662 IntrinsicData{"frexp", ast::Intrinsic::kFrexp},
1663 IntrinsicData{"fwidth", ast::Intrinsic::kFwidth},
1664 IntrinsicData{"fwidthCoarse", ast::Intrinsic::kFwidthCoarse},
1665 IntrinsicData{"fwidthFine", ast::Intrinsic::kFwidthFine},
1666 IntrinsicData{"inverseSqrt", ast::Intrinsic::kInverseSqrt},
1667 IntrinsicData{"isFinite", ast::Intrinsic::kIsFinite},
1668 IntrinsicData{"isInf", ast::Intrinsic::kIsInf},
1669 IntrinsicData{"isNan", ast::Intrinsic::kIsNan},
1670 IntrinsicData{"isNormal", ast::Intrinsic::kIsNormal},
1671 IntrinsicData{"ldexp", ast::Intrinsic::kLdexp},
1672 IntrinsicData{"length", ast::Intrinsic::kLength},
1673 IntrinsicData{"log", ast::Intrinsic::kLog},
1674 IntrinsicData{"log2", ast::Intrinsic::kLog2},
1675 IntrinsicData{"max", ast::Intrinsic::kMax},
1676 IntrinsicData{"min", ast::Intrinsic::kMin},
1677 IntrinsicData{"mix", ast::Intrinsic::kMix},
1678 IntrinsicData{"modf", ast::Intrinsic::kModf},
1679 IntrinsicData{"normalize", ast::Intrinsic::kNormalize},
dan sinclairb4fee2f2020-09-22 19:42:13 +00001680 IntrinsicData{"pow", ast::Intrinsic::kPow},
1681 IntrinsicData{"reflect", ast::Intrinsic::kReflect},
1682 IntrinsicData{"reverseBits", ast::Intrinsic::kReverseBits},
1683 IntrinsicData{"round", ast::Intrinsic::kRound},
1684 IntrinsicData{"select", ast::Intrinsic::kSelect},
1685 IntrinsicData{"sign", ast::Intrinsic::kSign},
1686 IntrinsicData{"sin", ast::Intrinsic::kSin},
1687 IntrinsicData{"sinh", ast::Intrinsic::kSinh},
1688 IntrinsicData{"smoothStep", ast::Intrinsic::kSmoothStep},
1689 IntrinsicData{"sqrt", ast::Intrinsic::kSqrt},
1690 IntrinsicData{"step", ast::Intrinsic::kStep},
1691 IntrinsicData{"tan", ast::Intrinsic::kTan},
1692 IntrinsicData{"tanh", ast::Intrinsic::kTanh},
Ben Clayton4a0b9f72021-01-11 21:07:32 +00001693 IntrinsicData{"textureDimensions", ast::Intrinsic::kTextureDimensions},
dan sinclairb4fee2f2020-09-22 19:42:13 +00001694 IntrinsicData{"textureLoad", ast::Intrinsic::kTextureLoad},
Ben Claytonc21f1f92021-01-14 16:50:07 +00001695 IntrinsicData{"textureNumLayers", ast::Intrinsic::kTextureNumLayers},
Ben Claytond9713202021-01-14 18:06:57 +00001696 IntrinsicData{"textureNumLevels", ast::Intrinsic::kTextureNumLevels},
Ben Clayton0a68b362021-01-14 18:11:17 +00001697 IntrinsicData{"textureNumSamples", ast::Intrinsic::kTextureNumSamples},
dan sinclairb4fee2f2020-09-22 19:42:13 +00001698 IntrinsicData{"textureSample", ast::Intrinsic::kTextureSample},
1699 IntrinsicData{"textureSampleBias", ast::Intrinsic::kTextureSampleBias},
1700 IntrinsicData{"textureSampleCompare",
1701 ast::Intrinsic::kTextureSampleCompare},
Ben Clayton3ea3c992020-11-18 21:19:22 +00001702 IntrinsicData{"textureSampleGrad", ast::Intrinsic::kTextureSampleGrad},
dan sinclairb4fee2f2020-09-22 19:42:13 +00001703 IntrinsicData{"textureSampleLevel",
1704 ast::Intrinsic::kTextureSampleLevel},
1705 IntrinsicData{"trunc", ast::Intrinsic::kTrunc}));
1706
1707TEST_F(TypeDeterminerTest, IntrinsicNotSetIfNotMatched) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001708 auto* ident = Expr("not_intrinsic");
1709 EXPECT_FALSE(td()->SetIntrinsicIfNeeded(ident));
1710 EXPECT_EQ(ident->intrinsic(), ast::Intrinsic::kNone);
1711 EXPECT_FALSE(ident->IsIntrinsic());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001712}
1713
1714using ImportData_SingleParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair37d62c92020-04-21 12:55:06 +00001715TEST_P(ImportData_SingleParamTest, Scalar) {
dan sinclairca1723e2020-04-20 15:47:55 +00001716 auto param = GetParam();
1717
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001718 auto* ident = Expr(param.name);
1719 auto* call = Call(ident, 1.f);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001720
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001721 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001722 ASSERT_NE(TypeOf(ident), nullptr);
1723 EXPECT_TRUE(TypeOf(ident)->is_float_scalar());
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001724}
1725
dan sinclair37d62c92020-04-21 12:55:06 +00001726TEST_P(ImportData_SingleParamTest, Vector) {
dan sinclairca1723e2020-04-20 15:47:55 +00001727 auto param = GetParam();
1728
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001729 auto* ident = Expr(param.name);
1730 auto* call = Call(ident, vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001731
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001732 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001733 ASSERT_NE(TypeOf(ident), nullptr);
1734 EXPECT_TRUE(TypeOf(ident)->is_float_vector());
1735 EXPECT_EQ(TypeOf(ident)->As<type::Vector>()->size(), 3u);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001736}
1737
dan sinclair37d62c92020-04-21 12:55:06 +00001738TEST_P(ImportData_SingleParamTest, Error_NoParams) {
dan sinclairca1723e2020-04-20 15:47:55 +00001739 auto param = GetParam();
1740
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001741 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001742
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001743 EXPECT_FALSE(td()->DetermineResultType(call));
Alan Bakere809fb32021-02-01 15:33:13 +00001744 EXPECT_EQ(td()->error(),
1745 "missing parameter 0 required for type determination in builtin " +
1746 std::string(param.name));
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001747}
1748
dan sinclaira49328f2020-04-20 15:49:50 +00001749INSTANTIATE_TEST_SUITE_P(
1750 TypeDeterminerTest,
dan sinclair37d62c92020-04-21 12:55:06 +00001751 ImportData_SingleParamTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00001752 testing::Values(IntrinsicData{"acos", ast::Intrinsic::kAcos},
1753 IntrinsicData{"asin", ast::Intrinsic::kAsin},
1754 IntrinsicData{"atan", ast::Intrinsic::kAtan},
1755 IntrinsicData{"ceil", ast::Intrinsic::kCeil},
1756 IntrinsicData{"cos", ast::Intrinsic::kCos},
1757 IntrinsicData{"cosh", ast::Intrinsic::kCosh},
1758 IntrinsicData{"exp", ast::Intrinsic::kExp},
1759 IntrinsicData{"exp2", ast::Intrinsic::kExp2},
1760 IntrinsicData{"floor", ast::Intrinsic::kFloor},
1761 IntrinsicData{"fract", ast::Intrinsic::kFract},
1762 IntrinsicData{"inverseSqrt", ast::Intrinsic::kInverseSqrt},
1763 IntrinsicData{"log", ast::Intrinsic::kLog},
1764 IntrinsicData{"log2", ast::Intrinsic::kLog2},
1765 IntrinsicData{"normalize", ast::Intrinsic::kNormalize},
1766 IntrinsicData{"round", ast::Intrinsic::kRound},
1767 IntrinsicData{"sign", ast::Intrinsic::kSign},
1768 IntrinsicData{"sin", ast::Intrinsic::kSin},
1769 IntrinsicData{"sinh", ast::Intrinsic::kSinh},
1770 IntrinsicData{"sqrt", ast::Intrinsic::kSqrt},
1771 IntrinsicData{"tan", ast::Intrinsic::kTan},
1772 IntrinsicData{"tanh", ast::Intrinsic::kTanh},
1773 IntrinsicData{"trunc", ast::Intrinsic::kTrunc}));
1774
1775using ImportData_SingleParam_FloatOrInt_Test =
1776 TypeDeterminerTestWithParam<IntrinsicData>;
1777TEST_P(ImportData_SingleParam_FloatOrInt_Test, Float_Scalar) {
1778 auto param = GetParam();
1779
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001780 auto* ident = Expr(param.name);
1781 auto* call = Call(ident, 1.f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001782
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001783 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001784 ASSERT_NE(TypeOf(ident), nullptr);
1785 EXPECT_TRUE(TypeOf(ident)->is_float_scalar());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001786}
1787
1788TEST_P(ImportData_SingleParam_FloatOrInt_Test, Float_Vector) {
1789 auto param = GetParam();
1790
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001791 auto* ident = Expr(param.name);
1792 auto* call = Call(ident, vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001793
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001794 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001795 ASSERT_NE(TypeOf(ident), nullptr);
1796 EXPECT_TRUE(TypeOf(ident)->is_float_vector());
1797 EXPECT_EQ(TypeOf(ident)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001798}
1799
1800TEST_P(ImportData_SingleParam_FloatOrInt_Test, Sint_Scalar) {
1801 auto param = GetParam();
1802
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001803 auto* ident = Expr(param.name);
1804 auto* call = Call(ident, -1);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001805
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001806 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001807 ASSERT_NE(TypeOf(ident), nullptr);
1808 EXPECT_TRUE(TypeOf(ident)->Is<type::I32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001809}
1810
1811TEST_P(ImportData_SingleParam_FloatOrInt_Test, Sint_Vector) {
1812 auto param = GetParam();
1813
dan sinclairb4fee2f2020-09-22 19:42:13 +00001814 ast::ExpressionList vals;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001815 vals.push_back(Expr(1));
1816 vals.push_back(Expr(1));
1817 vals.push_back(Expr(3));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001818
1819 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001820 params.push_back(vec3<i32>(vals));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001821
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001822 auto* ident = Expr(param.name);
1823 auto* call = Call(ident, params);
Ben Clayton4bfe4612020-11-16 16:41:47 +00001824
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001825 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001826 ASSERT_NE(TypeOf(ident), nullptr);
1827 EXPECT_TRUE(TypeOf(ident)->is_signed_integer_vector());
1828 EXPECT_EQ(TypeOf(ident)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001829}
1830
1831TEST_P(ImportData_SingleParam_FloatOrInt_Test, Uint_Scalar) {
1832 auto param = GetParam();
1833
dan sinclairb4fee2f2020-09-22 19:42:13 +00001834 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001835 params.push_back(Expr(1u));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001836
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001837 auto* ident = Expr(param.name);
1838 auto* call = Call(ident, params);
Ben Clayton4bfe4612020-11-16 16:41:47 +00001839
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001840 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001841 ASSERT_NE(TypeOf(ident), nullptr);
1842 EXPECT_TRUE(TypeOf(ident)->Is<type::U32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00001843}
1844
1845TEST_P(ImportData_SingleParam_FloatOrInt_Test, Uint_Vector) {
1846 auto param = GetParam();
1847
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001848 auto* ident = Expr(param.name);
1849 auto* call = Call(ident, vec3<u32>(1u, 1u, 3u));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001850
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001851 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001852 ASSERT_NE(TypeOf(ident), nullptr);
1853 EXPECT_TRUE(TypeOf(ident)->is_unsigned_integer_vector());
1854 EXPECT_EQ(TypeOf(ident)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001855}
1856
dan sinclairb4fee2f2020-09-22 19:42:13 +00001857TEST_P(ImportData_SingleParam_FloatOrInt_Test, Error_NoParams) {
1858 auto param = GetParam();
1859
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001860 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001861
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001862 EXPECT_FALSE(td()->DetermineResultType(call));
Alan Bakere809fb32021-02-01 15:33:13 +00001863 EXPECT_EQ(td()->error(),
1864 "missing parameter 0 required for type determination in builtin " +
1865 std::string(param.name));
dan sinclairb4fee2f2020-09-22 19:42:13 +00001866}
1867
1868INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
1869 ImportData_SingleParam_FloatOrInt_Test,
1870 testing::Values(IntrinsicData{"abs",
1871 ast::Intrinsic::kAbs}));
dan sinclairca1723e2020-04-20 15:47:55 +00001872
dan sinclair652a4b92020-04-20 21:09:14 +00001873TEST_F(TypeDeterminerTest, ImportData_Length_Scalar) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001874 auto* ident = Expr("length");
dan sinclair652a4b92020-04-20 21:09:14 +00001875
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001876 auto* call = Call(ident, 1.f);
dan sinclair652a4b92020-04-20 21:09:14 +00001877
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001878 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001879 ASSERT_NE(TypeOf(ident), nullptr);
1880 EXPECT_TRUE(TypeOf(ident)->is_float_scalar());
dan sinclair652a4b92020-04-20 21:09:14 +00001881}
1882
1883TEST_F(TypeDeterminerTest, ImportData_Length_FloatVector) {
dan sinclair652a4b92020-04-20 21:09:14 +00001884 ast::ExpressionList params;
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001885 params.push_back(vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair652a4b92020-04-20 21:09:14 +00001886
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001887 auto* ident = Expr("length");
Ben Clayton4bfe4612020-11-16 16:41:47 +00001888
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001889 auto* call = Call(ident, params);
dan sinclair652a4b92020-04-20 21:09:14 +00001890
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001891 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001892 ASSERT_NE(TypeOf(ident), nullptr);
1893 EXPECT_TRUE(TypeOf(ident)->is_float_scalar());
dan sinclair652a4b92020-04-20 21:09:14 +00001894}
1895
dan sinclairb4fee2f2020-09-22 19:42:13 +00001896using ImportData_TwoParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair37d62c92020-04-21 12:55:06 +00001897TEST_P(ImportData_TwoParamTest, Scalar) {
1898 auto param = GetParam();
1899
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001900 auto* ident = Expr(param.name);
1901 auto* call = Call(ident, 1.f, 1.f);
dan sinclair37d62c92020-04-21 12:55:06 +00001902
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001903 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001904 ASSERT_NE(TypeOf(ident), nullptr);
1905 EXPECT_TRUE(TypeOf(ident)->is_float_scalar());
dan sinclair37d62c92020-04-21 12:55:06 +00001906}
1907
1908TEST_P(ImportData_TwoParamTest, Vector) {
1909 auto param = GetParam();
1910
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001911 auto* ident = Expr(param.name);
1912 auto* call =
1913 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 +00001914
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001915 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001916 ASSERT_NE(TypeOf(ident), nullptr);
1917 EXPECT_TRUE(TypeOf(ident)->is_float_vector());
1918 EXPECT_EQ(TypeOf(ident)->As<type::Vector>()->size(), 3u);
dan sinclair37d62c92020-04-21 12:55:06 +00001919}
dan sinclair37d62c92020-04-21 12:55:06 +00001920TEST_P(ImportData_TwoParamTest, Error_NoParams) {
1921 auto param = GetParam();
1922
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001923 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00001924
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001925 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair37d62c92020-04-21 12:55:06 +00001926 EXPECT_EQ(td()->error(),
Alan Bakere809fb32021-02-01 15:33:13 +00001927 "missing parameter 0 required for type determination in builtin " +
1928 std::string(param.name));
dan sinclair37d62c92020-04-21 12:55:06 +00001929}
dan sinclairb4fee2f2020-09-22 19:42:13 +00001930INSTANTIATE_TEST_SUITE_P(
1931 TypeDeterminerTest,
1932 ImportData_TwoParamTest,
1933 testing::Values(IntrinsicData{"atan2", ast::Intrinsic::kAtan2},
1934 IntrinsicData{"pow", ast::Intrinsic::kPow},
1935 IntrinsicData{"step", ast::Intrinsic::kStep},
1936 IntrinsicData{"reflect", ast::Intrinsic::kReflect}));
dan sinclair37d62c92020-04-21 12:55:06 +00001937
dan sinclair54444382020-04-21 13:04:15 +00001938TEST_F(TypeDeterminerTest, ImportData_Distance_Scalar) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001939 auto* ident = Expr("distance");
dan sinclair54444382020-04-21 13:04:15 +00001940
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001941 auto* call = Call(ident, 1.f, 1.f);
dan sinclair54444382020-04-21 13:04:15 +00001942
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001943 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001944 ASSERT_NE(TypeOf(ident), nullptr);
1945 EXPECT_TRUE(TypeOf(ident)->is_float_scalar());
dan sinclair54444382020-04-21 13:04:15 +00001946}
1947
1948TEST_F(TypeDeterminerTest, ImportData_Distance_Vector) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001949 auto* ident = Expr("distance");
dan sinclair54444382020-04-21 13:04:15 +00001950
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001951 auto* call =
1952 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 +00001953
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001954 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001955 ASSERT_NE(TypeOf(ident), nullptr);
1956 EXPECT_TRUE(TypeOf(ident)->Is<type::F32>());
dan sinclair54444382020-04-21 13:04:15 +00001957}
1958
dan sinclairee392252020-06-08 23:48:15 +00001959TEST_F(TypeDeterminerTest, ImportData_Cross) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001960 auto* ident = Expr("cross");
dan sinclair2287d012020-04-22 00:23:57 +00001961
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001962 auto* call =
1963 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 +00001964
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001965 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001966 ASSERT_NE(TypeOf(ident), nullptr);
1967 EXPECT_TRUE(TypeOf(ident)->is_float_vector());
1968 EXPECT_EQ(TypeOf(ident)->As<type::Vector>()->size(), 3u);
dan sinclairee392252020-06-08 23:48:15 +00001969}
1970
Alan Bakere809fb32021-02-01 15:33:13 +00001971TEST_F(TypeDeterminerTest, ImportData_Cross_AutoType) {
1972 auto* ident = Expr("cross");
dan sinclairee392252020-06-08 23:48:15 +00001973
Alan Bakere809fb32021-02-01 15:33:13 +00001974 auto* call = Call(ident);
dan sinclairee392252020-06-08 23:48:15 +00001975
Alan Bakere809fb32021-02-01 15:33:13 +00001976 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
1977 ASSERT_NE(TypeOf(ident), nullptr);
1978 EXPECT_TRUE(TypeOf(ident)->is_float_vector());
1979 EXPECT_EQ(TypeOf(ident)->As<type::Vector>()->size(), 3u);
dan sinclairee392252020-06-08 23:48:15 +00001980}
1981
dan sinclairb4fee2f2020-09-22 19:42:13 +00001982using ImportData_ThreeParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair2287d012020-04-22 00:23:57 +00001983TEST_P(ImportData_ThreeParamTest, Scalar) {
1984 auto param = GetParam();
1985
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001986 auto* ident = Expr(param.name);
1987 auto* call = Call(ident, 1.f, 1.f, 1.f);
dan sinclair2287d012020-04-22 00:23:57 +00001988
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001989 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00001990 ASSERT_NE(TypeOf(ident), nullptr);
1991 EXPECT_TRUE(TypeOf(ident)->is_float_scalar());
dan sinclair2287d012020-04-22 00:23:57 +00001992}
1993
1994TEST_P(ImportData_ThreeParamTest, Vector) {
1995 auto param = GetParam();
1996
Ben Clayton7eaf4b52020-12-14 22:08:27 +00001997 auto* ident = Expr(param.name);
1998 auto* call = Call(ident, vec3<f32>(1.0f, 1.0f, 3.0f),
1999 vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclair2287d012020-04-22 00:23:57 +00002000
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002001 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00002002 ASSERT_NE(TypeOf(ident), nullptr);
2003 EXPECT_TRUE(TypeOf(ident)->is_float_vector());
2004 EXPECT_EQ(TypeOf(ident)->As<type::Vector>()->size(), 3u);
dan sinclair2287d012020-04-22 00:23:57 +00002005}
dan sinclair2287d012020-04-22 00:23:57 +00002006TEST_P(ImportData_ThreeParamTest, Error_NoParams) {
2007 auto param = GetParam();
2008
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002009 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002010
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002011 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair2287d012020-04-22 00:23:57 +00002012 EXPECT_EQ(td()->error(),
Alan Bakere809fb32021-02-01 15:33:13 +00002013 "missing parameter 0 required for type determination in builtin " +
2014 std::string(param.name));
dan sinclair2287d012020-04-22 00:23:57 +00002015}
2016
2017INSTANTIATE_TEST_SUITE_P(
2018 TypeDeterminerTest,
2019 ImportData_ThreeParamTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00002020 testing::Values(IntrinsicData{"mix", ast::Intrinsic::kMix},
2021 IntrinsicData{"smoothStep", ast::Intrinsic::kSmoothStep},
2022 IntrinsicData{"fma", ast::Intrinsic::kFma},
2023 IntrinsicData{"faceForward",
2024 ast::Intrinsic::kFaceForward}));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002025
dan sinclairb4fee2f2020-09-22 19:42:13 +00002026using ImportData_ThreeParam_FloatOrInt_Test =
2027 TypeDeterminerTestWithParam<IntrinsicData>;
2028TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Float_Scalar) {
2029 auto param = GetParam();
2030
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002031 auto* ident = Expr(param.name);
2032 auto* call = Call(ident, 1.f, 1.f, 1.f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002033
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002034 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00002035 ASSERT_NE(TypeOf(ident), nullptr);
2036 EXPECT_TRUE(TypeOf(ident)->is_float_scalar());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002037}
2038
2039TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Float_Vector) {
2040 auto param = GetParam();
2041
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002042 auto* ident = Expr(param.name);
2043 auto* call = Call(ident, vec3<f32>(1.0f, 1.0f, 3.0f),
2044 vec3<f32>(1.0f, 1.0f, 3.0f), vec3<f32>(1.0f, 1.0f, 3.0f));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002045
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002046 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00002047 ASSERT_NE(TypeOf(ident), nullptr);
2048 EXPECT_TRUE(TypeOf(ident)->is_float_vector());
2049 EXPECT_EQ(TypeOf(ident)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002050}
2051
2052TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Sint_Scalar) {
2053 auto param = GetParam();
2054
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002055 auto* ident = Expr(param.name);
2056 auto* call = Call(ident, 1, 1, 1);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002057
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002058 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00002059 ASSERT_NE(TypeOf(ident), nullptr);
2060 EXPECT_TRUE(TypeOf(ident)->Is<type::I32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002061}
2062
2063TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Sint_Vector) {
2064 auto param = GetParam();
2065
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002066 auto* ident = Expr(param.name);
2067 auto* call =
2068 Call(ident, vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002069
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002070 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00002071 ASSERT_NE(TypeOf(ident), nullptr);
2072 EXPECT_TRUE(TypeOf(ident)->is_signed_integer_vector());
2073 EXPECT_EQ(TypeOf(ident)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002074}
2075
2076TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Uint_Scalar) {
2077 auto param = GetParam();
2078
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002079 auto* ident = Expr(param.name);
2080 auto* call = Call(ident, 1u, 1u, 1u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002081
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002082 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00002083 ASSERT_NE(TypeOf(ident), nullptr);
2084 EXPECT_TRUE(TypeOf(ident)->Is<type::U32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002085}
2086
2087TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Uint_Vector) {
2088 auto param = GetParam();
2089
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002090 auto* ident = Expr(param.name);
2091 auto* call = Call(ident, vec3<u32>(1u, 1u, 3u), vec3<u32>(1u, 1u, 3u),
2092 vec3<u32>(1u, 1u, 3u));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002093
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002094 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00002095 ASSERT_NE(TypeOf(ident), nullptr);
2096 EXPECT_TRUE(TypeOf(ident)->is_unsigned_integer_vector());
2097 EXPECT_EQ(TypeOf(ident)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002098}
2099
dan sinclairb4fee2f2020-09-22 19:42:13 +00002100TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_NoParams) {
2101 auto param = GetParam();
2102
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002103 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002104
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002105 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002106 EXPECT_EQ(td()->error(),
Alan Bakere809fb32021-02-01 15:33:13 +00002107 "missing parameter 0 required for type determination in builtin " +
2108 std::string(param.name));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002109}
2110
2111INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
2112 ImportData_ThreeParam_FloatOrInt_Test,
2113 testing::Values(IntrinsicData{
2114 "clamp", ast::Intrinsic::kClamp}));
2115
2116using ImportData_Int_SingleParamTest =
2117 TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002118TEST_P(ImportData_Int_SingleParamTest, Scalar) {
2119 auto param = GetParam();
2120
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002121 auto* ident = Expr(param.name);
2122 auto* call = Call(ident, 1);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002123
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002124 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00002125 ASSERT_NE(TypeOf(ident), nullptr);
2126 EXPECT_TRUE(TypeOf(ident)->is_integer_scalar());
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002127}
2128
2129TEST_P(ImportData_Int_SingleParamTest, Vector) {
2130 auto param = GetParam();
2131
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002132 auto* ident = Expr(param.name);
2133 auto* call = Call(ident, vec3<i32>(1, 1, 3));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002134
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002135 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00002136 ASSERT_NE(TypeOf(ident), nullptr);
2137 EXPECT_TRUE(TypeOf(ident)->is_signed_integer_vector());
2138 EXPECT_EQ(TypeOf(ident)->As<type::Vector>()->size(), 3u);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002139}
2140
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002141TEST_P(ImportData_Int_SingleParamTest, Error_NoParams) {
2142 auto param = GetParam();
2143
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002144 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002145
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002146 EXPECT_FALSE(td()->DetermineResultType(call));
Alan Bakere809fb32021-02-01 15:33:13 +00002147 EXPECT_EQ(td()->error(),
2148 "missing parameter 0 required for type determination in builtin " +
2149 std::string(param.name));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002150}
2151
dan sinclairaf5df702020-06-08 23:48:26 +00002152INSTANTIATE_TEST_SUITE_P(
2153 TypeDeterminerTest,
2154 ImportData_Int_SingleParamTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00002155 testing::Values(
2156 IntrinsicData{"countOneBits", ast::Intrinsic::kCountOneBits},
2157 IntrinsicData{"reverseBits", ast::Intrinsic::kReverseBits}));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00002158
dan sinclairb4fee2f2020-09-22 19:42:13 +00002159using ImportData_FloatOrInt_TwoParamTest =
2160 TypeDeterminerTestWithParam<IntrinsicData>;
2161TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Signed) {
dan sinclair92bb5572020-06-08 23:48:07 +00002162 auto param = GetParam();
2163
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002164 auto* ident = Expr(param.name);
2165 auto* call = Call(ident, 1, 1);
dan sinclair92bb5572020-06-08 23:48:07 +00002166
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002167 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00002168 ASSERT_NE(TypeOf(ident), nullptr);
2169 EXPECT_TRUE(TypeOf(ident)->Is<type::I32>());
dan sinclair92bb5572020-06-08 23:48:07 +00002170}
2171
dan sinclairb4fee2f2020-09-22 19:42:13 +00002172TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Unsigned) {
dan sinclair92bb5572020-06-08 23:48:07 +00002173 auto param = GetParam();
2174
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002175 auto* ident = Expr(param.name);
2176 auto* call = Call(ident, 1u, 1u);
dan sinclair92bb5572020-06-08 23:48:07 +00002177
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002178 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00002179 ASSERT_NE(TypeOf(ident), nullptr);
2180 EXPECT_TRUE(TypeOf(ident)->Is<type::U32>());
dan sinclair92bb5572020-06-08 23:48:07 +00002181}
2182
dan sinclairb4fee2f2020-09-22 19:42:13 +00002183TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Float) {
2184 auto param = GetParam();
2185
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002186 auto* ident = Expr(param.name);
2187 auto* call = Call(ident, 1.0f, 1.0f);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002188
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002189 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00002190 ASSERT_NE(TypeOf(ident), nullptr);
2191 EXPECT_TRUE(TypeOf(ident)->Is<type::F32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00002192}
2193
2194TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Signed) {
dan sinclair92bb5572020-06-08 23:48:07 +00002195 auto param = GetParam();
2196
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002197 auto* ident = Expr(param.name);
2198 auto* call = Call(ident, vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3));
dan sinclair92bb5572020-06-08 23:48:07 +00002199
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002200 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00002201 ASSERT_NE(TypeOf(ident), nullptr);
2202 EXPECT_TRUE(TypeOf(ident)->is_signed_integer_vector());
2203 EXPECT_EQ(TypeOf(ident)->As<type::Vector>()->size(), 3u);
dan sinclair92bb5572020-06-08 23:48:07 +00002204}
2205
dan sinclairb4fee2f2020-09-22 19:42:13 +00002206TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Unsigned) {
dan sinclair92bb5572020-06-08 23:48:07 +00002207 auto param = GetParam();
2208
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002209 auto* ident = Expr(param.name);
2210 auto* call = Call(ident, vec3<u32>(1u, 1u, 3u), vec3<u32>(1u, 1u, 3u));
dan sinclair92bb5572020-06-08 23:48:07 +00002211
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002212 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00002213 ASSERT_NE(TypeOf(ident), nullptr);
2214 EXPECT_TRUE(TypeOf(ident)->is_unsigned_integer_vector());
2215 EXPECT_EQ(TypeOf(ident)->As<type::Vector>()->size(), 3u);
dan sinclair92bb5572020-06-08 23:48:07 +00002216}
2217
dan sinclairb4fee2f2020-09-22 19:42:13 +00002218TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Float) {
dan sinclair92bb5572020-06-08 23:48:07 +00002219 auto param = GetParam();
2220
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002221 auto* ident = Expr(param.name);
2222 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 +00002223
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002224 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00002225 ASSERT_NE(TypeOf(ident), nullptr);
2226 EXPECT_TRUE(TypeOf(ident)->is_float_vector());
2227 EXPECT_EQ(TypeOf(ident)->As<type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002228}
2229
dan sinclairb4fee2f2020-09-22 19:42:13 +00002230TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_NoParams) {
dan sinclair92bb5572020-06-08 23:48:07 +00002231 auto param = GetParam();
2232
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002233 auto* call = Call(param.name);
dan sinclairb4fee2f2020-09-22 19:42:13 +00002234
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002235 EXPECT_FALSE(td()->DetermineResultType(call));
dan sinclair92bb5572020-06-08 23:48:07 +00002236 EXPECT_EQ(td()->error(),
Alan Bakere809fb32021-02-01 15:33:13 +00002237 "missing parameter 0 required for type determination in builtin " +
2238 std::string(param.name));
dan sinclair92bb5572020-06-08 23:48:07 +00002239}
2240
dan sinclairb4fee2f2020-09-22 19:42:13 +00002241INSTANTIATE_TEST_SUITE_P(
2242 TypeDeterminerTest,
2243 ImportData_FloatOrInt_TwoParamTest,
2244 testing::Values(IntrinsicData{"min", ast::Intrinsic::kMin},
2245 IntrinsicData{"max", ast::Intrinsic::kMax}));
dan sinclair92bb5572020-06-08 23:48:07 +00002246
dan sinclair3238eaa2020-06-17 20:22:08 +00002247TEST_F(TypeDeterminerTest, ImportData_GLSL_Determinant) {
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002248 auto* var = Var("var", ast::StorageClass::kFunction, ty.mat3x3<f32>());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00002249 AST().AddGlobalVariable(var);
dan sinclair3819c262020-06-17 18:39:17 +00002250
dan sinclair3819c262020-06-17 18:39:17 +00002251 ASSERT_TRUE(td()->Determine()) << td()->error();
2252
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002253 auto* ident = Expr("determinant");
dan sinclair3819c262020-06-17 18:39:17 +00002254
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002255 auto* call = Call(ident, "var");
Ben Clayton4bfe4612020-11-16 16:41:47 +00002256
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002257 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton33352542021-01-29 16:43:41 +00002258 ASSERT_NE(TypeOf(ident), nullptr);
2259 EXPECT_TRUE(TypeOf(ident)->Is<type::F32>());
dan sinclair3819c262020-06-17 18:39:17 +00002260}
2261
dan sinclairb4fee2f2020-09-22 19:42:13 +00002262using ImportData_Matrix_OneParam_Test =
2263 TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair3819c262020-06-17 18:39:17 +00002264
dan sinclair3238eaa2020-06-17 20:22:08 +00002265TEST_P(ImportData_Matrix_OneParam_Test, NoParams) {
2266 auto param = GetParam();
2267
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002268 auto* call = Call(param.name);
dan sinclair3819c262020-06-17 18:39:17 +00002269
Alan Bakere809fb32021-02-01 15:33:13 +00002270 EXPECT_TRUE(td()->DetermineResultType(call)) << td()->error();
2271 EXPECT_TRUE(TypeOf(call)->Is<type::F32>());
dan sinclair3819c262020-06-17 18:39:17 +00002272}
2273
dan sinclaire9598d62020-06-18 18:03:00 +00002274INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00002275 ImportData_Matrix_OneParam_Test,
2276 testing::Values(IntrinsicData{
2277 "determinant", ast::Intrinsic::kDeterminant}));
dan sinclaire9598d62020-06-18 18:03:00 +00002278
dan sinclair05926432020-09-21 17:51:31 +00002279TEST_F(TypeDeterminerTest, Function_EntryPoints_StageDecoration) {
dan sinclair05926432020-09-21 17:51:31 +00002280 // fn b() {}
2281 // fn c() { b(); }
2282 // fn a() { c(); }
2283 // fn ep_1() { a(); b(); }
2284 // fn ep_2() { c();}
2285 //
2286 // c -> {ep_1, ep_2}
2287 // a -> {ep_1}
2288 // b -> {ep_1, ep_2}
2289 // ep_1 -> {}
2290 // ep_2 -> {}
2291
2292 ast::VariableList params;
Ben Clayton8d391f72021-01-26 16:57:10 +00002293 auto* func_b = Func("b", params, ty.f32(), ast::StatementList{},
dan sinclair181d8ba2020-12-16 15:15:40 +00002294 ast::FunctionDecorationList{});
dan sinclaira41132f2020-12-11 18:24:53 +00002295 auto* func_c =
Ben Clayton8d391f72021-01-26 16:57:10 +00002296 Func("c", params, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +00002297 ast::StatementList{
2298 create<ast::AssignmentStatement>(Expr("second"), Call("b")),
2299 },
2300 ast::FunctionDecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00002301
dan sinclaira41132f2020-12-11 18:24:53 +00002302 auto* func_a =
Ben Clayton8d391f72021-01-26 16:57:10 +00002303 Func("a", params, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +00002304 ast::StatementList{
2305 create<ast::AssignmentStatement>(Expr("first"), Call("c")),
2306 },
2307 ast::FunctionDecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00002308
dan sinclair181d8ba2020-12-16 15:15:40 +00002309 auto* ep_1 =
Ben Clayton8d391f72021-01-26 16:57:10 +00002310 Func("ep_1", params, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +00002311 ast::StatementList{
2312 create<ast::AssignmentStatement>(Expr("call_a"), Call("a")),
2313 create<ast::AssignmentStatement>(Expr("call_b"), Call("b")),
2314 },
2315 ast::FunctionDecorationList{
2316 create<ast::StageDecoration>(ast::PipelineStage::kVertex),
2317 });
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002318
dan sinclair181d8ba2020-12-16 15:15:40 +00002319 auto* ep_2 =
Ben Clayton8d391f72021-01-26 16:57:10 +00002320 Func("ep_2", params, ty.f32(),
dan sinclair181d8ba2020-12-16 15:15:40 +00002321 ast::StatementList{
2322 create<ast::AssignmentStatement>(Expr("call_c"), Call("c")),
2323 },
2324 ast::FunctionDecorationList{
2325 create<ast::StageDecoration>(ast::PipelineStage::kVertex),
2326 });
dan sinclair05926432020-09-21 17:51:31 +00002327
Ben Clayton1f7e18b2021-01-26 16:57:10 +00002328 AST().Functions().Add(func_b);
2329 AST().Functions().Add(func_c);
2330 AST().Functions().Add(func_a);
2331 AST().Functions().Add(ep_1);
2332 AST().Functions().Add(ep_2);
dan sinclair05926432020-09-21 17:51:31 +00002333
Ben Clayton1f7e18b2021-01-26 16:57:10 +00002334 AST().AddGlobalVariable(Var("first", ast::StorageClass::kPrivate, ty.f32()));
2335 AST().AddGlobalVariable(Var("second", ast::StorageClass::kPrivate, ty.f32()));
2336 AST().AddGlobalVariable(Var("call_a", ast::StorageClass::kPrivate, ty.f32()));
2337 AST().AddGlobalVariable(Var("call_b", ast::StorageClass::kPrivate, ty.f32()));
2338 AST().AddGlobalVariable(Var("call_c", ast::StorageClass::kPrivate, ty.f32()));
dan sinclairff267ca2020-10-14 18:26:31 +00002339
dan sinclair05926432020-09-21 17:51:31 +00002340 // Register the functions and calculate the callers
2341 ASSERT_TRUE(td()->Determine()) << td()->error();
2342
Ben Clayton4bfe4612020-11-16 16:41:47 +00002343 const auto& b_eps = func_b->ancestor_entry_points();
dan sinclair05926432020-09-21 17:51:31 +00002344 ASSERT_EQ(2u, b_eps.size());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00002345 EXPECT_EQ(Symbols().Register("ep_1"), b_eps[0]);
2346 EXPECT_EQ(Symbols().Register("ep_2"), b_eps[1]);
dan sinclair05926432020-09-21 17:51:31 +00002347
Ben Clayton4bfe4612020-11-16 16:41:47 +00002348 const auto& a_eps = func_a->ancestor_entry_points();
dan sinclair05926432020-09-21 17:51:31 +00002349 ASSERT_EQ(1u, a_eps.size());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00002350 EXPECT_EQ(Symbols().Register("ep_1"), a_eps[0]);
dan sinclair05926432020-09-21 17:51:31 +00002351
Ben Clayton4bfe4612020-11-16 16:41:47 +00002352 const auto& c_eps = func_c->ancestor_entry_points();
dan sinclair05926432020-09-21 17:51:31 +00002353 ASSERT_EQ(2u, c_eps.size());
Ben Clayton1f7e18b2021-01-26 16:57:10 +00002354 EXPECT_EQ(Symbols().Register("ep_1"), c_eps[0]);
2355 EXPECT_EQ(Symbols().Register("ep_2"), c_eps[1]);
dan sinclair05926432020-09-21 17:51:31 +00002356
Ben Clayton4bfe4612020-11-16 16:41:47 +00002357 EXPECT_TRUE(ep_1->ancestor_entry_points().empty());
2358 EXPECT_TRUE(ep_2->ancestor_entry_points().empty());
dan sinclair05926432020-09-21 17:51:31 +00002359}
2360
Ben Clayton3ea3c992020-11-18 21:19:22 +00002361using TypeDeterminerTextureIntrinsicTest =
2362 TypeDeterminerTestWithParam<ast::intrinsic::test::TextureOverloadCase>;
2363
2364INSTANTIATE_TEST_SUITE_P(
2365 TypeDeterminerTest,
2366 TypeDeterminerTextureIntrinsicTest,
2367 testing::ValuesIn(ast::intrinsic::test::TextureOverloadCase::ValidCases()));
2368
2369std::string to_str(const std::string& function,
2370 const ast::intrinsic::TextureSignature* sig) {
2371 struct Parameter {
2372 size_t idx;
2373 std::string name;
2374 };
2375 std::vector<Parameter> params;
2376 auto maybe_add_param = [&params](size_t idx, const char* name) {
2377 if (idx != ast::intrinsic::TextureSignature::Parameters::kNotUsed) {
2378 params.emplace_back(Parameter{idx, name});
2379 }
2380 };
2381 maybe_add_param(sig->params.idx.array_index, "array_index");
2382 maybe_add_param(sig->params.idx.bias, "bias");
2383 maybe_add_param(sig->params.idx.coords, "coords");
2384 maybe_add_param(sig->params.idx.depth_ref, "depth_ref");
2385 maybe_add_param(sig->params.idx.ddx, "ddx");
2386 maybe_add_param(sig->params.idx.ddy, "ddy");
2387 maybe_add_param(sig->params.idx.level, "level");
2388 maybe_add_param(sig->params.idx.offset, "offset");
2389 maybe_add_param(sig->params.idx.sampler, "sampler");
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002390 maybe_add_param(sig->params.idx.sample_index, "sample_index");
Ben Clayton3ea3c992020-11-18 21:19:22 +00002391 maybe_add_param(sig->params.idx.texture, "texture");
Ben Clayton591268d2020-12-10 18:39:41 +00002392 maybe_add_param(sig->params.idx.value, "value");
Ben Clayton3ea3c992020-11-18 21:19:22 +00002393 std::sort(
2394 params.begin(), params.end(),
2395 [](const Parameter& a, const Parameter& b) { return a.idx < b.idx; });
2396
2397 std::stringstream out;
2398 out << function << "(";
2399 bool first = true;
2400 for (auto& param : params) {
2401 if (!first) {
2402 out << ", ";
2403 }
2404 out << param.name;
2405 first = false;
2406 }
2407 out << ")";
2408 return out.str();
2409}
2410
2411const char* expected_texture_overload(
2412 ast::intrinsic::test::ValidTextureOverload overload) {
2413 using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
2414 switch (overload) {
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002415 case ValidTextureOverload::kDimensions1d:
2416 case ValidTextureOverload::kDimensions1dArray:
2417 case ValidTextureOverload::kDimensions2d:
2418 case ValidTextureOverload::kDimensions2dArray:
2419 case ValidTextureOverload::kDimensions3d:
2420 case ValidTextureOverload::kDimensionsCube:
2421 case ValidTextureOverload::kDimensionsCubeArray:
Ben Clayton6e5b5ec2021-01-14 18:09:07 +00002422 case ValidTextureOverload::kDimensionsMultisampled2d:
2423 case ValidTextureOverload::kDimensionsMultisampled2dArray:
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002424 case ValidTextureOverload::kDimensionsDepth2d:
2425 case ValidTextureOverload::kDimensionsDepth2dArray:
2426 case ValidTextureOverload::kDimensionsDepthCube:
2427 case ValidTextureOverload::kDimensionsDepthCubeArray:
2428 case ValidTextureOverload::kDimensionsStorageRO1d:
2429 case ValidTextureOverload::kDimensionsStorageRO1dArray:
2430 case ValidTextureOverload::kDimensionsStorageRO2d:
2431 case ValidTextureOverload::kDimensionsStorageRO2dArray:
2432 case ValidTextureOverload::kDimensionsStorageRO3d:
2433 case ValidTextureOverload::kDimensionsStorageWO1d:
2434 case ValidTextureOverload::kDimensionsStorageWO1dArray:
2435 case ValidTextureOverload::kDimensionsStorageWO2d:
2436 case ValidTextureOverload::kDimensionsStorageWO2dArray:
2437 case ValidTextureOverload::kDimensionsStorageWO3d:
2438 return R"(textureDimensions(texture))";
Ben Claytonc21f1f92021-01-14 16:50:07 +00002439 case ValidTextureOverload::kNumLayers1dArray:
2440 case ValidTextureOverload::kNumLayers2dArray:
2441 case ValidTextureOverload::kNumLayersCubeArray:
Ben Clayton6e5b5ec2021-01-14 18:09:07 +00002442 case ValidTextureOverload::kNumLayersMultisampled2dArray:
Ben Claytonc21f1f92021-01-14 16:50:07 +00002443 case ValidTextureOverload::kNumLayersDepth2dArray:
2444 case ValidTextureOverload::kNumLayersDepthCubeArray:
2445 case ValidTextureOverload::kNumLayersStorageWO1dArray:
2446 case ValidTextureOverload::kNumLayersStorageWO2dArray:
2447 return R"(textureNumLayers(texture))";
Ben Claytond9713202021-01-14 18:06:57 +00002448 case ValidTextureOverload::kNumLevels2d:
2449 case ValidTextureOverload::kNumLevels2dArray:
2450 case ValidTextureOverload::kNumLevels3d:
2451 case ValidTextureOverload::kNumLevelsCube:
2452 case ValidTextureOverload::kNumLevelsCubeArray:
2453 case ValidTextureOverload::kNumLevelsDepth2d:
2454 case ValidTextureOverload::kNumLevelsDepth2dArray:
2455 case ValidTextureOverload::kNumLevelsDepthCube:
2456 case ValidTextureOverload::kNumLevelsDepthCubeArray:
2457 return R"(textureNumLevels(texture))";
Ben Clayton0a68b362021-01-14 18:11:17 +00002458 case ValidTextureOverload::kNumSamplesMultisampled2d:
2459 case ValidTextureOverload::kNumSamplesMultisampled2dArray:
2460 return R"(textureNumSamples(texture))";
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002461 case ValidTextureOverload::kDimensions2dLevel:
2462 case ValidTextureOverload::kDimensions2dArrayLevel:
2463 case ValidTextureOverload::kDimensions3dLevel:
2464 case ValidTextureOverload::kDimensionsCubeLevel:
2465 case ValidTextureOverload::kDimensionsCubeArrayLevel:
2466 case ValidTextureOverload::kDimensionsDepth2dLevel:
2467 case ValidTextureOverload::kDimensionsDepth2dArrayLevel:
2468 case ValidTextureOverload::kDimensionsDepthCubeLevel:
2469 case ValidTextureOverload::kDimensionsDepthCubeArrayLevel:
2470 return R"(textureDimensions(texture, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002471 case ValidTextureOverload::kSample1dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002472 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002473 case ValidTextureOverload::kSample1dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002474 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002475 case ValidTextureOverload::kSample2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002476 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002477 case ValidTextureOverload::kSample2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002478 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002479 case ValidTextureOverload::kSample2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002480 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002481 case ValidTextureOverload::kSample2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002482 return R"(textureSample(texture, sampler, coords, array_index, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002483 case ValidTextureOverload::kSample3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002484 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002485 case ValidTextureOverload::kSample3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002486 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002487 case ValidTextureOverload::kSampleCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002488 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002489 case ValidTextureOverload::kSampleCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002490 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002491 case ValidTextureOverload::kSampleDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002492 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002493 case ValidTextureOverload::kSampleDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002494 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002495 case ValidTextureOverload::kSampleDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002496 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002497 case ValidTextureOverload::kSampleDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002498 return R"(textureSample(texture, sampler, coords, array_index, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002499 case ValidTextureOverload::kSampleDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002500 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002501 case ValidTextureOverload::kSampleDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002502 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002503 case ValidTextureOverload::kSampleBias2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002504 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002505 case ValidTextureOverload::kSampleBias2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002506 return R"(textureSampleBias(texture, sampler, coords, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002507 case ValidTextureOverload::kSampleBias2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002508 return R"(textureSampleBias(texture, sampler, coords, array_index, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002509 case ValidTextureOverload::kSampleBias2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002510 return R"(textureSampleBias(texture, sampler, coords, array_index, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002511 case ValidTextureOverload::kSampleBias3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002512 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002513 case ValidTextureOverload::kSampleBias3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002514 return R"(textureSampleBias(texture, sampler, coords, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002515 case ValidTextureOverload::kSampleBiasCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002516 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002517 case ValidTextureOverload::kSampleBiasCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002518 return R"(textureSampleBias(texture, sampler, coords, array_index, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002519 case ValidTextureOverload::kSampleLevel2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002520 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002521 case ValidTextureOverload::kSampleLevel2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002522 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002523 case ValidTextureOverload::kSampleLevel2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002524 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002525 case ValidTextureOverload::kSampleLevel2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002526 return R"(textureSampleLevel(texture, sampler, coords, array_index, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002527 case ValidTextureOverload::kSampleLevel3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002528 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002529 case ValidTextureOverload::kSampleLevel3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002530 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002531 case ValidTextureOverload::kSampleLevelCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002532 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002533 case ValidTextureOverload::kSampleLevelCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002534 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002535 case ValidTextureOverload::kSampleLevelDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002536 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002537 case ValidTextureOverload::kSampleLevelDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002538 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002539 case ValidTextureOverload::kSampleLevelDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002540 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002541 case ValidTextureOverload::kSampleLevelDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002542 return R"(textureSampleLevel(texture, sampler, coords, array_index, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002543 case ValidTextureOverload::kSampleLevelDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002544 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002545 case ValidTextureOverload::kSampleLevelDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002546 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002547 case ValidTextureOverload::kSampleGrad2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002548 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002549 case ValidTextureOverload::kSampleGrad2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002550 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002551 case ValidTextureOverload::kSampleGrad2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002552 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002553 case ValidTextureOverload::kSampleGrad2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002554 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002555 case ValidTextureOverload::kSampleGrad3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002556 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002557 case ValidTextureOverload::kSampleGrad3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002558 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002559 case ValidTextureOverload::kSampleGradCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002560 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002561 case ValidTextureOverload::kSampleGradCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002562 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy))";
Ben Clayton57166262021-01-13 16:36:51 +00002563 case ValidTextureOverload::kSampleCompareDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002564 return R"(textureSampleCompare(texture, sampler, coords, depth_ref))";
Ben Clayton57166262021-01-13 16:36:51 +00002565 case ValidTextureOverload::kSampleCompareDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002566 return R"(textureSampleCompare(texture, sampler, coords, depth_ref, offset))";
Ben Clayton57166262021-01-13 16:36:51 +00002567 case ValidTextureOverload::kSampleCompareDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002568 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref))";
Ben Clayton57166262021-01-13 16:36:51 +00002569 case ValidTextureOverload::kSampleCompareDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002570 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref, offset))";
Ben Clayton57166262021-01-13 16:36:51 +00002571 case ValidTextureOverload::kSampleCompareDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002572 return R"(textureSampleCompare(texture, sampler, coords, depth_ref))";
Ben Clayton57166262021-01-13 16:36:51 +00002573 case ValidTextureOverload::kSampleCompareDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002574 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref))";
2575 case ValidTextureOverload::kLoad1dF32:
2576 return R"(textureLoad(texture, coords))";
2577 case ValidTextureOverload::kLoad1dU32:
2578 return R"(textureLoad(texture, coords))";
2579 case ValidTextureOverload::kLoad1dI32:
2580 return R"(textureLoad(texture, coords))";
2581 case ValidTextureOverload::kLoad1dArrayF32:
2582 return R"(textureLoad(texture, coords, array_index))";
2583 case ValidTextureOverload::kLoad1dArrayU32:
2584 return R"(textureLoad(texture, coords, array_index))";
2585 case ValidTextureOverload::kLoad1dArrayI32:
2586 return R"(textureLoad(texture, coords, array_index))";
2587 case ValidTextureOverload::kLoad2dF32:
2588 return R"(textureLoad(texture, coords))";
2589 case ValidTextureOverload::kLoad2dU32:
2590 return R"(textureLoad(texture, coords))";
2591 case ValidTextureOverload::kLoad2dI32:
2592 return R"(textureLoad(texture, coords))";
2593 case ValidTextureOverload::kLoad2dLevelF32:
2594 return R"(textureLoad(texture, coords, level))";
2595 case ValidTextureOverload::kLoad2dLevelU32:
2596 return R"(textureLoad(texture, coords, level))";
2597 case ValidTextureOverload::kLoad2dLevelI32:
2598 return R"(textureLoad(texture, coords, level))";
2599 case ValidTextureOverload::kLoad2dArrayF32:
2600 return R"(textureLoad(texture, coords, array_index))";
2601 case ValidTextureOverload::kLoad2dArrayU32:
2602 return R"(textureLoad(texture, coords, array_index))";
2603 case ValidTextureOverload::kLoad2dArrayI32:
2604 return R"(textureLoad(texture, coords, array_index))";
2605 case ValidTextureOverload::kLoad2dArrayLevelF32:
2606 return R"(textureLoad(texture, coords, array_index, level))";
2607 case ValidTextureOverload::kLoad2dArrayLevelU32:
2608 return R"(textureLoad(texture, coords, array_index, level))";
2609 case ValidTextureOverload::kLoad2dArrayLevelI32:
2610 return R"(textureLoad(texture, coords, array_index, level))";
2611 case ValidTextureOverload::kLoad3dF32:
2612 return R"(textureLoad(texture, coords))";
2613 case ValidTextureOverload::kLoad3dU32:
2614 return R"(textureLoad(texture, coords))";
2615 case ValidTextureOverload::kLoad3dI32:
2616 return R"(textureLoad(texture, coords))";
2617 case ValidTextureOverload::kLoad3dLevelF32:
2618 return R"(textureLoad(texture, coords, level))";
2619 case ValidTextureOverload::kLoad3dLevelU32:
2620 return R"(textureLoad(texture, coords, level))";
2621 case ValidTextureOverload::kLoad3dLevelI32:
2622 return R"(textureLoad(texture, coords, level))";
2623 case ValidTextureOverload::kLoadMultisampled2dF32:
2624 return R"(textureLoad(texture, coords, sample_index))";
2625 case ValidTextureOverload::kLoadMultisampled2dU32:
2626 return R"(textureLoad(texture, coords, sample_index))";
2627 case ValidTextureOverload::kLoadMultisampled2dI32:
2628 return R"(textureLoad(texture, coords, sample_index))";
2629 case ValidTextureOverload::kLoadMultisampled2dArrayF32:
2630 return R"(textureLoad(texture, coords, array_index, sample_index))";
2631 case ValidTextureOverload::kLoadMultisampled2dArrayU32:
2632 return R"(textureLoad(texture, coords, array_index, sample_index))";
2633 case ValidTextureOverload::kLoadMultisampled2dArrayI32:
2634 return R"(textureLoad(texture, coords, array_index, sample_index))";
2635 case ValidTextureOverload::kLoadDepth2dF32:
2636 return R"(textureLoad(texture, coords))";
2637 case ValidTextureOverload::kLoadDepth2dLevelF32:
2638 return R"(textureLoad(texture, coords, level))";
2639 case ValidTextureOverload::kLoadDepth2dArrayF32:
2640 return R"(textureLoad(texture, coords, array_index))";
2641 case ValidTextureOverload::kLoadDepth2dArrayLevelF32:
2642 return R"(textureLoad(texture, coords, array_index, level))";
2643 case ValidTextureOverload::kLoadStorageRO1dRgba32float:
2644 return R"(textureLoad(texture, coords))";
2645 case ValidTextureOverload::kLoadStorageRO1dArrayRgba32float:
2646 return R"(textureLoad(texture, coords, array_index))";
2647 case ValidTextureOverload::kLoadStorageRO2dRgba8unorm:
2648 case ValidTextureOverload::kLoadStorageRO2dRgba8snorm:
2649 case ValidTextureOverload::kLoadStorageRO2dRgba8uint:
2650 case ValidTextureOverload::kLoadStorageRO2dRgba8sint:
2651 case ValidTextureOverload::kLoadStorageRO2dRgba16uint:
2652 case ValidTextureOverload::kLoadStorageRO2dRgba16sint:
2653 case ValidTextureOverload::kLoadStorageRO2dRgba16float:
2654 case ValidTextureOverload::kLoadStorageRO2dR32uint:
2655 case ValidTextureOverload::kLoadStorageRO2dR32sint:
2656 case ValidTextureOverload::kLoadStorageRO2dR32float:
2657 case ValidTextureOverload::kLoadStorageRO2dRg32uint:
2658 case ValidTextureOverload::kLoadStorageRO2dRg32sint:
2659 case ValidTextureOverload::kLoadStorageRO2dRg32float:
2660 case ValidTextureOverload::kLoadStorageRO2dRgba32uint:
2661 case ValidTextureOverload::kLoadStorageRO2dRgba32sint:
2662 case ValidTextureOverload::kLoadStorageRO2dRgba32float:
2663 return R"(textureLoad(texture, coords))";
2664 case ValidTextureOverload::kLoadStorageRO2dArrayRgba32float:
2665 return R"(textureLoad(texture, coords, array_index))";
2666 case ValidTextureOverload::kLoadStorageRO3dRgba32float:
2667 return R"(textureLoad(texture, coords))";
Ben Clayton591268d2020-12-10 18:39:41 +00002668 case ValidTextureOverload::kStoreWO1dRgba32float:
2669 return R"(textureStore(texture, coords, value))";
2670 case ValidTextureOverload::kStoreWO1dArrayRgba32float:
2671 return R"(textureStore(texture, coords, array_index, value))";
2672 case ValidTextureOverload::kStoreWO2dRgba32float:
2673 return R"(textureStore(texture, coords, value))";
2674 case ValidTextureOverload::kStoreWO2dArrayRgba32float:
2675 return R"(textureStore(texture, coords, array_index, value))";
2676 case ValidTextureOverload::kStoreWO3dRgba32float:
2677 return R"(textureStore(texture, coords, value))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00002678 }
2679 return "<unmatched texture overload>";
2680}
2681
2682TEST_P(TypeDeterminerTextureIntrinsicTest, Call) {
2683 auto param = GetParam();
2684
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002685 param.buildTextureVariable(this);
2686 param.buildSamplerVariable(this);
Ben Clayton3ea3c992020-11-18 21:19:22 +00002687
2688 auto* ident = Expr(param.function);
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002689 auto* call = Call(ident, param.args(this));
Ben Clayton3ea3c992020-11-18 21:19:22 +00002690
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002691 ASSERT_TRUE(td()->Determine()) << td()->error();
Ben Clayton7eaf4b52020-12-14 22:08:27 +00002692 ASSERT_TRUE(td()->DetermineResultType(call)) << td()->error();
Ben Clayton3ea3c992020-11-18 21:19:22 +00002693
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002694 if (std::string(param.function) == "textureDimensions") {
2695 switch (param.texture_dimension) {
2696 default:
2697 FAIL() << "invalid texture dimensions: " << param.texture_dimension;
Ben Clayton207b5e22021-01-21 15:42:10 +00002698 case type::TextureDimension::k1d:
2699 case type::TextureDimension::k1dArray:
Ben Clayton33352542021-01-29 16:43:41 +00002700 EXPECT_EQ(TypeOf(call)->type_name(), ty.i32()->type_name());
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002701 break;
Ben Clayton207b5e22021-01-21 15:42:10 +00002702 case type::TextureDimension::k2d:
2703 case type::TextureDimension::k2dArray:
Ben Clayton33352542021-01-29 16:43:41 +00002704 EXPECT_EQ(TypeOf(call)->type_name(), ty.vec2<i32>()->type_name());
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002705 break;
Ben Clayton207b5e22021-01-21 15:42:10 +00002706 case type::TextureDimension::k3d:
2707 case type::TextureDimension::kCube:
2708 case type::TextureDimension::kCubeArray:
Ben Clayton33352542021-01-29 16:43:41 +00002709 EXPECT_EQ(TypeOf(call)->type_name(), ty.vec3<i32>()->type_name());
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002710 break;
2711 }
Ben Claytonc21f1f92021-01-14 16:50:07 +00002712 } else if (std::string(param.function) == "textureNumLayers") {
Ben Clayton33352542021-01-29 16:43:41 +00002713 EXPECT_EQ(TypeOf(call), ty.i32());
Ben Claytond9713202021-01-14 18:06:57 +00002714 } else if (std::string(param.function) == "textureNumLevels") {
Ben Clayton33352542021-01-29 16:43:41 +00002715 EXPECT_EQ(TypeOf(call), ty.i32());
Ben Clayton0a68b362021-01-14 18:11:17 +00002716 } else if (std::string(param.function) == "textureNumSamples") {
Ben Clayton33352542021-01-29 16:43:41 +00002717 EXPECT_EQ(TypeOf(call), ty.i32());
Ben Clayton4a0b9f72021-01-11 21:07:32 +00002718 } else if (std::string(param.function) == "textureStore") {
Ben Clayton33352542021-01-29 16:43:41 +00002719 EXPECT_EQ(TypeOf(call), ty.void_());
Ben Clayton591268d2020-12-10 18:39:41 +00002720 } else {
2721 switch (param.texture_kind) {
2722 case ast::intrinsic::test::TextureKind::kRegular:
2723 case ast::intrinsic::test::TextureKind::kMultisampled:
2724 case ast::intrinsic::test::TextureKind::kStorage: {
2725 auto* datatype = param.resultVectorComponentType(this);
Ben Clayton33352542021-01-29 16:43:41 +00002726 ASSERT_TRUE(TypeOf(call)->Is<type::Vector>());
2727 EXPECT_EQ(TypeOf(call)->As<type::Vector>()->type(), datatype);
Ben Clayton591268d2020-12-10 18:39:41 +00002728 break;
2729 }
2730 case ast::intrinsic::test::TextureKind::kDepth: {
Ben Clayton33352542021-01-29 16:43:41 +00002731 EXPECT_EQ(TypeOf(call), ty.f32());
Ben Clayton591268d2020-12-10 18:39:41 +00002732 break;
2733 }
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002734 }
Ben Clayton3ea3c992020-11-18 21:19:22 +00002735 }
2736
2737 auto* sig = static_cast<const ast::intrinsic::TextureSignature*>(
2738 ident->intrinsic_signature());
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002739 ASSERT_NE(sig, nullptr);
Ben Clayton3ea3c992020-11-18 21:19:22 +00002740
Ben Clayton708dc2d2021-01-29 11:22:40 +00002741 auto got = ::tint::to_str(param.function, sig);
Ben Clayton3ea3c992020-11-18 21:19:22 +00002742 auto* expected = expected_texture_overload(param.overload);
Ben Clayton7f04e5c2020-12-09 15:57:00 +00002743 EXPECT_EQ(got, expected);
Ben Clayton3ea3c992020-11-18 21:19:22 +00002744}
2745
dan sinclairb7edc4c2020-04-07 12:46:30 +00002746} // namespace
2747} // namespace tint