blob: 36eb7004711c016155e7ffe2b852b4d80ea77925 [file] [log] [blame]
dan sinclairb7edc4c2020-04-07 12:46:30 +00001// Copyright 2020 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "src/type_determiner.h"
16
Ben Clayton3ea3c992020-11-18 21:19:22 +000017#include <algorithm>
dan sinclairb7edc4c2020-04-07 12:46:30 +000018#include <memory>
19#include <utility>
dan sinclairfd5d4ca2020-04-20 15:46:18 +000020#include <vector>
dan sinclairb7edc4c2020-04-07 12:46:30 +000021
22#include "gtest/gtest.h"
dan sinclair973bd6a2020-04-07 12:57:42 +000023#include "src/ast/array_accessor_expression.h"
dan sinclair6c498fc2020-04-07 12:47:23 +000024#include "src/ast/assignment_statement.h"
dan sinclair1c9b4862020-04-07 19:27:41 +000025#include "src/ast/binary_expression.h"
dan sinclaira7d498e2020-09-22 22:07:13 +000026#include "src/ast/bitcast_expression.h"
dan sinclair0975dd52020-07-27 15:25:00 +000027#include "src/ast/block_statement.h"
dan sinclairb4fee2f2020-09-22 19:42:13 +000028#include "src/ast/bool_literal.h"
dan sinclairb7ea6e22020-04-07 12:54:10 +000029#include "src/ast/break_statement.h"
Ben Clayton3ea3c992020-11-18 21:19:22 +000030#include "src/ast/builder.h"
dan sinclair3ca87462020-04-07 16:41:10 +000031#include "src/ast/call_expression.h"
dan sinclair50080b72020-07-21 13:42:13 +000032#include "src/ast/call_statement.h"
dan sinclair6010b292020-04-07 12:54:20 +000033#include "src/ast/case_statement.h"
dan sinclairaec965e2020-04-07 12:54:29 +000034#include "src/ast/continue_statement.h"
dan sinclair0cf685f2020-04-07 12:54:37 +000035#include "src/ast/else_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000036#include "src/ast/float_literal.h"
dan sinclaircab0e732020-04-07 12:57:27 +000037#include "src/ast/identifier_expression.h"
dan sinclair91c44a52020-04-07 12:55:25 +000038#include "src/ast/if_statement.h"
Ben Clayton3ea3c992020-11-18 21:19:22 +000039#include "src/ast/intrinsic_texture_helper_test.h"
dan sinclairbc71eda2020-04-07 12:55:51 +000040#include "src/ast/loop_statement.h"
dan sinclair8ee1d222020-04-07 16:41:33 +000041#include "src/ast/member_accessor_expression.h"
dan sinclair05926432020-09-21 17:51:31 +000042#include "src/ast/pipeline_stage.h"
dan sinclairbf0fff82020-04-07 12:56:24 +000043#include "src/ast/return_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000044#include "src/ast/scalar_constructor_expression.h"
dan sinclairc6f29472020-06-02 20:11:44 +000045#include "src/ast/sint_literal.h"
dan sinclair05926432020-09-21 17:51:31 +000046#include "src/ast/stage_decoration.h"
dan sinclair8ee1d222020-04-07 16:41:33 +000047#include "src/ast/struct.h"
48#include "src/ast/struct_member.h"
dan sinclair18b32852020-04-07 12:56:45 +000049#include "src/ast/switch_statement.h"
dan sinclairb445a9b2020-04-24 00:40:45 +000050#include "src/ast/type/alias_type.h"
dan sinclair973bd6a2020-04-07 12:57:42 +000051#include "src/ast/type/array_type.h"
dan sinclair9b978022020-04-07 19:26:39 +000052#include "src/ast/type/bool_type.h"
Tomek Ponitka1a61fc42020-08-31 15:24:54 +000053#include "src/ast/type/depth_texture_type.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000054#include "src/ast/type/f32_type.h"
dan sinclair6c498fc2020-04-07 12:47:23 +000055#include "src/ast/type/i32_type.h"
dan sinclair973bd6a2020-04-07 12:57:42 +000056#include "src/ast/type/matrix_type.h"
Ben Clayton7f04e5c2020-12-09 15:57:00 +000057#include "src/ast/type/multisampled_texture_type.h"
dan sinclair8eddb782020-04-23 22:26:52 +000058#include "src/ast/type/pointer_type.h"
Tomek Ponitka1a61fc42020-08-31 15:24:54 +000059#include "src/ast/type/sampled_texture_type.h"
60#include "src/ast/type/sampler_type.h"
61#include "src/ast/type/storage_texture_type.h"
dan sinclair8ee1d222020-04-07 16:41:33 +000062#include "src/ast/type/struct_type.h"
Tomek Ponitka1a61fc42020-08-31 15:24:54 +000063#include "src/ast/type/texture_type.h"
dan sinclair92bb5572020-06-08 23:48:07 +000064#include "src/ast/type/u32_type.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000065#include "src/ast/type/vector_type.h"
66#include "src/ast/type_constructor_expression.h"
dan sinclair92bb5572020-06-08 23:48:07 +000067#include "src/ast/uint_literal.h"
dan sinclair327ed1b2020-04-07 19:27:21 +000068#include "src/ast/unary_op_expression.h"
dan sinclairca893e32020-04-07 12:57:12 +000069#include "src/ast/variable_decl_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000070
71namespace tint {
72namespace {
73
dan sinclair7456f422020-04-08 19:58:35 +000074class FakeStmt : public ast::Statement {
75 public:
Ben Clayton604bc722020-12-12 01:24:53 +000076 explicit FakeStmt(Source source) : ast::Statement(source) {}
Ben Claytoned2b9782020-12-01 18:04:17 +000077 FakeStmt* Clone(ast::CloneContext*) const override { return nullptr; }
dan sinclair7456f422020-04-08 19:58:35 +000078 bool IsValid() const override { return true; }
dan sinclair0975dd52020-07-27 15:25:00 +000079 void to_str(std::ostream& out, size_t) const override { out << "Fake"; }
dan sinclair7456f422020-04-08 19:58:35 +000080};
81
82class FakeExpr : public ast::Expression {
83 public:
Ben Clayton604bc722020-12-12 01:24:53 +000084 explicit FakeExpr(Source source) : ast::Expression(source) {}
Ben Claytoned2b9782020-12-01 18:04:17 +000085 FakeExpr* Clone(ast::CloneContext*) const override { return nullptr; }
dan sinclair7456f422020-04-08 19:58:35 +000086 bool IsValid() const override { return true; }
87 void to_str(std::ostream&, size_t) const override {}
88};
89
dan sinclair685cb022020-12-02 21:17:58 +000090class TypeDeterminerHelper : public ast::BuilderWithModule {
dan sinclairb7edc4c2020-04-07 12:46:30 +000091 public:
dan sinclair685cb022020-12-02 21:17:58 +000092 TypeDeterminerHelper() : td_(std::make_unique<TypeDeterminer>(mod)) {}
dan sinclairb7edc4c2020-04-07 12:46:30 +000093
94 TypeDeterminer* td() const { return td_.get(); }
Ben Clayton62625922020-11-13 22:09:38 +000095
dan sinclairb7edc4c2020-04-07 12:46:30 +000096 private:
Ben Clayton3ea3c992020-11-18 21:19:22 +000097 void OnVariableBuilt(ast::Variable* var) override {
98 td_->RegisterVariableForTesting(var);
99 }
100
dan sinclairb7edc4c2020-04-07 12:46:30 +0000101 std::unique_ptr<TypeDeterminer> td_;
102};
103
dan sinclaircd077b02020-04-20 14:19:04 +0000104class TypeDeterminerTest : public TypeDeterminerHelper, public testing::Test {};
105
106template <typename T>
107class TypeDeterminerTestWithParam : public TypeDeterminerHelper,
108 public testing::TestWithParam<T> {};
109
dan sinclair7456f422020-04-08 19:58:35 +0000110TEST_F(TypeDeterminerTest, Error_WithEmptySource) {
Ben Clayton604bc722020-12-12 01:24:53 +0000111 FakeStmt s(Source{});
dan sinclair7456f422020-04-08 19:58:35 +0000112
113 EXPECT_FALSE(td()->DetermineResultType(&s));
dan sinclair0975dd52020-07-27 15:25:00 +0000114 EXPECT_EQ(td()->error(),
115 "unknown statement type for type determination: Fake");
dan sinclair7456f422020-04-08 19:58:35 +0000116}
117
118TEST_F(TypeDeterminerTest, Stmt_Error_Unknown) {
Ben Clayton604bc722020-12-12 01:24:53 +0000119 FakeStmt s(Source{Source::Location{2, 30}});
dan sinclair7456f422020-04-08 19:58:35 +0000120
121 EXPECT_FALSE(td()->DetermineResultType(&s));
122 EXPECT_EQ(td()->error(),
dan sinclair0975dd52020-07-27 15:25:00 +0000123 "2:30: unknown statement type for type determination: Fake");
dan sinclair7456f422020-04-08 19:58:35 +0000124}
125
dan sinclair6c498fc2020-04-07 12:47:23 +0000126TEST_F(TypeDeterminerTest, Stmt_Assign) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000127 ast::type::F32 f32;
128 ast::type::I32 i32;
dan sinclair6c498fc2020-04-07 12:47:23 +0000129
Ben Claytonb053acf2020-11-16 16:31:07 +0000130 auto* lhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000131 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000132 auto* rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000133 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.3f));
dan sinclair6c498fc2020-04-07 12:47:23 +0000134
Ben Claytonbbefff62020-12-12 11:58:44 +0000135 ast::AssignmentStatement assign(Source{}, lhs, rhs);
dan sinclair6c498fc2020-04-07 12:47:23 +0000136
137 EXPECT_TRUE(td()->DetermineResultType(&assign));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000138 ASSERT_NE(lhs->result_type(), nullptr);
139 ASSERT_NE(rhs->result_type(), nullptr);
dan sinclair6c498fc2020-04-07 12:47:23 +0000140
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000141 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
142 EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32>());
dan sinclair6c498fc2020-04-07 12:47:23 +0000143}
144
dan sinclair6010b292020-04-07 12:54:20 +0000145TEST_F(TypeDeterminerTest, Stmt_Case) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000146 ast::type::I32 i32;
147 ast::type::F32 f32;
dan sinclair6010b292020-04-07 12:54:20 +0000148
Ben Claytonb053acf2020-11-16 16:31:07 +0000149 auto* lhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000150 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000151 auto* rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000152 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.3f));
dan sinclair6010b292020-04-07 12:54:20 +0000153
Ben Claytondb5ce652020-12-14 20:25:27 +0000154 auto* body = create<ast::BlockStatement>(
155 Source{}, ast::StatementList{
156 create<ast::AssignmentStatement>(Source{}, lhs, rhs),
157 });
dan sinclair1aadbd42020-06-01 16:56:46 +0000158 ast::CaseSelectorList lit;
Ben Clayton5ed161b2020-12-12 01:35:43 +0000159 lit.push_back(create<ast::SintLiteral>(Source{}, &i32, 3));
Ben Claytonbbefff62020-12-12 11:58:44 +0000160 ast::CaseStatement cse(Source{}, lit, body);
dan sinclair6010b292020-04-07 12:54:20 +0000161
162 EXPECT_TRUE(td()->DetermineResultType(&cse));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000163 ASSERT_NE(lhs->result_type(), nullptr);
164 ASSERT_NE(rhs->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000165 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
166 EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32>());
dan sinclair6010b292020-04-07 12:54:20 +0000167}
168
dan sinclair0975dd52020-07-27 15:25:00 +0000169TEST_F(TypeDeterminerTest, Stmt_Block) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000170 ast::type::I32 i32;
171 ast::type::F32 f32;
dan sinclair0975dd52020-07-27 15:25:00 +0000172
Ben Claytonb053acf2020-11-16 16:31:07 +0000173 auto* lhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000174 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000175 auto* rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000176 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.3f));
dan sinclair0975dd52020-07-27 15:25:00 +0000177
Ben Claytondb5ce652020-12-14 20:25:27 +0000178 ast::BlockStatement block(
179 Source{}, ast::StatementList{
180 create<ast::AssignmentStatement>(Source{}, lhs, rhs),
181 });
dan sinclair0975dd52020-07-27 15:25:00 +0000182
183 EXPECT_TRUE(td()->DetermineResultType(&block));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000184 ASSERT_NE(lhs->result_type(), nullptr);
185 ASSERT_NE(rhs->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000186 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
187 EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32>());
dan sinclair0975dd52020-07-27 15:25:00 +0000188}
189
dan sinclair0cf685f2020-04-07 12:54:37 +0000190TEST_F(TypeDeterminerTest, Stmt_Else) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000191 ast::type::I32 i32;
192 ast::type::F32 f32;
dan sinclair0cf685f2020-04-07 12:54:37 +0000193
Ben Claytonb053acf2020-11-16 16:31:07 +0000194 auto* lhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000195 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000196 auto* rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000197 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.3f));
dan sinclair0cf685f2020-04-07 12:54:37 +0000198
Ben Claytondb5ce652020-12-14 20:25:27 +0000199 auto* body = create<ast::BlockStatement>(
200 Source{}, ast::StatementList{
201 create<ast::AssignmentStatement>(Source{}, lhs, rhs),
202 });
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000203 ast::ElseStatement stmt(
Ben Claytonbbefff62020-12-12 11:58:44 +0000204 Source{},
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000205 create<ast::ScalarConstructorExpression>(
206 Source{}, create<ast::SintLiteral>(Source{}, &i32, 3)),
207 body);
dan sinclair0cf685f2020-04-07 12:54:37 +0000208
209 EXPECT_TRUE(td()->DetermineResultType(&stmt));
210 ASSERT_NE(stmt.condition()->result_type(), nullptr);
Ben Clayton4bfe4612020-11-16 16:41:47 +0000211 ASSERT_NE(lhs->result_type(), nullptr);
212 ASSERT_NE(rhs->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000213 EXPECT_TRUE(stmt.condition()->result_type()->Is<ast::type::I32>());
214 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
215 EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32>());
dan sinclair0cf685f2020-04-07 12:54:37 +0000216}
217
dan sinclair91c44a52020-04-07 12:55:25 +0000218TEST_F(TypeDeterminerTest, Stmt_If) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000219 ast::type::I32 i32;
220 ast::type::F32 f32;
dan sinclair91c44a52020-04-07 12:55:25 +0000221
Ben Claytonb053acf2020-11-16 16:31:07 +0000222 auto* else_lhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000223 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000224 auto* else_rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000225 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.3f));
dan sinclair91c44a52020-04-07 12:55:25 +0000226
Ben Claytondb5ce652020-12-14 20:25:27 +0000227 auto* else_body = create<ast::BlockStatement>(
228 Source{},
229 ast::StatementList{
230 create<ast::AssignmentStatement>(Source{}, else_lhs, else_rhs),
231 });
dan sinclair91c44a52020-04-07 12:55:25 +0000232
Ben Clayton5ed161b2020-12-12 01:35:43 +0000233 auto* else_stmt = create<ast::ElseStatement>(
Ben Claytonbbefff62020-12-12 11:58:44 +0000234 Source{},
Ben Clayton5ed161b2020-12-12 01:35:43 +0000235 create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000236 Source{}, create<ast::SintLiteral>(Source{}, &i32, 3)),
Ben Clayton5ed161b2020-12-12 01:35:43 +0000237 else_body);
dan sinclair91c44a52020-04-07 12:55:25 +0000238
Ben Claytonb053acf2020-11-16 16:31:07 +0000239 auto* lhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000240 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000241 auto* rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000242 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.3f));
dan sinclair91c44a52020-04-07 12:55:25 +0000243
Ben Claytondb5ce652020-12-14 20:25:27 +0000244 auto* body = create<ast::BlockStatement>(
245 Source{}, ast::StatementList{
246 create<ast::AssignmentStatement>(Source{}, lhs, rhs),
247 });
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000248 ast::IfStatement stmt(
249 Source{},
250 create<ast::ScalarConstructorExpression>(
251 Source{}, create<ast::SintLiteral>(Source{}, &i32, 3)),
252 body, ast::ElseStatementList{else_stmt});
dan sinclair91c44a52020-04-07 12:55:25 +0000253
254 EXPECT_TRUE(td()->DetermineResultType(&stmt));
255 ASSERT_NE(stmt.condition()->result_type(), nullptr);
Ben Clayton4bfe4612020-11-16 16:41:47 +0000256 ASSERT_NE(else_lhs->result_type(), nullptr);
257 ASSERT_NE(else_rhs->result_type(), nullptr);
258 ASSERT_NE(lhs->result_type(), nullptr);
259 ASSERT_NE(rhs->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000260 EXPECT_TRUE(stmt.condition()->result_type()->Is<ast::type::I32>());
261 EXPECT_TRUE(else_lhs->result_type()->Is<ast::type::I32>());
262 EXPECT_TRUE(else_rhs->result_type()->Is<ast::type::F32>());
263 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
264 EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32>());
dan sinclair91c44a52020-04-07 12:55:25 +0000265}
266
dan sinclairbc71eda2020-04-07 12:55:51 +0000267TEST_F(TypeDeterminerTest, Stmt_Loop) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000268 ast::type::I32 i32;
269 ast::type::F32 f32;
dan sinclairbc71eda2020-04-07 12:55:51 +0000270
Ben Claytonb053acf2020-11-16 16:31:07 +0000271 auto* body_lhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000272 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000273 auto* body_rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000274 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.3f));
dan sinclairbc71eda2020-04-07 12:55:51 +0000275
Ben Claytondb5ce652020-12-14 20:25:27 +0000276 auto* body = create<ast::BlockStatement>(
277 Source{},
278 ast::StatementList{
279 create<ast::AssignmentStatement>(Source{}, body_lhs, body_rhs),
280 });
Ben Claytonb053acf2020-11-16 16:31:07 +0000281 auto* continuing_lhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000282 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000283 auto* continuing_rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000284 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.3f));
dan sinclairbc71eda2020-04-07 12:55:51 +0000285
Ben Claytondb5ce652020-12-14 20:25:27 +0000286 auto* continuing = create<ast::BlockStatement>(
287 Source{}, ast::StatementList{
288 create<ast::AssignmentStatement>(Source{}, continuing_lhs,
289 continuing_rhs),
290 });
Ben Claytonbbefff62020-12-12 11:58:44 +0000291 ast::LoopStatement stmt(Source{}, body, continuing);
dan sinclairbc71eda2020-04-07 12:55:51 +0000292
293 EXPECT_TRUE(td()->DetermineResultType(&stmt));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000294 ASSERT_NE(body_lhs->result_type(), nullptr);
295 ASSERT_NE(body_rhs->result_type(), nullptr);
296 ASSERT_NE(continuing_lhs->result_type(), nullptr);
297 ASSERT_NE(continuing_rhs->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000298 EXPECT_TRUE(body_lhs->result_type()->Is<ast::type::I32>());
299 EXPECT_TRUE(body_rhs->result_type()->Is<ast::type::F32>());
300 EXPECT_TRUE(continuing_lhs->result_type()->Is<ast::type::I32>());
301 EXPECT_TRUE(continuing_rhs->result_type()->Is<ast::type::F32>());
dan sinclairbc71eda2020-04-07 12:55:51 +0000302}
303
dan sinclairbf0fff82020-04-07 12:56:24 +0000304TEST_F(TypeDeterminerTest, Stmt_Return) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000305 ast::type::I32 i32;
dan sinclairbf0fff82020-04-07 12:56:24 +0000306
Ben Claytonb053acf2020-11-16 16:31:07 +0000307 auto* cond = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000308 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2));
dan sinclairbf0fff82020-04-07 12:56:24 +0000309
Ben Claytond0dda252020-12-07 21:09:57 +0000310 ast::ReturnStatement ret(Source{}, cond);
dan sinclairbf0fff82020-04-07 12:56:24 +0000311
312 EXPECT_TRUE(td()->DetermineResultType(&ret));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000313 ASSERT_NE(cond->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000314 EXPECT_TRUE(cond->result_type()->Is<ast::type::I32>());
dan sinclairbf0fff82020-04-07 12:56:24 +0000315}
316
dan sinclair327ed1b2020-04-07 19:27:21 +0000317TEST_F(TypeDeterminerTest, Stmt_Return_WithoutValue) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000318 ast::type::I32 i32;
Ben Claytond0dda252020-12-07 21:09:57 +0000319 ast::ReturnStatement ret(Source{});
dan sinclair327ed1b2020-04-07 19:27:21 +0000320 EXPECT_TRUE(td()->DetermineResultType(&ret));
321}
322
dan sinclair18b32852020-04-07 12:56:45 +0000323TEST_F(TypeDeterminerTest, Stmt_Switch) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000324 ast::type::I32 i32;
325 ast::type::F32 f32;
dan sinclair18b32852020-04-07 12:56:45 +0000326
Ben Claytonb053acf2020-11-16 16:31:07 +0000327 auto* lhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000328 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000329 auto* rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000330 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.3f));
dan sinclair18b32852020-04-07 12:56:45 +0000331
Ben Claytondb5ce652020-12-14 20:25:27 +0000332 auto* body = create<ast::BlockStatement>(
333 Source{}, ast::StatementList{
334 create<ast::AssignmentStatement>(Source{}, lhs, rhs),
335 });
dan sinclair1aadbd42020-06-01 16:56:46 +0000336 ast::CaseSelectorList lit;
Ben Clayton5ed161b2020-12-12 01:35:43 +0000337 lit.push_back(create<ast::SintLiteral>(Source{}, &i32, 3));
dan sinclair1aadbd42020-06-01 16:56:46 +0000338
dan sinclair18b32852020-04-07 12:56:45 +0000339 ast::CaseStatementList cases;
Ben Claytonbbefff62020-12-12 11:58:44 +0000340 cases.push_back(create<ast::CaseStatement>(Source{}, lit, body));
dan sinclair18b32852020-04-07 12:56:45 +0000341
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000342 ast::SwitchStatement stmt(
Ben Claytonbbefff62020-12-12 11:58:44 +0000343 Source{},
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000344 create<ast::ScalarConstructorExpression>(
345 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2)),
346 cases);
dan sinclair18b32852020-04-07 12:56:45 +0000347
348 EXPECT_TRUE(td()->DetermineResultType(&stmt)) << td()->error();
349 ASSERT_NE(stmt.condition()->result_type(), nullptr);
Ben Clayton4bfe4612020-11-16 16:41:47 +0000350 ASSERT_NE(lhs->result_type(), nullptr);
351 ASSERT_NE(rhs->result_type(), nullptr);
dan sinclair18b32852020-04-07 12:56:45 +0000352
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000353 EXPECT_TRUE(stmt.condition()->result_type()->Is<ast::type::I32>());
354 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
355 EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32>());
dan sinclair18b32852020-04-07 12:56:45 +0000356}
357
dan sinclair50080b72020-07-21 13:42:13 +0000358TEST_F(TypeDeterminerTest, Stmt_Call) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000359 ast::type::F32 f32;
dan sinclair50080b72020-07-21 13:42:13 +0000360
361 ast::VariableList params;
dan sinclaira41132f2020-12-11 18:24:53 +0000362 auto* func = create<ast::Function>(
363 Source{}, mod->RegisterSymbol("my_func"), "my_func", params, &f32,
Ben Claytondb5ce652020-12-14 20:25:27 +0000364 create<ast::BlockStatement>(Source{}, ast::StatementList{}),
365 ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000366 mod->AddFunction(func);
dan sinclair50080b72020-07-21 13:42:13 +0000367
368 // Register the function
369 EXPECT_TRUE(td()->Determine());
370
371 ast::ExpressionList call_params;
Ben Claytonb053acf2020-11-16 16:31:07 +0000372 auto* expr = create<ast::CallExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000373 Source{},
374 create<ast::IdentifierExpression>(
375 Source{}, mod->RegisterSymbol("my_func"), "my_func"),
dan sinclair6b59bf42020-12-11 19:16:13 +0000376 call_params);
dan sinclair50080b72020-07-21 13:42:13 +0000377
Ben Claytonbbefff62020-12-12 11:58:44 +0000378 ast::CallStatement call(Source{}, expr);
dan sinclair50080b72020-07-21 13:42:13 +0000379 EXPECT_TRUE(td()->DetermineResultType(&call));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000380 ASSERT_NE(expr->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000381 EXPECT_TRUE(expr->result_type()->Is<ast::type::F32>());
dan sinclair50080b72020-07-21 13:42:13 +0000382}
383
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000384TEST_F(TypeDeterminerTest, Stmt_Call_undeclared) {
385 // fn main() -> void {func(); return; }
386 // fn func() -> void { return; }
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000387 ast::type::F32 f32;
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000388 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +0000389 auto* call_expr = create<ast::CallExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000390 Source{},
dan sinclair6b59bf42020-12-11 19:16:13 +0000391 create<ast::IdentifierExpression>(Source{Source::Location{12, 34}},
392 mod->RegisterSymbol("func"), "func"),
393 call_params);
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000394 ast::VariableList params0;
Ben Claytondb5ce652020-12-14 20:25:27 +0000395 auto* main_body = create<ast::BlockStatement>(
396 Source{}, ast::StatementList{
397 create<ast::CallStatement>(Source{}, call_expr),
398 create<ast::ReturnStatement>(Source{}),
399 });
400
dan sinclaira41132f2020-12-11 18:24:53 +0000401 auto* func_main = create<ast::Function>(Source{}, mod->RegisterSymbol("main"),
402 "main", params0, &f32, main_body,
403 ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000404 mod->AddFunction(func_main);
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000405
Ben Claytondb5ce652020-12-14 20:25:27 +0000406 auto* body = create<ast::BlockStatement>(
407 Source{}, ast::StatementList{
408 create<ast::ReturnStatement>(Source{}),
409 });
dan sinclaira41132f2020-12-11 18:24:53 +0000410 auto* func =
411 create<ast::Function>(Source{}, mod->RegisterSymbol("func"), "func",
412 params0, &f32, body, ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000413 mod->AddFunction(func);
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000414
415 EXPECT_FALSE(td()->Determine()) << td()->error();
416 EXPECT_EQ(td()->error(),
dan sinclairff267ca2020-10-14 18:26:31 +0000417 "12:34: v-0006: identifier must be declared before use: func");
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000418}
419
dan sinclairca893e32020-04-07 12:57:12 +0000420TEST_F(TypeDeterminerTest, Stmt_VariableDecl) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000421 ast::type::I32 i32;
Ben Claytona80511e2020-12-11 13:07:02 +0000422 auto* var = create<ast::Variable>(
423 Source{}, // source
424 "my_var", // name
425 ast::StorageClass::kNone, // storage_class
426 &i32, // type
427 false, // is_const
428 create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000429 Source{},
Ben Clayton5ed161b2020-12-12 01:35:43 +0000430 create<ast::SintLiteral>(Source{}, &i32, 2)), // constructor
431 ast::VariableDecorationList{}); // decorations
Ben Clayton4bfe4612020-11-16 16:41:47 +0000432 auto* init = var->constructor();
dan sinclairca893e32020-04-07 12:57:12 +0000433
Ben Claytonbbefff62020-12-12 11:58:44 +0000434 ast::VariableDeclStatement decl(Source{}, var);
dan sinclairca893e32020-04-07 12:57:12 +0000435
436 EXPECT_TRUE(td()->DetermineResultType(&decl));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000437 ASSERT_NE(init->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000438 EXPECT_TRUE(init->result_type()->Is<ast::type::I32>());
dan sinclairca893e32020-04-07 12:57:12 +0000439}
440
dan sinclair7be237a2020-06-15 20:55:09 +0000441TEST_F(TypeDeterminerTest, Stmt_VariableDecl_ModuleScope) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000442 ast::type::I32 i32;
Ben Claytona80511e2020-12-11 13:07:02 +0000443 auto* var = create<ast::Variable>(
444 Source{}, // source
445 "my_var", // name
446 ast::StorageClass::kNone, // storage_class
447 &i32, // type
448 false, // is_const
449 create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000450 Source{},
Ben Clayton5ed161b2020-12-12 01:35:43 +0000451 create<ast::SintLiteral>(Source{}, &i32, 2)), // constructor
452 ast::VariableDecorationList{}); // decorations
Ben Clayton4bfe4612020-11-16 16:41:47 +0000453 auto* init = var->constructor();
dan sinclair7be237a2020-06-15 20:55:09 +0000454
Ben Clayton3ea3c992020-11-18 21:19:22 +0000455 mod->AddGlobalVariable(var);
dan sinclair7be237a2020-06-15 20:55:09 +0000456
457 EXPECT_TRUE(td()->Determine());
Ben Clayton4bfe4612020-11-16 16:41:47 +0000458 ASSERT_NE(init->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000459 EXPECT_TRUE(init->result_type()->Is<ast::type::I32>());
dan sinclair7be237a2020-06-15 20:55:09 +0000460}
461
dan sinclair7456f422020-04-08 19:58:35 +0000462TEST_F(TypeDeterminerTest, Expr_Error_Unknown) {
Ben Clayton604bc722020-12-12 01:24:53 +0000463 FakeExpr e(Source{Source::Location{2, 30}});
dan sinclair7456f422020-04-08 19:58:35 +0000464
465 EXPECT_FALSE(td()->DetermineResultType(&e));
466 EXPECT_EQ(td()->error(), "2:30: unknown expression for type determination");
467}
468
dan sinclair973bd6a2020-04-07 12:57:42 +0000469TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000470 ast::type::I32 i32;
471 ast::type::F32 f32;
Ben Clayton8b0ffe92020-12-07 22:19:27 +0000472 ast::type::Array ary(&f32, 3, ast::ArrayDecorationList{});
dan sinclair973bd6a2020-04-07 12:57:42 +0000473
Ben Claytonb053acf2020-11-16 16:31:07 +0000474 auto* idx = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000475 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2));
Ben Claytona80511e2020-12-11 13:07:02 +0000476 auto* var =
477 create<ast::Variable>(Source{}, // source
478 "my_var", // name
479 ast::StorageClass::kFunction, // storage_class
480 &ary, // type
481 false, // is_const
482 nullptr, // constructor
483 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +0000484 mod->AddGlobalVariable(var);
dan sinclair8eddb782020-04-23 22:26:52 +0000485
486 // Register the global
487 EXPECT_TRUE(td()->Determine());
488
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000489 ast::ArrayAccessorExpression acc(
490 Source{},
491 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("my_var"),
492 "my_var"),
493 idx);
dan sinclair8eddb782020-04-23 22:26:52 +0000494 EXPECT_TRUE(td()->DetermineResultType(&acc));
495 ASSERT_NE(acc.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000496 ASSERT_TRUE(acc.result_type()->Is<ast::type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000497
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000498 auto* ptr = acc.result_type()->As<ast::type::Pointer>();
499 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000500}
501
David Neto9c88ea52020-06-22 20:33:12 +0000502TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Alias_Array) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000503 ast::type::I32 i32;
504 ast::type::F32 f32;
Ben Clayton8b0ffe92020-12-07 22:19:27 +0000505 ast::type::Array ary(&f32, 3, ast::ArrayDecorationList{});
dan sinclair4226b6a2020-12-11 19:35:03 +0000506 ast::type::Alias aary(mod->RegisterSymbol("myarrty"), "myarrty", &ary);
David Neto9c88ea52020-06-22 20:33:12 +0000507
Ben Claytonb053acf2020-11-16 16:31:07 +0000508 auto* idx = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000509 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2));
Ben Claytona80511e2020-12-11 13:07:02 +0000510 auto* var =
511 create<ast::Variable>(Source{}, // source
512 "my_var", // name
513 ast::StorageClass::kFunction, // storage_class
514 &aary, // type
515 false, // is_const
516 nullptr, // constructor
517 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +0000518 mod->AddGlobalVariable(var);
David Neto9c88ea52020-06-22 20:33:12 +0000519
520 // Register the global
521 EXPECT_TRUE(td()->Determine());
522
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000523 ast::ArrayAccessorExpression acc(
524 Source{},
525 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("my_var"),
526 "my_var"),
527 idx);
David Neto9c88ea52020-06-22 20:33:12 +0000528 EXPECT_TRUE(td()->DetermineResultType(&acc));
529 ASSERT_NE(acc.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000530 ASSERT_TRUE(acc.result_type()->Is<ast::type::Pointer>());
David Neto9c88ea52020-06-22 20:33:12 +0000531
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000532 auto* ptr = acc.result_type()->As<ast::type::Pointer>();
533 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
David Neto9c88ea52020-06-22 20:33:12 +0000534}
535
dan sinclair8eddb782020-04-23 22:26:52 +0000536TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array_Constant) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000537 ast::type::I32 i32;
538 ast::type::F32 f32;
Ben Clayton8b0ffe92020-12-07 22:19:27 +0000539 ast::type::Array ary(&f32, 3, ast::ArrayDecorationList{});
dan sinclair8eddb782020-04-23 22:26:52 +0000540
Ben Claytonb053acf2020-11-16 16:31:07 +0000541 auto* idx = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000542 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2));
Ben Claytona80511e2020-12-11 13:07:02 +0000543 auto* var =
544 create<ast::Variable>(Source{}, // source
545 "my_var", // name
546 ast::StorageClass::kFunction, // storage_class
547 &ary, // type
548 true, // is_const
549 nullptr, // constructor
550 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +0000551 mod->AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000552
553 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000554 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000555
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000556 ast::ArrayAccessorExpression acc(
557 Source{},
558 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("my_var"),
559 "my_var"),
560 idx);
dan sinclair973bd6a2020-04-07 12:57:42 +0000561 EXPECT_TRUE(td()->DetermineResultType(&acc));
562 ASSERT_NE(acc.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000563 EXPECT_TRUE(acc.result_type()->Is<ast::type::F32>())
Ben Clayton75f39be2020-11-30 23:30:58 +0000564 << acc.result_type()->type_name();
dan sinclair973bd6a2020-04-07 12:57:42 +0000565}
566
567TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000568 ast::type::I32 i32;
569 ast::type::F32 f32;
570 ast::type::Matrix mat(&f32, 3, 2);
dan sinclair973bd6a2020-04-07 12:57:42 +0000571
Ben Claytonb053acf2020-11-16 16:31:07 +0000572 auto* idx = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000573 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2));
Ben Clayton321e5a92020-12-07 21:08:07 +0000574 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +0000575 create<ast::Variable>(Source{}, // source
576 "my_var", // name
577 ast::StorageClass::kNone, // storage_class
578 &mat, // type
579 false, // is_const
580 nullptr, // constructor
581 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +0000582 mod->AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000583
584 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000585 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000586
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000587 ast::ArrayAccessorExpression acc(
588 Source{},
589 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("my_var"),
590 "my_var"),
591 idx);
dan sinclair973bd6a2020-04-07 12:57:42 +0000592 EXPECT_TRUE(td()->DetermineResultType(&acc));
593 ASSERT_NE(acc.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000594 ASSERT_TRUE(acc.result_type()->Is<ast::type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000595
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000596 auto* ptr = acc.result_type()->As<ast::type::Pointer>();
597 ASSERT_TRUE(ptr->type()->Is<ast::type::Vector>());
598 EXPECT_EQ(ptr->type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair973bd6a2020-04-07 12:57:42 +0000599}
600
601TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix_BothDimensions) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000602 ast::type::I32 i32;
603 ast::type::F32 f32;
604 ast::type::Matrix mat(&f32, 3, 2);
dan sinclair973bd6a2020-04-07 12:57:42 +0000605
Ben Claytonb053acf2020-11-16 16:31:07 +0000606 auto* idx1 = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000607 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000608 auto* idx2 = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000609 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1));
Ben Clayton321e5a92020-12-07 21:08:07 +0000610 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +0000611 create<ast::Variable>(Source{}, // source
612 "my_var", // name
613 ast::StorageClass::kNone, // storage_class
614 &mat, // type
615 false, // is_const
616 nullptr, // constructor
617 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +0000618 mod->AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000619
620 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000621 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000622
623 ast::ArrayAccessorExpression acc(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000624 Source{},
Ben Clayton62625922020-11-13 22:09:38 +0000625 create<ast::ArrayAccessorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000626 Source{},
627 create<ast::IdentifierExpression>(
628 Source{}, mod->RegisterSymbol("my_var"), "my_var"),
dan sinclair6b59bf42020-12-11 19:16:13 +0000629 idx1),
Ben Clayton4bfe4612020-11-16 16:41:47 +0000630 idx2);
dan sinclair973bd6a2020-04-07 12:57:42 +0000631
632 EXPECT_TRUE(td()->DetermineResultType(&acc));
633 ASSERT_NE(acc.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000634 ASSERT_TRUE(acc.result_type()->Is<ast::type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000635
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000636 auto* ptr = acc.result_type()->As<ast::type::Pointer>();
637 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000638}
639
640TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Vector) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000641 ast::type::I32 i32;
642 ast::type::F32 f32;
643 ast::type::Vector vec(&f32, 3);
dan sinclair973bd6a2020-04-07 12:57:42 +0000644
Ben Claytonb053acf2020-11-16 16:31:07 +0000645 auto* idx = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000646 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2));
Ben Clayton321e5a92020-12-07 21:08:07 +0000647 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +0000648 create<ast::Variable>(Source{}, // source
649 "my_var", // name
650 ast::StorageClass::kNone, // storage_class
651 &vec, // type
652 false, // is_const
653 nullptr, // constructor
654 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +0000655 mod->AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000656
657 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000658 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000659
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000660 ast::ArrayAccessorExpression acc(
661 Source{},
662 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("my_var"),
663 "my_var"),
664 idx);
dan sinclair973bd6a2020-04-07 12:57:42 +0000665 EXPECT_TRUE(td()->DetermineResultType(&acc));
666 ASSERT_NE(acc.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000667 ASSERT_TRUE(acc.result_type()->Is<ast::type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000668
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000669 auto* ptr = acc.result_type()->As<ast::type::Pointer>();
670 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000671}
672
dan sinclaira7d498e2020-09-22 22:07:13 +0000673TEST_F(TypeDeterminerTest, Expr_Bitcast) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000674 ast::type::F32 f32;
dan sinclair6b59bf42020-12-11 19:16:13 +0000675 ast::BitcastExpression bitcast(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000676 Source{}, &f32,
677 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("name"),
678 "name"));
dan sinclaira01777c2020-04-07 12:57:52 +0000679
Ben Claytona80511e2020-12-11 13:07:02 +0000680 ast::Variable v(Source{}, "name", ast::StorageClass::kPrivate, &f32, false,
681 nullptr, ast::VariableDecorationList{});
dan sinclairff267ca2020-10-14 18:26:31 +0000682 td()->RegisterVariableForTesting(&v);
683
dan sinclaira7d498e2020-09-22 22:07:13 +0000684 EXPECT_TRUE(td()->DetermineResultType(&bitcast));
685 ASSERT_NE(bitcast.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000686 EXPECT_TRUE(bitcast.result_type()->Is<ast::type::F32>());
dan sinclaira01777c2020-04-07 12:57:52 +0000687}
688
dan sinclair3ca87462020-04-07 16:41:10 +0000689TEST_F(TypeDeterminerTest, Expr_Call) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000690 ast::type::F32 f32;
dan sinclair3ca87462020-04-07 16:41:10 +0000691
692 ast::VariableList params;
dan sinclaira41132f2020-12-11 18:24:53 +0000693 auto* func = create<ast::Function>(
694 Source{}, mod->RegisterSymbol("my_func"), "my_func", params, &f32,
Ben Claytondb5ce652020-12-14 20:25:27 +0000695 create<ast::BlockStatement>(Source{}, ast::StatementList{}),
696 ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000697 mod->AddFunction(func);
dan sinclair3ca87462020-04-07 16:41:10 +0000698
699 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000700 EXPECT_TRUE(td()->Determine());
dan sinclair3ca87462020-04-07 16:41:10 +0000701
702 ast::ExpressionList call_params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000703 ast::CallExpression call(
704 Source{},
705 create<ast::IdentifierExpression>(
706 Source{}, mod->RegisterSymbol("my_func"), "my_func"),
707 call_params);
dan sinclair3ca87462020-04-07 16:41:10 +0000708 EXPECT_TRUE(td()->DetermineResultType(&call));
709 ASSERT_NE(call.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000710 EXPECT_TRUE(call.result_type()->Is<ast::type::F32>());
dan sinclair3ca87462020-04-07 16:41:10 +0000711}
712
dan sinclairccb52dc2020-04-20 14:18:54 +0000713TEST_F(TypeDeterminerTest, Expr_Call_WithParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000714 ast::type::F32 f32;
dan sinclairccb52dc2020-04-20 14:18:54 +0000715
716 ast::VariableList params;
dan sinclaira41132f2020-12-11 18:24:53 +0000717 auto* func = create<ast::Function>(
718 Source{}, mod->RegisterSymbol("my_func"), "my_func", params, &f32,
Ben Claytondb5ce652020-12-14 20:25:27 +0000719 create<ast::BlockStatement>(Source{}, ast::StatementList{}),
720 ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000721 mod->AddFunction(func);
dan sinclairccb52dc2020-04-20 14:18:54 +0000722
723 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000724 EXPECT_TRUE(td()->Determine());
dan sinclairccb52dc2020-04-20 14:18:54 +0000725
726 ast::ExpressionList call_params;
Ben Clayton62625922020-11-13 22:09:38 +0000727 call_params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000728 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.4)));
dan sinclairccb52dc2020-04-20 14:18:54 +0000729
Ben Clayton4bfe4612020-11-16 16:41:47 +0000730 auto* param = call_params.back();
dan sinclairccb52dc2020-04-20 14:18:54 +0000731
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000732 ast::CallExpression call(
733 Source{},
734 create<ast::IdentifierExpression>(
735 Source{}, mod->RegisterSymbol("my_func"), "my_func"),
736 call_params);
dan sinclairccb52dc2020-04-20 14:18:54 +0000737 EXPECT_TRUE(td()->DetermineResultType(&call));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000738 ASSERT_NE(param->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000739 EXPECT_TRUE(param->result_type()->Is<ast::type::F32>());
dan sinclairccb52dc2020-04-20 14:18:54 +0000740}
741
dan sinclairb4fee2f2020-09-22 19:42:13 +0000742TEST_F(TypeDeterminerTest, Expr_Call_Intrinsic) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000743 ast::type::F32 f32;
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000744
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000745 // Register the function
746 EXPECT_TRUE(td()->Determine());
747
748 ast::ExpressionList call_params;
Ben Clayton62625922020-11-13 22:09:38 +0000749 call_params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000750 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.4)));
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000751
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000752 ast::CallExpression call(Source{},
753 create<ast::IdentifierExpression>(
754 Source{}, mod->RegisterSymbol("round"), "round"),
755 call_params);
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000756
757 EXPECT_TRUE(td()->DetermineResultType(&call));
758 ASSERT_NE(call.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000759 EXPECT_TRUE(call.result_type()->Is<ast::type::F32>());
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000760}
761
dan sinclair4e807952020-04-07 16:41:23 +0000762TEST_F(TypeDeterminerTest, Expr_Cast) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000763 ast::type::F32 f32;
dan sinclair3c025922020-09-24 14:38:44 +0000764
765 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000766 params.push_back(create<ast::IdentifierExpression>(
767 Source{}, mod->RegisterSymbol("name"), "name"));
768 ast::TypeConstructorExpression cast(Source{}, &f32, params);
dan sinclair4e807952020-04-07 16:41:23 +0000769
Ben Claytona80511e2020-12-11 13:07:02 +0000770 ast::Variable v(Source{}, "name", ast::StorageClass::kPrivate, &f32, false,
771 nullptr, ast::VariableDecorationList{});
dan sinclairff267ca2020-10-14 18:26:31 +0000772 td()->RegisterVariableForTesting(&v);
773
dan sinclair4e807952020-04-07 16:41:23 +0000774 EXPECT_TRUE(td()->DetermineResultType(&cast));
775 ASSERT_NE(cast.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000776 EXPECT_TRUE(cast.result_type()->Is<ast::type::F32>());
dan sinclair4e807952020-04-07 16:41:23 +0000777}
778
dan sinclairb7edc4c2020-04-07 12:46:30 +0000779TEST_F(TypeDeterminerTest, Expr_Constructor_Scalar) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000780 ast::type::F32 f32;
Ben Clayton5ed161b2020-12-12 01:35:43 +0000781 ast::ScalarConstructorExpression s(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000782 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f));
dan sinclairb7edc4c2020-04-07 12:46:30 +0000783
784 EXPECT_TRUE(td()->DetermineResultType(&s));
785 ASSERT_NE(s.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000786 EXPECT_TRUE(s.result_type()->Is<ast::type::F32>());
dan sinclairb7edc4c2020-04-07 12:46:30 +0000787}
788
789TEST_F(TypeDeterminerTest, Expr_Constructor_Type) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000790 ast::type::F32 f32;
791 ast::type::Vector vec(&f32, 3);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000792
793 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +0000794 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000795 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +0000796 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000797 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +0000798 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000799 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclairb7edc4c2020-04-07 12:46:30 +0000800
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000801 ast::TypeConstructorExpression tc(Source{}, &vec, vals);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000802
803 EXPECT_TRUE(td()->DetermineResultType(&tc));
804 ASSERT_NE(tc.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000805 ASSERT_TRUE(tc.result_type()->Is<ast::type::Vector>());
806 EXPECT_TRUE(
807 tc.result_type()->As<ast::type::Vector>()->type()->Is<ast::type::F32>());
808 EXPECT_EQ(tc.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000809}
810
dan sinclaircab0e732020-04-07 12:57:27 +0000811TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalVariable) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000812 ast::type::F32 f32;
Ben Clayton321e5a92020-12-07 21:08:07 +0000813 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +0000814 create<ast::Variable>(Source{}, // source
815 "my_var", // name
816 ast::StorageClass::kNone, // storage_class
817 &f32, // type
818 false, // is_const
819 nullptr, // constructor
820 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +0000821 mod->AddGlobalVariable(var);
dan sinclaircab0e732020-04-07 12:57:27 +0000822
823 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000824 EXPECT_TRUE(td()->Determine());
dan sinclaircab0e732020-04-07 12:57:27 +0000825
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000826 ast::IdentifierExpression ident(Source{}, mod->RegisterSymbol("my_var"),
827 "my_var");
dan sinclaircab0e732020-04-07 12:57:27 +0000828 EXPECT_TRUE(td()->DetermineResultType(&ident));
829 ASSERT_NE(ident.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000830 EXPECT_TRUE(ident.result_type()->Is<ast::type::Pointer>());
Ben Claytonc52f4212020-11-30 23:30:58 +0000831 EXPECT_TRUE(ident.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000832 ->As<ast::type::Pointer>()
Ben Claytonc52f4212020-11-30 23:30:58 +0000833 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000834 ->Is<ast::type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000835}
836
837TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalConstant) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000838 ast::type::F32 f32;
Ben Claytona80511e2020-12-11 13:07:02 +0000839 mod->AddGlobalVariable(
840 create<ast::Variable>(Source{}, // source
841 "my_var", // name
842 ast::StorageClass::kNone, // storage_class
843 &f32, // type
844 true, // is_const
845 nullptr, // constructor
846 ast::VariableDecorationList{})); // decorations
dan sinclair8eddb782020-04-23 22:26:52 +0000847
848 // Register the global
849 EXPECT_TRUE(td()->Determine());
850
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000851 ast::IdentifierExpression ident(Source{}, mod->RegisterSymbol("my_var"),
852 "my_var");
dan sinclair8eddb782020-04-23 22:26:52 +0000853 EXPECT_TRUE(td()->DetermineResultType(&ident));
854 ASSERT_NE(ident.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000855 EXPECT_TRUE(ident.result_type()->Is<ast::type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000856}
857
dan sinclair8eddb782020-04-23 22:26:52 +0000858TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable_Const) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000859 ast::type::F32 f32;
dan sinclair8eddb782020-04-23 22:26:52 +0000860
dan sinclair6b59bf42020-12-11 19:16:13 +0000861 auto* my_var = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000862 Source{}, mod->RegisterSymbol("my_var"), "my_var");
dan sinclair8eddb782020-04-23 22:26:52 +0000863
Ben Clayton321e5a92020-12-07 21:08:07 +0000864 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +0000865 create<ast::Variable>(Source{}, // source
866 "my_var", // name
867 ast::StorageClass::kNone, // storage_class
868 &f32, // type
869 true, // is_const
870 nullptr, // constructor
871 ast::VariableDecorationList{}); // decorations
dan sinclair8eddb782020-04-23 22:26:52 +0000872
Ben Claytondb5ce652020-12-14 20:25:27 +0000873 auto* body = create<ast::BlockStatement>(
874 Source{}, ast::StatementList{
875 create<ast::VariableDeclStatement>(Source{}, var),
876 create<ast::AssignmentStatement>(
877 Source{}, my_var,
878 create<ast::IdentifierExpression>(
879 Source{}, mod->RegisterSymbol("my_var"), "my_var")),
880 });
dan sinclaira41132f2020-12-11 18:24:53 +0000881 ast::Function f(Source{}, mod->RegisterSymbol("my_func"), "my_func", {}, &f32,
882 body, ast::FunctionDecorationList{});
dan sinclair8eddb782020-04-23 22:26:52 +0000883
884 EXPECT_TRUE(td()->DetermineFunction(&f));
885
Ben Clayton4bfe4612020-11-16 16:41:47 +0000886 ASSERT_NE(my_var->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000887 EXPECT_TRUE(my_var->result_type()->Is<ast::type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000888}
889
dan sinclaircab0e732020-04-07 12:57:27 +0000890TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000891 ast::type::F32 f32;
dan sinclaircab0e732020-04-07 12:57:27 +0000892
dan sinclair6b59bf42020-12-11 19:16:13 +0000893 auto* my_var = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000894 Source{}, mod->RegisterSymbol("my_var"), "my_var");
dan sinclaircab0e732020-04-07 12:57:27 +0000895
Ben Claytondb5ce652020-12-14 20:25:27 +0000896 auto* body = create<ast::BlockStatement>(
Ben Claytonbbefff62020-12-12 11:58:44 +0000897 Source{},
Ben Claytondb5ce652020-12-14 20:25:27 +0000898 ast::StatementList{
899 create<ast::VariableDeclStatement>(
900 Source{}, create<ast::Variable>(
901 Source{}, // source
902 "my_var", // name
903 ast::StorageClass::kNone, // storage_class
904 &f32, // type
905 false, // is_const
906 nullptr, // constructor
907 ast::VariableDecorationList{})), // decorations
908 create<ast::AssignmentStatement>(
909 Source{}, my_var,
910 create<ast::IdentifierExpression>(
911 Source{}, mod->RegisterSymbol("my_var"), "my_var")),
912 });
dan sinclaircab0e732020-04-07 12:57:27 +0000913
dan sinclaira41132f2020-12-11 18:24:53 +0000914 ast::Function f(Source{}, mod->RegisterSymbol("myfunc"), "my_func", {}, &f32,
915 body, ast::FunctionDecorationList{});
dan sinclaircab0e732020-04-07 12:57:27 +0000916
917 EXPECT_TRUE(td()->DetermineFunction(&f));
918
Ben Clayton4bfe4612020-11-16 16:41:47 +0000919 ASSERT_NE(my_var->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000920 EXPECT_TRUE(my_var->result_type()->Is<ast::type::Pointer>());
Ben Claytonc52f4212020-11-30 23:30:58 +0000921 EXPECT_TRUE(my_var->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000922 ->As<ast::type::Pointer>()
Ben Claytonc52f4212020-11-30 23:30:58 +0000923 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000924 ->Is<ast::type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000925}
926
dan sinclair5e989302020-09-16 21:20:36 +0000927TEST_F(TypeDeterminerTest, Expr_Identifier_Function_Ptr) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000928 ast::type::F32 f32;
929 ast::type::Pointer ptr(&f32, ast::StorageClass::kFunction);
dan sinclair5e989302020-09-16 21:20:36 +0000930
dan sinclair6b59bf42020-12-11 19:16:13 +0000931 auto* my_var = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000932 Source{}, mod->RegisterSymbol("my_var"), "my_var");
dan sinclair5e989302020-09-16 21:20:36 +0000933
Ben Claytondb5ce652020-12-14 20:25:27 +0000934 auto* body = create<ast::BlockStatement>(
Ben Claytonbbefff62020-12-12 11:58:44 +0000935 Source{},
Ben Claytondb5ce652020-12-14 20:25:27 +0000936 ast::StatementList{
937 create<ast::VariableDeclStatement>(
938 Source{}, create<ast::Variable>(
939 Source{}, // source
940 "my_var", // name
941 ast::StorageClass::kNone, // storage_class
942 &ptr, // type
943 false, // is_const
944 nullptr, // constructor
945 ast::VariableDecorationList{})), // decorations
946 create<ast::AssignmentStatement>(
947 Source{}, my_var,
948 create<ast::IdentifierExpression>(
949 Source{}, mod->RegisterSymbol("my_var"), "my_var")),
950 });
dan sinclair5e989302020-09-16 21:20:36 +0000951
dan sinclaira41132f2020-12-11 18:24:53 +0000952 ast::Function f(Source{}, mod->RegisterSymbol("my_func"), "my_func", {}, &f32,
953 body, ast::FunctionDecorationList{});
dan sinclair5e989302020-09-16 21:20:36 +0000954
955 EXPECT_TRUE(td()->DetermineFunction(&f));
956
Ben Clayton4bfe4612020-11-16 16:41:47 +0000957 ASSERT_NE(my_var->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000958 EXPECT_TRUE(my_var->result_type()->Is<ast::type::Pointer>());
Ben Claytonc52f4212020-11-30 23:30:58 +0000959 EXPECT_TRUE(my_var->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000960 ->As<ast::type::Pointer>()
Ben Claytonc52f4212020-11-30 23:30:58 +0000961 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000962 ->Is<ast::type::F32>());
dan sinclair5e989302020-09-16 21:20:36 +0000963}
964
dan sinclaircab0e732020-04-07 12:57:27 +0000965TEST_F(TypeDeterminerTest, Expr_Identifier_Function) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000966 ast::type::F32 f32;
dan sinclaircab0e732020-04-07 12:57:27 +0000967
968 ast::VariableList params;
dan sinclaira41132f2020-12-11 18:24:53 +0000969 auto* func = create<ast::Function>(
970 Source{}, mod->RegisterSymbol("my_func"), "my_func", params, &f32,
Ben Claytondb5ce652020-12-14 20:25:27 +0000971 create<ast::BlockStatement>(Source{}, ast::StatementList{}),
972 ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000973 mod->AddFunction(func);
dan sinclaircab0e732020-04-07 12:57:27 +0000974
975 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000976 EXPECT_TRUE(td()->Determine());
dan sinclaircab0e732020-04-07 12:57:27 +0000977
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000978 ast::IdentifierExpression ident(Source{}, mod->RegisterSymbol("my_func"),
979 "my_func");
dan sinclaircab0e732020-04-07 12:57:27 +0000980 EXPECT_TRUE(td()->DetermineResultType(&ident));
981 ASSERT_NE(ident.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000982 EXPECT_TRUE(ident.result_type()->Is<ast::type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000983}
984
dan sinclairff267ca2020-10-14 18:26:31 +0000985TEST_F(TypeDeterminerTest, Expr_Identifier_Unknown) {
Ben Clayton1ff59cd2020-12-12 01:38:13 +0000986 ast::IdentifierExpression a(Source{}, mod->RegisterSymbol("a"), "a");
dan sinclairff267ca2020-10-14 18:26:31 +0000987 EXPECT_FALSE(td()->DetermineResultType(&a));
988}
989
dan sinclair13d2a3b2020-06-22 20:52:24 +0000990TEST_F(TypeDeterminerTest, Function_RegisterInputOutputVariables) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000991 ast::type::F32 f32;
dan sinclair13d2a3b2020-06-22 20:52:24 +0000992
Ben Claytona80511e2020-12-11 13:07:02 +0000993 auto* in_var =
994 create<ast::Variable>(Source{}, // source
995 "in_var", // name
996 ast::StorageClass::kInput, // storage_class
997 &f32, // type
998 false, // is_const
999 nullptr, // constructor
1000 ast::VariableDecorationList{}); // decorations
1001 auto* out_var =
1002 create<ast::Variable>(Source{}, // source
1003 "out_var", // name
1004 ast::StorageClass::kOutput, // storage_class
1005 &f32, // type
1006 false, // is_const
1007 nullptr, // constructor
1008 ast::VariableDecorationList{}); // decorations
1009 auto* sb_var =
1010 create<ast::Variable>(Source{}, // source
1011 "sb_var", // name
1012 ast::StorageClass::kStorageBuffer, // storage_class
1013 &f32, // type
1014 false, // is_const
1015 nullptr, // constructor
1016 ast::VariableDecorationList{}); // decorations
1017 auto* wg_var =
1018 create<ast::Variable>(Source{}, // source
1019 "wg_var", // name
1020 ast::StorageClass::kWorkgroup, // storage_class
1021 &f32, // type
1022 false, // is_const
1023 nullptr, // constructor
1024 ast::VariableDecorationList{}); // decorations
1025 auto* priv_var =
1026 create<ast::Variable>(Source{}, // source
1027 "priv_var", // name
1028 ast::StorageClass::kPrivate, // storage_class
1029 &f32, // type
1030 false, // is_const
1031 nullptr, // constructor
1032 ast::VariableDecorationList{}); // decorations
dan sinclair13d2a3b2020-06-22 20:52:24 +00001033
Ben Clayton3ea3c992020-11-18 21:19:22 +00001034 mod->AddGlobalVariable(in_var);
1035 mod->AddGlobalVariable(out_var);
1036 mod->AddGlobalVariable(sb_var);
1037 mod->AddGlobalVariable(wg_var);
1038 mod->AddGlobalVariable(priv_var);
dan sinclair13d2a3b2020-06-22 20:52:24 +00001039
1040 ast::VariableList params;
Ben Claytondb5ce652020-12-14 20:25:27 +00001041 auto* body = create<ast::BlockStatement>(
Ben Claytonbbefff62020-12-12 11:58:44 +00001042 Source{},
Ben Claytondb5ce652020-12-14 20:25:27 +00001043 ast::StatementList{
1044 create<ast::AssignmentStatement>(
1045 Source{},
1046 create<ast::IdentifierExpression>(
1047 Source{}, mod->RegisterSymbol("out_var"), "out_var"),
1048 create<ast::IdentifierExpression>(
1049 Source{}, mod->RegisterSymbol("in_var"), "in_var")),
1050 create<ast::AssignmentStatement>(
1051 Source{},
1052 create<ast::IdentifierExpression>(
1053 Source{}, mod->RegisterSymbol("wg_var"), "wg_var"),
1054 create<ast::IdentifierExpression>(
1055 Source{}, mod->RegisterSymbol("wg_var"), "wg_var")),
1056 create<ast::AssignmentStatement>(
1057 Source{},
1058 create<ast::IdentifierExpression>(
1059 Source{}, mod->RegisterSymbol("sb_var"), "sb_var"),
1060 create<ast::IdentifierExpression>(
1061 Source{}, mod->RegisterSymbol("sb_var"), "sb_var")),
1062 create<ast::AssignmentStatement>(
1063 Source{},
1064 create<ast::IdentifierExpression>(
1065 Source{}, mod->RegisterSymbol("priv_var"), "priv_var"),
1066 create<ast::IdentifierExpression>(
1067 Source{}, mod->RegisterSymbol("priv_var"), "priv_var")),
1068 });
dan sinclaira41132f2020-12-11 18:24:53 +00001069 auto* func =
1070 create<ast::Function>(Source{}, mod->RegisterSymbol("my_func"), "my_func",
1071 params, &f32, body, ast::FunctionDecorationList{});
dan sinclair13d2a3b2020-06-22 20:52:24 +00001072
Ben Clayton3ea3c992020-11-18 21:19:22 +00001073 mod->AddFunction(func);
dan sinclair13d2a3b2020-06-22 20:52:24 +00001074
1075 // Register the function
1076 EXPECT_TRUE(td()->Determine());
1077
Ben Clayton4bfe4612020-11-16 16:41:47 +00001078 const auto& vars = func->referenced_module_variables();
Ryan Harrison9a452c12020-06-23 16:38:47 +00001079 ASSERT_EQ(vars.size(), 5u);
Ben Clayton4bfe4612020-11-16 16:41:47 +00001080 EXPECT_EQ(vars[0], out_var);
1081 EXPECT_EQ(vars[1], in_var);
1082 EXPECT_EQ(vars[2], wg_var);
1083 EXPECT_EQ(vars[3], sb_var);
1084 EXPECT_EQ(vars[4], priv_var);
dan sinclair13d2a3b2020-06-22 20:52:24 +00001085}
1086
dan sinclairde2dd682020-07-14 20:37:28 +00001087TEST_F(TypeDeterminerTest, Function_RegisterInputOutputVariables_SubFunction) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001088 ast::type::F32 f32;
dan sinclairde2dd682020-07-14 20:37:28 +00001089
Ben Claytona80511e2020-12-11 13:07:02 +00001090 auto* in_var =
1091 create<ast::Variable>(Source{}, // source
1092 "in_var", // name
1093 ast::StorageClass::kInput, // storage_class
1094 &f32, // type
1095 false, // is_const
1096 nullptr, // constructor
1097 ast::VariableDecorationList{}); // decorations
1098 auto* out_var =
1099 create<ast::Variable>(Source{}, // source
1100 "out_var", // name
1101 ast::StorageClass::kOutput, // storage_class
1102 &f32, // type
1103 false, // is_const
1104 nullptr, // constructor
1105 ast::VariableDecorationList{}); // decorations
1106 auto* sb_var =
1107 create<ast::Variable>(Source{}, // source
1108 "sb_var", // name
1109 ast::StorageClass::kStorageBuffer, // storage_class
1110 &f32, // type
1111 false, // is_const
1112 nullptr, // constructor
1113 ast::VariableDecorationList{}); // decorations
1114 auto* wg_var =
1115 create<ast::Variable>(Source{}, // source
1116 "wg_var", // name
1117 ast::StorageClass::kWorkgroup, // storage_class
1118 &f32, // type
1119 false, // is_const
1120 nullptr, // constructor
1121 ast::VariableDecorationList{}); // decorations
1122 auto* priv_var =
1123 create<ast::Variable>(Source{}, // source
1124 "priv_var", // name
1125 ast::StorageClass::kPrivate, // storage_class
1126 &f32, // type
1127 false, // is_const
1128 nullptr, // constructor
1129 ast::VariableDecorationList{}); // decorations
dan sinclairde2dd682020-07-14 20:37:28 +00001130
Ben Clayton3ea3c992020-11-18 21:19:22 +00001131 mod->AddGlobalVariable(in_var);
1132 mod->AddGlobalVariable(out_var);
1133 mod->AddGlobalVariable(sb_var);
1134 mod->AddGlobalVariable(wg_var);
1135 mod->AddGlobalVariable(priv_var);
dan sinclairde2dd682020-07-14 20:37:28 +00001136
Ben Claytondb5ce652020-12-14 20:25:27 +00001137 auto* body = create<ast::BlockStatement>(
Ben Claytonbbefff62020-12-12 11:58:44 +00001138 Source{},
Ben Claytondb5ce652020-12-14 20:25:27 +00001139 ast::StatementList{
1140 create<ast::AssignmentStatement>(
1141 Source{},
1142 create<ast::IdentifierExpression>(
1143 Source{}, mod->RegisterSymbol("out_var"), "out_var"),
1144 create<ast::IdentifierExpression>(
1145 Source{}, mod->RegisterSymbol("in_var"), "in_var")),
1146 create<ast::AssignmentStatement>(
1147 Source{},
1148 create<ast::IdentifierExpression>(
1149 Source{}, mod->RegisterSymbol("wg_var"), "wg_var"),
1150 create<ast::IdentifierExpression>(
1151 Source{}, mod->RegisterSymbol("wg_var"), "wg_var")),
1152 create<ast::AssignmentStatement>(
1153 Source{},
1154 create<ast::IdentifierExpression>(
1155 Source{}, mod->RegisterSymbol("sb_var"), "sb_var"),
1156 create<ast::IdentifierExpression>(
1157 Source{}, mod->RegisterSymbol("sb_var"), "sb_var")),
1158 create<ast::AssignmentStatement>(
1159 Source{},
1160 create<ast::IdentifierExpression>(
1161 Source{}, mod->RegisterSymbol("priv_var"), "priv_var"),
1162 create<ast::IdentifierExpression>(
1163 Source{}, mod->RegisterSymbol("priv_var"), "priv_var")),
1164 });
Ben Claytonb29b09f2020-11-14 01:13:04 +00001165 ast::VariableList params;
dan sinclaira41132f2020-12-11 18:24:53 +00001166 auto* func =
1167 create<ast::Function>(Source{}, mod->RegisterSymbol("my_func"), "my_func",
1168 params, &f32, body, ast::FunctionDecorationList{});
dan sinclairde2dd682020-07-14 20:37:28 +00001169
Ben Clayton3ea3c992020-11-18 21:19:22 +00001170 mod->AddFunction(func);
dan sinclairde2dd682020-07-14 20:37:28 +00001171
Ben Claytondb5ce652020-12-14 20:25:27 +00001172 body = create<ast::BlockStatement>(
Ben Claytonbbefff62020-12-12 11:58:44 +00001173 Source{},
Ben Claytondb5ce652020-12-14 20:25:27 +00001174 ast::StatementList{
1175 create<ast::AssignmentStatement>(
1176 Source{},
1177 create<ast::IdentifierExpression>(
1178 Source{}, mod->RegisterSymbol("out_var"), "out_var"),
1179 create<ast::CallExpression>(
1180 Source{},
1181 create<ast::IdentifierExpression>(
1182 Source{}, mod->RegisterSymbol("my_func"), "my_func"),
1183 ast::ExpressionList{})),
1184 });
1185
dan sinclaira41132f2020-12-11 18:24:53 +00001186 auto* func2 =
1187 create<ast::Function>(Source{}, mod->RegisterSymbol("func"), "func",
1188 params, &f32, body, ast::FunctionDecorationList{});
dan sinclairde2dd682020-07-14 20:37:28 +00001189
Ben Clayton3ea3c992020-11-18 21:19:22 +00001190 mod->AddFunction(func2);
dan sinclairde2dd682020-07-14 20:37:28 +00001191
1192 // Register the function
1193 EXPECT_TRUE(td()->Determine());
1194
Ben Clayton4bfe4612020-11-16 16:41:47 +00001195 const auto& vars = func2->referenced_module_variables();
dan sinclairde2dd682020-07-14 20:37:28 +00001196 ASSERT_EQ(vars.size(), 5u);
Ben Clayton4bfe4612020-11-16 16:41:47 +00001197 EXPECT_EQ(vars[0], out_var);
1198 EXPECT_EQ(vars[1], in_var);
1199 EXPECT_EQ(vars[2], wg_var);
1200 EXPECT_EQ(vars[3], sb_var);
1201 EXPECT_EQ(vars[4], priv_var);
dan sinclairde2dd682020-07-14 20:37:28 +00001202}
1203
dan sinclair13d2a3b2020-06-22 20:52:24 +00001204TEST_F(TypeDeterminerTest, Function_NotRegisterFunctionVariable) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001205 ast::type::F32 f32;
dan sinclair13d2a3b2020-06-22 20:52:24 +00001206
Ben Claytona80511e2020-12-11 13:07:02 +00001207 auto* var =
1208 create<ast::Variable>(Source{}, // source
1209 "in_var", // name
1210 ast::StorageClass::kFunction, // storage_class
1211 &f32, // type
1212 false, // is_const
1213 nullptr, // constructor
1214 ast::VariableDecorationList{}); // decorations
dan sinclair13d2a3b2020-06-22 20:52:24 +00001215
Ben Claytondb5ce652020-12-14 20:25:27 +00001216 auto* body = create<ast::BlockStatement>(
Ben Claytonbbefff62020-12-12 11:58:44 +00001217 Source{},
Ben Claytondb5ce652020-12-14 20:25:27 +00001218 ast::StatementList{
1219 create<ast::VariableDeclStatement>(Source{}, var),
1220 create<ast::AssignmentStatement>(
1221 Source{},
1222 create<ast::IdentifierExpression>(
1223 Source{}, mod->RegisterSymbol("var"), "var"),
1224 create<ast::ScalarConstructorExpression>(
1225 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f))),
1226 });
Ben Claytonb29b09f2020-11-14 01:13:04 +00001227 ast::VariableList params;
dan sinclaira41132f2020-12-11 18:24:53 +00001228 auto* func =
1229 create<ast::Function>(Source{}, mod->RegisterSymbol("my_func"), "my_func",
1230 params, &f32, body, ast::FunctionDecorationList{});
dan sinclair13d2a3b2020-06-22 20:52:24 +00001231
Ben Clayton3ea3c992020-11-18 21:19:22 +00001232 mod->AddFunction(func);
dan sinclair13d2a3b2020-06-22 20:52:24 +00001233
Ben Claytona80511e2020-12-11 13:07:02 +00001234 ast::Variable v(Source{}, "var", ast::StorageClass::kFunction, &f32, false,
1235 nullptr, ast::VariableDecorationList{});
dan sinclairff267ca2020-10-14 18:26:31 +00001236 td()->RegisterVariableForTesting(&v);
1237
dan sinclair13d2a3b2020-06-22 20:52:24 +00001238 // Register the function
dan sinclairff267ca2020-10-14 18:26:31 +00001239 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair13d2a3b2020-06-22 20:52:24 +00001240
Ben Clayton4bfe4612020-11-16 16:41:47 +00001241 EXPECT_EQ(func->referenced_module_variables().size(), 0u);
dan sinclair13d2a3b2020-06-22 20:52:24 +00001242}
1243
dan sinclair8ee1d222020-04-07 16:41:33 +00001244TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001245 ast::type::I32 i32;
1246 ast::type::F32 f32;
dan sinclair8ee1d222020-04-07 16:41:33 +00001247
1248 ast::StructMemberDecorationList decos;
1249 ast::StructMemberList members;
Ben Clayton4543d1a2020-12-12 12:18:04 +00001250 members.push_back(
1251 create<ast::StructMember>(Source{}, "first_member", &i32, decos));
1252 members.push_back(
1253 create<ast::StructMember>(Source{}, "second_member", &f32, decos));
dan sinclair8ee1d222020-04-07 16:41:33 +00001254
Ben Claytonbcf37542020-12-12 12:52:44 +00001255 auto* strct =
1256 create<ast::Struct>(Source{}, members, ast::StructDecorationList{});
dan sinclair8ee1d222020-04-07 16:41:33 +00001257
dan sinclair24bbbbb2020-12-14 16:01:37 +00001258 ast::type::Struct st(mod->RegisterSymbol("S"), "S", strct);
dan sinclair8ee1d222020-04-07 16:41:33 +00001259
Ben Claytona80511e2020-12-11 13:07:02 +00001260 auto* var =
1261 create<ast::Variable>(Source{}, // source
1262 "my_struct", // name
1263 ast::StorageClass::kNone, // storage_class
1264 &st, // type
1265 false, // is_const
1266 nullptr, // constructor
1267 ast::VariableDecorationList{}); // decorations
dan sinclair8ee1d222020-04-07 16:41:33 +00001268
Ben Clayton3ea3c992020-11-18 21:19:22 +00001269 mod->AddGlobalVariable(var);
dan sinclair8ee1d222020-04-07 16:41:33 +00001270
1271 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001272 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +00001273
dan sinclair6b59bf42020-12-11 19:16:13 +00001274 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001275 Source{}, mod->RegisterSymbol("my_struct"), "my_struct");
dan sinclair6b59bf42020-12-11 19:16:13 +00001276 auto* mem_ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001277 Source{}, mod->RegisterSymbol("second_member"), "second_member");
dan sinclair8ee1d222020-04-07 16:41:33 +00001278
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001279 ast::MemberAccessorExpression mem(Source{}, ident, mem_ident);
dan sinclair8ee1d222020-04-07 16:41:33 +00001280 EXPECT_TRUE(td()->DetermineResultType(&mem));
1281 ASSERT_NE(mem.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001282 ASSERT_TRUE(mem.result_type()->Is<ast::type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +00001283
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001284 auto* ptr = mem.result_type()->As<ast::type::Pointer>();
1285 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclair8ee1d222020-04-07 16:41:33 +00001286}
1287
dan sinclairb445a9b2020-04-24 00:40:45 +00001288TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct_Alias) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001289 ast::type::I32 i32;
1290 ast::type::F32 f32;
dan sinclairb445a9b2020-04-24 00:40:45 +00001291
1292 ast::StructMemberDecorationList decos;
1293 ast::StructMemberList members;
Ben Clayton4543d1a2020-12-12 12:18:04 +00001294 members.push_back(
1295 create<ast::StructMember>(Source{}, "first_member", &i32, decos));
1296 members.push_back(
1297 create<ast::StructMember>(Source{}, "second_member", &f32, decos));
dan sinclairb445a9b2020-04-24 00:40:45 +00001298
Ben Claytonbcf37542020-12-12 12:52:44 +00001299 auto* strct =
1300 create<ast::Struct>(Source{}, members, ast::StructDecorationList{});
dan sinclairb445a9b2020-04-24 00:40:45 +00001301
dan sinclair24bbbbb2020-12-14 16:01:37 +00001302 auto st = std::make_unique<ast::type::Struct>(mod->RegisterSymbol("alias"),
1303 "alias", strct);
dan sinclair4226b6a2020-12-11 19:35:03 +00001304 ast::type::Alias alias(mod->RegisterSymbol("alias"), "alias", st.get());
dan sinclairb445a9b2020-04-24 00:40:45 +00001305
Ben Claytona80511e2020-12-11 13:07:02 +00001306 auto* var =
1307 create<ast::Variable>(Source{}, // source
1308 "my_struct", // name
1309 ast::StorageClass::kNone, // storage_class
1310 &alias, // type
1311 false, // is_const
1312 nullptr, // constructor
1313 ast::VariableDecorationList{}); // decorations
dan sinclairb445a9b2020-04-24 00:40:45 +00001314
Ben Clayton3ea3c992020-11-18 21:19:22 +00001315 mod->AddGlobalVariable(var);
dan sinclairb445a9b2020-04-24 00:40:45 +00001316
1317 // Register the global
1318 EXPECT_TRUE(td()->Determine());
1319
dan sinclair6b59bf42020-12-11 19:16:13 +00001320 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001321 Source{}, mod->RegisterSymbol("my_struct"), "my_struct");
dan sinclair6b59bf42020-12-11 19:16:13 +00001322 auto* mem_ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001323 Source{}, mod->RegisterSymbol("second_member"), "second_member");
dan sinclairb445a9b2020-04-24 00:40:45 +00001324
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001325 ast::MemberAccessorExpression mem(Source{}, ident, mem_ident);
dan sinclairb445a9b2020-04-24 00:40:45 +00001326 EXPECT_TRUE(td()->DetermineResultType(&mem));
1327 ASSERT_NE(mem.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001328 ASSERT_TRUE(mem.result_type()->Is<ast::type::Pointer>());
dan sinclairb445a9b2020-04-24 00:40:45 +00001329
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001330 auto* ptr = mem.result_type()->As<ast::type::Pointer>();
1331 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclairb445a9b2020-04-24 00:40:45 +00001332}
1333
dan sinclair8ee1d222020-04-07 16:41:33 +00001334TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001335 ast::type::F32 f32;
1336 ast::type::Vector vec3(&f32, 3);
dan sinclair8ee1d222020-04-07 16:41:33 +00001337
Ben Claytona80511e2020-12-11 13:07:02 +00001338 auto* var =
1339 create<ast::Variable>(Source{}, // source
1340 "my_vec", // name
1341 ast::StorageClass::kNone, // storage_class
1342 &vec3, // type
1343 false, // is_const
1344 nullptr, // constructor
1345 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001346 mod->AddGlobalVariable(var);
dan sinclair8ee1d222020-04-07 16:41:33 +00001347
1348 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001349 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +00001350
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001351 auto* ident = create<ast::IdentifierExpression>(
1352 Source{}, mod->RegisterSymbol("my_vec"), "my_vec");
1353 auto* swizzle = create<ast::IdentifierExpression>(
1354 Source{}, mod->RegisterSymbol("xy"), "xy");
dan sinclair8ee1d222020-04-07 16:41:33 +00001355
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001356 ast::MemberAccessorExpression mem(Source{}, ident, swizzle);
dan sinclair8ee1d222020-04-07 16:41:33 +00001357 EXPECT_TRUE(td()->DetermineResultType(&mem)) << td()->error();
1358 ASSERT_NE(mem.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001359 ASSERT_TRUE(mem.result_type()->Is<ast::type::Vector>());
1360 EXPECT_TRUE(
1361 mem.result_type()->As<ast::type::Vector>()->type()->Is<ast::type::F32>());
1362 EXPECT_EQ(mem.result_type()->As<ast::type::Vector>()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +00001363}
1364
dan sinclairaac58652020-04-21 13:05:34 +00001365TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle_SingleElement) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001366 ast::type::F32 f32;
1367 ast::type::Vector vec3(&f32, 3);
dan sinclairaac58652020-04-21 13:05:34 +00001368
Ben Claytona80511e2020-12-11 13:07:02 +00001369 auto* var =
1370 create<ast::Variable>(Source{}, // source
1371 "my_vec", // name
1372 ast::StorageClass::kNone, // storage_class
1373 &vec3, // type
1374 false, // is_const
1375 nullptr, // constructor
1376 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001377 mod->AddGlobalVariable(var);
dan sinclairaac58652020-04-21 13:05:34 +00001378
1379 // Register the global
1380 EXPECT_TRUE(td()->Determine());
1381
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001382 auto* ident = create<ast::IdentifierExpression>(
1383 Source{}, mod->RegisterSymbol("my_vec"), "my_vec");
1384 auto* swizzle = create<ast::IdentifierExpression>(
1385 Source{}, mod->RegisterSymbol("x"), "x");
dan sinclairaac58652020-04-21 13:05:34 +00001386
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001387 ast::MemberAccessorExpression mem(Source{}, ident, swizzle);
dan sinclairaac58652020-04-21 13:05:34 +00001388 EXPECT_TRUE(td()->DetermineResultType(&mem)) << td()->error();
1389 ASSERT_NE(mem.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001390 ASSERT_TRUE(mem.result_type()->Is<ast::type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +00001391
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001392 auto* ptr = mem.result_type()->As<ast::type::Pointer>();
1393 ASSERT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclairaac58652020-04-21 13:05:34 +00001394}
1395
dan sinclair8eddb782020-04-23 22:26:52 +00001396TEST_F(TypeDeterminerTest, Expr_Accessor_MultiLevel) {
dan sinclair8ee1d222020-04-07 16:41:33 +00001397 // struct b {
1398 // vec4<f32> foo
1399 // }
1400 // struct A {
1401 // vec3<struct b> mem
1402 // }
1403 // var c : A
1404 // c.mem[0].foo.yx
1405 // -> vec2<f32>
1406 //
1407 // MemberAccessor{
1408 // MemberAccessor{
1409 // ArrayAccessor{
1410 // MemberAccessor{
1411 // Identifier{c}
1412 // Identifier{mem}
1413 // }
1414 // ScalarConstructor{0}
1415 // }
1416 // Identifier{foo}
1417 // }
1418 // Identifier{yx}
1419 // }
1420 //
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001421 ast::type::I32 i32;
1422 ast::type::F32 f32;
dan sinclair8ee1d222020-04-07 16:41:33 +00001423
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001424 ast::type::Vector vec4(&f32, 4);
dan sinclair8ee1d222020-04-07 16:41:33 +00001425
1426 ast::StructMemberDecorationList decos;
1427 ast::StructMemberList b_members;
Ben Clayton4543d1a2020-12-12 12:18:04 +00001428 b_members.push_back(create<ast::StructMember>(Source{}, "foo", &vec4, decos));
dan sinclair8ee1d222020-04-07 16:41:33 +00001429
Ben Claytonbcf37542020-12-12 12:52:44 +00001430 auto* strctB =
1431 create<ast::Struct>(Source{}, b_members, ast::StructDecorationList{});
dan sinclair24bbbbb2020-12-14 16:01:37 +00001432 ast::type::Struct stB(mod->RegisterSymbol("B"), "B", strctB);
dan sinclair8ee1d222020-04-07 16:41:33 +00001433
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001434 ast::type::Vector vecB(&stB, 3);
dan sinclair8ee1d222020-04-07 16:41:33 +00001435
1436 ast::StructMemberList a_members;
Ben Clayton4543d1a2020-12-12 12:18:04 +00001437 a_members.push_back(create<ast::StructMember>(Source{}, "mem", &vecB, decos));
dan sinclair8ee1d222020-04-07 16:41:33 +00001438
Ben Claytonbcf37542020-12-12 12:52:44 +00001439 auto* strctA =
1440 create<ast::Struct>(Source{}, a_members, ast::StructDecorationList{});
dan sinclair8ee1d222020-04-07 16:41:33 +00001441
dan sinclair24bbbbb2020-12-14 16:01:37 +00001442 ast::type::Struct stA(mod->RegisterSymbol("A"), "A", strctA);
dan sinclair8ee1d222020-04-07 16:41:33 +00001443
Ben Clayton321e5a92020-12-07 21:08:07 +00001444 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00001445 create<ast::Variable>(Source{}, // source
1446 "c", // name
1447 ast::StorageClass::kNone, // storage_class
1448 &stA, // type
1449 false, // is_const
1450 nullptr, // constructor
1451 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001452 mod->AddGlobalVariable(var);
dan sinclair8ee1d222020-04-07 16:41:33 +00001453
1454 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001455 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +00001456
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001457 auto* ident = create<ast::IdentifierExpression>(
1458 Source{}, mod->RegisterSymbol("c"), "c");
1459 auto* mem_ident = create<ast::IdentifierExpression>(
1460 Source{}, mod->RegisterSymbol("mem"), "mem");
1461 auto* foo_ident = create<ast::IdentifierExpression>(
1462 Source{}, mod->RegisterSymbol("foo"), "foo");
Ben Claytonb053acf2020-11-16 16:31:07 +00001463 auto* idx = create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001464 Source{}, create<ast::SintLiteral>(Source{}, &i32, 0));
1465 auto* swizzle = create<ast::IdentifierExpression>(
1466 Source{}, mod->RegisterSymbol("yx"), "yx");
dan sinclair8ee1d222020-04-07 16:41:33 +00001467
1468 ast::MemberAccessorExpression mem(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001469 Source{},
Ben Clayton62625922020-11-13 22:09:38 +00001470 create<ast::MemberAccessorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001471 Source{},
Ben Clayton62625922020-11-13 22:09:38 +00001472 create<ast::ArrayAccessorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001473 Source{},
1474 create<ast::MemberAccessorExpression>(Source{}, ident, mem_ident),
1475 idx),
Ben Clayton4bfe4612020-11-16 16:41:47 +00001476 foo_ident),
1477 swizzle);
dan sinclair8ee1d222020-04-07 16:41:33 +00001478 EXPECT_TRUE(td()->DetermineResultType(&mem)) << td()->error();
dan sinclair8eddb782020-04-23 22:26:52 +00001479
dan sinclair8ee1d222020-04-07 16:41:33 +00001480 ASSERT_NE(mem.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001481 ASSERT_TRUE(mem.result_type()->Is<ast::type::Vector>());
1482 EXPECT_TRUE(
1483 mem.result_type()->As<ast::type::Vector>()->type()->Is<ast::type::F32>());
1484 EXPECT_EQ(mem.result_type()->As<ast::type::Vector>()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +00001485}
1486
dan sinclaircd077b02020-04-20 14:19:04 +00001487using Expr_Binary_BitwiseTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +00001488TEST_P(Expr_Binary_BitwiseTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001489 auto op = GetParam();
1490
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001491 ast::type::I32 i32;
dan sinclair9b978022020-04-07 19:26:39 +00001492
Ben Clayton321e5a92020-12-07 21:08:07 +00001493 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00001494 create<ast::Variable>(Source{}, // source
1495 "val", // name
1496 ast::StorageClass::kNone, // storage_class
1497 &i32, // type
1498 false, // is_const
1499 nullptr, // constructor
1500 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001501 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001502
1503 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001504 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001505
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001506 ast::BinaryExpression expr(Source{}, op,
1507 create<ast::IdentifierExpression>(
1508 Source{}, mod->RegisterSymbol("val"), "val"),
1509 create<ast::IdentifierExpression>(
1510 Source{}, mod->RegisterSymbol("val"), "val"));
dan sinclair9b978022020-04-07 19:26:39 +00001511
dan sinclaircd077b02020-04-20 14:19:04 +00001512 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001513 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001514 EXPECT_TRUE(expr.result_type()->Is<ast::type::I32>());
dan sinclair9b978022020-04-07 19:26:39 +00001515}
1516
dan sinclair1c9b4862020-04-07 19:27:41 +00001517TEST_P(Expr_Binary_BitwiseTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001518 auto op = GetParam();
1519
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001520 ast::type::I32 i32;
1521 ast::type::Vector vec3(&i32, 3);
dan sinclair9b978022020-04-07 19:26:39 +00001522
Ben Clayton321e5a92020-12-07 21:08:07 +00001523 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00001524 create<ast::Variable>(Source{}, // source
1525 "val", // name
1526 ast::StorageClass::kNone, // storage_class
1527 &vec3, // type
1528 false, // is_const
1529 nullptr, // constructor
1530 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001531 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001532
1533 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001534 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001535
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001536 ast::BinaryExpression expr(Source{}, op,
1537 create<ast::IdentifierExpression>(
1538 Source{}, mod->RegisterSymbol("val"), "val"),
1539 create<ast::IdentifierExpression>(
1540 Source{}, mod->RegisterSymbol("val"), "val"));
dan sinclair9b978022020-04-07 19:26:39 +00001541
dan sinclaircd077b02020-04-20 14:19:04 +00001542 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001543 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001544 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00001545 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001546 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001547 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001548 ->Is<ast::type::I32>());
1549 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001550}
1551INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +00001552 Expr_Binary_BitwiseTest,
1553 testing::Values(ast::BinaryOp::kAnd,
1554 ast::BinaryOp::kOr,
1555 ast::BinaryOp::kXor,
1556 ast::BinaryOp::kShiftLeft,
1557 ast::BinaryOp::kShiftRight,
dan sinclair1c9b4862020-04-07 19:27:41 +00001558 ast::BinaryOp::kAdd,
1559 ast::BinaryOp::kSubtract,
1560 ast::BinaryOp::kDivide,
1561 ast::BinaryOp::kModulo));
dan sinclair9b978022020-04-07 19:26:39 +00001562
dan sinclaircd077b02020-04-20 14:19:04 +00001563using Expr_Binary_LogicalTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +00001564TEST_P(Expr_Binary_LogicalTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001565 auto op = GetParam();
1566
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001567 ast::type::Bool bool_type;
dan sinclair9b978022020-04-07 19:26:39 +00001568
Ben Claytona80511e2020-12-11 13:07:02 +00001569 auto* var =
1570 create<ast::Variable>(Source{}, // source
1571 "val", // name
1572 ast::StorageClass::kNone, // storage_class
1573 &bool_type, // type
1574 false, // is_const
1575 nullptr, // constructor
1576 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001577 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001578
1579 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001580 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001581
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001582 ast::BinaryExpression expr(Source{}, op,
1583 create<ast::IdentifierExpression>(
1584 Source{}, mod->RegisterSymbol("val"), "val"),
1585 create<ast::IdentifierExpression>(
1586 Source{}, mod->RegisterSymbol("val"), "val"));
dan sinclair9b978022020-04-07 19:26:39 +00001587
dan sinclaircd077b02020-04-20 14:19:04 +00001588 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001589 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001590 EXPECT_TRUE(expr.result_type()->Is<ast::type::Bool>());
dan sinclair9b978022020-04-07 19:26:39 +00001591}
1592
dan sinclair1c9b4862020-04-07 19:27:41 +00001593TEST_P(Expr_Binary_LogicalTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001594 auto op = GetParam();
1595
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001596 ast::type::Bool bool_type;
1597 ast::type::Vector vec3(&bool_type, 3);
dan sinclair9b978022020-04-07 19:26:39 +00001598
Ben Clayton321e5a92020-12-07 21:08:07 +00001599 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00001600 create<ast::Variable>(Source{}, // source
1601 "val", // name
1602 ast::StorageClass::kNone, // storage_class
1603 &vec3, // type
1604 false, // is_const
1605 nullptr, // constructor
1606 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001607 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001608
1609 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001610 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001611
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001612 ast::BinaryExpression expr(Source{}, op,
1613 create<ast::IdentifierExpression>(
1614 Source{}, mod->RegisterSymbol("val"), "val"),
1615 create<ast::IdentifierExpression>(
1616 Source{}, mod->RegisterSymbol("val"), "val"));
dan sinclair9b978022020-04-07 19:26:39 +00001617
dan sinclaircd077b02020-04-20 14:19:04 +00001618 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001619 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001620 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00001621 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001622 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001623 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001624 ->Is<ast::type::Bool>());
1625 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001626}
1627INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +00001628 Expr_Binary_LogicalTest,
1629 testing::Values(ast::BinaryOp::kLogicalAnd,
1630 ast::BinaryOp::kLogicalOr));
dan sinclair9b978022020-04-07 19:26:39 +00001631
dan sinclaircd077b02020-04-20 14:19:04 +00001632using Expr_Binary_CompareTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +00001633TEST_P(Expr_Binary_CompareTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001634 auto op = GetParam();
1635
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001636 ast::type::I32 i32;
dan sinclair9b978022020-04-07 19:26:39 +00001637
Ben Clayton321e5a92020-12-07 21:08:07 +00001638 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00001639 create<ast::Variable>(Source{}, // source
1640 "val", // name
1641 ast::StorageClass::kNone, // storage_class
1642 &i32, // type
1643 false, // is_const
1644 nullptr, // constructor
1645 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001646 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001647
1648 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001649 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001650
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001651 ast::BinaryExpression expr(Source{}, op,
1652 create<ast::IdentifierExpression>(
1653 Source{}, mod->RegisterSymbol("val"), "val"),
1654 create<ast::IdentifierExpression>(
1655 Source{}, mod->RegisterSymbol("val"), "val"));
dan sinclair9b978022020-04-07 19:26:39 +00001656
dan sinclaircd077b02020-04-20 14:19:04 +00001657 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001658 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001659 EXPECT_TRUE(expr.result_type()->Is<ast::type::Bool>());
dan sinclair9b978022020-04-07 19:26:39 +00001660}
1661
dan sinclair1c9b4862020-04-07 19:27:41 +00001662TEST_P(Expr_Binary_CompareTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001663 auto op = GetParam();
1664
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001665 ast::type::I32 i32;
1666 ast::type::Vector vec3(&i32, 3);
dan sinclair9b978022020-04-07 19:26:39 +00001667
Ben Clayton321e5a92020-12-07 21:08:07 +00001668 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00001669 create<ast::Variable>(Source{}, // source
1670 "val", // name
1671 ast::StorageClass::kNone, // storage_class
1672 &vec3, // type
1673 false, // is_const
1674 nullptr, // constructor
1675 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001676 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001677
1678 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001679 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001680
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001681 ast::BinaryExpression expr(Source{}, op,
1682 create<ast::IdentifierExpression>(
1683 Source{}, mod->RegisterSymbol("val"), "val"),
1684 create<ast::IdentifierExpression>(
1685 Source{}, mod->RegisterSymbol("val"), "val"));
dan sinclair9b978022020-04-07 19:26:39 +00001686
dan sinclaircd077b02020-04-20 14:19:04 +00001687 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001688 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001689 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00001690 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001691 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001692 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001693 ->Is<ast::type::Bool>());
1694 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001695}
1696INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +00001697 Expr_Binary_CompareTest,
1698 testing::Values(ast::BinaryOp::kEqual,
1699 ast::BinaryOp::kNotEqual,
1700 ast::BinaryOp::kLessThan,
1701 ast::BinaryOp::kGreaterThan,
1702 ast::BinaryOp::kLessThanEqual,
1703 ast::BinaryOp::kGreaterThanEqual));
dan sinclair9b978022020-04-07 19:26:39 +00001704
dan sinclair1c9b4862020-04-07 19:27:41 +00001705TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Scalar) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001706 ast::type::I32 i32;
dan sinclair9b978022020-04-07 19:26:39 +00001707
Ben Clayton321e5a92020-12-07 21:08:07 +00001708 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00001709 create<ast::Variable>(Source{}, // source
1710 "val", // name
1711 ast::StorageClass::kNone, // storage_class
1712 &i32, // type
1713 false, // is_const
1714 nullptr, // constructor
1715 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001716 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001717
1718 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001719 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001720
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001721 ast::BinaryExpression expr(Source{}, ast::BinaryOp::kMultiply,
1722 create<ast::IdentifierExpression>(
1723 Source{}, mod->RegisterSymbol("val"), "val"),
1724 create<ast::IdentifierExpression>(
1725 Source{}, mod->RegisterSymbol("val"), "val"));
dan sinclair9b978022020-04-07 19:26:39 +00001726
dan sinclaircd077b02020-04-20 14:19:04 +00001727 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001728 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001729 EXPECT_TRUE(expr.result_type()->Is<ast::type::I32>());
dan sinclair9b978022020-04-07 19:26:39 +00001730}
1731
dan sinclair1c9b4862020-04-07 19:27:41 +00001732TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Scalar) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001733 ast::type::F32 f32;
1734 ast::type::Vector vec3(&f32, 3);
dan sinclair9b978022020-04-07 19:26:39 +00001735
Ben Claytonb053acf2020-11-16 16:31:07 +00001736 auto* scalar =
Ben Claytona80511e2020-12-11 13:07:02 +00001737 create<ast::Variable>(Source{}, // source
1738 "scalar", // name
1739 ast::StorageClass::kNone, // storage_class
1740 &f32, // type
1741 false, // is_const
1742 nullptr, // constructor
1743 ast::VariableDecorationList{}); // decorations
1744 auto* vector =
1745 create<ast::Variable>(Source{}, // source
1746 "vector", // name
1747 ast::StorageClass::kNone, // storage_class
1748 &vec3, // type
1749 false, // is_const
1750 nullptr, // constructor
1751 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001752 mod->AddGlobalVariable(scalar);
1753 mod->AddGlobalVariable(vector);
dan sinclair9b978022020-04-07 19:26:39 +00001754
1755 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001756 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001757
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001758 ast::BinaryExpression expr(
1759 Source{}, ast::BinaryOp::kMultiply,
1760 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("vector"),
1761 "vector"),
1762 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("scalar"),
1763 "scalar"));
dan sinclair9b978022020-04-07 19:26:39 +00001764
dan sinclaircd077b02020-04-20 14:19:04 +00001765 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001766 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001767 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00001768 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001769 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001770 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001771 ->Is<ast::type::F32>());
1772 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001773}
1774
dan sinclair1c9b4862020-04-07 19:27:41 +00001775TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Vector) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001776 ast::type::F32 f32;
1777 ast::type::Vector vec3(&f32, 3);
dan sinclair9b978022020-04-07 19:26:39 +00001778
Ben Claytonb053acf2020-11-16 16:31:07 +00001779 auto* scalar =
Ben Claytona80511e2020-12-11 13:07:02 +00001780 create<ast::Variable>(Source{}, // source
1781 "scalar", // name
1782 ast::StorageClass::kNone, // storage_class
1783 &f32, // type
1784 false, // is_const
1785 nullptr, // constructor
1786 ast::VariableDecorationList{}); // decorations
1787 auto* vector =
1788 create<ast::Variable>(Source{}, // source
1789 "vector", // name
1790 ast::StorageClass::kNone, // storage_class
1791 &vec3, // type
1792 false, // is_const
1793 nullptr, // constructor
1794 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001795 mod->AddGlobalVariable(scalar);
1796 mod->AddGlobalVariable(vector);
dan sinclair9b978022020-04-07 19:26:39 +00001797
1798 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001799 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001800
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001801 ast::BinaryExpression expr(
1802 Source{}, ast::BinaryOp::kMultiply,
1803 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("scalar"),
1804 "scalar"),
1805 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("vector"),
1806 "vector"));
dan sinclair9b978022020-04-07 19:26:39 +00001807
dan sinclaircd077b02020-04-20 14:19:04 +00001808 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001809 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001810 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00001811 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001812 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001813 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001814 ->Is<ast::type::F32>());
1815 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001816}
1817
dan sinclair1c9b4862020-04-07 19:27:41 +00001818TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Vector) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001819 ast::type::F32 f32;
1820 ast::type::Vector vec3(&f32, 3);
dan sinclair9b978022020-04-07 19:26:39 +00001821
Ben Claytona80511e2020-12-11 13:07:02 +00001822 auto* vector =
1823 create<ast::Variable>(Source{}, // source
1824 "vector", // name
1825 ast::StorageClass::kNone, // storage_class
1826 &vec3, // type
1827 false, // is_const
1828 nullptr, // constructor
1829 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001830 mod->AddGlobalVariable(vector);
dan sinclair9b978022020-04-07 19:26:39 +00001831
1832 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001833 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001834
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001835 ast::BinaryExpression expr(
1836 Source{}, ast::BinaryOp::kMultiply,
1837 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("vector"),
1838 "vector"),
1839 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("vector"),
1840 "vector"));
dan sinclair9b978022020-04-07 19:26:39 +00001841
dan sinclaircd077b02020-04-20 14:19:04 +00001842 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001843 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001844 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00001845 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001846 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001847 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001848 ->Is<ast::type::F32>());
1849 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001850}
1851
dan sinclair1c9b4862020-04-07 19:27:41 +00001852TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Scalar) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001853 ast::type::F32 f32;
1854 ast::type::Matrix mat3x2(&f32, 3, 2);
dan sinclair9b978022020-04-07 19:26:39 +00001855
Ben Claytonb053acf2020-11-16 16:31:07 +00001856 auto* scalar =
Ben Claytona80511e2020-12-11 13:07:02 +00001857 create<ast::Variable>(Source{}, // source
1858 "scalar", // name
1859 ast::StorageClass::kNone, // storage_class
1860 &f32, // type
1861 false, // is_const
1862 nullptr, // constructor
1863 ast::VariableDecorationList{}); // decorations
1864 auto* matrix =
1865 create<ast::Variable>(Source{}, // source
1866 "matrix", // name
1867 ast::StorageClass::kNone, // storage_class
1868 &mat3x2, // type
1869 false, // is_const
1870 nullptr, // constructor
1871 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001872 mod->AddGlobalVariable(scalar);
1873 mod->AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001874
1875 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001876 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001877
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001878 ast::BinaryExpression expr(
1879 Source{}, ast::BinaryOp::kMultiply,
1880 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("matrix"),
1881 "matrix"),
1882 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("scalar"),
1883 "scalar"));
dan sinclair9b978022020-04-07 19:26:39 +00001884
dan sinclaircd077b02020-04-20 14:19:04 +00001885 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001886 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001887 ASSERT_TRUE(expr.result_type()->Is<ast::type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001888
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001889 auto* mat = expr.result_type()->As<ast::type::Matrix>();
1890 EXPECT_TRUE(mat->type()->Is<ast::type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001891 EXPECT_EQ(mat->rows(), 3u);
1892 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001893}
1894
dan sinclair1c9b4862020-04-07 19:27:41 +00001895TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Matrix) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001896 ast::type::F32 f32;
1897 ast::type::Matrix mat3x2(&f32, 3, 2);
dan sinclair9b978022020-04-07 19:26:39 +00001898
Ben Claytonb053acf2020-11-16 16:31:07 +00001899 auto* scalar =
Ben Claytona80511e2020-12-11 13:07:02 +00001900 create<ast::Variable>(Source{}, // source
1901 "scalar", // name
1902 ast::StorageClass::kNone, // storage_class
1903 &f32, // type
1904 false, // is_const
1905 nullptr, // constructor
1906 ast::VariableDecorationList{}); // decorations
1907 auto* matrix =
1908 create<ast::Variable>(Source{}, // source
1909 "matrix", // name
1910 ast::StorageClass::kNone, // storage_class
1911 &mat3x2, // type
1912 false, // is_const
1913 nullptr, // constructor
1914 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001915 mod->AddGlobalVariable(scalar);
1916 mod->AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001917
1918 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001919 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001920
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001921 ast::BinaryExpression expr(
1922 Source{}, ast::BinaryOp::kMultiply,
1923 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("scalar"),
1924 "scalar"),
1925 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("matrix"),
1926 "matrix"));
dan sinclair9b978022020-04-07 19:26:39 +00001927
dan sinclaircd077b02020-04-20 14:19:04 +00001928 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001929 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001930 ASSERT_TRUE(expr.result_type()->Is<ast::type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001931
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001932 auto* mat = expr.result_type()->As<ast::type::Matrix>();
1933 EXPECT_TRUE(mat->type()->Is<ast::type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001934 EXPECT_EQ(mat->rows(), 3u);
1935 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001936}
1937
dan sinclair1c9b4862020-04-07 19:27:41 +00001938TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Vector) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001939 ast::type::F32 f32;
1940 ast::type::Vector vec3(&f32, 2);
1941 ast::type::Matrix mat3x2(&f32, 3, 2);
dan sinclair9b978022020-04-07 19:26:39 +00001942
Ben Claytona80511e2020-12-11 13:07:02 +00001943 auto* vector =
1944 create<ast::Variable>(Source{}, // source
1945 "vector", // name
1946 ast::StorageClass::kNone, // storage_class
1947 &vec3, // type
1948 false, // is_const
1949 nullptr, // constructor
1950 ast::VariableDecorationList{}); // decorations
1951 auto* matrix =
1952 create<ast::Variable>(Source{}, // source
1953 "matrix", // name
1954 ast::StorageClass::kNone, // storage_class
1955 &mat3x2, // type
1956 false, // is_const
1957 nullptr, // constructor
1958 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001959 mod->AddGlobalVariable(vector);
1960 mod->AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001961
1962 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001963 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001964
Ben Clayton1ff59cd2020-12-12 01:38:13 +00001965 ast::BinaryExpression expr(
1966 Source{}, ast::BinaryOp::kMultiply,
1967 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("matrix"),
1968 "matrix"),
1969 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("vector"),
1970 "vector"));
dan sinclair9b978022020-04-07 19:26:39 +00001971
dan sinclaircd077b02020-04-20 14:19:04 +00001972 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001973 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001974 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00001975 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001976 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001977 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001978 ->Is<ast::type::F32>());
1979 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001980}
1981
dan sinclair1c9b4862020-04-07 19:27:41 +00001982TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Matrix) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001983 ast::type::F32 f32;
1984 ast::type::Vector vec3(&f32, 3);
1985 ast::type::Matrix mat3x2(&f32, 3, 2);
dan sinclair9b978022020-04-07 19:26:39 +00001986
Ben Claytona80511e2020-12-11 13:07:02 +00001987 auto* vector =
1988 create<ast::Variable>(Source{}, // source
1989 "vector", // name
1990 ast::StorageClass::kNone, // storage_class
1991 &vec3, // type
1992 false, // is_const
1993 nullptr, // constructor
1994 ast::VariableDecorationList{}); // decorations
1995 auto* matrix =
1996 create<ast::Variable>(Source{}, // source
1997 "matrix", // name
1998 ast::StorageClass::kNone, // storage_class
1999 &mat3x2, // type
2000 false, // is_const
2001 nullptr, // constructor
2002 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002003 mod->AddGlobalVariable(vector);
2004 mod->AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00002005
2006 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00002007 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00002008
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002009 ast::BinaryExpression expr(
2010 Source{}, ast::BinaryOp::kMultiply,
2011 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("vector"),
2012 "vector"),
2013 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("matrix"),
2014 "matrix"));
dan sinclair9b978022020-04-07 19:26:39 +00002015
dan sinclaircd077b02020-04-20 14:19:04 +00002016 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00002017 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002018 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00002019 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002020 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002021 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002022 ->Is<ast::type::F32>());
2023 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00002024}
2025
dan sinclair1c9b4862020-04-07 19:27:41 +00002026TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Matrix) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002027 ast::type::F32 f32;
2028 ast::type::Matrix mat4x3(&f32, 4, 3);
2029 ast::type::Matrix mat3x4(&f32, 3, 4);
dan sinclair9b978022020-04-07 19:26:39 +00002030
Ben Claytona80511e2020-12-11 13:07:02 +00002031 auto* matrix1 =
2032 create<ast::Variable>(Source{}, // source
2033 "mat4x3", // name
2034 ast::StorageClass::kNone, // storage_class
2035 &mat4x3, // type
2036 false, // is_const
2037 nullptr, // constructor
2038 ast::VariableDecorationList{}); // decorations
2039 auto* matrix2 =
2040 create<ast::Variable>(Source{}, // source
2041 "mat3x4", // name
2042 ast::StorageClass::kNone, // storage_class
2043 &mat3x4, // type
2044 false, // is_const
2045 nullptr, // constructor
2046 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002047 mod->AddGlobalVariable(matrix1);
2048 mod->AddGlobalVariable(matrix2);
dan sinclair9b978022020-04-07 19:26:39 +00002049
2050 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00002051 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00002052
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002053 ast::BinaryExpression expr(
2054 Source{}, ast::BinaryOp::kMultiply,
2055 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("mat4x3"),
2056 "mat4x3"),
2057 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("mat3x4"),
2058 "mat3x4"));
dan sinclair9b978022020-04-07 19:26:39 +00002059
dan sinclaircd077b02020-04-20 14:19:04 +00002060 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00002061 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002062 ASSERT_TRUE(expr.result_type()->Is<ast::type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00002063
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002064 auto* mat = expr.result_type()->As<ast::type::Matrix>();
2065 EXPECT_TRUE(mat->type()->Is<ast::type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00002066 EXPECT_EQ(mat->rows(), 4u);
2067 EXPECT_EQ(mat->columns(), 4u);
dan sinclair9b978022020-04-07 19:26:39 +00002068}
2069
dan sinclair46e959d2020-06-01 13:43:22 +00002070using IntrinsicDerivativeTest = TypeDeterminerTestWithParam<std::string>;
2071TEST_P(IntrinsicDerivativeTest, Scalar) {
2072 auto name = GetParam();
dan sinclairb1730562020-04-07 19:26:49 +00002073
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002074 ast::type::F32 f32;
dan sinclairb1730562020-04-07 19:26:49 +00002075
Ben Clayton321e5a92020-12-07 21:08:07 +00002076 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002077 create<ast::Variable>(Source{}, // source
2078 "ident", // name
2079 ast::StorageClass::kNone, // storage_class
2080 &f32, // type
2081 false, // is_const
2082 nullptr, // constructor
2083 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002084 mod->AddGlobalVariable(var);
dan sinclair46e959d2020-06-01 13:43:22 +00002085
2086 // Register the global
2087 EXPECT_TRUE(td()->Determine());
2088
2089 ast::ExpressionList call_params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002090 call_params.push_back(create<ast::IdentifierExpression>(
2091 Source{}, mod->RegisterSymbol("ident"), "ident"));
dan sinclair46e959d2020-06-01 13:43:22 +00002092
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002093 ast::CallExpression expr(Source{},
2094 create<ast::IdentifierExpression>(
2095 Source{}, mod->RegisterSymbol(name), name),
2096 call_params);
dan sinclair46e959d2020-06-01 13:43:22 +00002097 EXPECT_TRUE(td()->DetermineResultType(&expr));
2098
2099 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002100 ASSERT_TRUE(expr.result_type()->Is<ast::type::F32>());
dan sinclair46e959d2020-06-01 13:43:22 +00002101}
2102
2103TEST_P(IntrinsicDerivativeTest, Vector) {
2104 auto name = GetParam();
2105
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002106 ast::type::F32 f32;
2107 ast::type::Vector vec4(&f32, 4);
dan sinclairb1730562020-04-07 19:26:49 +00002108
Ben Clayton321e5a92020-12-07 21:08:07 +00002109 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002110 create<ast::Variable>(Source{}, // source
2111 "ident", // name
2112 ast::StorageClass::kNone, // storage_class
2113 &vec4, // type
2114 false, // is_const
2115 nullptr, // constructor
2116 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002117 mod->AddGlobalVariable(var);
dan sinclairb1730562020-04-07 19:26:49 +00002118
2119 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00002120 EXPECT_TRUE(td()->Determine());
dan sinclairb1730562020-04-07 19:26:49 +00002121
dan sinclair46e959d2020-06-01 13:43:22 +00002122 ast::ExpressionList call_params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002123 call_params.push_back(create<ast::IdentifierExpression>(
2124 Source{}, mod->RegisterSymbol("ident"), "ident"));
dan sinclair46e959d2020-06-01 13:43:22 +00002125
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002126 ast::CallExpression expr(Source{},
2127 create<ast::IdentifierExpression>(
2128 Source{}, mod->RegisterSymbol(name), name),
2129 call_params);
dan sinclair46e959d2020-06-01 13:43:22 +00002130 EXPECT_TRUE(td()->DetermineResultType(&expr));
2131
2132 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002133 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00002134 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002135 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002136 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002137 ->Is<ast::type::F32>());
2138 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 4u);
dan sinclair46e959d2020-06-01 13:43:22 +00002139}
2140
2141TEST_P(IntrinsicDerivativeTest, MissingParam) {
2142 auto name = GetParam();
2143
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002144 ast::type::F32 f32;
2145 ast::type::Vector vec4(&f32, 4);
dan sinclair46e959d2020-06-01 13:43:22 +00002146
2147 // Register the global
2148 EXPECT_TRUE(td()->Determine());
2149
2150 ast::ExpressionList call_params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002151 ast::CallExpression expr(Source{},
2152 create<ast::IdentifierExpression>(
2153 Source{}, mod->RegisterSymbol(name), name),
2154 call_params);
dan sinclair46e959d2020-06-01 13:43:22 +00002155 EXPECT_FALSE(td()->DetermineResultType(&expr));
2156 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
2157}
2158
2159TEST_P(IntrinsicDerivativeTest, ToomManyParams) {
2160 auto name = GetParam();
2161
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002162 ast::type::F32 f32;
2163 ast::type::Vector vec4(&f32, 4);
dan sinclair46e959d2020-06-01 13:43:22 +00002164
Ben Claytona80511e2020-12-11 13:07:02 +00002165 auto* var1 =
2166 create<ast::Variable>(Source{}, // source
2167 "ident1", // name
2168 ast::StorageClass::kNone, // storage_class
2169 &vec4, // type
2170 false, // is_const
2171 nullptr, // constructor
2172 ast::VariableDecorationList{}); // decorations
2173 auto* var2 =
2174 create<ast::Variable>(Source{}, // source
2175 "ident2", // name
2176 ast::StorageClass::kNone, // storage_class
2177 &vec4, // type
2178 false, // is_const
2179 nullptr, // constructor
2180 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002181 mod->AddGlobalVariable(var1);
2182 mod->AddGlobalVariable(var2);
dan sinclair46e959d2020-06-01 13:43:22 +00002183
2184 // Register the global
2185 EXPECT_TRUE(td()->Determine());
2186
2187 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002188 call_params.push_back(create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002189 Source{}, mod->RegisterSymbol("ident1"), "ident1"));
dan sinclair6b59bf42020-12-11 19:16:13 +00002190 call_params.push_back(create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002191 Source{}, mod->RegisterSymbol("ident2"), "ident2"));
dan sinclair46e959d2020-06-01 13:43:22 +00002192
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002193 ast::CallExpression expr(Source{},
2194 create<ast::IdentifierExpression>(
2195 Source{}, mod->RegisterSymbol(name), name),
2196 call_params);
dan sinclair46e959d2020-06-01 13:43:22 +00002197 EXPECT_FALSE(td()->DetermineResultType(&expr));
2198 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
dan sinclairb1730562020-04-07 19:26:49 +00002199}
2200INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair46e959d2020-06-01 13:43:22 +00002201 IntrinsicDerivativeTest,
2202 testing::Values("dpdx",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00002203 "dpdxCoarse",
2204 "dpdxFine",
dan sinclair46e959d2020-06-01 13:43:22 +00002205 "dpdy",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00002206 "dpdyCoarse",
2207 "dpdyFine",
dan sinclair46e959d2020-06-01 13:43:22 +00002208 "fwidth",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00002209 "fwidthCoarse",
2210 "fwidthFine"));
dan sinclairb1730562020-04-07 19:26:49 +00002211
dan sinclair46e959d2020-06-01 13:43:22 +00002212using Intrinsic = TypeDeterminerTestWithParam<std::string>;
2213TEST_P(Intrinsic, Test) {
2214 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00002215
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002216 ast::type::Bool bool_type;
2217 ast::type::Vector vec3(&bool_type, 3);
dan sinclair8dcfd102020-04-07 19:27:00 +00002218
Ben Claytona80511e2020-12-11 13:07:02 +00002219 auto* var =
2220 create<ast::Variable>(Source{}, // source
2221 "my_var", // name
2222 ast::StorageClass::kNone, // storage_class
2223 &vec3, // type
2224 false, // is_const
2225 nullptr, // constructor
2226 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002227 mod->AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00002228
dan sinclair46e959d2020-06-01 13:43:22 +00002229 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002230 call_params.push_back(create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002231 Source{}, mod->RegisterSymbol("my_var"), "my_var"));
dan sinclair8dcfd102020-04-07 19:27:00 +00002232
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002233 ast::CallExpression expr(Source{},
2234 create<ast::IdentifierExpression>(
2235 Source{}, mod->RegisterSymbol(name), name),
2236 call_params);
dan sinclair8dcfd102020-04-07 19:27:00 +00002237
dan sinclair8dcfd102020-04-07 19:27:00 +00002238 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00002239 EXPECT_TRUE(td()->Determine());
dan sinclair8dcfd102020-04-07 19:27:00 +00002240
dan sinclair46e959d2020-06-01 13:43:22 +00002241 EXPECT_TRUE(td()->DetermineResultType(&expr));
2242 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002243 EXPECT_TRUE(expr.result_type()->Is<ast::type::Bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00002244}
2245INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair46e959d2020-06-01 13:43:22 +00002246 Intrinsic,
2247 testing::Values("any", "all"));
dan sinclair8dcfd102020-04-07 19:27:00 +00002248
dan sinclair46e959d2020-06-01 13:43:22 +00002249using Intrinsic_FloatMethod = TypeDeterminerTestWithParam<std::string>;
2250TEST_P(Intrinsic_FloatMethod, Vector) {
2251 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00002252
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002253 ast::type::F32 f32;
2254 ast::type::Vector vec3(&f32, 3);
dan sinclair8dcfd102020-04-07 19:27:00 +00002255
Ben Claytona80511e2020-12-11 13:07:02 +00002256 auto* var =
2257 create<ast::Variable>(Source{}, // source
2258 "my_var", // name
2259 ast::StorageClass::kNone, // storage_class
2260 &vec3, // type
2261 false, // is_const
2262 nullptr, // constructor
2263 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002264 mod->AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00002265
dan sinclair46e959d2020-06-01 13:43:22 +00002266 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002267 call_params.push_back(create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002268 Source{}, mod->RegisterSymbol("my_var"), "my_var"));
dan sinclair8dcfd102020-04-07 19:27:00 +00002269
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002270 ast::CallExpression expr(Source{},
2271 create<ast::IdentifierExpression>(
2272 Source{}, mod->RegisterSymbol(name), name),
2273 call_params);
dan sinclair8dcfd102020-04-07 19:27:00 +00002274
dan sinclair8dcfd102020-04-07 19:27:00 +00002275 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00002276 EXPECT_TRUE(td()->Determine());
dan sinclair46e959d2020-06-01 13:43:22 +00002277 EXPECT_TRUE(td()->DetermineResultType(&expr));
dan sinclair8dcfd102020-04-07 19:27:00 +00002278
dan sinclair46e959d2020-06-01 13:43:22 +00002279 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002280 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00002281 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002282 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002283 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002284 ->Is<ast::type::Bool>());
2285 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair8dcfd102020-04-07 19:27:00 +00002286}
dan sinclair46e959d2020-06-01 13:43:22 +00002287
2288TEST_P(Intrinsic_FloatMethod, Scalar) {
2289 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00002290
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002291 ast::type::F32 f32;
dan sinclair8dcfd102020-04-07 19:27:00 +00002292
Ben Clayton321e5a92020-12-07 21:08:07 +00002293 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002294 create<ast::Variable>(Source{}, // source
2295 "my_var", // name
2296 ast::StorageClass::kNone, // storage_class
2297 &f32, // type
2298 false, // is_const
2299 nullptr, // constructor
2300 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002301 mod->AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00002302
dan sinclair46e959d2020-06-01 13:43:22 +00002303 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002304 call_params.push_back(create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002305 Source{}, mod->RegisterSymbol("my_var"), "my_var"));
dan sinclair8dcfd102020-04-07 19:27:00 +00002306
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002307 ast::CallExpression expr(Source{},
2308 create<ast::IdentifierExpression>(
2309 Source{}, mod->RegisterSymbol(name), name),
2310 call_params);
dan sinclair8dcfd102020-04-07 19:27:00 +00002311
dan sinclair8dcfd102020-04-07 19:27:00 +00002312 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00002313 EXPECT_TRUE(td()->Determine());
dan sinclair46e959d2020-06-01 13:43:22 +00002314 EXPECT_TRUE(td()->DetermineResultType(&expr));
2315 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002316 EXPECT_TRUE(expr.result_type()->Is<ast::type::Bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00002317}
dan sinclair8dcfd102020-04-07 19:27:00 +00002318
dan sinclair46e959d2020-06-01 13:43:22 +00002319TEST_P(Intrinsic_FloatMethod, MissingParam) {
2320 auto name = GetParam();
2321
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002322 ast::type::F32 f32;
dan sinclair46e959d2020-06-01 13:43:22 +00002323
Ben Clayton321e5a92020-12-07 21:08:07 +00002324 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002325 create<ast::Variable>(Source{}, // source
2326 "my_var", // name
2327 ast::StorageClass::kNone, // storage_class
2328 &f32, // type
2329 false, // is_const
2330 nullptr, // constructor
2331 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002332 mod->AddGlobalVariable(var);
dan sinclair46e959d2020-06-01 13:43:22 +00002333
2334 ast::ExpressionList call_params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002335 ast::CallExpression expr(Source{},
2336 create<ast::IdentifierExpression>(
2337 Source{}, mod->RegisterSymbol(name), name),
2338 call_params);
dan sinclair46e959d2020-06-01 13:43:22 +00002339
2340 // Register the variable
2341 EXPECT_TRUE(td()->Determine());
2342 EXPECT_FALSE(td()->DetermineResultType(&expr));
2343 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
2344}
2345
2346TEST_P(Intrinsic_FloatMethod, TooManyParams) {
2347 auto name = GetParam();
2348
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002349 ast::type::F32 f32;
dan sinclair46e959d2020-06-01 13:43:22 +00002350
Ben Clayton321e5a92020-12-07 21:08:07 +00002351 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002352 create<ast::Variable>(Source{}, // source
2353 "my_var", // name
2354 ast::StorageClass::kNone, // storage_class
2355 &f32, // type
2356 false, // is_const
2357 nullptr, // constructor
2358 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002359 mod->AddGlobalVariable(var);
dan sinclair46e959d2020-06-01 13:43:22 +00002360
2361 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002362 call_params.push_back(create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002363 Source{}, mod->RegisterSymbol("my_var"), "my_var"));
dan sinclair6b59bf42020-12-11 19:16:13 +00002364 call_params.push_back(create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002365 Source{}, mod->RegisterSymbol("my_var"), "my_var"));
dan sinclair46e959d2020-06-01 13:43:22 +00002366
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002367 ast::CallExpression expr(Source{},
2368 create<ast::IdentifierExpression>(
2369 Source{}, mod->RegisterSymbol(name), name),
2370 call_params);
dan sinclair46e959d2020-06-01 13:43:22 +00002371
2372 // Register the variable
2373 EXPECT_TRUE(td()->Determine());
2374 EXPECT_FALSE(td()->DetermineResultType(&expr));
2375 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
2376}
2377INSTANTIATE_TEST_SUITE_P(
2378 TypeDeterminerTest,
2379 Intrinsic_FloatMethod,
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00002380 testing::Values("isInf", "isNan", "isFinite", "isNormal"));
dan sinclair46e959d2020-06-01 13:43:22 +00002381
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002382enum class Texture { kF32, kI32, kU32 };
2383inline std::ostream& operator<<(std::ostream& out, Texture data) {
2384 if (data == Texture::kF32) {
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002385 out << "f32";
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002386 } else if (data == Texture::kI32) {
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002387 out << "i32";
2388 } else {
2389 out << "u32";
2390 }
2391 return out;
2392}
2393
2394struct TextureTestParams {
2395 ast::type::TextureDimension dim;
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002396 Texture type = Texture::kF32;
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002397 ast::type::ImageFormat format = ast::type::ImageFormat::kR16Float;
2398};
2399inline std::ostream& operator<<(std::ostream& out, TextureTestParams data) {
2400 out << data.dim << "_" << data.type;
2401 return out;
2402}
2403
2404class Intrinsic_TextureOperation
2405 : public TypeDeterminerTestWithParam<TextureTestParams> {
2406 public:
2407 std::unique_ptr<ast::type::Type> get_coords_type(
2408 ast::type::TextureDimension dim,
2409 ast::type::Type* type) {
2410 if (dim == ast::type::TextureDimension::k1d) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002411 if (type->Is<ast::type::I32>()) {
2412 return std::make_unique<ast::type::I32>();
2413 } else if (type->Is<ast::type::U32>()) {
2414 return std::make_unique<ast::type::U32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002415 } else {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002416 return std::make_unique<ast::type::F32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002417 }
2418 } else if (dim == ast::type::TextureDimension::k1dArray ||
dan sinclaird3f75ca2020-09-17 03:53:04 +00002419 dim == ast::type::TextureDimension::k2d) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002420 return std::make_unique<ast::type::Vector>(type, 2);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002421 } else if (dim == ast::type::TextureDimension::kCubeArray) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002422 return std::make_unique<ast::type::Vector>(type, 4);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002423 } else {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002424 return std::make_unique<ast::type::Vector>(type, 3);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002425 }
2426 }
2427
2428 void add_call_param(std::string name,
2429 ast::type::Type* type,
2430 ast::ExpressionList* call_params) {
Ben Clayton321e5a92020-12-07 21:08:07 +00002431 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002432 create<ast::Variable>(Source{}, // source
2433 name, // name
2434 ast::StorageClass::kNone, // storage_class
2435 type, // type
2436 false, // is_const
2437 nullptr, // constructor
2438 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002439 mod->AddGlobalVariable(var);
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002440 call_params->push_back(create<ast::IdentifierExpression>(
2441 Source{}, mod->RegisterSymbol(name), name));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002442 }
2443
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002444 std::unique_ptr<ast::type::Type> subtype(Texture type) {
2445 if (type == Texture::kF32) {
2446 return std::make_unique<ast::type::F32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002447 }
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002448 if (type == Texture::kI32) {
2449 return std::make_unique<ast::type::I32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002450 }
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002451 return std::make_unique<ast::type::U32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002452 }
2453};
2454
2455using Intrinsic_StorageTextureOperation = Intrinsic_TextureOperation;
2456TEST_P(Intrinsic_StorageTextureOperation, TextureLoadRo) {
2457 auto dim = GetParam().dim;
2458 auto type = GetParam().type;
2459 auto format = GetParam().format;
2460
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002461 ast::type::I32 i32;
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002462 auto coords_type = get_coords_type(dim, &i32);
2463
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002464 ast::type::Type* texture_type = mod->create<ast::type::StorageTexture>(
Ben Clayton7e4ffa02020-11-23 19:58:55 +00002465 dim, ast::AccessControl::kReadOnly, format);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002466
2467 ast::ExpressionList call_params;
2468
2469 add_call_param("texture", texture_type, &call_params);
2470 add_call_param("coords", coords_type.get(), &call_params);
2471 add_call_param("lod", &i32, &call_params);
2472
dan sinclair6b59bf42020-12-11 19:16:13 +00002473 ast::CallExpression expr(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002474 Source{},
2475 create<ast::IdentifierExpression>(
2476 Source{}, mod->RegisterSymbol("textureLoad"), "textureLoad"),
dan sinclair6b59bf42020-12-11 19:16:13 +00002477 call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002478
2479 EXPECT_TRUE(td()->Determine());
2480 EXPECT_TRUE(td()->DetermineResultType(&expr));
2481
2482 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002483 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
2484 if (type == Texture::kF32) {
Ben Clayton8a083ce2020-11-30 23:30:58 +00002485 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002486 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002487 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002488 ->Is<ast::type::F32>());
2489 } else if (type == Texture::kI32) {
Ben Clayton8a083ce2020-11-30 23:30:58 +00002490 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002491 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002492 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002493 ->Is<ast::type::I32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002494 } else {
Ben Clayton8a083ce2020-11-30 23:30:58 +00002495 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002496 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002497 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002498 ->Is<ast::type::U32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002499 }
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002500 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 4u);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002501}
2502
2503INSTANTIATE_TEST_SUITE_P(
2504 TypeDeterminerTest,
2505 Intrinsic_StorageTextureOperation,
2506 testing::Values(
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002507 TextureTestParams{ast::type::TextureDimension::k1d, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002508 ast::type::ImageFormat::kR16Float},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002509 TextureTestParams{ast::type::TextureDimension::k1d, Texture::kI32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002510 ast::type::ImageFormat::kR16Sint},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002511 TextureTestParams{ast::type::TextureDimension::k1d, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002512 ast::type::ImageFormat::kR8Unorm},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002513 TextureTestParams{ast::type::TextureDimension::k1dArray, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002514 ast::type::ImageFormat::kR16Float},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002515 TextureTestParams{ast::type::TextureDimension::k1dArray, Texture::kI32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002516 ast::type::ImageFormat::kR16Sint},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002517 TextureTestParams{ast::type::TextureDimension::k1dArray, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002518 ast::type::ImageFormat::kR8Unorm},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002519 TextureTestParams{ast::type::TextureDimension::k2d, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002520 ast::type::ImageFormat::kR16Float},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002521 TextureTestParams{ast::type::TextureDimension::k2d, Texture::kI32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002522 ast::type::ImageFormat::kR16Sint},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002523 TextureTestParams{ast::type::TextureDimension::k2d, Texture::kF32,
2524 ast::type::ImageFormat::kR8Unorm},
2525 TextureTestParams{ast::type::TextureDimension::k2dArray, Texture::kF32,
2526 ast::type::ImageFormat::kR16Float},
2527 TextureTestParams{ast::type::TextureDimension::k2dArray, Texture::kI32,
2528 ast::type::ImageFormat::kR16Sint},
2529 TextureTestParams{ast::type::TextureDimension::k2dArray, Texture::kF32,
2530 ast::type::ImageFormat::kR8Unorm},
2531 TextureTestParams{ast::type::TextureDimension::k3d, Texture::kF32,
2532 ast::type::ImageFormat::kR16Float},
2533 TextureTestParams{ast::type::TextureDimension::k3d, Texture::kI32,
2534 ast::type::ImageFormat::kR16Sint},
2535 TextureTestParams{ast::type::TextureDimension::k3d, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002536 ast::type::ImageFormat::kR8Unorm}));
2537
2538using Intrinsic_SampledTextureOperation = Intrinsic_TextureOperation;
2539TEST_P(Intrinsic_SampledTextureOperation, TextureLoadSampled) {
2540 auto dim = GetParam().dim;
2541 auto type = GetParam().type;
2542
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002543 ast::type::I32 i32;
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002544 std::unique_ptr<ast::type::Type> s = subtype(type);
2545 auto coords_type = get_coords_type(dim, &i32);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002546 auto texture_type = std::make_unique<ast::type::SampledTexture>(dim, s.get());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002547
2548 ast::ExpressionList call_params;
2549
2550 add_call_param("texture", texture_type.get(), &call_params);
2551 add_call_param("coords", coords_type.get(), &call_params);
2552 add_call_param("lod", &i32, &call_params);
2553
dan sinclair6b59bf42020-12-11 19:16:13 +00002554 ast::CallExpression expr(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002555 Source{},
2556 create<ast::IdentifierExpression>(
2557 Source{}, mod->RegisterSymbol("textureLoad"), "textureLoad"),
dan sinclair6b59bf42020-12-11 19:16:13 +00002558 call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002559
2560 EXPECT_TRUE(td()->Determine());
2561 EXPECT_TRUE(td()->DetermineResultType(&expr));
2562
2563 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002564 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
2565 if (type == Texture::kF32) {
Ben Clayton8a083ce2020-11-30 23:30:58 +00002566 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002567 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002568 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002569 ->Is<ast::type::F32>());
2570 } else if (type == Texture::kI32) {
Ben Clayton8a083ce2020-11-30 23:30:58 +00002571 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002572 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002573 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002574 ->Is<ast::type::I32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002575 } else {
Ben Clayton8a083ce2020-11-30 23:30:58 +00002576 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002577 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002578 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002579 ->Is<ast::type::U32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002580 }
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002581 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 4u);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002582}
2583
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002584INSTANTIATE_TEST_SUITE_P(
2585 TypeDeterminerTest,
2586 Intrinsic_SampledTextureOperation,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002587 testing::Values(TextureTestParams{ast::type::TextureDimension::k2d},
2588 TextureTestParams{ast::type::TextureDimension::k2dArray},
2589 TextureTestParams{ast::type::TextureDimension::kCube},
2590 TextureTestParams{
2591 ast::type::TextureDimension::kCubeArray}));
2592
dan sinclair46e959d2020-06-01 13:43:22 +00002593TEST_F(TypeDeterminerTest, Intrinsic_Dot) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002594 ast::type::F32 f32;
2595 ast::type::Vector vec3(&f32, 3);
dan sinclair8dcfd102020-04-07 19:27:00 +00002596
Ben Claytona80511e2020-12-11 13:07:02 +00002597 auto* var =
2598 create<ast::Variable>(Source{}, // source
2599 "my_var", // name
2600 ast::StorageClass::kNone, // storage_class
2601 &vec3, // type
2602 false, // is_const
2603 nullptr, // constructor
2604 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002605 mod->AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00002606
dan sinclair46e959d2020-06-01 13:43:22 +00002607 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002608 call_params.push_back(create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002609 Source{}, mod->RegisterSymbol("my_var"), "my_var"));
dan sinclair6b59bf42020-12-11 19:16:13 +00002610 call_params.push_back(create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002611 Source{}, mod->RegisterSymbol("my_var"), "my_var"));
dan sinclair8dcfd102020-04-07 19:27:00 +00002612
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002613 ast::CallExpression expr(Source{},
2614 create<ast::IdentifierExpression>(
2615 Source{}, mod->RegisterSymbol("dot"), "dot"),
2616 call_params);
dan sinclair8dcfd102020-04-07 19:27:00 +00002617
dan sinclair8dcfd102020-04-07 19:27:00 +00002618 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00002619 EXPECT_TRUE(td()->Determine());
dan sinclair46e959d2020-06-01 13:43:22 +00002620 EXPECT_TRUE(td()->DetermineResultType(&expr));
2621 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002622 EXPECT_TRUE(expr.result_type()->Is<ast::type::F32>());
dan sinclair8dcfd102020-04-07 19:27:00 +00002623}
2624
dan sinclair16a2ea12020-07-21 17:44:44 +00002625TEST_F(TypeDeterminerTest, Intrinsic_Select) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002626 ast::type::F32 f32;
2627 ast::type::Bool bool_type;
2628 ast::type::Vector vec3(&f32, 3);
2629 ast::type::Vector bool_vec3(&bool_type, 3);
dan sinclair16a2ea12020-07-21 17:44:44 +00002630
Ben Claytona80511e2020-12-11 13:07:02 +00002631 auto* var =
2632 create<ast::Variable>(Source{}, // source
2633 "my_var", // name
2634 ast::StorageClass::kNone, // storage_class
2635 &vec3, // type
2636 false, // is_const
2637 nullptr, // constructor
2638 ast::VariableDecorationList{}); // decorations
2639 auto* bool_var =
2640 create<ast::Variable>(Source{}, // source
2641 "bool_var", // name
2642 ast::StorageClass::kNone, // storage_class
2643 &bool_vec3, // type
2644 false, // is_const
2645 nullptr, // constructor
2646 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002647 mod->AddGlobalVariable(var);
2648 mod->AddGlobalVariable(bool_var);
dan sinclair16a2ea12020-07-21 17:44:44 +00002649
2650 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002651 call_params.push_back(create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002652 Source{}, mod->RegisterSymbol("my_var"), "my_var"));
dan sinclair6b59bf42020-12-11 19:16:13 +00002653 call_params.push_back(create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002654 Source{}, mod->RegisterSymbol("my_var"), "my_var"));
dan sinclair6b59bf42020-12-11 19:16:13 +00002655 call_params.push_back(create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002656 Source{}, mod->RegisterSymbol("bool_var"), "bool_var"));
dan sinclair16a2ea12020-07-21 17:44:44 +00002657
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002658 ast::CallExpression expr(
2659 Source{},
2660 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("select"),
2661 "select"),
2662 call_params);
dan sinclair16a2ea12020-07-21 17:44:44 +00002663
2664 // Register the variable
2665 EXPECT_TRUE(td()->Determine());
2666 EXPECT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
2667 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002668 EXPECT_TRUE(expr.result_type()->Is<ast::type::Vector>());
2669 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
Ben Clayton8a083ce2020-11-30 23:30:58 +00002670 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002671 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002672 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002673 ->Is<ast::type::F32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00002674}
2675
2676TEST_F(TypeDeterminerTest, Intrinsic_Select_TooFewParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002677 ast::type::F32 f32;
2678 ast::type::Vector vec3(&f32, 3);
dan sinclair16a2ea12020-07-21 17:44:44 +00002679
Ben Clayton321e5a92020-12-07 21:08:07 +00002680 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002681 create<ast::Variable>(Source{}, // source
2682 "v", // name
2683 ast::StorageClass::kNone, // storage_class
2684 &vec3, // type
2685 false, // is_const
2686 nullptr, // constructor
2687 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002688 mod->AddGlobalVariable(var);
dan sinclair16a2ea12020-07-21 17:44:44 +00002689
2690 ast::ExpressionList call_params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002691 call_params.push_back(create<ast::IdentifierExpression>(
2692 Source{}, mod->RegisterSymbol("v"), "v"));
dan sinclair16a2ea12020-07-21 17:44:44 +00002693
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002694 ast::CallExpression expr(
2695 Source{},
2696 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("select"),
2697 "select"),
2698 call_params);
dan sinclair16a2ea12020-07-21 17:44:44 +00002699
2700 // Register the variable
2701 EXPECT_TRUE(td()->Determine());
2702 EXPECT_FALSE(td()->DetermineResultType(&expr));
2703 EXPECT_EQ(td()->error(),
2704 "incorrect number of parameters for select expected 3 got 1");
2705}
2706
2707TEST_F(TypeDeterminerTest, Intrinsic_Select_TooManyParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002708 ast::type::F32 f32;
2709 ast::type::Vector vec3(&f32, 3);
dan sinclair16a2ea12020-07-21 17:44:44 +00002710
Ben Clayton321e5a92020-12-07 21:08:07 +00002711 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002712 create<ast::Variable>(Source{}, // source
2713 "v", // name
2714 ast::StorageClass::kNone, // storage_class
2715 &vec3, // type
2716 false, // is_const
2717 nullptr, // constructor
2718 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002719 mod->AddGlobalVariable(var);
dan sinclair16a2ea12020-07-21 17:44:44 +00002720
2721 ast::ExpressionList call_params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002722 call_params.push_back(create<ast::IdentifierExpression>(
2723 Source{}, mod->RegisterSymbol("v"), "v"));
2724 call_params.push_back(create<ast::IdentifierExpression>(
2725 Source{}, mod->RegisterSymbol("v"), "v"));
2726 call_params.push_back(create<ast::IdentifierExpression>(
2727 Source{}, mod->RegisterSymbol("v"), "v"));
2728 call_params.push_back(create<ast::IdentifierExpression>(
2729 Source{}, mod->RegisterSymbol("v"), "v"));
dan sinclair16a2ea12020-07-21 17:44:44 +00002730
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002731 ast::CallExpression expr(
2732 Source{},
2733 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("select"),
2734 "select"),
2735 call_params);
dan sinclair16a2ea12020-07-21 17:44:44 +00002736
2737 // Register the variable
2738 EXPECT_TRUE(td()->Determine());
2739 EXPECT_FALSE(td()->DetermineResultType(&expr));
2740 EXPECT_EQ(td()->error(),
2741 "incorrect number of parameters for select expected 3 got 4");
2742}
2743
dan sinclair46e959d2020-06-01 13:43:22 +00002744TEST_F(TypeDeterminerTest, Intrinsic_OuterProduct) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002745 ast::type::F32 f32;
2746 ast::type::Vector vec3(&f32, 3);
2747 ast::type::Vector vec2(&f32, 2);
dan sinclair8dcfd102020-04-07 19:27:00 +00002748
Ben Clayton321e5a92020-12-07 21:08:07 +00002749 auto* var1 =
Ben Claytona80511e2020-12-11 13:07:02 +00002750 create<ast::Variable>(Source{}, // source
2751 "v3", // name
2752 ast::StorageClass::kNone, // storage_class
2753 &vec3, // type
2754 false, // is_const
2755 nullptr, // constructor
2756 ast::VariableDecorationList{}); // decorations
Ben Clayton321e5a92020-12-07 21:08:07 +00002757 auto* var2 =
Ben Claytona80511e2020-12-11 13:07:02 +00002758 create<ast::Variable>(Source{}, // source
2759 "v2", // name
2760 ast::StorageClass::kNone, // storage_class
2761 &vec2, // type
2762 false, // is_const
2763 nullptr, // constructor
2764 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002765 mod->AddGlobalVariable(var1);
2766 mod->AddGlobalVariable(var2);
dan sinclair8dcfd102020-04-07 19:27:00 +00002767
dan sinclair46e959d2020-06-01 13:43:22 +00002768 ast::ExpressionList call_params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002769 call_params.push_back(create<ast::IdentifierExpression>(
2770 Source{}, mod->RegisterSymbol("v3"), "v3"));
2771 call_params.push_back(create<ast::IdentifierExpression>(
2772 Source{}, mod->RegisterSymbol("v2"), "v2"));
dan sinclair8dcfd102020-04-07 19:27:00 +00002773
dan sinclair6b59bf42020-12-11 19:16:13 +00002774 ast::CallExpression expr(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002775 Source{},
2776 create<ast::IdentifierExpression>(
2777 Source{}, mod->RegisterSymbol("outerProduct"), "outerProduct"),
dan sinclair6b59bf42020-12-11 19:16:13 +00002778 call_params);
dan sinclair8dcfd102020-04-07 19:27:00 +00002779
dan sinclair8dcfd102020-04-07 19:27:00 +00002780 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00002781 EXPECT_TRUE(td()->Determine());
dan sinclair46e959d2020-06-01 13:43:22 +00002782 EXPECT_TRUE(td()->DetermineResultType(&expr));
dan sinclair8dcfd102020-04-07 19:27:00 +00002783
dan sinclair46e959d2020-06-01 13:43:22 +00002784 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002785 ASSERT_TRUE(expr.result_type()->Is<ast::type::Matrix>());
dan sinclair46e959d2020-06-01 13:43:22 +00002786
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002787 auto* mat = expr.result_type()->As<ast::type::Matrix>();
2788 EXPECT_TRUE(mat->type()->Is<ast::type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00002789 EXPECT_EQ(mat->rows(), 3u);
2790 EXPECT_EQ(mat->columns(), 2u);
dan sinclair8dcfd102020-04-07 19:27:00 +00002791}
2792
dan sinclair46e959d2020-06-01 13:43:22 +00002793TEST_F(TypeDeterminerTest, Intrinsic_OuterProduct_TooFewParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002794 ast::type::F32 f32;
2795 ast::type::Vector vec3(&f32, 3);
2796 ast::type::Vector vec2(&f32, 2);
dan sinclair46e959d2020-06-01 13:43:22 +00002797
Ben Clayton321e5a92020-12-07 21:08:07 +00002798 auto* var2 =
Ben Claytona80511e2020-12-11 13:07:02 +00002799 create<ast::Variable>(Source{}, // source
2800 "v2", // name
2801 ast::StorageClass::kNone, // storage_class
2802 &vec2, // type
2803 false, // is_const
2804 nullptr, // constructor
2805 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002806 mod->AddGlobalVariable(var2);
dan sinclair46e959d2020-06-01 13:43:22 +00002807
2808 ast::ExpressionList call_params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002809 call_params.push_back(create<ast::IdentifierExpression>(
2810 Source{}, mod->RegisterSymbol("v2"), "v2"));
dan sinclair46e959d2020-06-01 13:43:22 +00002811
dan sinclair6b59bf42020-12-11 19:16:13 +00002812 ast::CallExpression expr(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002813 Source{},
2814 create<ast::IdentifierExpression>(
2815 Source{}, mod->RegisterSymbol("outerProduct"), "outerProduct"),
dan sinclair6b59bf42020-12-11 19:16:13 +00002816 call_params);
dan sinclair46e959d2020-06-01 13:43:22 +00002817
2818 // Register the variable
2819 EXPECT_TRUE(td()->Determine());
2820 EXPECT_FALSE(td()->DetermineResultType(&expr));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002821 EXPECT_EQ(td()->error(), "incorrect number of parameters for outerProduct");
dan sinclair46e959d2020-06-01 13:43:22 +00002822}
2823
2824TEST_F(TypeDeterminerTest, Intrinsic_OuterProduct_TooManyParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002825 ast::type::F32 f32;
2826 ast::type::Vector vec3(&f32, 3);
2827 ast::type::Vector vec2(&f32, 2);
dan sinclair46e959d2020-06-01 13:43:22 +00002828
Ben Clayton321e5a92020-12-07 21:08:07 +00002829 auto* var2 =
Ben Claytona80511e2020-12-11 13:07:02 +00002830 create<ast::Variable>(Source{}, // source
2831 "v2", // name
2832 ast::StorageClass::kNone, // storage_class
2833 &vec2, // type
2834 false, // is_const
2835 nullptr, // constructor
2836 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002837 mod->AddGlobalVariable(var2);
dan sinclair46e959d2020-06-01 13:43:22 +00002838
2839 ast::ExpressionList call_params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002840 call_params.push_back(create<ast::IdentifierExpression>(
2841 Source{}, mod->RegisterSymbol("v2"), "v2"));
2842 call_params.push_back(create<ast::IdentifierExpression>(
2843 Source{}, mod->RegisterSymbol("v2"), "v2"));
2844 call_params.push_back(create<ast::IdentifierExpression>(
2845 Source{}, mod->RegisterSymbol("v2"), "v2"));
dan sinclair46e959d2020-06-01 13:43:22 +00002846
dan sinclair6b59bf42020-12-11 19:16:13 +00002847 ast::CallExpression expr(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002848 Source{},
2849 create<ast::IdentifierExpression>(
2850 Source{}, mod->RegisterSymbol("outerProduct"), "outerProduct"),
dan sinclair6b59bf42020-12-11 19:16:13 +00002851 call_params);
dan sinclair46e959d2020-06-01 13:43:22 +00002852
2853 // Register the variable
2854 EXPECT_TRUE(td()->Determine());
2855 EXPECT_FALSE(td()->DetermineResultType(&expr));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002856 EXPECT_EQ(td()->error(), "incorrect number of parameters for outerProduct");
dan sinclair46e959d2020-06-01 13:43:22 +00002857}
2858
dan sinclaircd077b02020-04-20 14:19:04 +00002859using UnaryOpExpressionTest = TypeDeterminerTestWithParam<ast::UnaryOp>;
dan sinclair0e257622020-04-07 19:27:11 +00002860TEST_P(UnaryOpExpressionTest, Expr_UnaryOp) {
2861 auto op = GetParam();
2862
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002863 ast::type::F32 f32;
dan sinclair0e257622020-04-07 19:27:11 +00002864
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002865 ast::type::Vector vec4(&f32, 4);
dan sinclair0e257622020-04-07 19:27:11 +00002866
Ben Clayton321e5a92020-12-07 21:08:07 +00002867 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002868 create<ast::Variable>(Source{}, // source
2869 "ident", // name
2870 ast::StorageClass::kNone, // storage_class
2871 &vec4, // type
2872 false, // is_const
2873 nullptr, // constructor
2874 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002875 mod->AddGlobalVariable(var);
dan sinclair0e257622020-04-07 19:27:11 +00002876
2877 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00002878 EXPECT_TRUE(td()->Determine());
dan sinclair0e257622020-04-07 19:27:11 +00002879
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002880 ast::UnaryOpExpression der(
2881 Source{}, op,
2882 create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("ident"),
2883 "ident"));
dan sinclaircd077b02020-04-20 14:19:04 +00002884 EXPECT_TRUE(td()->DetermineResultType(&der));
dan sinclair0e257622020-04-07 19:27:11 +00002885 ASSERT_NE(der.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002886 ASSERT_TRUE(der.result_type()->Is<ast::type::Vector>());
2887 EXPECT_TRUE(
2888 der.result_type()->As<ast::type::Vector>()->type()->Is<ast::type::F32>());
2889 EXPECT_EQ(der.result_type()->As<ast::type::Vector>()->size(), 4u);
dan sinclair0e257622020-04-07 19:27:11 +00002890}
2891INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
2892 UnaryOpExpressionTest,
2893 testing::Values(ast::UnaryOp::kNegation,
2894 ast::UnaryOp::kNot));
2895
dan sinclairee8ae042020-04-08 19:58:20 +00002896TEST_F(TypeDeterminerTest, StorageClass_SetsIfMissing) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002897 ast::type::I32 i32;
dan sinclairee8ae042020-04-08 19:58:20 +00002898
Ben Clayton321e5a92020-12-07 21:08:07 +00002899 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002900 create<ast::Variable>(Source{}, // source
2901 "var", // name
2902 ast::StorageClass::kNone, // storage_class
2903 &i32, // type
2904 false, // is_const
2905 nullptr, // constructor
2906 ast::VariableDecorationList{}); // decorations
Ben Claytonbbefff62020-12-12 11:58:44 +00002907 auto* stmt = create<ast::VariableDeclStatement>(Source{}, var);
dan sinclairee8ae042020-04-08 19:58:20 +00002908
Ben Claytondb5ce652020-12-14 20:25:27 +00002909 auto* body = create<ast::BlockStatement>(Source{}, ast::StatementList{
2910 stmt,
2911 });
dan sinclaira41132f2020-12-11 18:24:53 +00002912 auto* func = create<ast::Function>(Source{}, mod->RegisterSymbol("func"),
2913 "func", ast::VariableList{}, &i32, body,
2914 ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00002915
Ben Clayton3ea3c992020-11-18 21:19:22 +00002916 mod->AddFunction(func);
dan sinclairee8ae042020-04-08 19:58:20 +00002917
dan sinclairb950e802020-04-20 14:20:01 +00002918 EXPECT_TRUE(td()->Determine()) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002919 EXPECT_EQ(var->storage_class(), ast::StorageClass::kFunction);
dan sinclairee8ae042020-04-08 19:58:20 +00002920}
2921
2922TEST_F(TypeDeterminerTest, StorageClass_DoesNotSetOnConst) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002923 ast::type::I32 i32;
dan sinclairee8ae042020-04-08 19:58:20 +00002924
Ben Clayton321e5a92020-12-07 21:08:07 +00002925 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002926 create<ast::Variable>(Source{}, // source
2927 "var", // name
2928 ast::StorageClass::kNone, // storage_class
2929 &i32, // type
2930 true, // is_const
2931 nullptr, // constructor
2932 ast::VariableDecorationList{}); // decorations
Ben Claytonbbefff62020-12-12 11:58:44 +00002933 auto* stmt = create<ast::VariableDeclStatement>(Source{}, var);
dan sinclairee8ae042020-04-08 19:58:20 +00002934
Ben Claytondb5ce652020-12-14 20:25:27 +00002935 auto* body = create<ast::BlockStatement>(Source{}, ast::StatementList{
2936 stmt,
2937 });
dan sinclaira41132f2020-12-11 18:24:53 +00002938 auto* func = create<ast::Function>(Source{}, mod->RegisterSymbol("func"),
2939 "func", ast::VariableList{}, &i32, body,
2940 ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00002941
Ben Clayton3ea3c992020-11-18 21:19:22 +00002942 mod->AddFunction(func);
dan sinclairee8ae042020-04-08 19:58:20 +00002943
dan sinclairb950e802020-04-20 14:20:01 +00002944 EXPECT_TRUE(td()->Determine()) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002945 EXPECT_EQ(var->storage_class(), ast::StorageClass::kNone);
dan sinclairee8ae042020-04-08 19:58:20 +00002946}
2947
2948TEST_F(TypeDeterminerTest, StorageClass_NonFunctionClassError) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002949 ast::type::I32 i32;
dan sinclairee8ae042020-04-08 19:58:20 +00002950
Ben Claytona80511e2020-12-11 13:07:02 +00002951 auto* var =
2952 create<ast::Variable>(Source{}, // source
2953 "var", // name
2954 ast::StorageClass::kWorkgroup, // storage_class
2955 &i32, // type
2956 false, // is_const
2957 nullptr, // constructor
2958 ast::VariableDecorationList{}); // decorations
Ben Claytonbbefff62020-12-12 11:58:44 +00002959 auto* stmt = create<ast::VariableDeclStatement>(Source{}, var);
dan sinclairee8ae042020-04-08 19:58:20 +00002960
Ben Claytondb5ce652020-12-14 20:25:27 +00002961 auto* body = create<ast::BlockStatement>(Source{}, ast::StatementList{
2962 stmt,
2963 });
dan sinclaira41132f2020-12-11 18:24:53 +00002964 auto* func = create<ast::Function>(Source{}, mod->RegisterSymbol("func"),
2965 "func", ast::VariableList{}, &i32, body,
2966 ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00002967
Ben Clayton3ea3c992020-11-18 21:19:22 +00002968 mod->AddFunction(func);
dan sinclairee8ae042020-04-08 19:58:20 +00002969
dan sinclairb950e802020-04-20 14:20:01 +00002970 EXPECT_FALSE(td()->Determine());
dan sinclairee8ae042020-04-08 19:58:20 +00002971 EXPECT_EQ(td()->error(),
2972 "function variable has a non-function storage class");
2973}
2974
dan sinclairb4fee2f2020-09-22 19:42:13 +00002975struct IntrinsicData {
dan sinclairca1723e2020-04-20 15:47:55 +00002976 const char* name;
dan sinclairb4fee2f2020-09-22 19:42:13 +00002977 ast::Intrinsic intrinsic;
dan sinclairca1723e2020-04-20 15:47:55 +00002978};
dan sinclairb4fee2f2020-09-22 19:42:13 +00002979inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
dan sinclairca1723e2020-04-20 15:47:55 +00002980 out << data.name;
2981 return out;
2982}
dan sinclairb4fee2f2020-09-22 19:42:13 +00002983using IntrinsicDataTest = TypeDeterminerTestWithParam<IntrinsicData>;
2984TEST_P(IntrinsicDataTest, Lookup) {
2985 auto param = GetParam();
dan sinclairca1723e2020-04-20 15:47:55 +00002986
Ben Clayton1ff59cd2020-12-12 01:38:13 +00002987 ast::IdentifierExpression ident(Source{}, mod->RegisterSymbol(param.name),
2988 param.name);
dan sinclairff267ca2020-10-14 18:26:31 +00002989 EXPECT_TRUE(td()->SetIntrinsicIfNeeded(&ident));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002990 EXPECT_EQ(ident.intrinsic(), param.intrinsic);
2991 EXPECT_TRUE(ident.IsIntrinsic());
2992}
2993INSTANTIATE_TEST_SUITE_P(
2994 TypeDeterminerTest,
2995 IntrinsicDataTest,
2996 testing::Values(
2997 IntrinsicData{"abs", ast::Intrinsic::kAbs},
2998 IntrinsicData{"acos", ast::Intrinsic::kAcos},
2999 IntrinsicData{"all", ast::Intrinsic::kAll},
3000 IntrinsicData{"any", ast::Intrinsic::kAny},
dan sinclair007dc422020-10-08 17:01:55 +00003001 IntrinsicData{"arrayLength", ast::Intrinsic::kArrayLength},
dan sinclairb4fee2f2020-09-22 19:42:13 +00003002 IntrinsicData{"asin", ast::Intrinsic::kAsin},
3003 IntrinsicData{"atan", ast::Intrinsic::kAtan},
3004 IntrinsicData{"atan2", ast::Intrinsic::kAtan2},
3005 IntrinsicData{"ceil", ast::Intrinsic::kCeil},
3006 IntrinsicData{"clamp", ast::Intrinsic::kClamp},
3007 IntrinsicData{"cos", ast::Intrinsic::kCos},
3008 IntrinsicData{"cosh", ast::Intrinsic::kCosh},
3009 IntrinsicData{"countOneBits", ast::Intrinsic::kCountOneBits},
3010 IntrinsicData{"cross", ast::Intrinsic::kCross},
3011 IntrinsicData{"determinant", ast::Intrinsic::kDeterminant},
3012 IntrinsicData{"distance", ast::Intrinsic::kDistance},
3013 IntrinsicData{"dot", ast::Intrinsic::kDot},
3014 IntrinsicData{"dpdx", ast::Intrinsic::kDpdx},
3015 IntrinsicData{"dpdxCoarse", ast::Intrinsic::kDpdxCoarse},
3016 IntrinsicData{"dpdxFine", ast::Intrinsic::kDpdxFine},
3017 IntrinsicData{"dpdy", ast::Intrinsic::kDpdy},
3018 IntrinsicData{"dpdyCoarse", ast::Intrinsic::kDpdyCoarse},
3019 IntrinsicData{"dpdyFine", ast::Intrinsic::kDpdyFine},
3020 IntrinsicData{"exp", ast::Intrinsic::kExp},
3021 IntrinsicData{"exp2", ast::Intrinsic::kExp2},
3022 IntrinsicData{"faceForward", ast::Intrinsic::kFaceForward},
3023 IntrinsicData{"floor", ast::Intrinsic::kFloor},
3024 IntrinsicData{"fma", ast::Intrinsic::kFma},
3025 IntrinsicData{"fract", ast::Intrinsic::kFract},
3026 IntrinsicData{"frexp", ast::Intrinsic::kFrexp},
3027 IntrinsicData{"fwidth", ast::Intrinsic::kFwidth},
3028 IntrinsicData{"fwidthCoarse", ast::Intrinsic::kFwidthCoarse},
3029 IntrinsicData{"fwidthFine", ast::Intrinsic::kFwidthFine},
3030 IntrinsicData{"inverseSqrt", ast::Intrinsic::kInverseSqrt},
3031 IntrinsicData{"isFinite", ast::Intrinsic::kIsFinite},
3032 IntrinsicData{"isInf", ast::Intrinsic::kIsInf},
3033 IntrinsicData{"isNan", ast::Intrinsic::kIsNan},
3034 IntrinsicData{"isNormal", ast::Intrinsic::kIsNormal},
3035 IntrinsicData{"ldexp", ast::Intrinsic::kLdexp},
3036 IntrinsicData{"length", ast::Intrinsic::kLength},
3037 IntrinsicData{"log", ast::Intrinsic::kLog},
3038 IntrinsicData{"log2", ast::Intrinsic::kLog2},
3039 IntrinsicData{"max", ast::Intrinsic::kMax},
3040 IntrinsicData{"min", ast::Intrinsic::kMin},
3041 IntrinsicData{"mix", ast::Intrinsic::kMix},
3042 IntrinsicData{"modf", ast::Intrinsic::kModf},
3043 IntrinsicData{"normalize", ast::Intrinsic::kNormalize},
3044 IntrinsicData{"outerProduct", ast::Intrinsic::kOuterProduct},
3045 IntrinsicData{"pow", ast::Intrinsic::kPow},
3046 IntrinsicData{"reflect", ast::Intrinsic::kReflect},
3047 IntrinsicData{"reverseBits", ast::Intrinsic::kReverseBits},
3048 IntrinsicData{"round", ast::Intrinsic::kRound},
3049 IntrinsicData{"select", ast::Intrinsic::kSelect},
3050 IntrinsicData{"sign", ast::Intrinsic::kSign},
3051 IntrinsicData{"sin", ast::Intrinsic::kSin},
3052 IntrinsicData{"sinh", ast::Intrinsic::kSinh},
3053 IntrinsicData{"smoothStep", ast::Intrinsic::kSmoothStep},
3054 IntrinsicData{"sqrt", ast::Intrinsic::kSqrt},
3055 IntrinsicData{"step", ast::Intrinsic::kStep},
3056 IntrinsicData{"tan", ast::Intrinsic::kTan},
3057 IntrinsicData{"tanh", ast::Intrinsic::kTanh},
3058 IntrinsicData{"textureLoad", ast::Intrinsic::kTextureLoad},
3059 IntrinsicData{"textureSample", ast::Intrinsic::kTextureSample},
3060 IntrinsicData{"textureSampleBias", ast::Intrinsic::kTextureSampleBias},
3061 IntrinsicData{"textureSampleCompare",
3062 ast::Intrinsic::kTextureSampleCompare},
Ben Clayton3ea3c992020-11-18 21:19:22 +00003063 IntrinsicData{"textureSampleGrad", ast::Intrinsic::kTextureSampleGrad},
dan sinclairb4fee2f2020-09-22 19:42:13 +00003064 IntrinsicData{"textureSampleLevel",
3065 ast::Intrinsic::kTextureSampleLevel},
3066 IntrinsicData{"trunc", ast::Intrinsic::kTrunc}));
3067
3068TEST_F(TypeDeterminerTest, IntrinsicNotSetIfNotMatched) {
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003069 ast::IdentifierExpression ident(
3070 Source{}, mod->RegisterSymbol("not_intrinsic"), "not_intrinsic");
dan sinclairff267ca2020-10-14 18:26:31 +00003071 EXPECT_FALSE(td()->SetIntrinsicIfNeeded(&ident));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003072 EXPECT_EQ(ident.intrinsic(), ast::Intrinsic::kNone);
3073 EXPECT_FALSE(ident.IsIntrinsic());
3074}
3075
3076using ImportData_SingleParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair37d62c92020-04-21 12:55:06 +00003077TEST_P(ImportData_SingleParamTest, Scalar) {
dan sinclairca1723e2020-04-20 15:47:55 +00003078 auto param = GetParam();
3079
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003080 ast::type::F32 f32;
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003081
3082 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003083 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003084 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003085
dan sinclair6b59bf42020-12-11 19:16:13 +00003086 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003087 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003088
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003089 ast::CallExpression call(Source{}, ident, params);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003090
dan sinclairb4fee2f2020-09-22 19:42:13 +00003091 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003092 ASSERT_NE(ident->result_type(), nullptr);
3093 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003094}
3095
dan sinclair37d62c92020-04-21 12:55:06 +00003096TEST_P(ImportData_SingleParamTest, Vector) {
dan sinclairca1723e2020-04-20 15:47:55 +00003097 auto param = GetParam();
3098
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003099 ast::type::F32 f32;
3100 ast::type::Vector vec(&f32, 3);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003101
3102 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00003103 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003104 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003105 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003106 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003107 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003108 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003109
3110 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003111 params.push_back(
3112 create<ast::TypeConstructorExpression>(Source{}, &vec, vals));
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003113
dan sinclair6b59bf42020-12-11 19:16:13 +00003114 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003115 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003116
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003117 ast::CallExpression call(Source{}, ident, params);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003118
dan sinclairb4fee2f2020-09-22 19:42:13 +00003119 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003120 ASSERT_NE(ident->result_type(), nullptr);
3121 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003122 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003123}
3124
dan sinclair37d62c92020-04-21 12:55:06 +00003125TEST_P(ImportData_SingleParamTest, Error_Integer) {
dan sinclairca1723e2020-04-20 15:47:55 +00003126 auto param = GetParam();
3127
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003128 ast::type::I32 i32;
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003129
3130 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003131 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003132 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003133
dan sinclair6b59bf42020-12-11 19:16:13 +00003134 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003135 Source{}, mod->RegisterSymbol(param.name), param.name);
3136 ast::CallExpression call(Source{}, ident, params);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003137
dan sinclairb4fee2f2020-09-22 19:42:13 +00003138 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair53352042020-06-08 18:49:31 +00003139 EXPECT_EQ(td()->error(),
3140 std::string("incorrect type for ") + param.name +
3141 ". Requires float scalar or float vector values");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003142}
3143
dan sinclair37d62c92020-04-21 12:55:06 +00003144TEST_P(ImportData_SingleParamTest, Error_NoParams) {
dan sinclairca1723e2020-04-20 15:47:55 +00003145 auto param = GetParam();
3146
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003147 ast::ExpressionList params;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003148
dan sinclair6b59bf42020-12-11 19:16:13 +00003149 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003150 Source{}, mod->RegisterSymbol(param.name), param.name);
3151 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003152
3153 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclairca1723e2020-04-20 15:47:55 +00003154 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
3155 param.name + ". Expected 1 got 0");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003156}
3157
dan sinclair37d62c92020-04-21 12:55:06 +00003158TEST_P(ImportData_SingleParamTest, Error_MultipleParams) {
dan sinclairca1723e2020-04-20 15:47:55 +00003159 auto param = GetParam();
3160
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003161 ast::type::F32 f32;
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003162 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003163 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003164 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00003165 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003166 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00003167 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003168 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003169
dan sinclair6b59bf42020-12-11 19:16:13 +00003170 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003171 Source{}, mod->RegisterSymbol(param.name), param.name);
3172 ast::CallExpression call(Source{}, ident, params);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003173
dan sinclairb4fee2f2020-09-22 19:42:13 +00003174 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclairca1723e2020-04-20 15:47:55 +00003175 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
3176 param.name + ". Expected 1 got 3");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003177}
3178
dan sinclaira49328f2020-04-20 15:49:50 +00003179INSTANTIATE_TEST_SUITE_P(
3180 TypeDeterminerTest,
dan sinclair37d62c92020-04-21 12:55:06 +00003181 ImportData_SingleParamTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00003182 testing::Values(IntrinsicData{"acos", ast::Intrinsic::kAcos},
3183 IntrinsicData{"asin", ast::Intrinsic::kAsin},
3184 IntrinsicData{"atan", ast::Intrinsic::kAtan},
3185 IntrinsicData{"ceil", ast::Intrinsic::kCeil},
3186 IntrinsicData{"cos", ast::Intrinsic::kCos},
3187 IntrinsicData{"cosh", ast::Intrinsic::kCosh},
3188 IntrinsicData{"exp", ast::Intrinsic::kExp},
3189 IntrinsicData{"exp2", ast::Intrinsic::kExp2},
3190 IntrinsicData{"floor", ast::Intrinsic::kFloor},
3191 IntrinsicData{"fract", ast::Intrinsic::kFract},
3192 IntrinsicData{"inverseSqrt", ast::Intrinsic::kInverseSqrt},
3193 IntrinsicData{"log", ast::Intrinsic::kLog},
3194 IntrinsicData{"log2", ast::Intrinsic::kLog2},
3195 IntrinsicData{"normalize", ast::Intrinsic::kNormalize},
3196 IntrinsicData{"round", ast::Intrinsic::kRound},
3197 IntrinsicData{"sign", ast::Intrinsic::kSign},
3198 IntrinsicData{"sin", ast::Intrinsic::kSin},
3199 IntrinsicData{"sinh", ast::Intrinsic::kSinh},
3200 IntrinsicData{"sqrt", ast::Intrinsic::kSqrt},
3201 IntrinsicData{"tan", ast::Intrinsic::kTan},
3202 IntrinsicData{"tanh", ast::Intrinsic::kTanh},
3203 IntrinsicData{"trunc", ast::Intrinsic::kTrunc}));
3204
3205using ImportData_SingleParam_FloatOrInt_Test =
3206 TypeDeterminerTestWithParam<IntrinsicData>;
3207TEST_P(ImportData_SingleParam_FloatOrInt_Test, Float_Scalar) {
3208 auto param = GetParam();
3209
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003210 ast::type::F32 f32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003211
3212 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003213 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003214 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003215
dan sinclair6b59bf42020-12-11 19:16:13 +00003216 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003217 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003218
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003219 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003220
3221 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003222 ASSERT_NE(ident->result_type(), nullptr);
3223 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclairb4fee2f2020-09-22 19:42:13 +00003224}
3225
3226TEST_P(ImportData_SingleParam_FloatOrInt_Test, Float_Vector) {
3227 auto param = GetParam();
3228
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003229 ast::type::F32 f32;
3230 ast::type::Vector vec(&f32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003231
3232 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00003233 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003234 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003235 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003236 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003237 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003238 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003239
3240 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003241 params.push_back(
3242 create<ast::TypeConstructorExpression>(Source{}, &vec, vals));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003243
dan sinclair6b59bf42020-12-11 19:16:13 +00003244 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003245 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003246
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003247 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003248
3249 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003250 ASSERT_NE(ident->result_type(), nullptr);
3251 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003252 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003253}
3254
3255TEST_P(ImportData_SingleParam_FloatOrInt_Test, Sint_Scalar) {
3256 auto param = GetParam();
3257
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003258 ast::type::I32 i32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003259
3260 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003261 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003262 Source{}, create<ast::SintLiteral>(Source{}, &i32, -11)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003263
dan sinclair6b59bf42020-12-11 19:16:13 +00003264 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003265 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003266
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003267 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003268
3269 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003270 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003271 EXPECT_TRUE(ident->result_type()->Is<ast::type::I32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00003272}
3273
3274TEST_P(ImportData_SingleParam_FloatOrInt_Test, Sint_Vector) {
3275 auto param = GetParam();
3276
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003277 ast::type::I32 i32;
3278 ast::type::Vector vec(&i32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003279
3280 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00003281 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003282 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00003283 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003284 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00003285 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003286 Source{}, create<ast::SintLiteral>(Source{}, &i32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003287
3288 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003289 params.push_back(
3290 create<ast::TypeConstructorExpression>(Source{}, &vec, vals));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003291
dan sinclair6b59bf42020-12-11 19:16:13 +00003292 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003293 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003294
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003295 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003296
3297 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003298 ASSERT_NE(ident->result_type(), nullptr);
3299 EXPECT_TRUE(ident->result_type()->is_signed_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003300 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003301}
3302
3303TEST_P(ImportData_SingleParam_FloatOrInt_Test, Uint_Scalar) {
3304 auto param = GetParam();
3305
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003306 ast::type::U32 u32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003307
3308 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003309 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003310 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003311
dan sinclair6b59bf42020-12-11 19:16:13 +00003312 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003313 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003314
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003315 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003316
3317 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003318 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003319 EXPECT_TRUE(ident->result_type()->Is<ast::type::U32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00003320}
3321
3322TEST_P(ImportData_SingleParam_FloatOrInt_Test, Uint_Vector) {
3323 auto param = GetParam();
3324
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003325 ast::type::U32 u32;
3326 ast::type::Vector vec(&u32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003327
3328 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00003329 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003330 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003331 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003332 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003333 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003334 Source{}, create<ast::UintLiteral>(Source{}, &u32, 3.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003335
3336 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003337 params.push_back(
3338 create<ast::TypeConstructorExpression>(Source{}, &vec, vals));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003339
dan sinclair6b59bf42020-12-11 19:16:13 +00003340 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003341 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003342
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003343 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003344
3345 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003346 ASSERT_NE(ident->result_type(), nullptr);
3347 EXPECT_TRUE(ident->result_type()->is_unsigned_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003348 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003349}
3350
3351TEST_P(ImportData_SingleParam_FloatOrInt_Test, Error_Bool) {
3352 auto param = GetParam();
3353
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003354 ast::type::Bool bool_type;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003355
3356 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003357 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003358 Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, false)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003359
dan sinclair6b59bf42020-12-11 19:16:13 +00003360 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003361 Source{}, mod->RegisterSymbol(param.name), param.name);
3362 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003363
3364 EXPECT_FALSE(td()->DetermineResultType(&call));
3365 EXPECT_EQ(td()->error(),
3366 std::string("incorrect type for ") + param.name +
3367 ". Requires float or int, scalar or vector values");
3368}
3369
3370TEST_P(ImportData_SingleParam_FloatOrInt_Test, Error_NoParams) {
3371 auto param = GetParam();
3372
3373 ast::ExpressionList params;
3374
dan sinclair6b59bf42020-12-11 19:16:13 +00003375 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003376 Source{}, mod->RegisterSymbol(param.name), param.name);
3377 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003378
3379 EXPECT_FALSE(td()->DetermineResultType(&call));
3380 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
3381 param.name + ". Expected 1 got 0");
3382}
3383
3384TEST_P(ImportData_SingleParam_FloatOrInt_Test, Error_MultipleParams) {
3385 auto param = GetParam();
3386
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003387 ast::type::F32 f32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003388 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003389 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003390 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00003391 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003392 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00003393 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003394 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003395
dan sinclair6b59bf42020-12-11 19:16:13 +00003396 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003397 Source{}, mod->RegisterSymbol(param.name), param.name);
3398 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003399
3400 EXPECT_FALSE(td()->DetermineResultType(&call));
3401 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
3402 param.name + ". Expected 1 got 3");
3403}
3404
3405INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
3406 ImportData_SingleParam_FloatOrInt_Test,
3407 testing::Values(IntrinsicData{"abs",
3408 ast::Intrinsic::kAbs}));
dan sinclairca1723e2020-04-20 15:47:55 +00003409
dan sinclair652a4b92020-04-20 21:09:14 +00003410TEST_F(TypeDeterminerTest, ImportData_Length_Scalar) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003411 ast::type::F32 f32;
dan sinclair652a4b92020-04-20 21:09:14 +00003412
3413 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003414 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003415 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclair652a4b92020-04-20 21:09:14 +00003416
3417 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
3418
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003419 auto* ident = create<ast::IdentifierExpression>(
3420 Source{}, mod->RegisterSymbol("length"), "length");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003421
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003422 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003423
3424 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003425 ASSERT_NE(ident->result_type(), nullptr);
3426 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair652a4b92020-04-20 21:09:14 +00003427}
3428
3429TEST_F(TypeDeterminerTest, ImportData_Length_FloatVector) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003430 ast::type::F32 f32;
3431 ast::type::Vector vec(&f32, 3);
dan sinclair652a4b92020-04-20 21:09:14 +00003432
3433 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00003434 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003435 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003436 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003437 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003438 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003439 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclair652a4b92020-04-20 21:09:14 +00003440
3441 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003442 params.push_back(
3443 create<ast::TypeConstructorExpression>(Source{}, &vec, vals));
dan sinclair652a4b92020-04-20 21:09:14 +00003444
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003445 auto* ident = create<ast::IdentifierExpression>(
3446 Source{}, mod->RegisterSymbol("length"), "length");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003447
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003448 ast::CallExpression call(Source{}, ident, params);
dan sinclair652a4b92020-04-20 21:09:14 +00003449
dan sinclairb4fee2f2020-09-22 19:42:13 +00003450 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003451 ASSERT_NE(ident->result_type(), nullptr);
3452 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair652a4b92020-04-20 21:09:14 +00003453}
3454
3455TEST_F(TypeDeterminerTest, ImportData_Length_Error_Integer) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003456 ast::type::I32 i32;
dan sinclair652a4b92020-04-20 21:09:14 +00003457
3458 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003459 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003460 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
dan sinclair652a4b92020-04-20 21:09:14 +00003461
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003462 auto* ident = create<ast::IdentifierExpression>(
3463 Source{}, mod->RegisterSymbol("length"), "length");
3464 ast::CallExpression call(Source{}, ident, params);
dan sinclair652a4b92020-04-20 21:09:14 +00003465
dan sinclairb4fee2f2020-09-22 19:42:13 +00003466 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair53352042020-06-08 18:49:31 +00003467 EXPECT_EQ(td()->error(),
3468 "incorrect type for length. Requires float scalar or float vector "
3469 "values");
dan sinclair652a4b92020-04-20 21:09:14 +00003470}
3471
3472TEST_F(TypeDeterminerTest, ImportData_Length_Error_NoParams) {
3473 ast::ExpressionList params;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003474
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003475 auto* ident = create<ast::IdentifierExpression>(
3476 Source{}, mod->RegisterSymbol("length"), "length");
3477 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003478
3479 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair652a4b92020-04-20 21:09:14 +00003480 EXPECT_EQ(td()->error(),
3481 "incorrect number of parameters for length. Expected 1 got 0");
3482}
3483
3484TEST_F(TypeDeterminerTest, ImportData_Length_Error_MultipleParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003485 ast::type::F32 f32;
dan sinclair652a4b92020-04-20 21:09:14 +00003486 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003487 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003488 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00003489 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003490 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00003491 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003492 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclair652a4b92020-04-20 21:09:14 +00003493
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003494 auto* ident = create<ast::IdentifierExpression>(
3495 Source{}, mod->RegisterSymbol("length"), "length");
3496 ast::CallExpression call(Source{}, ident, params);
dan sinclair652a4b92020-04-20 21:09:14 +00003497
dan sinclairb4fee2f2020-09-22 19:42:13 +00003498 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair652a4b92020-04-20 21:09:14 +00003499 EXPECT_EQ(td()->error(),
3500 "incorrect number of parameters for length. Expected 1 got 3");
3501}
3502
dan sinclairb4fee2f2020-09-22 19:42:13 +00003503using ImportData_TwoParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair37d62c92020-04-21 12:55:06 +00003504TEST_P(ImportData_TwoParamTest, Scalar) {
3505 auto param = GetParam();
3506
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003507 ast::type::F32 f32;
dan sinclair37d62c92020-04-21 12:55:06 +00003508
3509 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003510 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003511 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00003512 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003513 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclair37d62c92020-04-21 12:55:06 +00003514
dan sinclair6b59bf42020-12-11 19:16:13 +00003515 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003516 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003517
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003518 ast::CallExpression call(Source{}, ident, params);
dan sinclair37d62c92020-04-21 12:55:06 +00003519
dan sinclairb4fee2f2020-09-22 19:42:13 +00003520 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003521 ASSERT_NE(ident->result_type(), nullptr);
3522 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair37d62c92020-04-21 12:55:06 +00003523}
3524
3525TEST_P(ImportData_TwoParamTest, Vector) {
3526 auto param = GetParam();
3527
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003528 ast::type::F32 f32;
3529 ast::type::Vector vec(&f32, 3);
dan sinclair37d62c92020-04-21 12:55:06 +00003530
3531 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00003532 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003533 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003534 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003535 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003536 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003537 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclair37d62c92020-04-21 12:55:06 +00003538
3539 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00003540 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003541 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003542 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003543 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003544 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003545 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclair37d62c92020-04-21 12:55:06 +00003546
3547 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003548 params.push_back(
3549 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_1));
3550 params.push_back(
3551 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_2));
dan sinclair37d62c92020-04-21 12:55:06 +00003552
dan sinclair6b59bf42020-12-11 19:16:13 +00003553 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003554 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003555
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003556 ast::CallExpression call(Source{}, ident, params);
dan sinclair37d62c92020-04-21 12:55:06 +00003557
dan sinclairb4fee2f2020-09-22 19:42:13 +00003558 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003559 ASSERT_NE(ident->result_type(), nullptr);
3560 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003561 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair37d62c92020-04-21 12:55:06 +00003562}
3563
3564TEST_P(ImportData_TwoParamTest, Error_Integer) {
3565 auto param = GetParam();
3566
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003567 ast::type::I32 i32;
dan sinclair37d62c92020-04-21 12:55:06 +00003568
3569 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003570 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003571 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00003572 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003573 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2)));
dan sinclair37d62c92020-04-21 12:55:06 +00003574
dan sinclair6b59bf42020-12-11 19:16:13 +00003575 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003576 Source{}, mod->RegisterSymbol(param.name), param.name);
3577 ast::CallExpression call(Source{}, ident, params);
dan sinclair37d62c92020-04-21 12:55:06 +00003578
dan sinclairb4fee2f2020-09-22 19:42:13 +00003579 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair37d62c92020-04-21 12:55:06 +00003580 EXPECT_EQ(td()->error(),
3581 std::string("incorrect type for ") + param.name +
dan sinclair53352042020-06-08 18:49:31 +00003582 ". Requires float scalar or float vector values");
dan sinclair37d62c92020-04-21 12:55:06 +00003583}
3584
3585TEST_P(ImportData_TwoParamTest, Error_NoParams) {
3586 auto param = GetParam();
3587
3588 ast::ExpressionList params;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003589
dan sinclair6b59bf42020-12-11 19:16:13 +00003590 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003591 Source{}, mod->RegisterSymbol(param.name), param.name);
3592 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003593
3594 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair37d62c92020-04-21 12:55:06 +00003595 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
3596 param.name + ". Expected 2 got 0");
3597}
3598
3599TEST_P(ImportData_TwoParamTest, Error_OneParam) {
3600 auto param = GetParam();
3601
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003602 ast::type::F32 f32;
dan sinclair37d62c92020-04-21 12:55:06 +00003603 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003604 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003605 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclair37d62c92020-04-21 12:55:06 +00003606
dan sinclair6b59bf42020-12-11 19:16:13 +00003607 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003608 Source{}, mod->RegisterSymbol(param.name), param.name);
3609 ast::CallExpression call(Source{}, ident, params);
dan sinclair37d62c92020-04-21 12:55:06 +00003610
dan sinclairb4fee2f2020-09-22 19:42:13 +00003611 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair37d62c92020-04-21 12:55:06 +00003612 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
3613 param.name + ". Expected 2 got 1");
3614}
3615
3616TEST_P(ImportData_TwoParamTest, Error_MismatchedParamCount) {
3617 auto param = GetParam();
3618
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003619 ast::type::F32 f32;
3620 ast::type::Vector vec2(&f32, 2);
3621 ast::type::Vector vec3(&f32, 3);
dan sinclair37d62c92020-04-21 12:55:06 +00003622
3623 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00003624 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003625 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003626 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003627 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
dan sinclair37d62c92020-04-21 12:55:06 +00003628
3629 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00003630 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003631 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003632 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003633 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003634 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003635 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclair37d62c92020-04-21 12:55:06 +00003636
3637 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003638 params.push_back(
3639 create<ast::TypeConstructorExpression>(Source{}, &vec2, vals_1));
3640 params.push_back(
3641 create<ast::TypeConstructorExpression>(Source{}, &vec3, vals_2));
dan sinclair37d62c92020-04-21 12:55:06 +00003642
dan sinclair6b59bf42020-12-11 19:16:13 +00003643 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003644 Source{}, mod->RegisterSymbol(param.name), param.name);
3645 ast::CallExpression call(Source{}, ident, params);
dan sinclair37d62c92020-04-21 12:55:06 +00003646
dan sinclairb4fee2f2020-09-22 19:42:13 +00003647 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair37d62c92020-04-21 12:55:06 +00003648 EXPECT_EQ(td()->error(),
3649 std::string("mismatched parameter types for ") + param.name);
3650}
3651
3652TEST_P(ImportData_TwoParamTest, Error_MismatchedParamType) {
3653 auto param = GetParam();
3654
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003655 ast::type::F32 f32;
3656 ast::type::Vector vec(&f32, 3);
dan sinclair37d62c92020-04-21 12:55:06 +00003657
3658 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00003659 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003660 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003661 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003662 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003663 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003664 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclair37d62c92020-04-21 12:55:06 +00003665
3666 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003667 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003668 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
3669 params.push_back(
3670 create<ast::TypeConstructorExpression>(Source{}, &vec, vals));
dan sinclair37d62c92020-04-21 12:55:06 +00003671
dan sinclair6b59bf42020-12-11 19:16:13 +00003672 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003673 Source{}, mod->RegisterSymbol(param.name), param.name);
3674 ast::CallExpression call(Source{}, ident, params);
dan sinclair37d62c92020-04-21 12:55:06 +00003675
dan sinclairb4fee2f2020-09-22 19:42:13 +00003676 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair37d62c92020-04-21 12:55:06 +00003677 EXPECT_EQ(td()->error(),
3678 std::string("mismatched parameter types for ") + param.name);
3679}
3680
3681TEST_P(ImportData_TwoParamTest, Error_TooManyParams) {
3682 auto param = GetParam();
3683
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003684 ast::type::F32 f32;
dan sinclair37d62c92020-04-21 12:55:06 +00003685 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003686 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003687 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00003688 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003689 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00003690 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003691 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclair37d62c92020-04-21 12:55:06 +00003692
dan sinclair6b59bf42020-12-11 19:16:13 +00003693 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003694 Source{}, mod->RegisterSymbol(param.name), param.name);
3695 ast::CallExpression call(Source{}, ident, params);
dan sinclair37d62c92020-04-21 12:55:06 +00003696
dan sinclairb4fee2f2020-09-22 19:42:13 +00003697 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair37d62c92020-04-21 12:55:06 +00003698 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
3699 param.name + ". Expected 2 got 3");
3700}
3701
dan sinclairb4fee2f2020-09-22 19:42:13 +00003702INSTANTIATE_TEST_SUITE_P(
3703 TypeDeterminerTest,
3704 ImportData_TwoParamTest,
3705 testing::Values(IntrinsicData{"atan2", ast::Intrinsic::kAtan2},
3706 IntrinsicData{"pow", ast::Intrinsic::kPow},
3707 IntrinsicData{"step", ast::Intrinsic::kStep},
3708 IntrinsicData{"reflect", ast::Intrinsic::kReflect}));
dan sinclair37d62c92020-04-21 12:55:06 +00003709
dan sinclair54444382020-04-21 13:04:15 +00003710TEST_F(TypeDeterminerTest, ImportData_Distance_Scalar) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003711 ast::type::F32 f32;
dan sinclair54444382020-04-21 13:04:15 +00003712
3713 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003714 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003715 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00003716 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003717 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclair54444382020-04-21 13:04:15 +00003718
dan sinclair6b59bf42020-12-11 19:16:13 +00003719 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003720 Source{}, mod->RegisterSymbol("distance"), "distance");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003721
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003722 ast::CallExpression call(Source{}, ident, params);
dan sinclair54444382020-04-21 13:04:15 +00003723
dan sinclairb4fee2f2020-09-22 19:42:13 +00003724 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003725 ASSERT_NE(ident->result_type(), nullptr);
3726 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair54444382020-04-21 13:04:15 +00003727}
3728
3729TEST_F(TypeDeterminerTest, ImportData_Distance_Vector) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003730 ast::type::F32 f32;
3731 ast::type::Vector vec(&f32, 3);
dan sinclair54444382020-04-21 13:04:15 +00003732
3733 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00003734 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003735 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003736 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003737 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003738 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003739 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclair54444382020-04-21 13:04:15 +00003740
3741 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00003742 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003743 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003744 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003745 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003746 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003747 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclair54444382020-04-21 13:04:15 +00003748
3749 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003750 params.push_back(
3751 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_1));
3752 params.push_back(
3753 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_2));
dan sinclair54444382020-04-21 13:04:15 +00003754
dan sinclair6b59bf42020-12-11 19:16:13 +00003755 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003756 Source{}, mod->RegisterSymbol("distance"), "distance");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003757
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003758 ast::CallExpression call(Source{}, ident, params);
dan sinclair54444382020-04-21 13:04:15 +00003759
dan sinclairb4fee2f2020-09-22 19:42:13 +00003760 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003761 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003762 EXPECT_TRUE(ident->result_type()->Is<ast::type::F32>());
dan sinclair54444382020-04-21 13:04:15 +00003763}
3764
3765TEST_F(TypeDeterminerTest, ImportData_Distance_Error_Integer) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003766 ast::type::I32 i32;
dan sinclair54444382020-04-21 13:04:15 +00003767
3768 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003769 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003770 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00003771 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003772 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2)));
dan sinclair54444382020-04-21 13:04:15 +00003773
dan sinclair6b59bf42020-12-11 19:16:13 +00003774 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003775 Source{}, mod->RegisterSymbol("distance"), "distance");
3776 ast::CallExpression call(Source{}, ident, params);
dan sinclair54444382020-04-21 13:04:15 +00003777
dan sinclairb4fee2f2020-09-22 19:42:13 +00003778 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair54444382020-04-21 13:04:15 +00003779 EXPECT_EQ(td()->error(),
dan sinclair53352042020-06-08 18:49:31 +00003780 "incorrect type for distance. Requires float scalar or float "
dan sinclair54444382020-04-21 13:04:15 +00003781 "vector values");
3782}
3783
3784TEST_F(TypeDeterminerTest, ImportData_Distance_Error_NoParams) {
3785 ast::ExpressionList params;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003786
dan sinclair6b59bf42020-12-11 19:16:13 +00003787 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003788 Source{}, mod->RegisterSymbol("distance"), "distance");
3789 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003790
3791 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair54444382020-04-21 13:04:15 +00003792 EXPECT_EQ(td()->error(),
3793 "incorrect number of parameters for distance. Expected 2 got 0");
3794}
3795
3796TEST_F(TypeDeterminerTest, ImportData_Distance_Error_OneParam) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003797 ast::type::F32 f32;
dan sinclair54444382020-04-21 13:04:15 +00003798 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003799 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003800 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclair54444382020-04-21 13:04:15 +00003801
dan sinclair6b59bf42020-12-11 19:16:13 +00003802 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003803 Source{}, mod->RegisterSymbol("distance"), "distance");
3804 ast::CallExpression call(Source{}, ident, params);
dan sinclair54444382020-04-21 13:04:15 +00003805
dan sinclairb4fee2f2020-09-22 19:42:13 +00003806 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair54444382020-04-21 13:04:15 +00003807 EXPECT_EQ(td()->error(),
3808 "incorrect number of parameters for distance. Expected 2 got 1");
3809}
3810
3811TEST_F(TypeDeterminerTest, ImportData_Distance_Error_MismatchedParamCount) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003812 ast::type::F32 f32;
3813 ast::type::Vector vec2(&f32, 2);
3814 ast::type::Vector vec3(&f32, 3);
dan sinclair54444382020-04-21 13:04:15 +00003815
3816 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00003817 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003818 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003819 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003820 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
dan sinclair54444382020-04-21 13:04:15 +00003821
3822 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00003823 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003824 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003825 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003826 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003827 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003828 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclair54444382020-04-21 13:04:15 +00003829
3830 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003831 params.push_back(
3832 create<ast::TypeConstructorExpression>(Source{}, &vec2, vals_1));
3833 params.push_back(
3834 create<ast::TypeConstructorExpression>(Source{}, &vec3, vals_2));
dan sinclair54444382020-04-21 13:04:15 +00003835
dan sinclair6b59bf42020-12-11 19:16:13 +00003836 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003837 Source{}, mod->RegisterSymbol("distance"), "distance");
3838 ast::CallExpression call(Source{}, ident, params);
dan sinclair54444382020-04-21 13:04:15 +00003839
dan sinclairb4fee2f2020-09-22 19:42:13 +00003840 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair54444382020-04-21 13:04:15 +00003841 EXPECT_EQ(td()->error(), "mismatched parameter types for distance");
3842}
3843
3844TEST_F(TypeDeterminerTest, ImportData_Distance_Error_MismatchedParamType) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003845 ast::type::F32 f32;
3846 ast::type::Vector vec(&f32, 3);
dan sinclair54444382020-04-21 13:04:15 +00003847
3848 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00003849 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003850 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003851 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003852 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003853 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003854 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclair54444382020-04-21 13:04:15 +00003855
3856 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003857 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003858 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
3859 params.push_back(
3860 create<ast::TypeConstructorExpression>(Source{}, &vec, vals));
dan sinclair54444382020-04-21 13:04:15 +00003861
dan sinclair6b59bf42020-12-11 19:16:13 +00003862 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003863 Source{}, mod->RegisterSymbol("distance"), "distance");
3864 ast::CallExpression call(Source{}, ident, params);
dan sinclair54444382020-04-21 13:04:15 +00003865
dan sinclairb4fee2f2020-09-22 19:42:13 +00003866 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair54444382020-04-21 13:04:15 +00003867 EXPECT_EQ(td()->error(), "mismatched parameter types for distance");
3868}
3869
3870TEST_F(TypeDeterminerTest, ImportData_Distance_Error_TooManyParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003871 ast::type::F32 f32;
dan sinclair54444382020-04-21 13:04:15 +00003872 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003873 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003874 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00003875 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003876 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00003877 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003878 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclair54444382020-04-21 13:04:15 +00003879
dan sinclair6b59bf42020-12-11 19:16:13 +00003880 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003881 Source{}, mod->RegisterSymbol("distance"), "distance");
3882 ast::CallExpression call(Source{}, ident, params);
dan sinclair54444382020-04-21 13:04:15 +00003883
dan sinclairb4fee2f2020-09-22 19:42:13 +00003884 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair54444382020-04-21 13:04:15 +00003885 EXPECT_EQ(td()->error(),
3886 "incorrect number of parameters for distance. Expected 2 got 3");
3887}
3888
dan sinclairee392252020-06-08 23:48:15 +00003889TEST_F(TypeDeterminerTest, ImportData_Cross) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003890 ast::type::F32 f32;
3891 ast::type::Vector vec(&f32, 3);
dan sinclair2287d012020-04-22 00:23:57 +00003892
dan sinclairee392252020-06-08 23:48:15 +00003893 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00003894 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003895 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003896 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003897 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003898 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003899 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclairee392252020-06-08 23:48:15 +00003900
3901 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00003902 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003903 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003904 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003905 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003906 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003907 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclairee392252020-06-08 23:48:15 +00003908
3909 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003910 params.push_back(
3911 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_1));
3912 params.push_back(
3913 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_2));
dan sinclairee392252020-06-08 23:48:15 +00003914
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003915 auto* ident = create<ast::IdentifierExpression>(
3916 Source{}, mod->RegisterSymbol("cross"), "cross");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003917
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003918 ast::CallExpression call(Source{}, ident, params);
dan sinclairee392252020-06-08 23:48:15 +00003919
dan sinclairb4fee2f2020-09-22 19:42:13 +00003920 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003921 ASSERT_NE(ident->result_type(), nullptr);
3922 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003923 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairee392252020-06-08 23:48:15 +00003924}
3925
3926TEST_F(TypeDeterminerTest, ImportData_Cross_Error_Scalar) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003927 ast::type::F32 f32;
dan sinclairee392252020-06-08 23:48:15 +00003928
3929 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003930 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003931 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003932 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003933 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
dan sinclairee392252020-06-08 23:48:15 +00003934
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003935 auto* ident = create<ast::IdentifierExpression>(
3936 Source{}, mod->RegisterSymbol("cross"), "cross");
3937 ast::CallExpression call(Source{}, ident, params);
dan sinclairee392252020-06-08 23:48:15 +00003938
dan sinclairb4fee2f2020-09-22 19:42:13 +00003939 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclairee392252020-06-08 23:48:15 +00003940 EXPECT_EQ(td()->error(),
3941 "incorrect type for cross. Requires float vector values");
3942}
3943
3944TEST_F(TypeDeterminerTest, ImportData_Cross_Error_IntType) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003945 ast::type::I32 i32;
3946 ast::type::Vector vec(&i32, 3);
dan sinclairee392252020-06-08 23:48:15 +00003947
3948 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00003949 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003950 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00003951 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003952 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00003953 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003954 Source{}, create<ast::SintLiteral>(Source{}, &i32, 3)));
dan sinclairee392252020-06-08 23:48:15 +00003955
3956 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00003957 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003958 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00003959 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003960 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00003961 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003962 Source{}, create<ast::SintLiteral>(Source{}, &i32, 3)));
dan sinclairee392252020-06-08 23:48:15 +00003963
3964 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003965 params.push_back(
3966 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_1));
3967 params.push_back(
3968 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_2));
dan sinclairee392252020-06-08 23:48:15 +00003969
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003970 auto* ident = create<ast::IdentifierExpression>(
3971 Source{}, mod->RegisterSymbol("cross"), "cross");
3972 ast::CallExpression call(Source{}, ident, params);
dan sinclairee392252020-06-08 23:48:15 +00003973
dan sinclairb4fee2f2020-09-22 19:42:13 +00003974 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclairee392252020-06-08 23:48:15 +00003975 EXPECT_EQ(td()->error(),
3976 "incorrect type for cross. Requires float vector values");
3977}
3978
3979TEST_F(TypeDeterminerTest, ImportData_Cross_Error_MissingParams) {
dan sinclairee392252020-06-08 23:48:15 +00003980 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003981 auto* ident = create<ast::IdentifierExpression>(
3982 Source{}, mod->RegisterSymbol("cross"), "cross");
3983 ast::CallExpression call(Source{}, ident, params);
dan sinclairee392252020-06-08 23:48:15 +00003984
dan sinclairb4fee2f2020-09-22 19:42:13 +00003985 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclairee392252020-06-08 23:48:15 +00003986 EXPECT_EQ(td()->error(),
3987 "incorrect number of parameters for cross. Expected 2 got 0");
3988}
3989
3990TEST_F(TypeDeterminerTest, ImportData_Cross_Error_TooFewParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003991 ast::type::F32 f32;
3992 ast::type::Vector vec(&f32, 3);
dan sinclairee392252020-06-08 23:48:15 +00003993
3994 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00003995 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003996 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003997 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00003998 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00003999 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004000 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclairee392252020-06-08 23:48:15 +00004001
4002 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004003 params.push_back(
4004 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_1));
dan sinclairee392252020-06-08 23:48:15 +00004005
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004006 auto* ident = create<ast::IdentifierExpression>(
4007 Source{}, mod->RegisterSymbol("cross"), "cross");
4008 ast::CallExpression call(Source{}, ident, params);
dan sinclairee392252020-06-08 23:48:15 +00004009
dan sinclairb4fee2f2020-09-22 19:42:13 +00004010 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclairee392252020-06-08 23:48:15 +00004011 EXPECT_EQ(td()->error(),
4012 "incorrect number of parameters for cross. Expected 2 got 1");
4013}
4014
4015TEST_F(TypeDeterminerTest, ImportData_Cross_Error_TooManyParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004016 ast::type::F32 f32;
4017 ast::type::Vector vec(&f32, 3);
dan sinclairee392252020-06-08 23:48:15 +00004018
4019 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004020 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004021 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004022 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004023 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004024 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004025 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclairee392252020-06-08 23:48:15 +00004026
4027 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004028 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004029 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004030 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004031 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004032 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004033 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclairee392252020-06-08 23:48:15 +00004034
4035 ast::ExpressionList vals_3;
Ben Clayton62625922020-11-13 22:09:38 +00004036 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004037 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004038 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004039 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004040 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004041 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclairee392252020-06-08 23:48:15 +00004042
4043 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004044 params.push_back(
4045 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_1));
4046 params.push_back(
4047 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_2));
4048 params.push_back(
4049 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_3));
dan sinclairee392252020-06-08 23:48:15 +00004050
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004051 auto* ident = create<ast::IdentifierExpression>(
4052 Source{}, mod->RegisterSymbol("cross"), "cross");
4053 ast::CallExpression call(Source{}, ident, params);
dan sinclairee392252020-06-08 23:48:15 +00004054
dan sinclairb4fee2f2020-09-22 19:42:13 +00004055 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclairee392252020-06-08 23:48:15 +00004056 EXPECT_EQ(td()->error(),
4057 "incorrect number of parameters for cross. Expected 2 got 3");
4058}
4059
dan sinclairb4fee2f2020-09-22 19:42:13 +00004060using ImportData_ThreeParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair2287d012020-04-22 00:23:57 +00004061TEST_P(ImportData_ThreeParamTest, Scalar) {
4062 auto param = GetParam();
4063
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004064 ast::type::F32 f32;
dan sinclair2287d012020-04-22 00:23:57 +00004065
4066 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004067 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004068 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00004069 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004070 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00004071 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004072 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclair2287d012020-04-22 00:23:57 +00004073
dan sinclair6b59bf42020-12-11 19:16:13 +00004074 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004075 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004076
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004077 ast::CallExpression call(Source{}, ident, params);
dan sinclair2287d012020-04-22 00:23:57 +00004078
dan sinclairb4fee2f2020-09-22 19:42:13 +00004079 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004080 ASSERT_NE(ident->result_type(), nullptr);
4081 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair2287d012020-04-22 00:23:57 +00004082}
4083
4084TEST_P(ImportData_ThreeParamTest, Vector) {
4085 auto param = GetParam();
4086
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004087 ast::type::F32 f32;
4088 ast::type::Vector vec(&f32, 3);
dan sinclair2287d012020-04-22 00:23:57 +00004089
4090 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004091 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004092 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004093 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004094 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004095 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004096 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclair2287d012020-04-22 00:23:57 +00004097
4098 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004099 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004100 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004101 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004102 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004103 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004104 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclair2287d012020-04-22 00:23:57 +00004105
4106 ast::ExpressionList vals_3;
Ben Clayton62625922020-11-13 22:09:38 +00004107 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004108 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004109 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004110 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004111 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004112 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclair2287d012020-04-22 00:23:57 +00004113
4114 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004115 params.push_back(
4116 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_1));
4117 params.push_back(
4118 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_2));
4119 params.push_back(
4120 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_3));
dan sinclair2287d012020-04-22 00:23:57 +00004121
dan sinclair6b59bf42020-12-11 19:16:13 +00004122 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004123 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004124
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004125 ast::CallExpression call(Source{}, ident, params);
dan sinclair2287d012020-04-22 00:23:57 +00004126
dan sinclairb4fee2f2020-09-22 19:42:13 +00004127 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004128 ASSERT_NE(ident->result_type(), nullptr);
4129 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004130 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair2287d012020-04-22 00:23:57 +00004131}
4132
4133TEST_P(ImportData_ThreeParamTest, Error_Integer) {
4134 auto param = GetParam();
4135
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004136 ast::type::I32 i32;
dan sinclair2287d012020-04-22 00:23:57 +00004137
4138 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004139 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004140 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004141 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004142 Source{}, create<ast::SintLiteral>(Source{}, &i32, 2)));
Ben Clayton62625922020-11-13 22:09:38 +00004143 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004144 Source{}, create<ast::SintLiteral>(Source{}, &i32, 3)));
dan sinclair2287d012020-04-22 00:23:57 +00004145
dan sinclair6b59bf42020-12-11 19:16:13 +00004146 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004147 Source{}, mod->RegisterSymbol(param.name), param.name);
4148 ast::CallExpression call(Source{}, ident, params);
dan sinclair2287d012020-04-22 00:23:57 +00004149
dan sinclairb4fee2f2020-09-22 19:42:13 +00004150 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair2287d012020-04-22 00:23:57 +00004151 EXPECT_EQ(td()->error(),
4152 std::string("incorrect type for ") + param.name +
dan sinclair53352042020-06-08 18:49:31 +00004153 ". Requires float scalar or float vector values");
dan sinclair2287d012020-04-22 00:23:57 +00004154}
4155
4156TEST_P(ImportData_ThreeParamTest, Error_NoParams) {
4157 auto param = GetParam();
4158
4159 ast::ExpressionList params;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004160
dan sinclair6b59bf42020-12-11 19:16:13 +00004161 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004162 Source{}, mod->RegisterSymbol(param.name), param.name);
4163 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004164
4165 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair2287d012020-04-22 00:23:57 +00004166 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4167 param.name + ". Expected 3 got 0");
4168}
4169
4170TEST_P(ImportData_ThreeParamTest, Error_OneParam) {
4171 auto param = GetParam();
4172
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004173 ast::type::F32 f32;
dan sinclair2287d012020-04-22 00:23:57 +00004174 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004175 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004176 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclair2287d012020-04-22 00:23:57 +00004177
dan sinclair6b59bf42020-12-11 19:16:13 +00004178 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004179 Source{}, mod->RegisterSymbol(param.name), param.name);
4180 ast::CallExpression call(Source{}, ident, params);
dan sinclair2287d012020-04-22 00:23:57 +00004181
dan sinclairb4fee2f2020-09-22 19:42:13 +00004182 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair2287d012020-04-22 00:23:57 +00004183 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4184 param.name + ". Expected 3 got 1");
4185}
4186
4187TEST_P(ImportData_ThreeParamTest, Error_TwoParams) {
4188 auto param = GetParam();
4189
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004190 ast::type::F32 f32;
dan sinclair2287d012020-04-22 00:23:57 +00004191 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004192 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004193 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00004194 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004195 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclair2287d012020-04-22 00:23:57 +00004196
dan sinclair6b59bf42020-12-11 19:16:13 +00004197 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004198 Source{}, mod->RegisterSymbol(param.name), param.name);
4199 ast::CallExpression call(Source{}, ident, params);
dan sinclair2287d012020-04-22 00:23:57 +00004200
dan sinclairb4fee2f2020-09-22 19:42:13 +00004201 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair2287d012020-04-22 00:23:57 +00004202 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4203 param.name + ". Expected 3 got 2");
4204}
4205
4206TEST_P(ImportData_ThreeParamTest, Error_MismatchedParamCount) {
4207 auto param = GetParam();
4208
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004209 ast::type::F32 f32;
4210 ast::type::Vector vec2(&f32, 2);
4211 ast::type::Vector vec3(&f32, 3);
dan sinclair2287d012020-04-22 00:23:57 +00004212
4213 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004214 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004215 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004216 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004217 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
dan sinclair2287d012020-04-22 00:23:57 +00004218
4219 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004220 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004221 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004222 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004223 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004224 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004225 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclair2287d012020-04-22 00:23:57 +00004226
4227 ast::ExpressionList vals_3;
Ben Clayton62625922020-11-13 22:09:38 +00004228 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004229 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004230 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004231 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004232 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004233 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclair2287d012020-04-22 00:23:57 +00004234
4235 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004236 params.push_back(
4237 create<ast::TypeConstructorExpression>(Source{}, &vec2, vals_1));
4238 params.push_back(
4239 create<ast::TypeConstructorExpression>(Source{}, &vec3, vals_2));
4240 params.push_back(
4241 create<ast::TypeConstructorExpression>(Source{}, &vec3, vals_3));
dan sinclair2287d012020-04-22 00:23:57 +00004242
dan sinclair6b59bf42020-12-11 19:16:13 +00004243 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004244 Source{}, mod->RegisterSymbol(param.name), param.name);
4245 ast::CallExpression call(Source{}, ident, params);
dan sinclair2287d012020-04-22 00:23:57 +00004246
dan sinclairb4fee2f2020-09-22 19:42:13 +00004247 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair2287d012020-04-22 00:23:57 +00004248 EXPECT_EQ(td()->error(),
4249 std::string("mismatched parameter types for ") + param.name);
4250}
4251
4252TEST_P(ImportData_ThreeParamTest, Error_MismatchedParamType) {
4253 auto param = GetParam();
4254
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004255 ast::type::F32 f32;
4256 ast::type::Vector vec(&f32, 3);
dan sinclair2287d012020-04-22 00:23:57 +00004257
4258 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00004259 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004260 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004261 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004262 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004263 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004264 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclair2287d012020-04-22 00:23:57 +00004265
4266 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004267 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004268 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004269 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004270 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
4271 params.push_back(
4272 create<ast::TypeConstructorExpression>(Source{}, &vec, vals));
dan sinclair2287d012020-04-22 00:23:57 +00004273
dan sinclair6b59bf42020-12-11 19:16:13 +00004274 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004275 Source{}, mod->RegisterSymbol(param.name), param.name);
4276 ast::CallExpression call(Source{}, ident, params);
dan sinclair2287d012020-04-22 00:23:57 +00004277
dan sinclairb4fee2f2020-09-22 19:42:13 +00004278 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair2287d012020-04-22 00:23:57 +00004279 EXPECT_EQ(td()->error(),
4280 std::string("mismatched parameter types for ") + param.name);
4281}
4282
4283TEST_P(ImportData_ThreeParamTest, Error_TooManyParams) {
4284 auto param = GetParam();
4285
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004286 ast::type::F32 f32;
dan sinclair2287d012020-04-22 00:23:57 +00004287 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004288 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004289 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00004290 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004291 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00004292 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004293 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00004294 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004295 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclair2287d012020-04-22 00:23:57 +00004296
dan sinclair6b59bf42020-12-11 19:16:13 +00004297 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004298 Source{}, mod->RegisterSymbol(param.name), param.name);
4299 ast::CallExpression call(Source{}, ident, params);
dan sinclair2287d012020-04-22 00:23:57 +00004300
dan sinclairb4fee2f2020-09-22 19:42:13 +00004301 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair2287d012020-04-22 00:23:57 +00004302 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4303 param.name + ". Expected 3 got 4");
4304}
4305
4306INSTANTIATE_TEST_SUITE_P(
4307 TypeDeterminerTest,
4308 ImportData_ThreeParamTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00004309 testing::Values(IntrinsicData{"mix", ast::Intrinsic::kMix},
4310 IntrinsicData{"smoothStep", ast::Intrinsic::kSmoothStep},
4311 IntrinsicData{"fma", ast::Intrinsic::kFma},
4312 IntrinsicData{"faceForward",
4313 ast::Intrinsic::kFaceForward}));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004314
dan sinclairb4fee2f2020-09-22 19:42:13 +00004315using ImportData_ThreeParam_FloatOrInt_Test =
4316 TypeDeterminerTestWithParam<IntrinsicData>;
4317TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Float_Scalar) {
4318 auto param = GetParam();
4319
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004320 ast::type::F32 f32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004321
4322 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004323 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004324 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00004325 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004326 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00004327 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004328 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004329
dan sinclair6b59bf42020-12-11 19:16:13 +00004330 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004331 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004332
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004333 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004334
4335 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004336 ASSERT_NE(ident->result_type(), nullptr);
4337 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclairb4fee2f2020-09-22 19:42:13 +00004338}
4339
4340TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Float_Vector) {
4341 auto param = GetParam();
4342
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004343 ast::type::F32 f32;
4344 ast::type::Vector vec(&f32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004345
4346 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004347 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004348 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004349 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004350 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004351 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004352 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004353
4354 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004355 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004356 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004357 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004358 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004359 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004360 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004361
4362 ast::ExpressionList vals_3;
Ben Clayton62625922020-11-13 22:09:38 +00004363 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004364 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004365 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004366 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004367 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004368 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004369
4370 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004371 params.push_back(
4372 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_1));
4373 params.push_back(
4374 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_2));
4375 params.push_back(
4376 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_3));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004377
dan sinclair6b59bf42020-12-11 19:16:13 +00004378 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004379 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004380
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004381 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004382
4383 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004384 ASSERT_NE(ident->result_type(), nullptr);
4385 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004386 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004387}
4388
4389TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Sint_Scalar) {
4390 auto param = GetParam();
4391
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004392 ast::type::I32 i32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004393
4394 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004395 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004396 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004397 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004398 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004399 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004400 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004401
dan sinclair6b59bf42020-12-11 19:16:13 +00004402 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004403 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004404
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004405 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004406
4407 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004408 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004409 EXPECT_TRUE(ident->result_type()->Is<ast::type::I32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00004410}
4411
4412TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Sint_Vector) {
4413 auto param = GetParam();
4414
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004415 ast::type::I32 i32;
4416 ast::type::Vector vec(&i32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004417
4418 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004419 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004420 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004421 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004422 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004423 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004424 Source{}, create<ast::SintLiteral>(Source{}, &i32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004425
4426 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004427 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004428 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004429 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004430 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004431 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004432 Source{}, create<ast::SintLiteral>(Source{}, &i32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004433
4434 ast::ExpressionList vals_3;
Ben Clayton62625922020-11-13 22:09:38 +00004435 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004436 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004437 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004438 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004439 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004440 Source{}, create<ast::SintLiteral>(Source{}, &i32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004441
4442 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004443 params.push_back(
4444 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_1));
4445 params.push_back(
4446 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_2));
4447 params.push_back(
4448 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_3));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004449
dan sinclair6b59bf42020-12-11 19:16:13 +00004450 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004451 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004452
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004453 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004454
4455 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004456 ASSERT_NE(ident->result_type(), nullptr);
4457 EXPECT_TRUE(ident->result_type()->is_signed_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004458 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004459}
4460
4461TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Uint_Scalar) {
4462 auto param = GetParam();
4463
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004464 ast::type::U32 u32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004465
4466 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004467 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004468 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004469 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004470 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004471 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004472 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004473
dan sinclair6b59bf42020-12-11 19:16:13 +00004474 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004475 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004476
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004477 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004478
4479 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004480 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004481 EXPECT_TRUE(ident->result_type()->Is<ast::type::U32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00004482}
4483
4484TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Uint_Vector) {
4485 auto param = GetParam();
4486
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004487 ast::type::U32 u32;
4488 ast::type::Vector vec(&u32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004489
4490 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004491 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004492 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004493 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004494 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004495 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004496 Source{}, create<ast::UintLiteral>(Source{}, &u32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004497
4498 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004499 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004500 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004501 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004502 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004503 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004504 Source{}, create<ast::UintLiteral>(Source{}, &u32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004505
4506 ast::ExpressionList vals_3;
Ben Clayton62625922020-11-13 22:09:38 +00004507 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004508 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004509 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004510 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004511 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004512 Source{}, create<ast::UintLiteral>(Source{}, &u32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004513
4514 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004515 params.push_back(
4516 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_1));
4517 params.push_back(
4518 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_2));
4519 params.push_back(
4520 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_3));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004521
dan sinclair6b59bf42020-12-11 19:16:13 +00004522 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004523 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004524
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004525 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004526
4527 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004528 ASSERT_NE(ident->result_type(), nullptr);
4529 EXPECT_TRUE(ident->result_type()->is_unsigned_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004530 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004531}
4532
4533TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_Bool) {
4534 auto param = GetParam();
4535
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004536 ast::type::Bool bool_type;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004537
4538 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004539 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004540 Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, true)));
Ben Clayton62625922020-11-13 22:09:38 +00004541 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004542 Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, false)));
Ben Clayton62625922020-11-13 22:09:38 +00004543 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004544 Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, true)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004545
dan sinclair6b59bf42020-12-11 19:16:13 +00004546 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004547 Source{}, mod->RegisterSymbol(param.name), param.name);
4548 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004549
4550 EXPECT_FALSE(td()->DetermineResultType(&call));
4551 EXPECT_EQ(td()->error(),
4552 std::string("incorrect type for ") + param.name +
4553 ". Requires float or int, scalar or vector values");
4554}
4555
4556TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_NoParams) {
4557 auto param = GetParam();
4558
4559 ast::ExpressionList params;
4560
dan sinclair6b59bf42020-12-11 19:16:13 +00004561 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004562 Source{}, mod->RegisterSymbol(param.name), param.name);
4563 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004564
4565 EXPECT_FALSE(td()->DetermineResultType(&call));
4566 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4567 param.name + ". Expected 3 got 0");
4568}
4569
4570TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_OneParam) {
4571 auto param = GetParam();
4572
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004573 ast::type::F32 f32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004574 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004575 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004576 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004577
dan sinclair6b59bf42020-12-11 19:16:13 +00004578 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004579 Source{}, mod->RegisterSymbol(param.name), param.name);
4580 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004581
4582 EXPECT_FALSE(td()->DetermineResultType(&call));
4583 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4584 param.name + ". Expected 3 got 1");
4585}
4586
4587TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_TwoParams) {
4588 auto param = GetParam();
4589
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004590 ast::type::F32 f32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004591 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004592 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004593 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00004594 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004595 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004596
dan sinclair6b59bf42020-12-11 19:16:13 +00004597 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004598 Source{}, mod->RegisterSymbol(param.name), param.name);
4599 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004600
4601 EXPECT_FALSE(td()->DetermineResultType(&call));
4602 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4603 param.name + ". Expected 3 got 2");
4604}
4605
4606TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_MismatchedParamCount) {
4607 auto param = GetParam();
4608
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004609 ast::type::F32 f32;
4610 ast::type::Vector vec2(&f32, 2);
4611 ast::type::Vector vec3(&f32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004612
4613 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004614 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004615 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004616 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004617 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004618
4619 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004620 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004621 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004622 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004623 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004624 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004625 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004626
4627 ast::ExpressionList vals_3;
Ben Clayton62625922020-11-13 22:09:38 +00004628 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004629 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004630 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004631 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004632 vals_3.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004633 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004634
4635 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004636 params.push_back(
4637 create<ast::TypeConstructorExpression>(Source{}, &vec2, vals_1));
4638 params.push_back(
4639 create<ast::TypeConstructorExpression>(Source{}, &vec3, vals_2));
4640 params.push_back(
4641 create<ast::TypeConstructorExpression>(Source{}, &vec3, vals_3));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004642
dan sinclair6b59bf42020-12-11 19:16:13 +00004643 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004644 Source{}, mod->RegisterSymbol(param.name), param.name);
4645 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004646
4647 EXPECT_FALSE(td()->DetermineResultType(&call));
4648 EXPECT_EQ(td()->error(),
4649 std::string("mismatched parameter types for ") + param.name);
4650}
4651
4652TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_MismatchedParamType) {
4653 auto param = GetParam();
4654
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004655 ast::type::F32 f32;
4656 ast::type::Vector vec(&f32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004657
4658 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00004659 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004660 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004661 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004662 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004663 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004664 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004665
4666 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004667 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004668 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
Ben Clayton62625922020-11-13 22:09:38 +00004669 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004670 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
4671 params.push_back(
4672 create<ast::TypeConstructorExpression>(Source{}, &vec, vals));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004673
dan sinclair6b59bf42020-12-11 19:16:13 +00004674 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004675 Source{}, mod->RegisterSymbol(param.name), param.name);
4676 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004677
4678 EXPECT_FALSE(td()->DetermineResultType(&call));
4679 EXPECT_EQ(td()->error(),
4680 std::string("mismatched parameter types for ") + param.name);
4681}
4682
4683TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_TooManyParams) {
4684 auto param = GetParam();
4685
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004686 ast::type::F32 f32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004687 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004688 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004689 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00004690 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004691 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00004692 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004693 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
Ben Clayton62625922020-11-13 22:09:38 +00004694 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004695 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004696
dan sinclair6b59bf42020-12-11 19:16:13 +00004697 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004698 Source{}, mod->RegisterSymbol(param.name), param.name);
4699 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004700
4701 EXPECT_FALSE(td()->DetermineResultType(&call));
4702 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4703 param.name + ". Expected 3 got 4");
4704}
4705
4706INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
4707 ImportData_ThreeParam_FloatOrInt_Test,
4708 testing::Values(IntrinsicData{
4709 "clamp", ast::Intrinsic::kClamp}));
4710
4711using ImportData_Int_SingleParamTest =
4712 TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004713TEST_P(ImportData_Int_SingleParamTest, Scalar) {
4714 auto param = GetParam();
4715
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004716 ast::type::I32 i32;
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004717
4718 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004719 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004720 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004721
dan sinclair6b59bf42020-12-11 19:16:13 +00004722 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004723 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004724
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004725 ast::CallExpression call(Source{}, ident, params);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004726
dan sinclairb4fee2f2020-09-22 19:42:13 +00004727 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004728 ASSERT_NE(ident->result_type(), nullptr);
4729 EXPECT_TRUE(ident->result_type()->is_integer_scalar());
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004730}
4731
4732TEST_P(ImportData_Int_SingleParamTest, Vector) {
4733 auto param = GetParam();
4734
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004735 ast::type::I32 i32;
4736 ast::type::Vector vec(&i32, 3);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004737
4738 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00004739 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004740 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004741 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004742 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004743 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004744 Source{}, create<ast::SintLiteral>(Source{}, &i32, 3)));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004745
4746 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004747 params.push_back(
4748 create<ast::TypeConstructorExpression>(Source{}, &vec, vals));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004749
dan sinclair6b59bf42020-12-11 19:16:13 +00004750 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004751 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004752
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004753 ast::CallExpression call(Source{}, ident, params);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004754
dan sinclairb4fee2f2020-09-22 19:42:13 +00004755 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004756 ASSERT_NE(ident->result_type(), nullptr);
4757 EXPECT_TRUE(ident->result_type()->is_signed_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004758 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004759}
4760
4761TEST_P(ImportData_Int_SingleParamTest, Error_Float) {
4762 auto param = GetParam();
4763
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004764 ast::type::F32 f32;
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004765
4766 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004767 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004768 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004769
dan sinclair6b59bf42020-12-11 19:16:13 +00004770 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004771 Source{}, mod->RegisterSymbol(param.name), param.name);
4772 ast::CallExpression call(Source{}, ident, params);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004773
dan sinclairb4fee2f2020-09-22 19:42:13 +00004774 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004775 EXPECT_EQ(td()->error(),
4776 std::string("incorrect type for ") + param.name +
4777 ". Requires integer scalar or integer vector values");
4778}
4779
4780TEST_P(ImportData_Int_SingleParamTest, Error_NoParams) {
4781 auto param = GetParam();
4782
4783 ast::ExpressionList params;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004784
dan sinclair6b59bf42020-12-11 19:16:13 +00004785 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004786 Source{}, mod->RegisterSymbol(param.name), param.name);
4787 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004788
4789 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004790 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4791 param.name + ". Expected 1 got 0");
4792}
4793
4794TEST_P(ImportData_Int_SingleParamTest, Error_MultipleParams) {
4795 auto param = GetParam();
4796
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004797 ast::type::I32 i32;
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004798 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004799 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004800 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004801 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004802 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004803 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004804 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004805
dan sinclair6b59bf42020-12-11 19:16:13 +00004806 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004807 Source{}, mod->RegisterSymbol(param.name), param.name);
4808 ast::CallExpression call(Source{}, ident, params);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004809
dan sinclairb4fee2f2020-09-22 19:42:13 +00004810 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004811 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4812 param.name + ". Expected 1 got 3");
4813}
4814
dan sinclairaf5df702020-06-08 23:48:26 +00004815INSTANTIATE_TEST_SUITE_P(
4816 TypeDeterminerTest,
4817 ImportData_Int_SingleParamTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00004818 testing::Values(
4819 IntrinsicData{"countOneBits", ast::Intrinsic::kCountOneBits},
4820 IntrinsicData{"reverseBits", ast::Intrinsic::kReverseBits}));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004821
dan sinclairb4fee2f2020-09-22 19:42:13 +00004822using ImportData_FloatOrInt_TwoParamTest =
4823 TypeDeterminerTestWithParam<IntrinsicData>;
4824TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Signed) {
dan sinclair92bb5572020-06-08 23:48:07 +00004825 auto param = GetParam();
4826
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004827 ast::type::I32 i32;
dan sinclair92bb5572020-06-08 23:48:07 +00004828
4829 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004830 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004831 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004832 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004833 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
dan sinclair92bb5572020-06-08 23:48:07 +00004834
dan sinclair6b59bf42020-12-11 19:16:13 +00004835 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004836 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004837
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004838 ast::CallExpression call(Source{}, ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00004839
dan sinclairb4fee2f2020-09-22 19:42:13 +00004840 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004841 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004842 EXPECT_TRUE(ident->result_type()->Is<ast::type::I32>());
dan sinclair92bb5572020-06-08 23:48:07 +00004843}
4844
dan sinclairb4fee2f2020-09-22 19:42:13 +00004845TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Unsigned) {
dan sinclair92bb5572020-06-08 23:48:07 +00004846 auto param = GetParam();
4847
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004848 ast::type::U32 u32;
dan sinclair92bb5572020-06-08 23:48:07 +00004849
4850 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004851 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004852 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004853 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004854 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
dan sinclair92bb5572020-06-08 23:48:07 +00004855
dan sinclair6b59bf42020-12-11 19:16:13 +00004856 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004857 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004858
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004859 ast::CallExpression call(Source{}, ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00004860
dan sinclairb4fee2f2020-09-22 19:42:13 +00004861 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004862 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004863 EXPECT_TRUE(ident->result_type()->Is<ast::type::U32>());
dan sinclair92bb5572020-06-08 23:48:07 +00004864}
4865
dan sinclairb4fee2f2020-09-22 19:42:13 +00004866TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Float) {
4867 auto param = GetParam();
4868
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004869 ast::type::F32 f32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004870
4871 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004872 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004873 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004874 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004875 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004876
dan sinclair6b59bf42020-12-11 19:16:13 +00004877 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004878 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004879
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004880 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004881
4882 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004883 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004884 EXPECT_TRUE(ident->result_type()->Is<ast::type::F32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00004885}
4886
4887TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Signed) {
dan sinclair92bb5572020-06-08 23:48:07 +00004888 auto param = GetParam();
4889
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004890 ast::type::I32 i32;
4891 ast::type::Vector vec(&i32, 3);
dan sinclair92bb5572020-06-08 23:48:07 +00004892
4893 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004894 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004895 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004896 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004897 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004898 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004899 Source{}, create<ast::SintLiteral>(Source{}, &i32, 3)));
dan sinclair92bb5572020-06-08 23:48:07 +00004900
4901 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004902 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004903 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004904 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004905 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004906 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004907 Source{}, create<ast::SintLiteral>(Source{}, &i32, 3)));
dan sinclair92bb5572020-06-08 23:48:07 +00004908
4909 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004910 params.push_back(
4911 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_1));
4912 params.push_back(
4913 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_2));
dan sinclair92bb5572020-06-08 23:48:07 +00004914
dan sinclair6b59bf42020-12-11 19:16:13 +00004915 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004916 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004917
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004918 ast::CallExpression call(Source{}, ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00004919
dan sinclairb4fee2f2020-09-22 19:42:13 +00004920 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004921 ASSERT_NE(ident->result_type(), nullptr);
4922 EXPECT_TRUE(ident->result_type()->is_signed_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004923 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair92bb5572020-06-08 23:48:07 +00004924}
4925
dan sinclairb4fee2f2020-09-22 19:42:13 +00004926TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Unsigned) {
dan sinclair92bb5572020-06-08 23:48:07 +00004927 auto param = GetParam();
4928
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004929 ast::type::U32 u32;
4930 ast::type::Vector vec(&u32, 3);
dan sinclair92bb5572020-06-08 23:48:07 +00004931
4932 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004933 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004934 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004935 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004936 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004937 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004938 Source{}, create<ast::UintLiteral>(Source{}, &u32, 3)));
dan sinclair92bb5572020-06-08 23:48:07 +00004939
4940 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004941 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004942 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004943 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004944 Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004945 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004946 Source{}, create<ast::UintLiteral>(Source{}, &u32, 3)));
dan sinclair92bb5572020-06-08 23:48:07 +00004947
4948 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004949 params.push_back(
4950 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_1));
4951 params.push_back(
4952 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_2));
dan sinclair92bb5572020-06-08 23:48:07 +00004953
dan sinclair6b59bf42020-12-11 19:16:13 +00004954 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004955 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004956
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004957 ast::CallExpression call(Source{}, ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00004958
dan sinclairb4fee2f2020-09-22 19:42:13 +00004959 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004960 ASSERT_NE(ident->result_type(), nullptr);
4961 EXPECT_TRUE(ident->result_type()->is_unsigned_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004962 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair92bb5572020-06-08 23:48:07 +00004963}
4964
dan sinclairb4fee2f2020-09-22 19:42:13 +00004965TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Float) {
dan sinclair92bb5572020-06-08 23:48:07 +00004966 auto param = GetParam();
4967
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004968 ast::type::F32 f32;
4969 ast::type::Vector vec(&f32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004970
4971 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004972 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004973 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004974 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004975 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004976 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004977 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004978
4979 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004980 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004981 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004982 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004983 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00004984 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004985 Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004986
4987 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004988 params.push_back(
4989 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_1));
4990 params.push_back(
4991 create<ast::TypeConstructorExpression>(Source{}, &vec, vals_2));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004992
dan sinclair6b59bf42020-12-11 19:16:13 +00004993 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004994 Source{}, mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004995
Ben Clayton1ff59cd2020-12-12 01:38:13 +00004996 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004997
4998 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004999 ASSERT_NE(ident->result_type(), nullptr);
5000 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00005001 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00005002}
5003
5004TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_Bool) {
5005 auto param = GetParam();
5006
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00005007 ast::type::Bool bool_type;
dan sinclair92bb5572020-06-08 23:48:07 +00005008
5009 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00005010 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005011 Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, true)));
Ben Clayton62625922020-11-13 22:09:38 +00005012 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005013 Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, false)));
dan sinclair92bb5572020-06-08 23:48:07 +00005014
dan sinclair6b59bf42020-12-11 19:16:13 +00005015 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005016 Source{}, mod->RegisterSymbol(param.name), param.name);
5017 ast::CallExpression call(Source{}, ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00005018
dan sinclairb4fee2f2020-09-22 19:42:13 +00005019 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair92bb5572020-06-08 23:48:07 +00005020 EXPECT_EQ(td()->error(),
5021 std::string("incorrect type for ") + param.name +
dan sinclairb4fee2f2020-09-22 19:42:13 +00005022 ". Requires float or int, scalar or vector values");
dan sinclair92bb5572020-06-08 23:48:07 +00005023}
5024
dan sinclairb4fee2f2020-09-22 19:42:13 +00005025TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_NoParams) {
dan sinclair92bb5572020-06-08 23:48:07 +00005026 auto param = GetParam();
5027
5028 ast::ExpressionList params;
dan sinclairb4fee2f2020-09-22 19:42:13 +00005029
dan sinclair6b59bf42020-12-11 19:16:13 +00005030 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005031 Source{}, mod->RegisterSymbol(param.name), param.name);
5032 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00005033
5034 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair92bb5572020-06-08 23:48:07 +00005035 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
5036 param.name + ". Expected 2 got 0");
5037}
5038
dan sinclairb4fee2f2020-09-22 19:42:13 +00005039TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_OneParam) {
dan sinclair92bb5572020-06-08 23:48:07 +00005040 auto param = GetParam();
5041
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00005042 ast::type::I32 i32;
dan sinclair92bb5572020-06-08 23:48:07 +00005043 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00005044 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005045 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
dan sinclair92bb5572020-06-08 23:48:07 +00005046
dan sinclair6b59bf42020-12-11 19:16:13 +00005047 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005048 Source{}, mod->RegisterSymbol(param.name), param.name);
5049 ast::CallExpression call(Source{}, ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00005050
dan sinclairb4fee2f2020-09-22 19:42:13 +00005051 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair92bb5572020-06-08 23:48:07 +00005052 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
5053 param.name + ". Expected 2 got 1");
5054}
5055
dan sinclairb4fee2f2020-09-22 19:42:13 +00005056TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_MismatchedParamCount) {
dan sinclair92bb5572020-06-08 23:48:07 +00005057 auto param = GetParam();
5058
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00005059 ast::type::I32 i32;
5060 ast::type::Vector vec2(&i32, 2);
5061 ast::type::Vector vec3(&i32, 3);
dan sinclair92bb5572020-06-08 23:48:07 +00005062
5063 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00005064 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005065 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00005066 vals_1.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005067 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
dan sinclair92bb5572020-06-08 23:48:07 +00005068
5069 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00005070 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005071 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00005072 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005073 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00005074 vals_2.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005075 Source{}, create<ast::SintLiteral>(Source{}, &i32, 3)));
dan sinclair92bb5572020-06-08 23:48:07 +00005076
5077 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005078 params.push_back(
5079 create<ast::TypeConstructorExpression>(Source{}, &vec2, vals_1));
5080 params.push_back(
5081 create<ast::TypeConstructorExpression>(Source{}, &vec3, vals_2));
dan sinclair92bb5572020-06-08 23:48:07 +00005082
dan sinclair6b59bf42020-12-11 19:16:13 +00005083 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005084 Source{}, mod->RegisterSymbol(param.name), param.name);
5085 ast::CallExpression call(Source{}, ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00005086
dan sinclairb4fee2f2020-09-22 19:42:13 +00005087 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair92bb5572020-06-08 23:48:07 +00005088 EXPECT_EQ(td()->error(),
5089 std::string("mismatched parameter types for ") + param.name);
5090}
5091
dan sinclairb4fee2f2020-09-22 19:42:13 +00005092TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_MismatchedParamType) {
dan sinclair92bb5572020-06-08 23:48:07 +00005093 auto param = GetParam();
5094
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00005095 ast::type::I32 i32;
5096 ast::type::Vector vec(&i32, 3);
dan sinclair92bb5572020-06-08 23:48:07 +00005097
5098 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00005099 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005100 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00005101 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005102 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00005103 vals.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005104 Source{}, create<ast::SintLiteral>(Source{}, &i32, 3)));
dan sinclair92bb5572020-06-08 23:48:07 +00005105
5106 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00005107 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005108 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
5109 params.push_back(
5110 create<ast::TypeConstructorExpression>(Source{}, &vec, vals));
dan sinclair92bb5572020-06-08 23:48:07 +00005111
dan sinclair6b59bf42020-12-11 19:16:13 +00005112 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005113 Source{}, mod->RegisterSymbol(param.name), param.name);
5114 ast::CallExpression call(Source{}, ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00005115
dan sinclairb4fee2f2020-09-22 19:42:13 +00005116 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair92bb5572020-06-08 23:48:07 +00005117 EXPECT_EQ(td()->error(),
5118 std::string("mismatched parameter types for ") + param.name);
5119}
5120
dan sinclairb4fee2f2020-09-22 19:42:13 +00005121TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_TooManyParams) {
dan sinclair92bb5572020-06-08 23:48:07 +00005122 auto param = GetParam();
5123
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00005124 ast::type::I32 i32;
dan sinclair92bb5572020-06-08 23:48:07 +00005125 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00005126 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005127 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00005128 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005129 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
Ben Clayton62625922020-11-13 22:09:38 +00005130 params.push_back(create<ast::ScalarConstructorExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005131 Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
dan sinclair92bb5572020-06-08 23:48:07 +00005132
dan sinclair6b59bf42020-12-11 19:16:13 +00005133 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005134 Source{}, mod->RegisterSymbol(param.name), param.name);
5135 ast::CallExpression call(Source{}, ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00005136
dan sinclairb4fee2f2020-09-22 19:42:13 +00005137 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair92bb5572020-06-08 23:48:07 +00005138 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
5139 param.name + ". Expected 2 got 3");
5140}
5141
dan sinclairb4fee2f2020-09-22 19:42:13 +00005142INSTANTIATE_TEST_SUITE_P(
5143 TypeDeterminerTest,
5144 ImportData_FloatOrInt_TwoParamTest,
5145 testing::Values(IntrinsicData{"min", ast::Intrinsic::kMin},
5146 IntrinsicData{"max", ast::Intrinsic::kMax}));
dan sinclair92bb5572020-06-08 23:48:07 +00005147
dan sinclair3238eaa2020-06-17 20:22:08 +00005148TEST_F(TypeDeterminerTest, ImportData_GLSL_Determinant) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00005149 ast::type::F32 f32;
5150 ast::type::Matrix mat(&f32, 3, 3);
dan sinclair3819c262020-06-17 18:39:17 +00005151
Ben Claytona80511e2020-12-11 13:07:02 +00005152 auto* var =
5153 create<ast::Variable>(Source{}, // source
5154 "var", // name
5155 ast::StorageClass::kFunction, // storage_class
5156 &mat, // type
5157 false, // is_const
5158 nullptr, // constructor
5159 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00005160 mod->AddGlobalVariable(var);
dan sinclair3819c262020-06-17 18:39:17 +00005161
5162 // Register the global
5163 ASSERT_TRUE(td()->Determine()) << td()->error();
5164
5165 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005166 params.push_back(create<ast::IdentifierExpression>(
5167 Source{}, mod->RegisterSymbol("var"), "var"));
dan sinclair3819c262020-06-17 18:39:17 +00005168
dan sinclair6b59bf42020-12-11 19:16:13 +00005169 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005170 Source{}, mod->RegisterSymbol("determinant"), "determinant");
Ben Clayton4bfe4612020-11-16 16:41:47 +00005171
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005172 ast::CallExpression call(Source{}, ident, params);
dan sinclair3819c262020-06-17 18:39:17 +00005173
dan sinclairb4fee2f2020-09-22 19:42:13 +00005174 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00005175 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00005176 EXPECT_TRUE(ident->result_type()->Is<ast::type::F32>());
dan sinclair3819c262020-06-17 18:39:17 +00005177}
5178
dan sinclairb4fee2f2020-09-22 19:42:13 +00005179using ImportData_Matrix_OneParam_Test =
5180 TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair3238eaa2020-06-17 20:22:08 +00005181TEST_P(ImportData_Matrix_OneParam_Test, Error_Float) {
5182 auto param = GetParam();
5183
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00005184 ast::type::F32 f32;
dan sinclair3819c262020-06-17 18:39:17 +00005185
Ben Claytona80511e2020-12-11 13:07:02 +00005186 auto* var =
5187 create<ast::Variable>(Source{}, // source
5188 "var", // name
5189 ast::StorageClass::kFunction, // storage_class
5190 &f32, // type
5191 false, // is_const
5192 nullptr, // constructor
5193 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00005194 mod->AddGlobalVariable(var);
dan sinclair3819c262020-06-17 18:39:17 +00005195
5196 // Register the global
5197 ASSERT_TRUE(td()->Determine()) << td()->error();
5198
5199 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005200 params.push_back(create<ast::IdentifierExpression>(
5201 Source{}, mod->RegisterSymbol("var"), "var"));
dan sinclair3819c262020-06-17 18:39:17 +00005202
dan sinclair6b59bf42020-12-11 19:16:13 +00005203 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005204 Source{}, mod->RegisterSymbol(param.name), param.name);
5205 ast::CallExpression call(Source{}, ident, params);
dan sinclair3819c262020-06-17 18:39:17 +00005206
dan sinclairb4fee2f2020-09-22 19:42:13 +00005207 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair3238eaa2020-06-17 20:22:08 +00005208 EXPECT_EQ(td()->error(), std::string("incorrect type for ") + param.name +
5209 ". Requires matrix value");
dan sinclair3819c262020-06-17 18:39:17 +00005210}
5211
dan sinclair3238eaa2020-06-17 20:22:08 +00005212TEST_P(ImportData_Matrix_OneParam_Test, NoParams) {
5213 auto param = GetParam();
5214
dan sinclair3819c262020-06-17 18:39:17 +00005215 ast::ExpressionList params;
5216
dan sinclair6b59bf42020-12-11 19:16:13 +00005217 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005218 Source{}, mod->RegisterSymbol(param.name), param.name);
5219 ast::CallExpression call(Source{}, ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00005220
5221 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair3238eaa2020-06-17 20:22:08 +00005222 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
5223 param.name + ". Expected 1 got 0");
dan sinclair3819c262020-06-17 18:39:17 +00005224}
5225
dan sinclair3238eaa2020-06-17 20:22:08 +00005226TEST_P(ImportData_Matrix_OneParam_Test, TooManyParams) {
5227 auto param = GetParam();
5228
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00005229 ast::type::F32 f32;
5230 ast::type::Matrix mat(&f32, 3, 3);
dan sinclair3819c262020-06-17 18:39:17 +00005231
Ben Claytona80511e2020-12-11 13:07:02 +00005232 auto* var =
5233 create<ast::Variable>(Source{}, // source
5234 "var", // name
5235 ast::StorageClass::kFunction, // storage_class
5236 &mat, // type
5237 false, // is_const
5238 nullptr, // constructor
5239 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00005240 mod->AddGlobalVariable(var);
dan sinclair3819c262020-06-17 18:39:17 +00005241
5242 // Register the global
5243 ASSERT_TRUE(td()->Determine()) << td()->error();
5244
5245 ast::ExpressionList params;
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005246 params.push_back(create<ast::IdentifierExpression>(
5247 Source{}, mod->RegisterSymbol("var"), "var"));
5248 params.push_back(create<ast::IdentifierExpression>(
5249 Source{}, mod->RegisterSymbol("var"), "var"));
dan sinclair3819c262020-06-17 18:39:17 +00005250
dan sinclair6b59bf42020-12-11 19:16:13 +00005251 auto* ident = create<ast::IdentifierExpression>(
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005252 Source{}, mod->RegisterSymbol(param.name), param.name);
5253 ast::CallExpression call(Source{}, ident, params);
dan sinclair3819c262020-06-17 18:39:17 +00005254
dan sinclairb4fee2f2020-09-22 19:42:13 +00005255 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair3238eaa2020-06-17 20:22:08 +00005256 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
5257 param.name + ". Expected 1 got 2");
dan sinclair3819c262020-06-17 18:39:17 +00005258}
dan sinclaire9598d62020-06-18 18:03:00 +00005259INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00005260 ImportData_Matrix_OneParam_Test,
5261 testing::Values(IntrinsicData{
5262 "determinant", ast::Intrinsic::kDeterminant}));
dan sinclaire9598d62020-06-18 18:03:00 +00005263
dan sinclair05926432020-09-21 17:51:31 +00005264TEST_F(TypeDeterminerTest, Function_EntryPoints_StageDecoration) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00005265 ast::type::F32 f32;
dan sinclair05926432020-09-21 17:51:31 +00005266
5267 // fn b() {}
5268 // fn c() { b(); }
5269 // fn a() { c(); }
5270 // fn ep_1() { a(); b(); }
5271 // fn ep_2() { c();}
5272 //
5273 // c -> {ep_1, ep_2}
5274 // a -> {ep_1}
5275 // b -> {ep_1, ep_2}
5276 // ep_1 -> {}
5277 // ep_2 -> {}
5278
5279 ast::VariableList params;
Ben Claytondb5ce652020-12-14 20:25:27 +00005280 auto* body = create<ast::BlockStatement>(Source{}, ast::StatementList{});
dan sinclaira41132f2020-12-11 18:24:53 +00005281 auto* func_b =
5282 create<ast::Function>(Source{}, mod->RegisterSymbol("b"), "b", params,
5283 &f32, body, ast::FunctionDecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00005284
Ben Claytondb5ce652020-12-14 20:25:27 +00005285 body = create<ast::BlockStatement>(
5286 Source{}, ast::StatementList{
5287 create<ast::AssignmentStatement>(
5288 Source{},
5289 create<ast::IdentifierExpression>(
5290 Source{}, mod->RegisterSymbol("second"), "second"),
5291 create<ast::CallExpression>(
5292 Source{},
5293 create<ast::IdentifierExpression>(
5294 Source{}, mod->RegisterSymbol("b"), "b"),
5295 ast::ExpressionList{})),
5296 });
dan sinclaira41132f2020-12-11 18:24:53 +00005297 auto* func_c =
5298 create<ast::Function>(Source{}, mod->RegisterSymbol("c"), "c", params,
5299 &f32, body, ast::FunctionDecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00005300
Ben Claytondb5ce652020-12-14 20:25:27 +00005301 body = create<ast::BlockStatement>(
5302 Source{}, ast::StatementList{
5303 create<ast::AssignmentStatement>(
5304 Source{},
5305 create<ast::IdentifierExpression>(
5306 Source{}, mod->RegisterSymbol("first"), "first"),
5307 create<ast::CallExpression>(
5308 Source{},
5309 create<ast::IdentifierExpression>(
5310 Source{}, mod->RegisterSymbol("c"), "c"),
5311 ast::ExpressionList{})),
5312 });
dan sinclaira41132f2020-12-11 18:24:53 +00005313 auto* func_a =
5314 create<ast::Function>(Source{}, mod->RegisterSymbol("a"), "a", params,
5315 &f32, body, ast::FunctionDecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00005316
Ben Claytondb5ce652020-12-14 20:25:27 +00005317 body = create<ast::BlockStatement>(
5318 Source{}, ast::StatementList{
5319 create<ast::AssignmentStatement>(
5320 Source{},
5321 create<ast::IdentifierExpression>(
5322 Source{}, mod->RegisterSymbol("call_a"), "call_a"),
5323 create<ast::CallExpression>(
5324 Source{},
5325 create<ast::IdentifierExpression>(
5326 Source{}, mod->RegisterSymbol("a"), "a"),
5327 ast::ExpressionList{})),
5328 create<ast::AssignmentStatement>(
5329 Source{},
5330 create<ast::IdentifierExpression>(
5331 Source{}, mod->RegisterSymbol("call_b"), "call_b"),
5332 create<ast::CallExpression>(
5333 Source{},
5334 create<ast::IdentifierExpression>(
5335 Source{}, mod->RegisterSymbol("b"), "b"),
5336 ast::ExpressionList{})),
5337 });
Ben Clayton234b7de2020-12-07 20:45:14 +00005338 auto* ep_1 = create<ast::Function>(
dan sinclaira41132f2020-12-11 18:24:53 +00005339 Source{}, mod->RegisterSymbol("ep_1"), "ep_1", params, &f32, body,
Ben Clayton234b7de2020-12-07 20:45:14 +00005340 ast::FunctionDecorationList{
5341 create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}),
5342 });
dan sinclair05926432020-09-21 17:51:31 +00005343
Ben Claytondb5ce652020-12-14 20:25:27 +00005344 body = create<ast::BlockStatement>(
5345 Source{}, ast::StatementList{
5346 create<ast::AssignmentStatement>(
5347 Source{},
5348 create<ast::IdentifierExpression>(
5349 Source{}, mod->RegisterSymbol("call_c"), "call_c"),
5350 create<ast::CallExpression>(
5351 Source{},
5352 create<ast::IdentifierExpression>(
5353 Source{}, mod->RegisterSymbol("c"), "c"),
5354 ast::ExpressionList{})),
5355 });
Ben Clayton234b7de2020-12-07 20:45:14 +00005356 auto* ep_2 = create<ast::Function>(
dan sinclaira41132f2020-12-11 18:24:53 +00005357 Source{}, mod->RegisterSymbol("ep_2"), "ep_2", params, &f32, body,
Ben Clayton234b7de2020-12-07 20:45:14 +00005358 ast::FunctionDecorationList{
5359 create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}),
5360 });
dan sinclair05926432020-09-21 17:51:31 +00005361
Ben Clayton3ea3c992020-11-18 21:19:22 +00005362 mod->AddFunction(func_b);
5363 mod->AddFunction(func_c);
5364 mod->AddFunction(func_a);
5365 mod->AddFunction(ep_1);
5366 mod->AddFunction(ep_2);
dan sinclair05926432020-09-21 17:51:31 +00005367
Ben Claytona80511e2020-12-11 13:07:02 +00005368 mod->AddGlobalVariable(
5369 create<ast::Variable>(Source{}, // source
5370 "first", // name
5371 ast::StorageClass::kPrivate, // storage_class
5372 &f32, // type
5373 false, // is_const
5374 nullptr, // constructor
5375 ast::VariableDecorationList{})); // decorations
5376 mod->AddGlobalVariable(
5377 create<ast::Variable>(Source{}, // source
5378 "second", // name
5379 ast::StorageClass::kPrivate, // storage_class
5380 &f32, // type
5381 false, // is_const
5382 nullptr, // constructor
5383 ast::VariableDecorationList{})); // decorations
5384 mod->AddGlobalVariable(
5385 create<ast::Variable>(Source{}, // source
5386 "call_a", // name
5387 ast::StorageClass::kPrivate, // storage_class
5388 &f32, // type
5389 false, // is_const
5390 nullptr, // constructor
5391 ast::VariableDecorationList{})); // decorations
5392 mod->AddGlobalVariable(
5393 create<ast::Variable>(Source{}, // source
5394 "call_b", // name
5395 ast::StorageClass::kPrivate, // storage_class
5396 &f32, // type
5397 false, // is_const
5398 nullptr, // constructor
5399 ast::VariableDecorationList{})); // decorations
5400 mod->AddGlobalVariable(
5401 create<ast::Variable>(Source{}, // source
5402 "call_c", // name
5403 ast::StorageClass::kPrivate, // storage_class
5404 &f32, // type
5405 false, // is_const
5406 nullptr, // constructor
5407 ast::VariableDecorationList{})); // decorations
dan sinclairff267ca2020-10-14 18:26:31 +00005408
dan sinclair05926432020-09-21 17:51:31 +00005409 // Register the functions and calculate the callers
5410 ASSERT_TRUE(td()->Determine()) << td()->error();
5411
Ben Clayton4bfe4612020-11-16 16:41:47 +00005412 const auto& b_eps = func_b->ancestor_entry_points();
dan sinclair05926432020-09-21 17:51:31 +00005413 ASSERT_EQ(2u, b_eps.size());
dan sinclaira41132f2020-12-11 18:24:53 +00005414 EXPECT_EQ(mod->RegisterSymbol("ep_1"), b_eps[0]);
5415 EXPECT_EQ(mod->RegisterSymbol("ep_2"), b_eps[1]);
dan sinclair05926432020-09-21 17:51:31 +00005416
Ben Clayton4bfe4612020-11-16 16:41:47 +00005417 const auto& a_eps = func_a->ancestor_entry_points();
dan sinclair05926432020-09-21 17:51:31 +00005418 ASSERT_EQ(1u, a_eps.size());
dan sinclaira41132f2020-12-11 18:24:53 +00005419 EXPECT_EQ(mod->RegisterSymbol("ep_1"), a_eps[0]);
dan sinclair05926432020-09-21 17:51:31 +00005420
Ben Clayton4bfe4612020-11-16 16:41:47 +00005421 const auto& c_eps = func_c->ancestor_entry_points();
dan sinclair05926432020-09-21 17:51:31 +00005422 ASSERT_EQ(2u, c_eps.size());
dan sinclaira41132f2020-12-11 18:24:53 +00005423 EXPECT_EQ(mod->RegisterSymbol("ep_1"), c_eps[0]);
5424 EXPECT_EQ(mod->RegisterSymbol("ep_2"), c_eps[1]);
dan sinclair05926432020-09-21 17:51:31 +00005425
Ben Clayton4bfe4612020-11-16 16:41:47 +00005426 EXPECT_TRUE(ep_1->ancestor_entry_points().empty());
5427 EXPECT_TRUE(ep_2->ancestor_entry_points().empty());
dan sinclair05926432020-09-21 17:51:31 +00005428}
5429
Ben Clayton3ea3c992020-11-18 21:19:22 +00005430using TypeDeterminerTextureIntrinsicTest =
5431 TypeDeterminerTestWithParam<ast::intrinsic::test::TextureOverloadCase>;
5432
5433INSTANTIATE_TEST_SUITE_P(
5434 TypeDeterminerTest,
5435 TypeDeterminerTextureIntrinsicTest,
5436 testing::ValuesIn(ast::intrinsic::test::TextureOverloadCase::ValidCases()));
5437
5438std::string to_str(const std::string& function,
5439 const ast::intrinsic::TextureSignature* sig) {
5440 struct Parameter {
5441 size_t idx;
5442 std::string name;
5443 };
5444 std::vector<Parameter> params;
5445 auto maybe_add_param = [&params](size_t idx, const char* name) {
5446 if (idx != ast::intrinsic::TextureSignature::Parameters::kNotUsed) {
5447 params.emplace_back(Parameter{idx, name});
5448 }
5449 };
5450 maybe_add_param(sig->params.idx.array_index, "array_index");
5451 maybe_add_param(sig->params.idx.bias, "bias");
5452 maybe_add_param(sig->params.idx.coords, "coords");
5453 maybe_add_param(sig->params.idx.depth_ref, "depth_ref");
5454 maybe_add_param(sig->params.idx.ddx, "ddx");
5455 maybe_add_param(sig->params.idx.ddy, "ddy");
5456 maybe_add_param(sig->params.idx.level, "level");
5457 maybe_add_param(sig->params.idx.offset, "offset");
5458 maybe_add_param(sig->params.idx.sampler, "sampler");
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005459 maybe_add_param(sig->params.idx.sample_index, "sample_index");
Ben Clayton3ea3c992020-11-18 21:19:22 +00005460 maybe_add_param(sig->params.idx.texture, "texture");
Ben Clayton591268d2020-12-10 18:39:41 +00005461 maybe_add_param(sig->params.idx.value, "value");
Ben Clayton3ea3c992020-11-18 21:19:22 +00005462 std::sort(
5463 params.begin(), params.end(),
5464 [](const Parameter& a, const Parameter& b) { return a.idx < b.idx; });
5465
5466 std::stringstream out;
5467 out << function << "(";
5468 bool first = true;
5469 for (auto& param : params) {
5470 if (!first) {
5471 out << ", ";
5472 }
5473 out << param.name;
5474 first = false;
5475 }
5476 out << ")";
5477 return out.str();
5478}
5479
5480const char* expected_texture_overload(
5481 ast::intrinsic::test::ValidTextureOverload overload) {
5482 using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
5483 switch (overload) {
5484 case ValidTextureOverload::kSample1dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005485 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005486 case ValidTextureOverload::kSample1dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005487 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005488 case ValidTextureOverload::kSample2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005489 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005490 case ValidTextureOverload::kSample2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005491 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005492 case ValidTextureOverload::kSample2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005493 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005494 case ValidTextureOverload::kSample2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005495 return R"(textureSample(texture, sampler, coords, array_index, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005496 case ValidTextureOverload::kSample3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005497 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005498 case ValidTextureOverload::kSample3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005499 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005500 case ValidTextureOverload::kSampleCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005501 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005502 case ValidTextureOverload::kSampleCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005503 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005504 case ValidTextureOverload::kSampleDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005505 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005506 case ValidTextureOverload::kSampleDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005507 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005508 case ValidTextureOverload::kSampleDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005509 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005510 case ValidTextureOverload::kSampleDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005511 return R"(textureSample(texture, sampler, coords, array_index, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005512 case ValidTextureOverload::kSampleDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005513 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005514 case ValidTextureOverload::kSampleDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005515 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005516 case ValidTextureOverload::kSampleBias2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005517 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005518 case ValidTextureOverload::kSampleBias2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005519 return R"(textureSampleBias(texture, sampler, coords, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005520 case ValidTextureOverload::kSampleBias2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005521 return R"(textureSampleBias(texture, sampler, coords, array_index, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005522 case ValidTextureOverload::kSampleBias2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005523 return R"(textureSampleBias(texture, sampler, coords, array_index, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005524 case ValidTextureOverload::kSampleBias3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005525 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005526 case ValidTextureOverload::kSampleBias3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005527 return R"(textureSampleBias(texture, sampler, coords, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005528 case ValidTextureOverload::kSampleBiasCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005529 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005530 case ValidTextureOverload::kSampleBiasCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005531 return R"(textureSampleBias(texture, sampler, coords, array_index, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005532 case ValidTextureOverload::kSampleLevel2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005533 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005534 case ValidTextureOverload::kSampleLevel2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005535 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005536 case ValidTextureOverload::kSampleLevel2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005537 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005538 case ValidTextureOverload::kSampleLevel2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005539 return R"(textureSampleLevel(texture, sampler, coords, array_index, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005540 case ValidTextureOverload::kSampleLevel3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005541 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005542 case ValidTextureOverload::kSampleLevel3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005543 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005544 case ValidTextureOverload::kSampleLevelCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005545 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005546 case ValidTextureOverload::kSampleLevelCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005547 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005548 case ValidTextureOverload::kSampleLevelDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005549 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005550 case ValidTextureOverload::kSampleLevelDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005551 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005552 case ValidTextureOverload::kSampleLevelDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005553 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005554 case ValidTextureOverload::kSampleLevelDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005555 return R"(textureSampleLevel(texture, sampler, coords, array_index, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005556 case ValidTextureOverload::kSampleLevelDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005557 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005558 case ValidTextureOverload::kSampleLevelDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005559 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005560 case ValidTextureOverload::kSampleGrad2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005561 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005562 case ValidTextureOverload::kSampleGrad2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005563 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005564 case ValidTextureOverload::kSampleGrad2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005565 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005566 case ValidTextureOverload::kSampleGrad2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005567 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005568 case ValidTextureOverload::kSampleGrad3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005569 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005570 case ValidTextureOverload::kSampleGrad3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005571 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005572 case ValidTextureOverload::kSampleGradCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005573 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005574 case ValidTextureOverload::kSampleGradCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005575 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005576 case ValidTextureOverload::kSampleGradDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005577 return R"(textureSampleCompare(texture, sampler, coords, depth_ref))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005578 case ValidTextureOverload::kSampleGradDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005579 return R"(textureSampleCompare(texture, sampler, coords, depth_ref, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005580 case ValidTextureOverload::kSampleGradDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005581 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005582 case ValidTextureOverload::kSampleGradDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005583 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005584 case ValidTextureOverload::kSampleGradDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005585 return R"(textureSampleCompare(texture, sampler, coords, depth_ref))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005586 case ValidTextureOverload::kSampleGradDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005587 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref))";
5588 case ValidTextureOverload::kLoad1dF32:
5589 return R"(textureLoad(texture, coords))";
5590 case ValidTextureOverload::kLoad1dU32:
5591 return R"(textureLoad(texture, coords))";
5592 case ValidTextureOverload::kLoad1dI32:
5593 return R"(textureLoad(texture, coords))";
5594 case ValidTextureOverload::kLoad1dArrayF32:
5595 return R"(textureLoad(texture, coords, array_index))";
5596 case ValidTextureOverload::kLoad1dArrayU32:
5597 return R"(textureLoad(texture, coords, array_index))";
5598 case ValidTextureOverload::kLoad1dArrayI32:
5599 return R"(textureLoad(texture, coords, array_index))";
5600 case ValidTextureOverload::kLoad2dF32:
5601 return R"(textureLoad(texture, coords))";
5602 case ValidTextureOverload::kLoad2dU32:
5603 return R"(textureLoad(texture, coords))";
5604 case ValidTextureOverload::kLoad2dI32:
5605 return R"(textureLoad(texture, coords))";
5606 case ValidTextureOverload::kLoad2dLevelF32:
5607 return R"(textureLoad(texture, coords, level))";
5608 case ValidTextureOverload::kLoad2dLevelU32:
5609 return R"(textureLoad(texture, coords, level))";
5610 case ValidTextureOverload::kLoad2dLevelI32:
5611 return R"(textureLoad(texture, coords, level))";
5612 case ValidTextureOverload::kLoad2dArrayF32:
5613 return R"(textureLoad(texture, coords, array_index))";
5614 case ValidTextureOverload::kLoad2dArrayU32:
5615 return R"(textureLoad(texture, coords, array_index))";
5616 case ValidTextureOverload::kLoad2dArrayI32:
5617 return R"(textureLoad(texture, coords, array_index))";
5618 case ValidTextureOverload::kLoad2dArrayLevelF32:
5619 return R"(textureLoad(texture, coords, array_index, level))";
5620 case ValidTextureOverload::kLoad2dArrayLevelU32:
5621 return R"(textureLoad(texture, coords, array_index, level))";
5622 case ValidTextureOverload::kLoad2dArrayLevelI32:
5623 return R"(textureLoad(texture, coords, array_index, level))";
5624 case ValidTextureOverload::kLoad3dF32:
5625 return R"(textureLoad(texture, coords))";
5626 case ValidTextureOverload::kLoad3dU32:
5627 return R"(textureLoad(texture, coords))";
5628 case ValidTextureOverload::kLoad3dI32:
5629 return R"(textureLoad(texture, coords))";
5630 case ValidTextureOverload::kLoad3dLevelF32:
5631 return R"(textureLoad(texture, coords, level))";
5632 case ValidTextureOverload::kLoad3dLevelU32:
5633 return R"(textureLoad(texture, coords, level))";
5634 case ValidTextureOverload::kLoad3dLevelI32:
5635 return R"(textureLoad(texture, coords, level))";
5636 case ValidTextureOverload::kLoadMultisampled2dF32:
5637 return R"(textureLoad(texture, coords, sample_index))";
5638 case ValidTextureOverload::kLoadMultisampled2dU32:
5639 return R"(textureLoad(texture, coords, sample_index))";
5640 case ValidTextureOverload::kLoadMultisampled2dI32:
5641 return R"(textureLoad(texture, coords, sample_index))";
5642 case ValidTextureOverload::kLoadMultisampled2dArrayF32:
5643 return R"(textureLoad(texture, coords, array_index, sample_index))";
5644 case ValidTextureOverload::kLoadMultisampled2dArrayU32:
5645 return R"(textureLoad(texture, coords, array_index, sample_index))";
5646 case ValidTextureOverload::kLoadMultisampled2dArrayI32:
5647 return R"(textureLoad(texture, coords, array_index, sample_index))";
5648 case ValidTextureOverload::kLoadDepth2dF32:
5649 return R"(textureLoad(texture, coords))";
5650 case ValidTextureOverload::kLoadDepth2dLevelF32:
5651 return R"(textureLoad(texture, coords, level))";
5652 case ValidTextureOverload::kLoadDepth2dArrayF32:
5653 return R"(textureLoad(texture, coords, array_index))";
5654 case ValidTextureOverload::kLoadDepth2dArrayLevelF32:
5655 return R"(textureLoad(texture, coords, array_index, level))";
5656 case ValidTextureOverload::kLoadStorageRO1dRgba32float:
5657 return R"(textureLoad(texture, coords))";
5658 case ValidTextureOverload::kLoadStorageRO1dArrayRgba32float:
5659 return R"(textureLoad(texture, coords, array_index))";
5660 case ValidTextureOverload::kLoadStorageRO2dRgba8unorm:
5661 case ValidTextureOverload::kLoadStorageRO2dRgba8snorm:
5662 case ValidTextureOverload::kLoadStorageRO2dRgba8uint:
5663 case ValidTextureOverload::kLoadStorageRO2dRgba8sint:
5664 case ValidTextureOverload::kLoadStorageRO2dRgba16uint:
5665 case ValidTextureOverload::kLoadStorageRO2dRgba16sint:
5666 case ValidTextureOverload::kLoadStorageRO2dRgba16float:
5667 case ValidTextureOverload::kLoadStorageRO2dR32uint:
5668 case ValidTextureOverload::kLoadStorageRO2dR32sint:
5669 case ValidTextureOverload::kLoadStorageRO2dR32float:
5670 case ValidTextureOverload::kLoadStorageRO2dRg32uint:
5671 case ValidTextureOverload::kLoadStorageRO2dRg32sint:
5672 case ValidTextureOverload::kLoadStorageRO2dRg32float:
5673 case ValidTextureOverload::kLoadStorageRO2dRgba32uint:
5674 case ValidTextureOverload::kLoadStorageRO2dRgba32sint:
5675 case ValidTextureOverload::kLoadStorageRO2dRgba32float:
5676 return R"(textureLoad(texture, coords))";
5677 case ValidTextureOverload::kLoadStorageRO2dArrayRgba32float:
5678 return R"(textureLoad(texture, coords, array_index))";
5679 case ValidTextureOverload::kLoadStorageRO3dRgba32float:
5680 return R"(textureLoad(texture, coords))";
Ben Clayton591268d2020-12-10 18:39:41 +00005681 case ValidTextureOverload::kStoreWO1dRgba32float:
5682 return R"(textureStore(texture, coords, value))";
5683 case ValidTextureOverload::kStoreWO1dArrayRgba32float:
5684 return R"(textureStore(texture, coords, array_index, value))";
5685 case ValidTextureOverload::kStoreWO2dRgba32float:
5686 return R"(textureStore(texture, coords, value))";
5687 case ValidTextureOverload::kStoreWO2dArrayRgba32float:
5688 return R"(textureStore(texture, coords, array_index, value))";
5689 case ValidTextureOverload::kStoreWO3dRgba32float:
5690 return R"(textureStore(texture, coords, value))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005691 }
5692 return "<unmatched texture overload>";
5693}
5694
5695TEST_P(TypeDeterminerTextureIntrinsicTest, Call) {
5696 auto param = GetParam();
5697
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005698 param.buildTextureVariable(this);
5699 param.buildSamplerVariable(this);
Ben Clayton3ea3c992020-11-18 21:19:22 +00005700
5701 auto* ident = Expr(param.function);
Ben Clayton1ff59cd2020-12-12 01:38:13 +00005702 ast::CallExpression call{Source{}, ident, param.args(this)};
Ben Clayton3ea3c992020-11-18 21:19:22 +00005703
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005704 ASSERT_TRUE(td()->Determine()) << td()->error();
5705 ASSERT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton3ea3c992020-11-18 21:19:22 +00005706
Ben Clayton591268d2020-12-10 18:39:41 +00005707 if (std::string(param.function) == "textureStore") {
5708 EXPECT_EQ(call.result_type(), ty.void_);
5709 } else {
5710 switch (param.texture_kind) {
5711 case ast::intrinsic::test::TextureKind::kRegular:
5712 case ast::intrinsic::test::TextureKind::kMultisampled:
5713 case ast::intrinsic::test::TextureKind::kStorage: {
5714 auto* datatype = param.resultVectorComponentType(this);
5715 ASSERT_TRUE(call.result_type()->Is<ast::type::Vector>());
5716 EXPECT_EQ(call.result_type()->As<ast::type::Vector>()->type(),
5717 datatype);
5718 break;
5719 }
5720 case ast::intrinsic::test::TextureKind::kDepth: {
5721 EXPECT_EQ(call.result_type(), ty.f32);
5722 break;
5723 }
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005724 }
Ben Clayton3ea3c992020-11-18 21:19:22 +00005725 }
5726
5727 auto* sig = static_cast<const ast::intrinsic::TextureSignature*>(
5728 ident->intrinsic_signature());
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005729 ASSERT_NE(sig, nullptr);
Ben Clayton3ea3c992020-11-18 21:19:22 +00005730
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005731 auto got = to_str(param.function, sig);
Ben Clayton3ea3c992020-11-18 21:19:22 +00005732 auto* expected = expected_texture_overload(param.overload);
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005733 EXPECT_EQ(got, expected);
Ben Clayton3ea3c992020-11-18 21:19:22 +00005734}
5735
dan sinclairb7edc4c2020-04-07 12:46:30 +00005736} // namespace
5737} // namespace tint