blob: 2372ef561c957d70cbfc09cea253d0a0ae06fe70 [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 Claytoned2b9782020-12-01 18:04:17 +000076 FakeStmt* Clone(ast::CloneContext*) const override { return nullptr; }
dan sinclair7456f422020-04-08 19:58:35 +000077 bool IsValid() const override { return true; }
dan sinclair0975dd52020-07-27 15:25:00 +000078 void to_str(std::ostream& out, size_t) const override { out << "Fake"; }
dan sinclair7456f422020-04-08 19:58:35 +000079};
80
81class FakeExpr : public ast::Expression {
82 public:
Ben Claytoned2b9782020-12-01 18:04:17 +000083 FakeExpr* Clone(ast::CloneContext*) const override { return nullptr; }
dan sinclair7456f422020-04-08 19:58:35 +000084 bool IsValid() const override { return true; }
85 void to_str(std::ostream&, size_t) const override {}
86};
87
dan sinclair685cb022020-12-02 21:17:58 +000088class TypeDeterminerHelper : public ast::BuilderWithModule {
dan sinclairb7edc4c2020-04-07 12:46:30 +000089 public:
dan sinclair685cb022020-12-02 21:17:58 +000090 TypeDeterminerHelper() : td_(std::make_unique<TypeDeterminer>(mod)) {}
dan sinclairb7edc4c2020-04-07 12:46:30 +000091
92 TypeDeterminer* td() const { return td_.get(); }
Ben Clayton62625922020-11-13 22:09:38 +000093
dan sinclairb7edc4c2020-04-07 12:46:30 +000094 private:
Ben Clayton3ea3c992020-11-18 21:19:22 +000095 void OnVariableBuilt(ast::Variable* var) override {
96 td_->RegisterVariableForTesting(var);
97 }
98
dan sinclairb7edc4c2020-04-07 12:46:30 +000099 std::unique_ptr<TypeDeterminer> td_;
100};
101
dan sinclaircd077b02020-04-20 14:19:04 +0000102class TypeDeterminerTest : public TypeDeterminerHelper, public testing::Test {};
103
104template <typename T>
105class TypeDeterminerTestWithParam : public TypeDeterminerHelper,
106 public testing::TestWithParam<T> {};
107
dan sinclair7456f422020-04-08 19:58:35 +0000108TEST_F(TypeDeterminerTest, Error_WithEmptySource) {
109 FakeStmt s;
Ben Claytonfc5a9cf2020-11-02 15:07:47 +0000110 s.set_source(Source{});
dan sinclair7456f422020-04-08 19:58:35 +0000111
112 EXPECT_FALSE(td()->DetermineResultType(&s));
dan sinclair0975dd52020-07-27 15:25:00 +0000113 EXPECT_EQ(td()->error(),
114 "unknown statement type for type determination: Fake");
dan sinclair7456f422020-04-08 19:58:35 +0000115}
116
117TEST_F(TypeDeterminerTest, Stmt_Error_Unknown) {
118 FakeStmt s;
Ben Claytonfc5a9cf2020-11-02 15:07:47 +0000119 s.set_source(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 Clayton62625922020-11-13 22:09:38 +0000131 create<ast::SintLiteral>(&i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000132 auto* rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000133 create<ast::FloatLiteral>(&f32, 2.3f));
dan sinclair6c498fc2020-04-07 12:47:23 +0000134
Ben Clayton4bfe4612020-11-16 16:41:47 +0000135 ast::AssignmentStatement assign(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 Clayton62625922020-11-13 22:09:38 +0000150 create<ast::SintLiteral>(&i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000151 auto* rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000152 create<ast::FloatLiteral>(&f32, 2.3f));
dan sinclair6010b292020-04-07 12:54:20 +0000153
Ben Claytonb053acf2020-11-16 16:31:07 +0000154 auto* body = create<ast::BlockStatement>();
Ben Clayton4bfe4612020-11-16 16:41:47 +0000155 body->append(create<ast::AssignmentStatement>(lhs, rhs));
dan sinclair6010b292020-04-07 12:54:20 +0000156
dan sinclair1aadbd42020-06-01 16:56:46 +0000157 ast::CaseSelectorList lit;
Ben Clayton62625922020-11-13 22:09:38 +0000158 lit.push_back(create<ast::SintLiteral>(&i32, 3));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000159 ast::CaseStatement cse(lit, body);
dan sinclair6010b292020-04-07 12:54:20 +0000160
161 EXPECT_TRUE(td()->DetermineResultType(&cse));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000162 ASSERT_NE(lhs->result_type(), nullptr);
163 ASSERT_NE(rhs->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000164 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
165 EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32>());
dan sinclair6010b292020-04-07 12:54:20 +0000166}
167
dan sinclair0975dd52020-07-27 15:25:00 +0000168TEST_F(TypeDeterminerTest, Stmt_Block) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000169 ast::type::I32 i32;
170 ast::type::F32 f32;
dan sinclair0975dd52020-07-27 15:25:00 +0000171
Ben Claytonb053acf2020-11-16 16:31:07 +0000172 auto* lhs = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000173 create<ast::SintLiteral>(&i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000174 auto* rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000175 create<ast::FloatLiteral>(&f32, 2.3f));
dan sinclair0975dd52020-07-27 15:25:00 +0000176
177 ast::BlockStatement block;
Ben Clayton4bfe4612020-11-16 16:41:47 +0000178 block.append(create<ast::AssignmentStatement>(lhs, rhs));
dan sinclair0975dd52020-07-27 15:25:00 +0000179
180 EXPECT_TRUE(td()->DetermineResultType(&block));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000181 ASSERT_NE(lhs->result_type(), nullptr);
182 ASSERT_NE(rhs->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000183 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
184 EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32>());
dan sinclair0975dd52020-07-27 15:25:00 +0000185}
186
dan sinclair0cf685f2020-04-07 12:54:37 +0000187TEST_F(TypeDeterminerTest, Stmt_Else) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000188 ast::type::I32 i32;
189 ast::type::F32 f32;
dan sinclair0cf685f2020-04-07 12:54:37 +0000190
Ben Claytonb053acf2020-11-16 16:31:07 +0000191 auto* lhs = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000192 create<ast::SintLiteral>(&i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000193 auto* rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000194 create<ast::FloatLiteral>(&f32, 2.3f));
dan sinclair0cf685f2020-04-07 12:54:37 +0000195
Ben Claytonb053acf2020-11-16 16:31:07 +0000196 auto* body = create<ast::BlockStatement>();
Ben Clayton4bfe4612020-11-16 16:41:47 +0000197 body->append(create<ast::AssignmentStatement>(lhs, rhs));
dan sinclair0cf685f2020-04-07 12:54:37 +0000198
Ben Clayton62625922020-11-13 22:09:38 +0000199 ast::ElseStatement stmt(create<ast::ScalarConstructorExpression>(
200 create<ast::SintLiteral>(&i32, 3)),
Ben Clayton4bfe4612020-11-16 16:41:47 +0000201 body);
dan sinclair0cf685f2020-04-07 12:54:37 +0000202
203 EXPECT_TRUE(td()->DetermineResultType(&stmt));
204 ASSERT_NE(stmt.condition()->result_type(), nullptr);
Ben Clayton4bfe4612020-11-16 16:41:47 +0000205 ASSERT_NE(lhs->result_type(), nullptr);
206 ASSERT_NE(rhs->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000207 EXPECT_TRUE(stmt.condition()->result_type()->Is<ast::type::I32>());
208 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
209 EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32>());
dan sinclair0cf685f2020-04-07 12:54:37 +0000210}
211
dan sinclair91c44a52020-04-07 12:55:25 +0000212TEST_F(TypeDeterminerTest, Stmt_If) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000213 ast::type::I32 i32;
214 ast::type::F32 f32;
dan sinclair91c44a52020-04-07 12:55:25 +0000215
Ben Claytonb053acf2020-11-16 16:31:07 +0000216 auto* else_lhs = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000217 create<ast::SintLiteral>(&i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000218 auto* else_rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000219 create<ast::FloatLiteral>(&f32, 2.3f));
dan sinclair91c44a52020-04-07 12:55:25 +0000220
Ben Claytonb053acf2020-11-16 16:31:07 +0000221 auto* else_body = create<ast::BlockStatement>();
Ben Clayton4bfe4612020-11-16 16:41:47 +0000222 else_body->append(create<ast::AssignmentStatement>(else_lhs, else_rhs));
dan sinclair91c44a52020-04-07 12:55:25 +0000223
Ben Claytonb053acf2020-11-16 16:31:07 +0000224 auto* else_stmt =
Ben Clayton62625922020-11-13 22:09:38 +0000225 create<ast::ElseStatement>(create<ast::ScalarConstructorExpression>(
226 create<ast::SintLiteral>(&i32, 3)),
Ben Clayton4bfe4612020-11-16 16:41:47 +0000227 else_body);
dan sinclair91c44a52020-04-07 12:55:25 +0000228
Ben Claytonb053acf2020-11-16 16:31:07 +0000229 auto* lhs = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000230 create<ast::SintLiteral>(&i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000231 auto* rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000232 create<ast::FloatLiteral>(&f32, 2.3f));
dan sinclair91c44a52020-04-07 12:55:25 +0000233
Ben Claytonb053acf2020-11-16 16:31:07 +0000234 auto* body = create<ast::BlockStatement>();
Ben Clayton4bfe4612020-11-16 16:41:47 +0000235 body->append(create<ast::AssignmentStatement>(lhs, rhs));
dan sinclair91c44a52020-04-07 12:55:25 +0000236
Ben Clayton98387682020-12-07 20:11:24 +0000237 ast::IfStatement stmt(Source{},
238 create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000239 create<ast::SintLiteral>(&i32, 3)),
Ben Clayton98387682020-12-07 20:11:24 +0000240 body, ast::ElseStatementList{else_stmt});
dan sinclair91c44a52020-04-07 12:55:25 +0000241
242 EXPECT_TRUE(td()->DetermineResultType(&stmt));
243 ASSERT_NE(stmt.condition()->result_type(), nullptr);
Ben Clayton4bfe4612020-11-16 16:41:47 +0000244 ASSERT_NE(else_lhs->result_type(), nullptr);
245 ASSERT_NE(else_rhs->result_type(), nullptr);
246 ASSERT_NE(lhs->result_type(), nullptr);
247 ASSERT_NE(rhs->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000248 EXPECT_TRUE(stmt.condition()->result_type()->Is<ast::type::I32>());
249 EXPECT_TRUE(else_lhs->result_type()->Is<ast::type::I32>());
250 EXPECT_TRUE(else_rhs->result_type()->Is<ast::type::F32>());
251 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
252 EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32>());
dan sinclair91c44a52020-04-07 12:55:25 +0000253}
254
dan sinclairbc71eda2020-04-07 12:55:51 +0000255TEST_F(TypeDeterminerTest, Stmt_Loop) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000256 ast::type::I32 i32;
257 ast::type::F32 f32;
dan sinclairbc71eda2020-04-07 12:55:51 +0000258
Ben Claytonb053acf2020-11-16 16:31:07 +0000259 auto* body_lhs = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000260 create<ast::SintLiteral>(&i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000261 auto* body_rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000262 create<ast::FloatLiteral>(&f32, 2.3f));
dan sinclairbc71eda2020-04-07 12:55:51 +0000263
Ben Claytonb053acf2020-11-16 16:31:07 +0000264 auto* body = create<ast::BlockStatement>();
Ben Clayton4bfe4612020-11-16 16:41:47 +0000265 body->append(create<ast::AssignmentStatement>(body_lhs, body_rhs));
dan sinclairbc71eda2020-04-07 12:55:51 +0000266
Ben Claytonb053acf2020-11-16 16:31:07 +0000267 auto* continuing_lhs = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000268 create<ast::SintLiteral>(&i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000269 auto* continuing_rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000270 create<ast::FloatLiteral>(&f32, 2.3f));
dan sinclairbc71eda2020-04-07 12:55:51 +0000271
Ben Claytonb053acf2020-11-16 16:31:07 +0000272 auto* continuing = create<ast::BlockStatement>();
Ben Clayton4bfe4612020-11-16 16:41:47 +0000273 continuing->append(
274 create<ast::AssignmentStatement>(continuing_lhs, continuing_rhs));
dan sinclairbc71eda2020-04-07 12:55:51 +0000275
Ben Clayton4bfe4612020-11-16 16:41:47 +0000276 ast::LoopStatement stmt(body, continuing);
dan sinclairbc71eda2020-04-07 12:55:51 +0000277
278 EXPECT_TRUE(td()->DetermineResultType(&stmt));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000279 ASSERT_NE(body_lhs->result_type(), nullptr);
280 ASSERT_NE(body_rhs->result_type(), nullptr);
281 ASSERT_NE(continuing_lhs->result_type(), nullptr);
282 ASSERT_NE(continuing_rhs->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000283 EXPECT_TRUE(body_lhs->result_type()->Is<ast::type::I32>());
284 EXPECT_TRUE(body_rhs->result_type()->Is<ast::type::F32>());
285 EXPECT_TRUE(continuing_lhs->result_type()->Is<ast::type::I32>());
286 EXPECT_TRUE(continuing_rhs->result_type()->Is<ast::type::F32>());
dan sinclairbc71eda2020-04-07 12:55:51 +0000287}
288
dan sinclairbf0fff82020-04-07 12:56:24 +0000289TEST_F(TypeDeterminerTest, Stmt_Return) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000290 ast::type::I32 i32;
dan sinclairbf0fff82020-04-07 12:56:24 +0000291
Ben Claytonb053acf2020-11-16 16:31:07 +0000292 auto* cond = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000293 create<ast::SintLiteral>(&i32, 2));
dan sinclairbf0fff82020-04-07 12:56:24 +0000294
Ben Claytond0dda252020-12-07 21:09:57 +0000295 ast::ReturnStatement ret(Source{}, cond);
dan sinclairbf0fff82020-04-07 12:56:24 +0000296
297 EXPECT_TRUE(td()->DetermineResultType(&ret));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000298 ASSERT_NE(cond->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000299 EXPECT_TRUE(cond->result_type()->Is<ast::type::I32>());
dan sinclairbf0fff82020-04-07 12:56:24 +0000300}
301
dan sinclair327ed1b2020-04-07 19:27:21 +0000302TEST_F(TypeDeterminerTest, Stmt_Return_WithoutValue) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000303 ast::type::I32 i32;
Ben Claytond0dda252020-12-07 21:09:57 +0000304 ast::ReturnStatement ret(Source{});
dan sinclair327ed1b2020-04-07 19:27:21 +0000305 EXPECT_TRUE(td()->DetermineResultType(&ret));
306}
307
dan sinclair18b32852020-04-07 12:56:45 +0000308TEST_F(TypeDeterminerTest, Stmt_Switch) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000309 ast::type::I32 i32;
310 ast::type::F32 f32;
dan sinclair18b32852020-04-07 12:56:45 +0000311
Ben Claytonb053acf2020-11-16 16:31:07 +0000312 auto* lhs = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000313 create<ast::SintLiteral>(&i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000314 auto* rhs = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000315 create<ast::FloatLiteral>(&f32, 2.3f));
dan sinclair18b32852020-04-07 12:56:45 +0000316
Ben Claytonb053acf2020-11-16 16:31:07 +0000317 auto* body = create<ast::BlockStatement>();
Ben Clayton4bfe4612020-11-16 16:41:47 +0000318 body->append(create<ast::AssignmentStatement>(lhs, rhs));
dan sinclair18b32852020-04-07 12:56:45 +0000319
dan sinclair1aadbd42020-06-01 16:56:46 +0000320 ast::CaseSelectorList lit;
Ben Clayton62625922020-11-13 22:09:38 +0000321 lit.push_back(create<ast::SintLiteral>(&i32, 3));
dan sinclair1aadbd42020-06-01 16:56:46 +0000322
dan sinclair18b32852020-04-07 12:56:45 +0000323 ast::CaseStatementList cases;
Ben Clayton4bfe4612020-11-16 16:41:47 +0000324 cases.push_back(create<ast::CaseStatement>(lit, body));
dan sinclair18b32852020-04-07 12:56:45 +0000325
Ben Clayton62625922020-11-13 22:09:38 +0000326 ast::SwitchStatement stmt(create<ast::ScalarConstructorExpression>(
327 create<ast::SintLiteral>(&i32, 2)),
Ben Clayton4bfe4612020-11-16 16:41:47 +0000328 cases);
dan sinclair18b32852020-04-07 12:56:45 +0000329
330 EXPECT_TRUE(td()->DetermineResultType(&stmt)) << td()->error();
331 ASSERT_NE(stmt.condition()->result_type(), nullptr);
Ben Clayton4bfe4612020-11-16 16:41:47 +0000332 ASSERT_NE(lhs->result_type(), nullptr);
333 ASSERT_NE(rhs->result_type(), nullptr);
dan sinclair18b32852020-04-07 12:56:45 +0000334
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000335 EXPECT_TRUE(stmt.condition()->result_type()->Is<ast::type::I32>());
336 EXPECT_TRUE(lhs->result_type()->Is<ast::type::I32>());
337 EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32>());
dan sinclair18b32852020-04-07 12:56:45 +0000338}
339
dan sinclair50080b72020-07-21 13:42:13 +0000340TEST_F(TypeDeterminerTest, Stmt_Call) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000341 ast::type::F32 f32;
dan sinclair50080b72020-07-21 13:42:13 +0000342
343 ast::VariableList params;
dan sinclaira41132f2020-12-11 18:24:53 +0000344 auto* func = create<ast::Function>(
345 Source{}, mod->RegisterSymbol("my_func"), "my_func", params, &f32,
346 create<ast::BlockStatement>(), ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000347 mod->AddFunction(func);
dan sinclair50080b72020-07-21 13:42:13 +0000348
349 // Register the function
350 EXPECT_TRUE(td()->Determine());
351
352 ast::ExpressionList call_params;
Ben Claytonb053acf2020-11-16 16:31:07 +0000353 auto* expr = create<ast::CallExpression>(
dan sinclair6b59bf42020-12-11 19:16:13 +0000354 create<ast::IdentifierExpression>(mod->RegisterSymbol("my_func"),
355 "my_func"),
356 call_params);
dan sinclair50080b72020-07-21 13:42:13 +0000357
Ben Clayton4bfe4612020-11-16 16:41:47 +0000358 ast::CallStatement call(expr);
dan sinclair50080b72020-07-21 13:42:13 +0000359 EXPECT_TRUE(td()->DetermineResultType(&call));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000360 ASSERT_NE(expr->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000361 EXPECT_TRUE(expr->result_type()->Is<ast::type::F32>());
dan sinclair50080b72020-07-21 13:42:13 +0000362}
363
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000364TEST_F(TypeDeterminerTest, Stmt_Call_undeclared) {
365 // fn main() -> void {func(); return; }
366 // fn func() -> void { return; }
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000367 ast::type::F32 f32;
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000368 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +0000369 auto* call_expr = create<ast::CallExpression>(
370 create<ast::IdentifierExpression>(Source{Source::Location{12, 34}},
371 mod->RegisterSymbol("func"), "func"),
372 call_params);
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000373 ast::VariableList params0;
Ben Claytonb053acf2020-11-16 16:31:07 +0000374 auto* main_body = create<ast::BlockStatement>();
Ben Clayton4bfe4612020-11-16 16:41:47 +0000375 main_body->append(create<ast::CallStatement>(call_expr));
Ben Claytond0dda252020-12-07 21:09:57 +0000376 main_body->append(create<ast::ReturnStatement>(Source{}));
dan sinclaira41132f2020-12-11 18:24:53 +0000377 auto* func_main = create<ast::Function>(Source{}, mod->RegisterSymbol("main"),
378 "main", params0, &f32, main_body,
379 ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000380 mod->AddFunction(func_main);
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000381
Ben Claytonb053acf2020-11-16 16:31:07 +0000382 auto* body = create<ast::BlockStatement>();
Ben Claytond0dda252020-12-07 21:09:57 +0000383 body->append(create<ast::ReturnStatement>(Source{}));
dan sinclaira41132f2020-12-11 18:24:53 +0000384 auto* func =
385 create<ast::Function>(Source{}, mod->RegisterSymbol("func"), "func",
386 params0, &f32, body, ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000387 mod->AddFunction(func);
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000388
389 EXPECT_FALSE(td()->Determine()) << td()->error();
390 EXPECT_EQ(td()->error(),
dan sinclairff267ca2020-10-14 18:26:31 +0000391 "12:34: v-0006: identifier must be declared before use: func");
Sarah Mashayekhi844f6322020-08-18 02:10:03 +0000392}
393
dan sinclairca893e32020-04-07 12:57:12 +0000394TEST_F(TypeDeterminerTest, Stmt_VariableDecl) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000395 ast::type::I32 i32;
Ben Claytona80511e2020-12-11 13:07:02 +0000396 auto* var = create<ast::Variable>(
397 Source{}, // source
398 "my_var", // name
399 ast::StorageClass::kNone, // storage_class
400 &i32, // type
401 false, // is_const
402 create<ast::ScalarConstructorExpression>(
403 create<ast::SintLiteral>(&i32, 2)), // constructor
404 ast::VariableDecorationList{}); // decorations
Ben Clayton4bfe4612020-11-16 16:41:47 +0000405 auto* init = var->constructor();
dan sinclairca893e32020-04-07 12:57:12 +0000406
Ben Clayton4bfe4612020-11-16 16:41:47 +0000407 ast::VariableDeclStatement decl(var);
dan sinclairca893e32020-04-07 12:57:12 +0000408
409 EXPECT_TRUE(td()->DetermineResultType(&decl));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000410 ASSERT_NE(init->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000411 EXPECT_TRUE(init->result_type()->Is<ast::type::I32>());
dan sinclairca893e32020-04-07 12:57:12 +0000412}
413
dan sinclair7be237a2020-06-15 20:55:09 +0000414TEST_F(TypeDeterminerTest, Stmt_VariableDecl_ModuleScope) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000415 ast::type::I32 i32;
Ben Claytona80511e2020-12-11 13:07:02 +0000416 auto* var = create<ast::Variable>(
417 Source{}, // source
418 "my_var", // name
419 ast::StorageClass::kNone, // storage_class
420 &i32, // type
421 false, // is_const
422 create<ast::ScalarConstructorExpression>(
423 create<ast::SintLiteral>(&i32, 2)), // constructor
424 ast::VariableDecorationList{}); // decorations
Ben Clayton4bfe4612020-11-16 16:41:47 +0000425 auto* init = var->constructor();
dan sinclair7be237a2020-06-15 20:55:09 +0000426
Ben Clayton3ea3c992020-11-18 21:19:22 +0000427 mod->AddGlobalVariable(var);
dan sinclair7be237a2020-06-15 20:55:09 +0000428
429 EXPECT_TRUE(td()->Determine());
Ben Clayton4bfe4612020-11-16 16:41:47 +0000430 ASSERT_NE(init->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000431 EXPECT_TRUE(init->result_type()->Is<ast::type::I32>());
dan sinclair7be237a2020-06-15 20:55:09 +0000432}
433
dan sinclair7456f422020-04-08 19:58:35 +0000434TEST_F(TypeDeterminerTest, Expr_Error_Unknown) {
435 FakeExpr e;
Ben Claytonfc5a9cf2020-11-02 15:07:47 +0000436 e.set_source(Source{Source::Location{2, 30}});
dan sinclair7456f422020-04-08 19:58:35 +0000437
438 EXPECT_FALSE(td()->DetermineResultType(&e));
439 EXPECT_EQ(td()->error(), "2:30: unknown expression for type determination");
440}
441
dan sinclair973bd6a2020-04-07 12:57:42 +0000442TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000443 ast::type::I32 i32;
444 ast::type::F32 f32;
Ben Clayton8b0ffe92020-12-07 22:19:27 +0000445 ast::type::Array ary(&f32, 3, ast::ArrayDecorationList{});
dan sinclair973bd6a2020-04-07 12:57:42 +0000446
Ben Claytonb053acf2020-11-16 16:31:07 +0000447 auto* idx = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000448 create<ast::SintLiteral>(&i32, 2));
Ben Claytona80511e2020-12-11 13:07:02 +0000449 auto* var =
450 create<ast::Variable>(Source{}, // source
451 "my_var", // name
452 ast::StorageClass::kFunction, // storage_class
453 &ary, // type
454 false, // is_const
455 nullptr, // constructor
456 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +0000457 mod->AddGlobalVariable(var);
dan sinclair8eddb782020-04-23 22:26:52 +0000458
459 // Register the global
460 EXPECT_TRUE(td()->Determine());
461
dan sinclair6b59bf42020-12-11 19:16:13 +0000462 ast::ArrayAccessorExpression acc(create<ast::IdentifierExpression>(
463 mod->RegisterSymbol("my_var"), "my_var"),
Ben Clayton4bfe4612020-11-16 16:41:47 +0000464 idx);
dan sinclair8eddb782020-04-23 22:26:52 +0000465 EXPECT_TRUE(td()->DetermineResultType(&acc));
466 ASSERT_NE(acc.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000467 ASSERT_TRUE(acc.result_type()->Is<ast::type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000468
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000469 auto* ptr = acc.result_type()->As<ast::type::Pointer>();
470 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000471}
472
David Neto9c88ea52020-06-22 20:33:12 +0000473TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Alias_Array) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000474 ast::type::I32 i32;
475 ast::type::F32 f32;
Ben Clayton8b0ffe92020-12-07 22:19:27 +0000476 ast::type::Array ary(&f32, 3, ast::ArrayDecorationList{});
dan sinclair4226b6a2020-12-11 19:35:03 +0000477 ast::type::Alias aary(mod->RegisterSymbol("myarrty"), "myarrty", &ary);
David Neto9c88ea52020-06-22 20:33:12 +0000478
Ben Claytonb053acf2020-11-16 16:31:07 +0000479 auto* idx = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000480 create<ast::SintLiteral>(&i32, 2));
Ben Claytona80511e2020-12-11 13:07:02 +0000481 auto* var =
482 create<ast::Variable>(Source{}, // source
483 "my_var", // name
484 ast::StorageClass::kFunction, // storage_class
485 &aary, // type
486 false, // is_const
487 nullptr, // constructor
488 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +0000489 mod->AddGlobalVariable(var);
David Neto9c88ea52020-06-22 20:33:12 +0000490
491 // Register the global
492 EXPECT_TRUE(td()->Determine());
493
dan sinclair6b59bf42020-12-11 19:16:13 +0000494 ast::ArrayAccessorExpression acc(create<ast::IdentifierExpression>(
495 mod->RegisterSymbol("my_var"), "my_var"),
Ben Clayton4bfe4612020-11-16 16:41:47 +0000496 idx);
David Neto9c88ea52020-06-22 20:33:12 +0000497 EXPECT_TRUE(td()->DetermineResultType(&acc));
498 ASSERT_NE(acc.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000499 ASSERT_TRUE(acc.result_type()->Is<ast::type::Pointer>());
David Neto9c88ea52020-06-22 20:33:12 +0000500
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000501 auto* ptr = acc.result_type()->As<ast::type::Pointer>();
502 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
David Neto9c88ea52020-06-22 20:33:12 +0000503}
504
dan sinclair8eddb782020-04-23 22:26:52 +0000505TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array_Constant) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000506 ast::type::I32 i32;
507 ast::type::F32 f32;
Ben Clayton8b0ffe92020-12-07 22:19:27 +0000508 ast::type::Array ary(&f32, 3, ast::ArrayDecorationList{});
dan sinclair8eddb782020-04-23 22:26:52 +0000509
Ben Claytonb053acf2020-11-16 16:31:07 +0000510 auto* idx = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000511 create<ast::SintLiteral>(&i32, 2));
Ben Claytona80511e2020-12-11 13:07:02 +0000512 auto* var =
513 create<ast::Variable>(Source{}, // source
514 "my_var", // name
515 ast::StorageClass::kFunction, // storage_class
516 &ary, // type
517 true, // is_const
518 nullptr, // constructor
519 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +0000520 mod->AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000521
522 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000523 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000524
dan sinclair6b59bf42020-12-11 19:16:13 +0000525 ast::ArrayAccessorExpression acc(create<ast::IdentifierExpression>(
526 mod->RegisterSymbol("my_var"), "my_var"),
Ben Clayton4bfe4612020-11-16 16:41:47 +0000527 idx);
dan sinclair973bd6a2020-04-07 12:57:42 +0000528 EXPECT_TRUE(td()->DetermineResultType(&acc));
529 ASSERT_NE(acc.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000530 EXPECT_TRUE(acc.result_type()->Is<ast::type::F32>())
Ben Clayton75f39be2020-11-30 23:30:58 +0000531 << acc.result_type()->type_name();
dan sinclair973bd6a2020-04-07 12:57:42 +0000532}
533
534TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000535 ast::type::I32 i32;
536 ast::type::F32 f32;
537 ast::type::Matrix mat(&f32, 3, 2);
dan sinclair973bd6a2020-04-07 12:57:42 +0000538
Ben Claytonb053acf2020-11-16 16:31:07 +0000539 auto* idx = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000540 create<ast::SintLiteral>(&i32, 2));
Ben Clayton321e5a92020-12-07 21:08:07 +0000541 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +0000542 create<ast::Variable>(Source{}, // source
543 "my_var", // name
544 ast::StorageClass::kNone, // storage_class
545 &mat, // type
546 false, // is_const
547 nullptr, // constructor
548 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +0000549 mod->AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000550
551 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000552 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000553
dan sinclair6b59bf42020-12-11 19:16:13 +0000554 ast::ArrayAccessorExpression acc(create<ast::IdentifierExpression>(
555 mod->RegisterSymbol("my_var"), "my_var"),
Ben Clayton4bfe4612020-11-16 16:41:47 +0000556 idx);
dan sinclair973bd6a2020-04-07 12:57:42 +0000557 EXPECT_TRUE(td()->DetermineResultType(&acc));
558 ASSERT_NE(acc.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000559 ASSERT_TRUE(acc.result_type()->Is<ast::type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000560
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000561 auto* ptr = acc.result_type()->As<ast::type::Pointer>();
562 ASSERT_TRUE(ptr->type()->Is<ast::type::Vector>());
563 EXPECT_EQ(ptr->type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair973bd6a2020-04-07 12:57:42 +0000564}
565
566TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix_BothDimensions) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000567 ast::type::I32 i32;
568 ast::type::F32 f32;
569 ast::type::Matrix mat(&f32, 3, 2);
dan sinclair973bd6a2020-04-07 12:57:42 +0000570
Ben Claytonb053acf2020-11-16 16:31:07 +0000571 auto* idx1 = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000572 create<ast::SintLiteral>(&i32, 2));
Ben Claytonb053acf2020-11-16 16:31:07 +0000573 auto* idx2 = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000574 create<ast::SintLiteral>(&i32, 1));
Ben Clayton321e5a92020-12-07 21:08:07 +0000575 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +0000576 create<ast::Variable>(Source{}, // source
577 "my_var", // name
578 ast::StorageClass::kNone, // storage_class
579 &mat, // type
580 false, // is_const
581 nullptr, // constructor
582 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +0000583 mod->AddGlobalVariable(var);
dan sinclair973bd6a2020-04-07 12:57:42 +0000584
585 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000586 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000587
588 ast::ArrayAccessorExpression acc(
Ben Clayton62625922020-11-13 22:09:38 +0000589 create<ast::ArrayAccessorExpression>(
dan sinclair6b59bf42020-12-11 19:16:13 +0000590 create<ast::IdentifierExpression>(mod->RegisterSymbol("my_var"),
591 "my_var"),
592 idx1),
Ben Clayton4bfe4612020-11-16 16:41:47 +0000593 idx2);
dan sinclair973bd6a2020-04-07 12:57:42 +0000594
595 EXPECT_TRUE(td()->DetermineResultType(&acc));
596 ASSERT_NE(acc.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000597 ASSERT_TRUE(acc.result_type()->Is<ast::type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000598
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000599 auto* ptr = acc.result_type()->As<ast::type::Pointer>();
600 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000601}
602
603TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Vector) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000604 ast::type::I32 i32;
605 ast::type::F32 f32;
606 ast::type::Vector vec(&f32, 3);
dan sinclair973bd6a2020-04-07 12:57:42 +0000607
Ben Claytonb053acf2020-11-16 16:31:07 +0000608 auto* idx = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +0000609 create<ast::SintLiteral>(&i32, 2));
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 &vec, // 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
dan sinclair6b59bf42020-12-11 19:16:13 +0000623 ast::ArrayAccessorExpression acc(create<ast::IdentifierExpression>(
624 mod->RegisterSymbol("my_var"), "my_var"),
Ben Clayton4bfe4612020-11-16 16:41:47 +0000625 idx);
dan sinclair973bd6a2020-04-07 12:57:42 +0000626 EXPECT_TRUE(td()->DetermineResultType(&acc));
627 ASSERT_NE(acc.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000628 ASSERT_TRUE(acc.result_type()->Is<ast::type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +0000629
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000630 auto* ptr = acc.result_type()->As<ast::type::Pointer>();
631 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclair973bd6a2020-04-07 12:57:42 +0000632}
633
dan sinclaira7d498e2020-09-22 22:07:13 +0000634TEST_F(TypeDeterminerTest, Expr_Bitcast) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000635 ast::type::F32 f32;
dan sinclair6b59bf42020-12-11 19:16:13 +0000636 ast::BitcastExpression bitcast(
637 &f32,
638 create<ast::IdentifierExpression>(mod->RegisterSymbol("name"), "name"));
dan sinclaira01777c2020-04-07 12:57:52 +0000639
Ben Claytona80511e2020-12-11 13:07:02 +0000640 ast::Variable v(Source{}, "name", ast::StorageClass::kPrivate, &f32, false,
641 nullptr, ast::VariableDecorationList{});
dan sinclairff267ca2020-10-14 18:26:31 +0000642 td()->RegisterVariableForTesting(&v);
643
dan sinclaira7d498e2020-09-22 22:07:13 +0000644 EXPECT_TRUE(td()->DetermineResultType(&bitcast));
645 ASSERT_NE(bitcast.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000646 EXPECT_TRUE(bitcast.result_type()->Is<ast::type::F32>());
dan sinclaira01777c2020-04-07 12:57:52 +0000647}
648
dan sinclair3ca87462020-04-07 16:41:10 +0000649TEST_F(TypeDeterminerTest, Expr_Call) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000650 ast::type::F32 f32;
dan sinclair3ca87462020-04-07 16:41:10 +0000651
652 ast::VariableList params;
dan sinclaira41132f2020-12-11 18:24:53 +0000653 auto* func = create<ast::Function>(
654 Source{}, mod->RegisterSymbol("my_func"), "my_func", params, &f32,
655 create<ast::BlockStatement>(), ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000656 mod->AddFunction(func);
dan sinclair3ca87462020-04-07 16:41:10 +0000657
658 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000659 EXPECT_TRUE(td()->Determine());
dan sinclair3ca87462020-04-07 16:41:10 +0000660
661 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +0000662 ast::CallExpression call(create<ast::IdentifierExpression>(
663 mod->RegisterSymbol("my_func"), "my_func"),
Ben Clayton4bfe4612020-11-16 16:41:47 +0000664 call_params);
dan sinclair3ca87462020-04-07 16:41:10 +0000665 EXPECT_TRUE(td()->DetermineResultType(&call));
666 ASSERT_NE(call.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000667 EXPECT_TRUE(call.result_type()->Is<ast::type::F32>());
dan sinclair3ca87462020-04-07 16:41:10 +0000668}
669
dan sinclairccb52dc2020-04-20 14:18:54 +0000670TEST_F(TypeDeterminerTest, Expr_Call_WithParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000671 ast::type::F32 f32;
dan sinclairccb52dc2020-04-20 14:18:54 +0000672
673 ast::VariableList params;
dan sinclaira41132f2020-12-11 18:24:53 +0000674 auto* func = create<ast::Function>(
675 Source{}, mod->RegisterSymbol("my_func"), "my_func", params, &f32,
676 create<ast::BlockStatement>(), ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000677 mod->AddFunction(func);
dan sinclairccb52dc2020-04-20 14:18:54 +0000678
679 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000680 EXPECT_TRUE(td()->Determine());
dan sinclairccb52dc2020-04-20 14:18:54 +0000681
682 ast::ExpressionList call_params;
Ben Clayton62625922020-11-13 22:09:38 +0000683 call_params.push_back(create<ast::ScalarConstructorExpression>(
684 create<ast::FloatLiteral>(&f32, 2.4)));
dan sinclairccb52dc2020-04-20 14:18:54 +0000685
Ben Clayton4bfe4612020-11-16 16:41:47 +0000686 auto* param = call_params.back();
dan sinclairccb52dc2020-04-20 14:18:54 +0000687
dan sinclair6b59bf42020-12-11 19:16:13 +0000688 ast::CallExpression call(create<ast::IdentifierExpression>(
689 mod->RegisterSymbol("my_func"), "my_func"),
Ben Clayton4bfe4612020-11-16 16:41:47 +0000690 call_params);
dan sinclairccb52dc2020-04-20 14:18:54 +0000691 EXPECT_TRUE(td()->DetermineResultType(&call));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000692 ASSERT_NE(param->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000693 EXPECT_TRUE(param->result_type()->Is<ast::type::F32>());
dan sinclairccb52dc2020-04-20 14:18:54 +0000694}
695
dan sinclairb4fee2f2020-09-22 19:42:13 +0000696TEST_F(TypeDeterminerTest, Expr_Call_Intrinsic) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000697 ast::type::F32 f32;
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000698
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000699 // Register the function
700 EXPECT_TRUE(td()->Determine());
701
702 ast::ExpressionList call_params;
Ben Clayton62625922020-11-13 22:09:38 +0000703 call_params.push_back(create<ast::ScalarConstructorExpression>(
704 create<ast::FloatLiteral>(&f32, 2.4)));
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000705
dan sinclair6b59bf42020-12-11 19:16:13 +0000706 ast::CallExpression call(
707 create<ast::IdentifierExpression>(mod->RegisterSymbol("round"), "round"),
708 call_params);
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000709
710 EXPECT_TRUE(td()->DetermineResultType(&call));
711 ASSERT_NE(call.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000712 EXPECT_TRUE(call.result_type()->Is<ast::type::F32>());
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000713}
714
dan sinclair4e807952020-04-07 16:41:23 +0000715TEST_F(TypeDeterminerTest, Expr_Cast) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000716 ast::type::F32 f32;
dan sinclair3c025922020-09-24 14:38:44 +0000717
718 ast::ExpressionList params;
dan sinclair6b59bf42020-12-11 19:16:13 +0000719 params.push_back(
720 create<ast::IdentifierExpression>(mod->RegisterSymbol("name"), "name"));
Ben Clayton4bfe4612020-11-16 16:41:47 +0000721 ast::TypeConstructorExpression cast(&f32, params);
dan sinclair4e807952020-04-07 16:41:23 +0000722
Ben Claytona80511e2020-12-11 13:07:02 +0000723 ast::Variable v(Source{}, "name", ast::StorageClass::kPrivate, &f32, false,
724 nullptr, ast::VariableDecorationList{});
dan sinclairff267ca2020-10-14 18:26:31 +0000725 td()->RegisterVariableForTesting(&v);
726
dan sinclair4e807952020-04-07 16:41:23 +0000727 EXPECT_TRUE(td()->DetermineResultType(&cast));
728 ASSERT_NE(cast.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000729 EXPECT_TRUE(cast.result_type()->Is<ast::type::F32>());
dan sinclair4e807952020-04-07 16:41:23 +0000730}
731
dan sinclairb7edc4c2020-04-07 12:46:30 +0000732TEST_F(TypeDeterminerTest, Expr_Constructor_Scalar) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000733 ast::type::F32 f32;
Ben Clayton62625922020-11-13 22:09:38 +0000734 ast::ScalarConstructorExpression s(create<ast::FloatLiteral>(&f32, 1.0f));
dan sinclairb7edc4c2020-04-07 12:46:30 +0000735
736 EXPECT_TRUE(td()->DetermineResultType(&s));
737 ASSERT_NE(s.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000738 EXPECT_TRUE(s.result_type()->Is<ast::type::F32>());
dan sinclairb7edc4c2020-04-07 12:46:30 +0000739}
740
741TEST_F(TypeDeterminerTest, Expr_Constructor_Type) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000742 ast::type::F32 f32;
743 ast::type::Vector vec(&f32, 3);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000744
745 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +0000746 vals.push_back(create<ast::ScalarConstructorExpression>(
747 create<ast::FloatLiteral>(&f32, 1.0f)));
748 vals.push_back(create<ast::ScalarConstructorExpression>(
749 create<ast::FloatLiteral>(&f32, 1.0f)));
750 vals.push_back(create<ast::ScalarConstructorExpression>(
751 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclairb7edc4c2020-04-07 12:46:30 +0000752
Ben Clayton4bfe4612020-11-16 16:41:47 +0000753 ast::TypeConstructorExpression tc(&vec, vals);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000754
755 EXPECT_TRUE(td()->DetermineResultType(&tc));
756 ASSERT_NE(tc.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000757 ASSERT_TRUE(tc.result_type()->Is<ast::type::Vector>());
758 EXPECT_TRUE(
759 tc.result_type()->As<ast::type::Vector>()->type()->Is<ast::type::F32>());
760 EXPECT_EQ(tc.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000761}
762
dan sinclaircab0e732020-04-07 12:57:27 +0000763TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalVariable) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000764 ast::type::F32 f32;
Ben Clayton321e5a92020-12-07 21:08:07 +0000765 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +0000766 create<ast::Variable>(Source{}, // source
767 "my_var", // name
768 ast::StorageClass::kNone, // storage_class
769 &f32, // type
770 false, // is_const
771 nullptr, // constructor
772 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +0000773 mod->AddGlobalVariable(var);
dan sinclaircab0e732020-04-07 12:57:27 +0000774
775 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000776 EXPECT_TRUE(td()->Determine());
dan sinclaircab0e732020-04-07 12:57:27 +0000777
dan sinclair6b59bf42020-12-11 19:16:13 +0000778 ast::IdentifierExpression ident(mod->RegisterSymbol("my_var"), "my_var");
dan sinclaircab0e732020-04-07 12:57:27 +0000779 EXPECT_TRUE(td()->DetermineResultType(&ident));
780 ASSERT_NE(ident.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000781 EXPECT_TRUE(ident.result_type()->Is<ast::type::Pointer>());
Ben Claytonc52f4212020-11-30 23:30:58 +0000782 EXPECT_TRUE(ident.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000783 ->As<ast::type::Pointer>()
Ben Claytonc52f4212020-11-30 23:30:58 +0000784 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000785 ->Is<ast::type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000786}
787
788TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalConstant) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000789 ast::type::F32 f32;
Ben Claytona80511e2020-12-11 13:07:02 +0000790 mod->AddGlobalVariable(
791 create<ast::Variable>(Source{}, // source
792 "my_var", // name
793 ast::StorageClass::kNone, // storage_class
794 &f32, // type
795 true, // is_const
796 nullptr, // constructor
797 ast::VariableDecorationList{})); // decorations
dan sinclair8eddb782020-04-23 22:26:52 +0000798
799 // Register the global
800 EXPECT_TRUE(td()->Determine());
801
dan sinclair6b59bf42020-12-11 19:16:13 +0000802 ast::IdentifierExpression ident(mod->RegisterSymbol("my_var"), "my_var");
dan sinclair8eddb782020-04-23 22:26:52 +0000803 EXPECT_TRUE(td()->DetermineResultType(&ident));
804 ASSERT_NE(ident.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000805 EXPECT_TRUE(ident.result_type()->Is<ast::type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000806}
807
dan sinclair8eddb782020-04-23 22:26:52 +0000808TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable_Const) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000809 ast::type::F32 f32;
dan sinclair8eddb782020-04-23 22:26:52 +0000810
dan sinclair6b59bf42020-12-11 19:16:13 +0000811 auto* my_var = create<ast::IdentifierExpression>(
812 mod->RegisterSymbol("my_var"), "my_var");
dan sinclair8eddb782020-04-23 22:26:52 +0000813
Ben Clayton321e5a92020-12-07 21:08:07 +0000814 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +0000815 create<ast::Variable>(Source{}, // source
816 "my_var", // name
817 ast::StorageClass::kNone, // storage_class
818 &f32, // type
819 true, // is_const
820 nullptr, // constructor
821 ast::VariableDecorationList{}); // decorations
dan sinclair8eddb782020-04-23 22:26:52 +0000822
Ben Claytonb053acf2020-11-16 16:31:07 +0000823 auto* body = create<ast::BlockStatement>();
Ben Clayton4bfe4612020-11-16 16:41:47 +0000824 body->append(create<ast::VariableDeclStatement>(var));
Ben Clayton62625922020-11-13 22:09:38 +0000825 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +0000826 my_var, create<ast::IdentifierExpression>(mod->RegisterSymbol("my_var"),
827 "my_var")));
dan sinclair8eddb782020-04-23 22:26:52 +0000828
dan sinclaira41132f2020-12-11 18:24:53 +0000829 ast::Function f(Source{}, mod->RegisterSymbol("my_func"), "my_func", {}, &f32,
830 body, ast::FunctionDecorationList{});
dan sinclair8eddb782020-04-23 22:26:52 +0000831
832 EXPECT_TRUE(td()->DetermineFunction(&f));
833
Ben Clayton4bfe4612020-11-16 16:41:47 +0000834 ASSERT_NE(my_var->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000835 EXPECT_TRUE(my_var->result_type()->Is<ast::type::F32>());
dan sinclair8eddb782020-04-23 22:26:52 +0000836}
837
dan sinclaircab0e732020-04-07 12:57:27 +0000838TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000839 ast::type::F32 f32;
dan sinclaircab0e732020-04-07 12:57:27 +0000840
dan sinclair6b59bf42020-12-11 19:16:13 +0000841 auto* my_var = create<ast::IdentifierExpression>(
842 mod->RegisterSymbol("my_var"), "my_var");
dan sinclaircab0e732020-04-07 12:57:27 +0000843
Ben Claytonb053acf2020-11-16 16:31:07 +0000844 auto* body = create<ast::BlockStatement>();
Ben Claytona80511e2020-12-11 13:07:02 +0000845 body->append(create<ast::VariableDeclStatement>(
846 create<ast::Variable>(Source{}, // source
847 "my_var", // name
848 ast::StorageClass::kNone, // storage_class
849 &f32, // type
850 false, // is_const
851 nullptr, // constructor
852 ast::VariableDecorationList{}))); // decorations
dan sinclaircab0e732020-04-07 12:57:27 +0000853
Ben Clayton62625922020-11-13 22:09:38 +0000854 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +0000855 my_var, create<ast::IdentifierExpression>(mod->RegisterSymbol("my_var"),
856 "my_var")));
dan sinclaircab0e732020-04-07 12:57:27 +0000857
dan sinclaira41132f2020-12-11 18:24:53 +0000858 ast::Function f(Source{}, mod->RegisterSymbol("myfunc"), "my_func", {}, &f32,
859 body, ast::FunctionDecorationList{});
dan sinclaircab0e732020-04-07 12:57:27 +0000860
861 EXPECT_TRUE(td()->DetermineFunction(&f));
862
Ben Clayton4bfe4612020-11-16 16:41:47 +0000863 ASSERT_NE(my_var->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000864 EXPECT_TRUE(my_var->result_type()->Is<ast::type::Pointer>());
Ben Claytonc52f4212020-11-30 23:30:58 +0000865 EXPECT_TRUE(my_var->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000866 ->As<ast::type::Pointer>()
Ben Claytonc52f4212020-11-30 23:30:58 +0000867 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000868 ->Is<ast::type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000869}
870
dan sinclair5e989302020-09-16 21:20:36 +0000871TEST_F(TypeDeterminerTest, Expr_Identifier_Function_Ptr) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000872 ast::type::F32 f32;
873 ast::type::Pointer ptr(&f32, ast::StorageClass::kFunction);
dan sinclair5e989302020-09-16 21:20:36 +0000874
dan sinclair6b59bf42020-12-11 19:16:13 +0000875 auto* my_var = create<ast::IdentifierExpression>(
876 mod->RegisterSymbol("my_var"), "my_var");
dan sinclair5e989302020-09-16 21:20:36 +0000877
Ben Claytonb053acf2020-11-16 16:31:07 +0000878 auto* body = create<ast::BlockStatement>();
Ben Claytona80511e2020-12-11 13:07:02 +0000879 body->append(create<ast::VariableDeclStatement>(
880 create<ast::Variable>(Source{}, // source
881 "my_var", // name
882 ast::StorageClass::kNone, // storage_class
883 &ptr, // type
884 false, // is_const
885 nullptr, // constructor
886 ast::VariableDecorationList{}))); // decorations
dan sinclair5e989302020-09-16 21:20:36 +0000887
Ben Clayton62625922020-11-13 22:09:38 +0000888 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +0000889 my_var, create<ast::IdentifierExpression>(mod->RegisterSymbol("my_var"),
890 "my_var")));
dan sinclair5e989302020-09-16 21:20:36 +0000891
dan sinclaira41132f2020-12-11 18:24:53 +0000892 ast::Function f(Source{}, mod->RegisterSymbol("my_func"), "my_func", {}, &f32,
893 body, ast::FunctionDecorationList{});
dan sinclair5e989302020-09-16 21:20:36 +0000894
895 EXPECT_TRUE(td()->DetermineFunction(&f));
896
Ben Clayton4bfe4612020-11-16 16:41:47 +0000897 ASSERT_NE(my_var->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000898 EXPECT_TRUE(my_var->result_type()->Is<ast::type::Pointer>());
Ben Claytonc52f4212020-11-30 23:30:58 +0000899 EXPECT_TRUE(my_var->result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000900 ->As<ast::type::Pointer>()
Ben Claytonc52f4212020-11-30 23:30:58 +0000901 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000902 ->Is<ast::type::F32>());
dan sinclair5e989302020-09-16 21:20:36 +0000903}
904
dan sinclaircab0e732020-04-07 12:57:27 +0000905TEST_F(TypeDeterminerTest, Expr_Identifier_Function) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000906 ast::type::F32 f32;
dan sinclaircab0e732020-04-07 12:57:27 +0000907
908 ast::VariableList params;
dan sinclaira41132f2020-12-11 18:24:53 +0000909 auto* func = create<ast::Function>(
910 Source{}, mod->RegisterSymbol("my_func"), "my_func", params, &f32,
911 create<ast::BlockStatement>(), ast::FunctionDecorationList{});
Ben Clayton3ea3c992020-11-18 21:19:22 +0000912 mod->AddFunction(func);
dan sinclaircab0e732020-04-07 12:57:27 +0000913
914 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000915 EXPECT_TRUE(td()->Determine());
dan sinclaircab0e732020-04-07 12:57:27 +0000916
dan sinclair6b59bf42020-12-11 19:16:13 +0000917 ast::IdentifierExpression ident(mod->RegisterSymbol("my_func"), "my_func");
dan sinclaircab0e732020-04-07 12:57:27 +0000918 EXPECT_TRUE(td()->DetermineResultType(&ident));
919 ASSERT_NE(ident.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000920 EXPECT_TRUE(ident.result_type()->Is<ast::type::F32>());
dan sinclaircab0e732020-04-07 12:57:27 +0000921}
922
dan sinclairff267ca2020-10-14 18:26:31 +0000923TEST_F(TypeDeterminerTest, Expr_Identifier_Unknown) {
dan sinclair6b59bf42020-12-11 19:16:13 +0000924 ast::IdentifierExpression a(mod->RegisterSymbol("a"), "a");
dan sinclairff267ca2020-10-14 18:26:31 +0000925 EXPECT_FALSE(td()->DetermineResultType(&a));
926}
927
dan sinclair13d2a3b2020-06-22 20:52:24 +0000928TEST_F(TypeDeterminerTest, Function_RegisterInputOutputVariables) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +0000929 ast::type::F32 f32;
dan sinclair13d2a3b2020-06-22 20:52:24 +0000930
Ben Claytona80511e2020-12-11 13:07:02 +0000931 auto* in_var =
932 create<ast::Variable>(Source{}, // source
933 "in_var", // name
934 ast::StorageClass::kInput, // storage_class
935 &f32, // type
936 false, // is_const
937 nullptr, // constructor
938 ast::VariableDecorationList{}); // decorations
939 auto* out_var =
940 create<ast::Variable>(Source{}, // source
941 "out_var", // name
942 ast::StorageClass::kOutput, // storage_class
943 &f32, // type
944 false, // is_const
945 nullptr, // constructor
946 ast::VariableDecorationList{}); // decorations
947 auto* sb_var =
948 create<ast::Variable>(Source{}, // source
949 "sb_var", // name
950 ast::StorageClass::kStorageBuffer, // storage_class
951 &f32, // type
952 false, // is_const
953 nullptr, // constructor
954 ast::VariableDecorationList{}); // decorations
955 auto* wg_var =
956 create<ast::Variable>(Source{}, // source
957 "wg_var", // name
958 ast::StorageClass::kWorkgroup, // storage_class
959 &f32, // type
960 false, // is_const
961 nullptr, // constructor
962 ast::VariableDecorationList{}); // decorations
963 auto* priv_var =
964 create<ast::Variable>(Source{}, // source
965 "priv_var", // name
966 ast::StorageClass::kPrivate, // storage_class
967 &f32, // type
968 false, // is_const
969 nullptr, // constructor
970 ast::VariableDecorationList{}); // decorations
dan sinclair13d2a3b2020-06-22 20:52:24 +0000971
Ben Clayton3ea3c992020-11-18 21:19:22 +0000972 mod->AddGlobalVariable(in_var);
973 mod->AddGlobalVariable(out_var);
974 mod->AddGlobalVariable(sb_var);
975 mod->AddGlobalVariable(wg_var);
976 mod->AddGlobalVariable(priv_var);
dan sinclair13d2a3b2020-06-22 20:52:24 +0000977
978 ast::VariableList params;
Ben Claytonb053acf2020-11-16 16:31:07 +0000979 auto* body = create<ast::BlockStatement>();
Ben Clayton62625922020-11-13 22:09:38 +0000980 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +0000981 create<ast::IdentifierExpression>(mod->RegisterSymbol("out_var"),
982 "out_var"),
983 create<ast::IdentifierExpression>(mod->RegisterSymbol("in_var"),
984 "in_var")));
Ben Clayton62625922020-11-13 22:09:38 +0000985 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +0000986 create<ast::IdentifierExpression>(mod->RegisterSymbol("wg_var"),
987 "wg_var"),
988 create<ast::IdentifierExpression>(mod->RegisterSymbol("wg_var"),
989 "wg_var")));
Ben Clayton62625922020-11-13 22:09:38 +0000990 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +0000991 create<ast::IdentifierExpression>(mod->RegisterSymbol("sb_var"),
992 "sb_var"),
993 create<ast::IdentifierExpression>(mod->RegisterSymbol("sb_var"),
994 "sb_var")));
Ben Clayton62625922020-11-13 22:09:38 +0000995 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +0000996 create<ast::IdentifierExpression>(mod->RegisterSymbol("priv_var"),
997 "priv_var"),
998 create<ast::IdentifierExpression>(mod->RegisterSymbol("priv_var"),
999 "priv_var")));
dan sinclaira41132f2020-12-11 18:24:53 +00001000 auto* func =
1001 create<ast::Function>(Source{}, mod->RegisterSymbol("my_func"), "my_func",
1002 params, &f32, body, ast::FunctionDecorationList{});
dan sinclair13d2a3b2020-06-22 20:52:24 +00001003
Ben Clayton3ea3c992020-11-18 21:19:22 +00001004 mod->AddFunction(func);
dan sinclair13d2a3b2020-06-22 20:52:24 +00001005
1006 // Register the function
1007 EXPECT_TRUE(td()->Determine());
1008
Ben Clayton4bfe4612020-11-16 16:41:47 +00001009 const auto& vars = func->referenced_module_variables();
Ryan Harrison9a452c12020-06-23 16:38:47 +00001010 ASSERT_EQ(vars.size(), 5u);
Ben Clayton4bfe4612020-11-16 16:41:47 +00001011 EXPECT_EQ(vars[0], out_var);
1012 EXPECT_EQ(vars[1], in_var);
1013 EXPECT_EQ(vars[2], wg_var);
1014 EXPECT_EQ(vars[3], sb_var);
1015 EXPECT_EQ(vars[4], priv_var);
dan sinclair13d2a3b2020-06-22 20:52:24 +00001016}
1017
dan sinclairde2dd682020-07-14 20:37:28 +00001018TEST_F(TypeDeterminerTest, Function_RegisterInputOutputVariables_SubFunction) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001019 ast::type::F32 f32;
dan sinclairde2dd682020-07-14 20:37:28 +00001020
Ben Claytona80511e2020-12-11 13:07:02 +00001021 auto* in_var =
1022 create<ast::Variable>(Source{}, // source
1023 "in_var", // name
1024 ast::StorageClass::kInput, // storage_class
1025 &f32, // type
1026 false, // is_const
1027 nullptr, // constructor
1028 ast::VariableDecorationList{}); // decorations
1029 auto* out_var =
1030 create<ast::Variable>(Source{}, // source
1031 "out_var", // name
1032 ast::StorageClass::kOutput, // storage_class
1033 &f32, // type
1034 false, // is_const
1035 nullptr, // constructor
1036 ast::VariableDecorationList{}); // decorations
1037 auto* sb_var =
1038 create<ast::Variable>(Source{}, // source
1039 "sb_var", // name
1040 ast::StorageClass::kStorageBuffer, // storage_class
1041 &f32, // type
1042 false, // is_const
1043 nullptr, // constructor
1044 ast::VariableDecorationList{}); // decorations
1045 auto* wg_var =
1046 create<ast::Variable>(Source{}, // source
1047 "wg_var", // name
1048 ast::StorageClass::kWorkgroup, // storage_class
1049 &f32, // type
1050 false, // is_const
1051 nullptr, // constructor
1052 ast::VariableDecorationList{}); // decorations
1053 auto* priv_var =
1054 create<ast::Variable>(Source{}, // source
1055 "priv_var", // name
1056 ast::StorageClass::kPrivate, // storage_class
1057 &f32, // type
1058 false, // is_const
1059 nullptr, // constructor
1060 ast::VariableDecorationList{}); // decorations
dan sinclairde2dd682020-07-14 20:37:28 +00001061
Ben Clayton3ea3c992020-11-18 21:19:22 +00001062 mod->AddGlobalVariable(in_var);
1063 mod->AddGlobalVariable(out_var);
1064 mod->AddGlobalVariable(sb_var);
1065 mod->AddGlobalVariable(wg_var);
1066 mod->AddGlobalVariable(priv_var);
dan sinclairde2dd682020-07-14 20:37:28 +00001067
Ben Claytonb053acf2020-11-16 16:31:07 +00001068 auto* body = create<ast::BlockStatement>();
Ben Clayton62625922020-11-13 22:09:38 +00001069 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +00001070 create<ast::IdentifierExpression>(mod->RegisterSymbol("out_var"),
1071 "out_var"),
1072 create<ast::IdentifierExpression>(mod->RegisterSymbol("in_var"),
1073 "in_var")));
Ben Clayton62625922020-11-13 22:09:38 +00001074 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +00001075 create<ast::IdentifierExpression>(mod->RegisterSymbol("wg_var"),
1076 "wg_var"),
1077 create<ast::IdentifierExpression>(mod->RegisterSymbol("wg_var"),
1078 "wg_var")));
Ben Clayton62625922020-11-13 22:09:38 +00001079 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +00001080 create<ast::IdentifierExpression>(mod->RegisterSymbol("sb_var"),
1081 "sb_var"),
1082 create<ast::IdentifierExpression>(mod->RegisterSymbol("sb_var"),
1083 "sb_var")));
Ben Clayton62625922020-11-13 22:09:38 +00001084 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +00001085 create<ast::IdentifierExpression>(mod->RegisterSymbol("priv_var"),
1086 "priv_var"),
1087 create<ast::IdentifierExpression>(mod->RegisterSymbol("priv_var"),
1088 "priv_var")));
Ben Claytonb29b09f2020-11-14 01:13:04 +00001089 ast::VariableList params;
dan sinclaira41132f2020-12-11 18:24:53 +00001090 auto* func =
1091 create<ast::Function>(Source{}, mod->RegisterSymbol("my_func"), "my_func",
1092 params, &f32, body, ast::FunctionDecorationList{});
dan sinclairde2dd682020-07-14 20:37:28 +00001093
Ben Clayton3ea3c992020-11-18 21:19:22 +00001094 mod->AddFunction(func);
dan sinclairde2dd682020-07-14 20:37:28 +00001095
Ben Clayton62625922020-11-13 22:09:38 +00001096 body = create<ast::BlockStatement>();
1097 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +00001098 create<ast::IdentifierExpression>(mod->RegisterSymbol("out_var"),
1099 "out_var"),
1100 create<ast::CallExpression>(
1101 create<ast::IdentifierExpression>(mod->RegisterSymbol("my_func"),
1102 "my_func"),
1103 ast::ExpressionList{})));
dan sinclaira41132f2020-12-11 18:24:53 +00001104 auto* func2 =
1105 create<ast::Function>(Source{}, mod->RegisterSymbol("func"), "func",
1106 params, &f32, body, ast::FunctionDecorationList{});
dan sinclairde2dd682020-07-14 20:37:28 +00001107
Ben Clayton3ea3c992020-11-18 21:19:22 +00001108 mod->AddFunction(func2);
dan sinclairde2dd682020-07-14 20:37:28 +00001109
1110 // Register the function
1111 EXPECT_TRUE(td()->Determine());
1112
Ben Clayton4bfe4612020-11-16 16:41:47 +00001113 const auto& vars = func2->referenced_module_variables();
dan sinclairde2dd682020-07-14 20:37:28 +00001114 ASSERT_EQ(vars.size(), 5u);
Ben Clayton4bfe4612020-11-16 16:41:47 +00001115 EXPECT_EQ(vars[0], out_var);
1116 EXPECT_EQ(vars[1], in_var);
1117 EXPECT_EQ(vars[2], wg_var);
1118 EXPECT_EQ(vars[3], sb_var);
1119 EXPECT_EQ(vars[4], priv_var);
dan sinclairde2dd682020-07-14 20:37:28 +00001120}
1121
dan sinclair13d2a3b2020-06-22 20:52:24 +00001122TEST_F(TypeDeterminerTest, Function_NotRegisterFunctionVariable) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001123 ast::type::F32 f32;
dan sinclair13d2a3b2020-06-22 20:52:24 +00001124
Ben Claytona80511e2020-12-11 13:07:02 +00001125 auto* var =
1126 create<ast::Variable>(Source{}, // source
1127 "in_var", // name
1128 ast::StorageClass::kFunction, // storage_class
1129 &f32, // type
1130 false, // is_const
1131 nullptr, // constructor
1132 ast::VariableDecorationList{}); // decorations
dan sinclair13d2a3b2020-06-22 20:52:24 +00001133
Ben Claytonb053acf2020-11-16 16:31:07 +00001134 auto* body = create<ast::BlockStatement>();
Ben Clayton4bfe4612020-11-16 16:41:47 +00001135 body->append(create<ast::VariableDeclStatement>(var));
Ben Clayton62625922020-11-13 22:09:38 +00001136 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +00001137 create<ast::IdentifierExpression>(mod->RegisterSymbol("var"), "var"),
Ben Clayton62625922020-11-13 22:09:38 +00001138 create<ast::ScalarConstructorExpression>(
1139 create<ast::FloatLiteral>(&f32, 1.f))));
Ben Claytonb29b09f2020-11-14 01:13:04 +00001140
1141 ast::VariableList params;
dan sinclaira41132f2020-12-11 18:24:53 +00001142 auto* func =
1143 create<ast::Function>(Source{}, mod->RegisterSymbol("my_func"), "my_func",
1144 params, &f32, body, ast::FunctionDecorationList{});
dan sinclair13d2a3b2020-06-22 20:52:24 +00001145
Ben Clayton3ea3c992020-11-18 21:19:22 +00001146 mod->AddFunction(func);
dan sinclair13d2a3b2020-06-22 20:52:24 +00001147
Ben Claytona80511e2020-12-11 13:07:02 +00001148 ast::Variable v(Source{}, "var", ast::StorageClass::kFunction, &f32, false,
1149 nullptr, ast::VariableDecorationList{});
dan sinclairff267ca2020-10-14 18:26:31 +00001150 td()->RegisterVariableForTesting(&v);
1151
dan sinclair13d2a3b2020-06-22 20:52:24 +00001152 // Register the function
dan sinclairff267ca2020-10-14 18:26:31 +00001153 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclair13d2a3b2020-06-22 20:52:24 +00001154
Ben Clayton4bfe4612020-11-16 16:41:47 +00001155 EXPECT_EQ(func->referenced_module_variables().size(), 0u);
dan sinclair13d2a3b2020-06-22 20:52:24 +00001156}
1157
dan sinclair8ee1d222020-04-07 16:41:33 +00001158TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001159 ast::type::I32 i32;
1160 ast::type::F32 f32;
dan sinclair8ee1d222020-04-07 16:41:33 +00001161
1162 ast::StructMemberDecorationList decos;
1163 ast::StructMemberList members;
Ben Clayton4bfe4612020-11-16 16:41:47 +00001164 members.push_back(create<ast::StructMember>("first_member", &i32, decos));
1165 members.push_back(create<ast::StructMember>("second_member", &f32, decos));
dan sinclair8ee1d222020-04-07 16:41:33 +00001166
Ben Clayton4bfe4612020-11-16 16:41:47 +00001167 auto* strct = create<ast::Struct>(members);
dan sinclair8ee1d222020-04-07 16:41:33 +00001168
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001169 ast::type::Struct st("S", strct);
dan sinclair8ee1d222020-04-07 16:41:33 +00001170
Ben Claytona80511e2020-12-11 13:07:02 +00001171 auto* var =
1172 create<ast::Variable>(Source{}, // source
1173 "my_struct", // name
1174 ast::StorageClass::kNone, // storage_class
1175 &st, // type
1176 false, // is_const
1177 nullptr, // constructor
1178 ast::VariableDecorationList{}); // decorations
dan sinclair8ee1d222020-04-07 16:41:33 +00001179
Ben Clayton3ea3c992020-11-18 21:19:22 +00001180 mod->AddGlobalVariable(var);
dan sinclair8ee1d222020-04-07 16:41:33 +00001181
1182 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001183 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +00001184
dan sinclair6b59bf42020-12-11 19:16:13 +00001185 auto* ident = create<ast::IdentifierExpression>(
1186 mod->RegisterSymbol("my_struct"), "my_struct");
1187 auto* mem_ident = create<ast::IdentifierExpression>(
1188 mod->RegisterSymbol("second_member"), "second_member");
dan sinclair8ee1d222020-04-07 16:41:33 +00001189
Ben Clayton4bfe4612020-11-16 16:41:47 +00001190 ast::MemberAccessorExpression mem(ident, mem_ident);
dan sinclair8ee1d222020-04-07 16:41:33 +00001191 EXPECT_TRUE(td()->DetermineResultType(&mem));
1192 ASSERT_NE(mem.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001193 ASSERT_TRUE(mem.result_type()->Is<ast::type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +00001194
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001195 auto* ptr = mem.result_type()->As<ast::type::Pointer>();
1196 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclair8ee1d222020-04-07 16:41:33 +00001197}
1198
dan sinclairb445a9b2020-04-24 00:40:45 +00001199TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct_Alias) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001200 ast::type::I32 i32;
1201 ast::type::F32 f32;
dan sinclairb445a9b2020-04-24 00:40:45 +00001202
1203 ast::StructMemberDecorationList decos;
1204 ast::StructMemberList members;
Ben Clayton4bfe4612020-11-16 16:41:47 +00001205 members.push_back(create<ast::StructMember>("first_member", &i32, decos));
1206 members.push_back(create<ast::StructMember>("second_member", &f32, decos));
dan sinclairb445a9b2020-04-24 00:40:45 +00001207
Ben Clayton4bfe4612020-11-16 16:41:47 +00001208 auto* strct = create<ast::Struct>(members);
dan sinclairb445a9b2020-04-24 00:40:45 +00001209
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001210 auto st = std::make_unique<ast::type::Struct>("alias", strct);
dan sinclair4226b6a2020-12-11 19:35:03 +00001211 ast::type::Alias alias(mod->RegisterSymbol("alias"), "alias", st.get());
dan sinclairb445a9b2020-04-24 00:40:45 +00001212
Ben Claytona80511e2020-12-11 13:07:02 +00001213 auto* var =
1214 create<ast::Variable>(Source{}, // source
1215 "my_struct", // name
1216 ast::StorageClass::kNone, // storage_class
1217 &alias, // type
1218 false, // is_const
1219 nullptr, // constructor
1220 ast::VariableDecorationList{}); // decorations
dan sinclairb445a9b2020-04-24 00:40:45 +00001221
Ben Clayton3ea3c992020-11-18 21:19:22 +00001222 mod->AddGlobalVariable(var);
dan sinclairb445a9b2020-04-24 00:40:45 +00001223
1224 // Register the global
1225 EXPECT_TRUE(td()->Determine());
1226
dan sinclair6b59bf42020-12-11 19:16:13 +00001227 auto* ident = create<ast::IdentifierExpression>(
1228 mod->RegisterSymbol("my_struct"), "my_struct");
1229 auto* mem_ident = create<ast::IdentifierExpression>(
1230 mod->RegisterSymbol("second_member"), "second_member");
dan sinclairb445a9b2020-04-24 00:40:45 +00001231
Ben Clayton4bfe4612020-11-16 16:41:47 +00001232 ast::MemberAccessorExpression mem(ident, mem_ident);
dan sinclairb445a9b2020-04-24 00:40:45 +00001233 EXPECT_TRUE(td()->DetermineResultType(&mem));
1234 ASSERT_NE(mem.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001235 ASSERT_TRUE(mem.result_type()->Is<ast::type::Pointer>());
dan sinclairb445a9b2020-04-24 00:40:45 +00001236
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001237 auto* ptr = mem.result_type()->As<ast::type::Pointer>();
1238 EXPECT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclairb445a9b2020-04-24 00:40:45 +00001239}
1240
dan sinclair8ee1d222020-04-07 16:41:33 +00001241TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001242 ast::type::F32 f32;
1243 ast::type::Vector vec3(&f32, 3);
dan sinclair8ee1d222020-04-07 16:41:33 +00001244
Ben Claytona80511e2020-12-11 13:07:02 +00001245 auto* var =
1246 create<ast::Variable>(Source{}, // source
1247 "my_vec", // name
1248 ast::StorageClass::kNone, // storage_class
1249 &vec3, // type
1250 false, // is_const
1251 nullptr, // constructor
1252 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001253 mod->AddGlobalVariable(var);
dan sinclair8ee1d222020-04-07 16:41:33 +00001254
1255 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001256 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +00001257
dan sinclair6b59bf42020-12-11 19:16:13 +00001258 auto* ident = create<ast::IdentifierExpression>(mod->RegisterSymbol("my_vec"),
1259 "my_vec");
1260 auto* swizzle =
1261 create<ast::IdentifierExpression>(mod->RegisterSymbol("xy"), "xy");
dan sinclair8ee1d222020-04-07 16:41:33 +00001262
Ben Clayton4bfe4612020-11-16 16:41:47 +00001263 ast::MemberAccessorExpression mem(ident, swizzle);
dan sinclair8ee1d222020-04-07 16:41:33 +00001264 EXPECT_TRUE(td()->DetermineResultType(&mem)) << td()->error();
1265 ASSERT_NE(mem.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001266 ASSERT_TRUE(mem.result_type()->Is<ast::type::Vector>());
1267 EXPECT_TRUE(
1268 mem.result_type()->As<ast::type::Vector>()->type()->Is<ast::type::F32>());
1269 EXPECT_EQ(mem.result_type()->As<ast::type::Vector>()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +00001270}
1271
dan sinclairaac58652020-04-21 13:05:34 +00001272TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle_SingleElement) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001273 ast::type::F32 f32;
1274 ast::type::Vector vec3(&f32, 3);
dan sinclairaac58652020-04-21 13:05:34 +00001275
Ben Claytona80511e2020-12-11 13:07:02 +00001276 auto* var =
1277 create<ast::Variable>(Source{}, // source
1278 "my_vec", // name
1279 ast::StorageClass::kNone, // storage_class
1280 &vec3, // type
1281 false, // is_const
1282 nullptr, // constructor
1283 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001284 mod->AddGlobalVariable(var);
dan sinclairaac58652020-04-21 13:05:34 +00001285
1286 // Register the global
1287 EXPECT_TRUE(td()->Determine());
1288
dan sinclair6b59bf42020-12-11 19:16:13 +00001289 auto* ident = create<ast::IdentifierExpression>(mod->RegisterSymbol("my_vec"),
1290 "my_vec");
1291 auto* swizzle =
1292 create<ast::IdentifierExpression>(mod->RegisterSymbol("x"), "x");
dan sinclairaac58652020-04-21 13:05:34 +00001293
Ben Clayton4bfe4612020-11-16 16:41:47 +00001294 ast::MemberAccessorExpression mem(ident, swizzle);
dan sinclairaac58652020-04-21 13:05:34 +00001295 EXPECT_TRUE(td()->DetermineResultType(&mem)) << td()->error();
1296 ASSERT_NE(mem.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001297 ASSERT_TRUE(mem.result_type()->Is<ast::type::Pointer>());
dan sinclair8eddb782020-04-23 22:26:52 +00001298
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001299 auto* ptr = mem.result_type()->As<ast::type::Pointer>();
1300 ASSERT_TRUE(ptr->type()->Is<ast::type::F32>());
dan sinclairaac58652020-04-21 13:05:34 +00001301}
1302
dan sinclair8eddb782020-04-23 22:26:52 +00001303TEST_F(TypeDeterminerTest, Expr_Accessor_MultiLevel) {
dan sinclair8ee1d222020-04-07 16:41:33 +00001304 // struct b {
1305 // vec4<f32> foo
1306 // }
1307 // struct A {
1308 // vec3<struct b> mem
1309 // }
1310 // var c : A
1311 // c.mem[0].foo.yx
1312 // -> vec2<f32>
1313 //
1314 // MemberAccessor{
1315 // MemberAccessor{
1316 // ArrayAccessor{
1317 // MemberAccessor{
1318 // Identifier{c}
1319 // Identifier{mem}
1320 // }
1321 // ScalarConstructor{0}
1322 // }
1323 // Identifier{foo}
1324 // }
1325 // Identifier{yx}
1326 // }
1327 //
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001328 ast::type::I32 i32;
1329 ast::type::F32 f32;
dan sinclair8ee1d222020-04-07 16:41:33 +00001330
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001331 ast::type::Vector vec4(&f32, 4);
dan sinclair8ee1d222020-04-07 16:41:33 +00001332
1333 ast::StructMemberDecorationList decos;
1334 ast::StructMemberList b_members;
Ben Clayton4bfe4612020-11-16 16:41:47 +00001335 b_members.push_back(create<ast::StructMember>("foo", &vec4, decos));
dan sinclair8ee1d222020-04-07 16:41:33 +00001336
Ben Clayton4bfe4612020-11-16 16:41:47 +00001337 auto* strctB = create<ast::Struct>(b_members);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001338 ast::type::Struct stB("B", strctB);
dan sinclair8ee1d222020-04-07 16:41:33 +00001339
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001340 ast::type::Vector vecB(&stB, 3);
dan sinclair8ee1d222020-04-07 16:41:33 +00001341
1342 ast::StructMemberList a_members;
Ben Clayton4bfe4612020-11-16 16:41:47 +00001343 a_members.push_back(create<ast::StructMember>("mem", &vecB, decos));
dan sinclair8ee1d222020-04-07 16:41:33 +00001344
Ben Clayton4bfe4612020-11-16 16:41:47 +00001345 auto* strctA = create<ast::Struct>(a_members);
dan sinclair8ee1d222020-04-07 16:41:33 +00001346
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001347 ast::type::Struct stA("A", strctA);
dan sinclair8ee1d222020-04-07 16:41:33 +00001348
Ben Clayton321e5a92020-12-07 21:08:07 +00001349 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00001350 create<ast::Variable>(Source{}, // source
1351 "c", // name
1352 ast::StorageClass::kNone, // storage_class
1353 &stA, // type
1354 false, // is_const
1355 nullptr, // constructor
1356 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001357 mod->AddGlobalVariable(var);
dan sinclair8ee1d222020-04-07 16:41:33 +00001358
1359 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001360 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +00001361
dan sinclair6b59bf42020-12-11 19:16:13 +00001362 auto* ident =
1363 create<ast::IdentifierExpression>(mod->RegisterSymbol("c"), "c");
1364 auto* mem_ident =
1365 create<ast::IdentifierExpression>(mod->RegisterSymbol("mem"), "mem");
1366 auto* foo_ident =
1367 create<ast::IdentifierExpression>(mod->RegisterSymbol("foo"), "foo");
Ben Claytonb053acf2020-11-16 16:31:07 +00001368 auto* idx = create<ast::ScalarConstructorExpression>(
Ben Clayton62625922020-11-13 22:09:38 +00001369 create<ast::SintLiteral>(&i32, 0));
dan sinclair6b59bf42020-12-11 19:16:13 +00001370 auto* swizzle =
1371 create<ast::IdentifierExpression>(mod->RegisterSymbol("yx"), "yx");
dan sinclair8ee1d222020-04-07 16:41:33 +00001372
1373 ast::MemberAccessorExpression mem(
Ben Clayton62625922020-11-13 22:09:38 +00001374 create<ast::MemberAccessorExpression>(
1375 create<ast::ArrayAccessorExpression>(
Ben Clayton4bfe4612020-11-16 16:41:47 +00001376 create<ast::MemberAccessorExpression>(ident, mem_ident), idx),
1377 foo_ident),
1378 swizzle);
dan sinclair8ee1d222020-04-07 16:41:33 +00001379 EXPECT_TRUE(td()->DetermineResultType(&mem)) << td()->error();
dan sinclair8eddb782020-04-23 22:26:52 +00001380
dan sinclair8ee1d222020-04-07 16:41:33 +00001381 ASSERT_NE(mem.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001382 ASSERT_TRUE(mem.result_type()->Is<ast::type::Vector>());
1383 EXPECT_TRUE(
1384 mem.result_type()->As<ast::type::Vector>()->type()->Is<ast::type::F32>());
1385 EXPECT_EQ(mem.result_type()->As<ast::type::Vector>()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +00001386}
1387
dan sinclaircd077b02020-04-20 14:19:04 +00001388using Expr_Binary_BitwiseTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +00001389TEST_P(Expr_Binary_BitwiseTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001390 auto op = GetParam();
1391
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001392 ast::type::I32 i32;
dan sinclair9b978022020-04-07 19:26:39 +00001393
Ben Clayton321e5a92020-12-07 21:08:07 +00001394 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00001395 create<ast::Variable>(Source{}, // source
1396 "val", // name
1397 ast::StorageClass::kNone, // storage_class
1398 &i32, // type
1399 false, // is_const
1400 nullptr, // constructor
1401 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001402 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001403
1404 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001405 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001406
dan sinclair6b59bf42020-12-11 19:16:13 +00001407 ast::BinaryExpression expr(
1408 op, create<ast::IdentifierExpression>(mod->RegisterSymbol("val"), "val"),
1409 create<ast::IdentifierExpression>(mod->RegisterSymbol("val"), "val"));
dan sinclair9b978022020-04-07 19:26:39 +00001410
dan sinclaircd077b02020-04-20 14:19:04 +00001411 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001412 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001413 EXPECT_TRUE(expr.result_type()->Is<ast::type::I32>());
dan sinclair9b978022020-04-07 19:26:39 +00001414}
1415
dan sinclair1c9b4862020-04-07 19:27:41 +00001416TEST_P(Expr_Binary_BitwiseTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001417 auto op = GetParam();
1418
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001419 ast::type::I32 i32;
1420 ast::type::Vector vec3(&i32, 3);
dan sinclair9b978022020-04-07 19:26:39 +00001421
Ben Clayton321e5a92020-12-07 21:08:07 +00001422 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00001423 create<ast::Variable>(Source{}, // source
1424 "val", // name
1425 ast::StorageClass::kNone, // storage_class
1426 &vec3, // type
1427 false, // is_const
1428 nullptr, // constructor
1429 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001430 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001431
1432 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001433 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001434
dan sinclair6b59bf42020-12-11 19:16:13 +00001435 ast::BinaryExpression expr(
1436 op, create<ast::IdentifierExpression>(mod->RegisterSymbol("val"), "val"),
1437 create<ast::IdentifierExpression>(mod->RegisterSymbol("val"), "val"));
dan sinclair9b978022020-04-07 19:26:39 +00001438
dan sinclaircd077b02020-04-20 14:19:04 +00001439 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001440 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001441 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00001442 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001443 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001444 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001445 ->Is<ast::type::I32>());
1446 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001447}
1448INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +00001449 Expr_Binary_BitwiseTest,
1450 testing::Values(ast::BinaryOp::kAnd,
1451 ast::BinaryOp::kOr,
1452 ast::BinaryOp::kXor,
1453 ast::BinaryOp::kShiftLeft,
1454 ast::BinaryOp::kShiftRight,
dan sinclair1c9b4862020-04-07 19:27:41 +00001455 ast::BinaryOp::kAdd,
1456 ast::BinaryOp::kSubtract,
1457 ast::BinaryOp::kDivide,
1458 ast::BinaryOp::kModulo));
dan sinclair9b978022020-04-07 19:26:39 +00001459
dan sinclaircd077b02020-04-20 14:19:04 +00001460using Expr_Binary_LogicalTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +00001461TEST_P(Expr_Binary_LogicalTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001462 auto op = GetParam();
1463
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001464 ast::type::Bool bool_type;
dan sinclair9b978022020-04-07 19:26:39 +00001465
Ben Claytona80511e2020-12-11 13:07:02 +00001466 auto* var =
1467 create<ast::Variable>(Source{}, // source
1468 "val", // name
1469 ast::StorageClass::kNone, // storage_class
1470 &bool_type, // type
1471 false, // is_const
1472 nullptr, // constructor
1473 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001474 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001475
1476 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001477 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001478
dan sinclair6b59bf42020-12-11 19:16:13 +00001479 ast::BinaryExpression expr(
1480 op, create<ast::IdentifierExpression>(mod->RegisterSymbol("val"), "val"),
1481 create<ast::IdentifierExpression>(mod->RegisterSymbol("val"), "val"));
dan sinclair9b978022020-04-07 19:26:39 +00001482
dan sinclaircd077b02020-04-20 14:19:04 +00001483 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001484 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001485 EXPECT_TRUE(expr.result_type()->Is<ast::type::Bool>());
dan sinclair9b978022020-04-07 19:26:39 +00001486}
1487
dan sinclair1c9b4862020-04-07 19:27:41 +00001488TEST_P(Expr_Binary_LogicalTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001489 auto op = GetParam();
1490
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001491 ast::type::Bool bool_type;
1492 ast::type::Vector vec3(&bool_type, 3);
dan sinclair9b978022020-04-07 19:26:39 +00001493
Ben Clayton321e5a92020-12-07 21:08:07 +00001494 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00001495 create<ast::Variable>(Source{}, // source
1496 "val", // name
1497 ast::StorageClass::kNone, // storage_class
1498 &vec3, // type
1499 false, // is_const
1500 nullptr, // constructor
1501 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001502 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001503
1504 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001505 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001506
dan sinclair6b59bf42020-12-11 19:16:13 +00001507 ast::BinaryExpression expr(
1508 op, create<ast::IdentifierExpression>(mod->RegisterSymbol("val"), "val"),
1509 create<ast::IdentifierExpression>(mod->RegisterSymbol("val"), "val"));
dan sinclair9b978022020-04-07 19:26:39 +00001510
dan sinclaircd077b02020-04-20 14:19:04 +00001511 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001512 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001513 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00001514 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001515 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001516 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001517 ->Is<ast::type::Bool>());
1518 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001519}
1520INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +00001521 Expr_Binary_LogicalTest,
1522 testing::Values(ast::BinaryOp::kLogicalAnd,
1523 ast::BinaryOp::kLogicalOr));
dan sinclair9b978022020-04-07 19:26:39 +00001524
dan sinclaircd077b02020-04-20 14:19:04 +00001525using Expr_Binary_CompareTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +00001526TEST_P(Expr_Binary_CompareTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001527 auto op = GetParam();
1528
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001529 ast::type::I32 i32;
dan sinclair9b978022020-04-07 19:26:39 +00001530
Ben Clayton321e5a92020-12-07 21:08:07 +00001531 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00001532 create<ast::Variable>(Source{}, // source
1533 "val", // name
1534 ast::StorageClass::kNone, // storage_class
1535 &i32, // type
1536 false, // is_const
1537 nullptr, // constructor
1538 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001539 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001540
1541 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001542 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001543
dan sinclair6b59bf42020-12-11 19:16:13 +00001544 ast::BinaryExpression expr(
1545 op, create<ast::IdentifierExpression>(mod->RegisterSymbol("val"), "val"),
1546 create<ast::IdentifierExpression>(mod->RegisterSymbol("val"), "val"));
dan sinclair9b978022020-04-07 19:26:39 +00001547
dan sinclaircd077b02020-04-20 14:19:04 +00001548 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001549 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001550 EXPECT_TRUE(expr.result_type()->Is<ast::type::Bool>());
dan sinclair9b978022020-04-07 19:26:39 +00001551}
1552
dan sinclair1c9b4862020-04-07 19:27:41 +00001553TEST_P(Expr_Binary_CompareTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001554 auto op = GetParam();
1555
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001556 ast::type::I32 i32;
1557 ast::type::Vector vec3(&i32, 3);
dan sinclair9b978022020-04-07 19:26:39 +00001558
Ben Clayton321e5a92020-12-07 21:08:07 +00001559 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00001560 create<ast::Variable>(Source{}, // source
1561 "val", // name
1562 ast::StorageClass::kNone, // storage_class
1563 &vec3, // type
1564 false, // is_const
1565 nullptr, // constructor
1566 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001567 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001568
1569 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001570 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001571
dan sinclair6b59bf42020-12-11 19:16:13 +00001572 ast::BinaryExpression expr(
1573 op, create<ast::IdentifierExpression>(mod->RegisterSymbol("val"), "val"),
1574 create<ast::IdentifierExpression>(mod->RegisterSymbol("val"), "val"));
dan sinclair9b978022020-04-07 19:26:39 +00001575
dan sinclaircd077b02020-04-20 14:19:04 +00001576 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001577 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001578 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00001579 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001580 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001581 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001582 ->Is<ast::type::Bool>());
1583 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001584}
1585INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +00001586 Expr_Binary_CompareTest,
1587 testing::Values(ast::BinaryOp::kEqual,
1588 ast::BinaryOp::kNotEqual,
1589 ast::BinaryOp::kLessThan,
1590 ast::BinaryOp::kGreaterThan,
1591 ast::BinaryOp::kLessThanEqual,
1592 ast::BinaryOp::kGreaterThanEqual));
dan sinclair9b978022020-04-07 19:26:39 +00001593
dan sinclair1c9b4862020-04-07 19:27:41 +00001594TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Scalar) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001595 ast::type::I32 i32;
dan sinclair9b978022020-04-07 19:26:39 +00001596
Ben Clayton321e5a92020-12-07 21:08:07 +00001597 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00001598 create<ast::Variable>(Source{}, // source
1599 "val", // name
1600 ast::StorageClass::kNone, // storage_class
1601 &i32, // type
1602 false, // is_const
1603 nullptr, // constructor
1604 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001605 mod->AddGlobalVariable(var);
dan sinclair9b978022020-04-07 19:26:39 +00001606
1607 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001608 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001609
dan sinclair6b59bf42020-12-11 19:16:13 +00001610 ast::BinaryExpression expr(
1611 ast::BinaryOp::kMultiply,
1612 create<ast::IdentifierExpression>(mod->RegisterSymbol("val"), "val"),
1613 create<ast::IdentifierExpression>(mod->RegisterSymbol("val"), "val"));
dan sinclair9b978022020-04-07 19:26:39 +00001614
dan sinclaircd077b02020-04-20 14:19:04 +00001615 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001616 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001617 EXPECT_TRUE(expr.result_type()->Is<ast::type::I32>());
dan sinclair9b978022020-04-07 19:26:39 +00001618}
1619
dan sinclair1c9b4862020-04-07 19:27:41 +00001620TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Scalar) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001621 ast::type::F32 f32;
1622 ast::type::Vector vec3(&f32, 3);
dan sinclair9b978022020-04-07 19:26:39 +00001623
Ben Claytonb053acf2020-11-16 16:31:07 +00001624 auto* scalar =
Ben Claytona80511e2020-12-11 13:07:02 +00001625 create<ast::Variable>(Source{}, // source
1626 "scalar", // name
1627 ast::StorageClass::kNone, // storage_class
1628 &f32, // type
1629 false, // is_const
1630 nullptr, // constructor
1631 ast::VariableDecorationList{}); // decorations
1632 auto* vector =
1633 create<ast::Variable>(Source{}, // source
1634 "vector", // name
1635 ast::StorageClass::kNone, // storage_class
1636 &vec3, // type
1637 false, // is_const
1638 nullptr, // constructor
1639 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001640 mod->AddGlobalVariable(scalar);
1641 mod->AddGlobalVariable(vector);
dan sinclair9b978022020-04-07 19:26:39 +00001642
1643 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001644 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001645
Ben Clayton62625922020-11-13 22:09:38 +00001646 ast::BinaryExpression expr(ast::BinaryOp::kMultiply,
dan sinclair6b59bf42020-12-11 19:16:13 +00001647 create<ast::IdentifierExpression>(
1648 mod->RegisterSymbol("vector"), "vector"),
1649 create<ast::IdentifierExpression>(
1650 mod->RegisterSymbol("scalar"), "scalar"));
dan sinclair9b978022020-04-07 19:26:39 +00001651
dan sinclaircd077b02020-04-20 14:19:04 +00001652 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001653 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001654 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00001655 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001656 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001657 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001658 ->Is<ast::type::F32>());
1659 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001660}
1661
dan sinclair1c9b4862020-04-07 19:27:41 +00001662TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Vector) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001663 ast::type::F32 f32;
1664 ast::type::Vector vec3(&f32, 3);
dan sinclair9b978022020-04-07 19:26:39 +00001665
Ben Claytonb053acf2020-11-16 16:31:07 +00001666 auto* scalar =
Ben Claytona80511e2020-12-11 13:07:02 +00001667 create<ast::Variable>(Source{}, // source
1668 "scalar", // name
1669 ast::StorageClass::kNone, // storage_class
1670 &f32, // type
1671 false, // is_const
1672 nullptr, // constructor
1673 ast::VariableDecorationList{}); // decorations
1674 auto* vector =
1675 create<ast::Variable>(Source{}, // source
1676 "vector", // name
1677 ast::StorageClass::kNone, // storage_class
1678 &vec3, // type
1679 false, // is_const
1680 nullptr, // constructor
1681 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001682 mod->AddGlobalVariable(scalar);
1683 mod->AddGlobalVariable(vector);
dan sinclair9b978022020-04-07 19:26:39 +00001684
1685 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001686 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001687
Ben Clayton62625922020-11-13 22:09:38 +00001688 ast::BinaryExpression expr(ast::BinaryOp::kMultiply,
dan sinclair6b59bf42020-12-11 19:16:13 +00001689 create<ast::IdentifierExpression>(
1690 mod->RegisterSymbol("scalar"), "scalar"),
1691 create<ast::IdentifierExpression>(
1692 mod->RegisterSymbol("vector"), "vector"));
dan sinclair9b978022020-04-07 19:26:39 +00001693
dan sinclaircd077b02020-04-20 14:19:04 +00001694 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001695 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001696 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00001697 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001698 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001699 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001700 ->Is<ast::type::F32>());
1701 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001702}
1703
dan sinclair1c9b4862020-04-07 19:27:41 +00001704TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Vector) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001705 ast::type::F32 f32;
1706 ast::type::Vector vec3(&f32, 3);
dan sinclair9b978022020-04-07 19:26:39 +00001707
Ben Claytona80511e2020-12-11 13:07:02 +00001708 auto* vector =
1709 create<ast::Variable>(Source{}, // source
1710 "vector", // name
1711 ast::StorageClass::kNone, // storage_class
1712 &vec3, // type
1713 false, // is_const
1714 nullptr, // constructor
1715 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001716 mod->AddGlobalVariable(vector);
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 Clayton62625922020-11-13 22:09:38 +00001721 ast::BinaryExpression expr(ast::BinaryOp::kMultiply,
dan sinclair6b59bf42020-12-11 19:16:13 +00001722 create<ast::IdentifierExpression>(
1723 mod->RegisterSymbol("vector"), "vector"),
1724 create<ast::IdentifierExpression>(
1725 mod->RegisterSymbol("vector"), "vector"));
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 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00001730 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001731 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001732 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001733 ->Is<ast::type::F32>());
1734 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001735}
1736
dan sinclair1c9b4862020-04-07 19:27:41 +00001737TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Scalar) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001738 ast::type::F32 f32;
1739 ast::type::Matrix mat3x2(&f32, 3, 2);
dan sinclair9b978022020-04-07 19:26:39 +00001740
Ben Claytonb053acf2020-11-16 16:31:07 +00001741 auto* scalar =
Ben Claytona80511e2020-12-11 13:07:02 +00001742 create<ast::Variable>(Source{}, // source
1743 "scalar", // name
1744 ast::StorageClass::kNone, // storage_class
1745 &f32, // type
1746 false, // is_const
1747 nullptr, // constructor
1748 ast::VariableDecorationList{}); // decorations
1749 auto* matrix =
1750 create<ast::Variable>(Source{}, // source
1751 "matrix", // name
1752 ast::StorageClass::kNone, // storage_class
1753 &mat3x2, // type
1754 false, // is_const
1755 nullptr, // constructor
1756 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001757 mod->AddGlobalVariable(scalar);
1758 mod->AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001759
1760 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001761 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001762
Ben Clayton62625922020-11-13 22:09:38 +00001763 ast::BinaryExpression expr(ast::BinaryOp::kMultiply,
dan sinclair6b59bf42020-12-11 19:16:13 +00001764 create<ast::IdentifierExpression>(
1765 mod->RegisterSymbol("matrix"), "matrix"),
1766 create<ast::IdentifierExpression>(
1767 mod->RegisterSymbol("scalar"), "scalar"));
dan sinclair9b978022020-04-07 19:26:39 +00001768
dan sinclaircd077b02020-04-20 14:19:04 +00001769 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001770 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001771 ASSERT_TRUE(expr.result_type()->Is<ast::type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001772
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001773 auto* mat = expr.result_type()->As<ast::type::Matrix>();
1774 EXPECT_TRUE(mat->type()->Is<ast::type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001775 EXPECT_EQ(mat->rows(), 3u);
1776 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001777}
1778
dan sinclair1c9b4862020-04-07 19:27:41 +00001779TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Matrix) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001780 ast::type::F32 f32;
1781 ast::type::Matrix mat3x2(&f32, 3, 2);
dan sinclair9b978022020-04-07 19:26:39 +00001782
Ben Claytonb053acf2020-11-16 16:31:07 +00001783 auto* scalar =
Ben Claytona80511e2020-12-11 13:07:02 +00001784 create<ast::Variable>(Source{}, // source
1785 "scalar", // name
1786 ast::StorageClass::kNone, // storage_class
1787 &f32, // type
1788 false, // is_const
1789 nullptr, // constructor
1790 ast::VariableDecorationList{}); // decorations
1791 auto* matrix =
1792 create<ast::Variable>(Source{}, // source
1793 "matrix", // name
1794 ast::StorageClass::kNone, // storage_class
1795 &mat3x2, // type
1796 false, // is_const
1797 nullptr, // constructor
1798 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001799 mod->AddGlobalVariable(scalar);
1800 mod->AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001801
1802 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001803 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001804
Ben Clayton62625922020-11-13 22:09:38 +00001805 ast::BinaryExpression expr(ast::BinaryOp::kMultiply,
dan sinclair6b59bf42020-12-11 19:16:13 +00001806 create<ast::IdentifierExpression>(
1807 mod->RegisterSymbol("scalar"), "scalar"),
1808 create<ast::IdentifierExpression>(
1809 mod->RegisterSymbol("matrix"), "matrix"));
dan sinclair9b978022020-04-07 19:26:39 +00001810
dan sinclaircd077b02020-04-20 14:19:04 +00001811 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001812 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001813 ASSERT_TRUE(expr.result_type()->Is<ast::type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001814
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001815 auto* mat = expr.result_type()->As<ast::type::Matrix>();
1816 EXPECT_TRUE(mat->type()->Is<ast::type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001817 EXPECT_EQ(mat->rows(), 3u);
1818 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001819}
1820
dan sinclair1c9b4862020-04-07 19:27:41 +00001821TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Vector) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001822 ast::type::F32 f32;
1823 ast::type::Vector vec3(&f32, 2);
1824 ast::type::Matrix mat3x2(&f32, 3, 2);
dan sinclair9b978022020-04-07 19:26:39 +00001825
Ben Claytona80511e2020-12-11 13:07:02 +00001826 auto* vector =
1827 create<ast::Variable>(Source{}, // source
1828 "vector", // name
1829 ast::StorageClass::kNone, // storage_class
1830 &vec3, // type
1831 false, // is_const
1832 nullptr, // constructor
1833 ast::VariableDecorationList{}); // decorations
1834 auto* matrix =
1835 create<ast::Variable>(Source{}, // source
1836 "matrix", // name
1837 ast::StorageClass::kNone, // storage_class
1838 &mat3x2, // type
1839 false, // is_const
1840 nullptr, // constructor
1841 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001842 mod->AddGlobalVariable(vector);
1843 mod->AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001844
1845 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001846 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001847
Ben Clayton62625922020-11-13 22:09:38 +00001848 ast::BinaryExpression expr(ast::BinaryOp::kMultiply,
dan sinclair6b59bf42020-12-11 19:16:13 +00001849 create<ast::IdentifierExpression>(
1850 mod->RegisterSymbol("matrix"), "matrix"),
1851 create<ast::IdentifierExpression>(
1852 mod->RegisterSymbol("vector"), "vector"));
dan sinclair9b978022020-04-07 19:26:39 +00001853
dan sinclaircd077b02020-04-20 14:19:04 +00001854 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001855 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001856 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00001857 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001858 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001859 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001860 ->Is<ast::type::F32>());
1861 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001862}
1863
dan sinclair1c9b4862020-04-07 19:27:41 +00001864TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Matrix) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001865 ast::type::F32 f32;
1866 ast::type::Vector vec3(&f32, 3);
1867 ast::type::Matrix mat3x2(&f32, 3, 2);
dan sinclair9b978022020-04-07 19:26:39 +00001868
Ben Claytona80511e2020-12-11 13:07:02 +00001869 auto* vector =
1870 create<ast::Variable>(Source{}, // source
1871 "vector", // name
1872 ast::StorageClass::kNone, // storage_class
1873 &vec3, // type
1874 false, // is_const
1875 nullptr, // constructor
1876 ast::VariableDecorationList{}); // decorations
1877 auto* matrix =
1878 create<ast::Variable>(Source{}, // source
1879 "matrix", // name
1880 ast::StorageClass::kNone, // storage_class
1881 &mat3x2, // type
1882 false, // is_const
1883 nullptr, // constructor
1884 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001885 mod->AddGlobalVariable(vector);
1886 mod->AddGlobalVariable(matrix);
dan sinclair9b978022020-04-07 19:26:39 +00001887
1888 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001889 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001890
Ben Clayton62625922020-11-13 22:09:38 +00001891 ast::BinaryExpression expr(ast::BinaryOp::kMultiply,
dan sinclair6b59bf42020-12-11 19:16:13 +00001892 create<ast::IdentifierExpression>(
1893 mod->RegisterSymbol("vector"), "vector"),
1894 create<ast::IdentifierExpression>(
1895 mod->RegisterSymbol("matrix"), "matrix"));
dan sinclair9b978022020-04-07 19:26:39 +00001896
dan sinclaircd077b02020-04-20 14:19:04 +00001897 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001898 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001899 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00001900 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001901 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00001902 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001903 ->Is<ast::type::F32>());
1904 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001905}
1906
dan sinclair1c9b4862020-04-07 19:27:41 +00001907TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Matrix) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001908 ast::type::F32 f32;
1909 ast::type::Matrix mat4x3(&f32, 4, 3);
1910 ast::type::Matrix mat3x4(&f32, 3, 4);
dan sinclair9b978022020-04-07 19:26:39 +00001911
Ben Claytona80511e2020-12-11 13:07:02 +00001912 auto* matrix1 =
1913 create<ast::Variable>(Source{}, // source
1914 "mat4x3", // name
1915 ast::StorageClass::kNone, // storage_class
1916 &mat4x3, // type
1917 false, // is_const
1918 nullptr, // constructor
1919 ast::VariableDecorationList{}); // decorations
1920 auto* matrix2 =
1921 create<ast::Variable>(Source{}, // source
1922 "mat3x4", // name
1923 ast::StorageClass::kNone, // storage_class
1924 &mat3x4, // type
1925 false, // is_const
1926 nullptr, // constructor
1927 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001928 mod->AddGlobalVariable(matrix1);
1929 mod->AddGlobalVariable(matrix2);
dan sinclair9b978022020-04-07 19:26:39 +00001930
1931 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001932 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001933
Ben Clayton62625922020-11-13 22:09:38 +00001934 ast::BinaryExpression expr(ast::BinaryOp::kMultiply,
dan sinclair6b59bf42020-12-11 19:16:13 +00001935 create<ast::IdentifierExpression>(
1936 mod->RegisterSymbol("mat4x3"), "mat4x3"),
1937 create<ast::IdentifierExpression>(
1938 mod->RegisterSymbol("mat3x4"), "mat3x4"));
dan sinclair9b978022020-04-07 19:26:39 +00001939
dan sinclaircd077b02020-04-20 14:19:04 +00001940 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001941 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001942 ASSERT_TRUE(expr.result_type()->Is<ast::type::Matrix>());
dan sinclair9b978022020-04-07 19:26:39 +00001943
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001944 auto* mat = expr.result_type()->As<ast::type::Matrix>();
1945 EXPECT_TRUE(mat->type()->Is<ast::type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001946 EXPECT_EQ(mat->rows(), 4u);
1947 EXPECT_EQ(mat->columns(), 4u);
dan sinclair9b978022020-04-07 19:26:39 +00001948}
1949
dan sinclair46e959d2020-06-01 13:43:22 +00001950using IntrinsicDerivativeTest = TypeDeterminerTestWithParam<std::string>;
1951TEST_P(IntrinsicDerivativeTest, Scalar) {
1952 auto name = GetParam();
dan sinclairb1730562020-04-07 19:26:49 +00001953
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001954 ast::type::F32 f32;
dan sinclairb1730562020-04-07 19:26:49 +00001955
Ben Clayton321e5a92020-12-07 21:08:07 +00001956 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00001957 create<ast::Variable>(Source{}, // source
1958 "ident", // name
1959 ast::StorageClass::kNone, // storage_class
1960 &f32, // type
1961 false, // is_const
1962 nullptr, // constructor
1963 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001964 mod->AddGlobalVariable(var);
dan sinclair46e959d2020-06-01 13:43:22 +00001965
1966 // Register the global
1967 EXPECT_TRUE(td()->Determine());
1968
1969 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00001970 call_params.push_back(
1971 create<ast::IdentifierExpression>(mod->RegisterSymbol("ident"), "ident"));
dan sinclair46e959d2020-06-01 13:43:22 +00001972
dan sinclair6b59bf42020-12-11 19:16:13 +00001973 ast::CallExpression expr(
1974 create<ast::IdentifierExpression>(mod->RegisterSymbol(name), name),
1975 call_params);
dan sinclair46e959d2020-06-01 13:43:22 +00001976 EXPECT_TRUE(td()->DetermineResultType(&expr));
1977
1978 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001979 ASSERT_TRUE(expr.result_type()->Is<ast::type::F32>());
dan sinclair46e959d2020-06-01 13:43:22 +00001980}
1981
1982TEST_P(IntrinsicDerivativeTest, Vector) {
1983 auto name = GetParam();
1984
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00001985 ast::type::F32 f32;
1986 ast::type::Vector vec4(&f32, 4);
dan sinclairb1730562020-04-07 19:26:49 +00001987
Ben Clayton321e5a92020-12-07 21:08:07 +00001988 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00001989 create<ast::Variable>(Source{}, // source
1990 "ident", // name
1991 ast::StorageClass::kNone, // storage_class
1992 &vec4, // type
1993 false, // is_const
1994 nullptr, // constructor
1995 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00001996 mod->AddGlobalVariable(var);
dan sinclairb1730562020-04-07 19:26:49 +00001997
1998 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001999 EXPECT_TRUE(td()->Determine());
dan sinclairb1730562020-04-07 19:26:49 +00002000
dan sinclair46e959d2020-06-01 13:43:22 +00002001 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002002 call_params.push_back(
2003 create<ast::IdentifierExpression>(mod->RegisterSymbol("ident"), "ident"));
dan sinclair46e959d2020-06-01 13:43:22 +00002004
dan sinclair6b59bf42020-12-11 19:16:13 +00002005 ast::CallExpression expr(
2006 create<ast::IdentifierExpression>(mod->RegisterSymbol(name), name),
2007 call_params);
dan sinclair46e959d2020-06-01 13:43:22 +00002008 EXPECT_TRUE(td()->DetermineResultType(&expr));
2009
2010 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002011 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00002012 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002013 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002014 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002015 ->Is<ast::type::F32>());
2016 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 4u);
dan sinclair46e959d2020-06-01 13:43:22 +00002017}
2018
2019TEST_P(IntrinsicDerivativeTest, MissingParam) {
2020 auto name = GetParam();
2021
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002022 ast::type::F32 f32;
2023 ast::type::Vector vec4(&f32, 4);
dan sinclair46e959d2020-06-01 13:43:22 +00002024
2025 // Register the global
2026 EXPECT_TRUE(td()->Determine());
2027
2028 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002029 ast::CallExpression expr(
2030 create<ast::IdentifierExpression>(mod->RegisterSymbol(name), name),
2031 call_params);
dan sinclair46e959d2020-06-01 13:43:22 +00002032 EXPECT_FALSE(td()->DetermineResultType(&expr));
2033 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
2034}
2035
2036TEST_P(IntrinsicDerivativeTest, ToomManyParams) {
2037 auto name = GetParam();
2038
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002039 ast::type::F32 f32;
2040 ast::type::Vector vec4(&f32, 4);
dan sinclair46e959d2020-06-01 13:43:22 +00002041
Ben Claytona80511e2020-12-11 13:07:02 +00002042 auto* var1 =
2043 create<ast::Variable>(Source{}, // source
2044 "ident1", // name
2045 ast::StorageClass::kNone, // storage_class
2046 &vec4, // type
2047 false, // is_const
2048 nullptr, // constructor
2049 ast::VariableDecorationList{}); // decorations
2050 auto* var2 =
2051 create<ast::Variable>(Source{}, // source
2052 "ident2", // name
2053 ast::StorageClass::kNone, // storage_class
2054 &vec4, // type
2055 false, // is_const
2056 nullptr, // constructor
2057 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002058 mod->AddGlobalVariable(var1);
2059 mod->AddGlobalVariable(var2);
dan sinclair46e959d2020-06-01 13:43:22 +00002060
2061 // Register the global
2062 EXPECT_TRUE(td()->Determine());
2063
2064 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002065 call_params.push_back(create<ast::IdentifierExpression>(
2066 mod->RegisterSymbol("ident1"), "ident1"));
2067 call_params.push_back(create<ast::IdentifierExpression>(
2068 mod->RegisterSymbol("ident2"), "ident2"));
dan sinclair46e959d2020-06-01 13:43:22 +00002069
dan sinclair6b59bf42020-12-11 19:16:13 +00002070 ast::CallExpression expr(
2071 create<ast::IdentifierExpression>(mod->RegisterSymbol(name), name),
2072 call_params);
dan sinclair46e959d2020-06-01 13:43:22 +00002073 EXPECT_FALSE(td()->DetermineResultType(&expr));
2074 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
dan sinclairb1730562020-04-07 19:26:49 +00002075}
2076INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair46e959d2020-06-01 13:43:22 +00002077 IntrinsicDerivativeTest,
2078 testing::Values("dpdx",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00002079 "dpdxCoarse",
2080 "dpdxFine",
dan sinclair46e959d2020-06-01 13:43:22 +00002081 "dpdy",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00002082 "dpdyCoarse",
2083 "dpdyFine",
dan sinclair46e959d2020-06-01 13:43:22 +00002084 "fwidth",
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00002085 "fwidthCoarse",
2086 "fwidthFine"));
dan sinclairb1730562020-04-07 19:26:49 +00002087
dan sinclair46e959d2020-06-01 13:43:22 +00002088using Intrinsic = TypeDeterminerTestWithParam<std::string>;
2089TEST_P(Intrinsic, Test) {
2090 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00002091
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002092 ast::type::Bool bool_type;
2093 ast::type::Vector vec3(&bool_type, 3);
dan sinclair8dcfd102020-04-07 19:27:00 +00002094
Ben Claytona80511e2020-12-11 13:07:02 +00002095 auto* var =
2096 create<ast::Variable>(Source{}, // source
2097 "my_var", // name
2098 ast::StorageClass::kNone, // storage_class
2099 &vec3, // type
2100 false, // is_const
2101 nullptr, // constructor
2102 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002103 mod->AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00002104
dan sinclair46e959d2020-06-01 13:43:22 +00002105 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002106 call_params.push_back(create<ast::IdentifierExpression>(
2107 mod->RegisterSymbol("my_var"), "my_var"));
dan sinclair8dcfd102020-04-07 19:27:00 +00002108
dan sinclair6b59bf42020-12-11 19:16:13 +00002109 ast::CallExpression expr(
2110 create<ast::IdentifierExpression>(mod->RegisterSymbol(name), name),
2111 call_params);
dan sinclair8dcfd102020-04-07 19:27:00 +00002112
dan sinclair8dcfd102020-04-07 19:27:00 +00002113 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00002114 EXPECT_TRUE(td()->Determine());
dan sinclair8dcfd102020-04-07 19:27:00 +00002115
dan sinclair46e959d2020-06-01 13:43:22 +00002116 EXPECT_TRUE(td()->DetermineResultType(&expr));
2117 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002118 EXPECT_TRUE(expr.result_type()->Is<ast::type::Bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00002119}
2120INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair46e959d2020-06-01 13:43:22 +00002121 Intrinsic,
2122 testing::Values("any", "all"));
dan sinclair8dcfd102020-04-07 19:27:00 +00002123
dan sinclair46e959d2020-06-01 13:43:22 +00002124using Intrinsic_FloatMethod = TypeDeterminerTestWithParam<std::string>;
2125TEST_P(Intrinsic_FloatMethod, Vector) {
2126 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00002127
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002128 ast::type::F32 f32;
2129 ast::type::Vector vec3(&f32, 3);
dan sinclair8dcfd102020-04-07 19:27:00 +00002130
Ben Claytona80511e2020-12-11 13:07:02 +00002131 auto* var =
2132 create<ast::Variable>(Source{}, // source
2133 "my_var", // name
2134 ast::StorageClass::kNone, // storage_class
2135 &vec3, // type
2136 false, // is_const
2137 nullptr, // constructor
2138 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002139 mod->AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00002140
dan sinclair46e959d2020-06-01 13:43:22 +00002141 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002142 call_params.push_back(create<ast::IdentifierExpression>(
2143 mod->RegisterSymbol("my_var"), "my_var"));
dan sinclair8dcfd102020-04-07 19:27:00 +00002144
dan sinclair6b59bf42020-12-11 19:16:13 +00002145 ast::CallExpression expr(
2146 create<ast::IdentifierExpression>(mod->RegisterSymbol(name), name),
2147 call_params);
dan sinclair8dcfd102020-04-07 19:27:00 +00002148
dan sinclair8dcfd102020-04-07 19:27:00 +00002149 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00002150 EXPECT_TRUE(td()->Determine());
dan sinclair46e959d2020-06-01 13:43:22 +00002151 EXPECT_TRUE(td()->DetermineResultType(&expr));
dan sinclair8dcfd102020-04-07 19:27:00 +00002152
dan sinclair46e959d2020-06-01 13:43:22 +00002153 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002154 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
Ben Clayton8a083ce2020-11-30 23:30:58 +00002155 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002156 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002157 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002158 ->Is<ast::type::Bool>());
2159 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair8dcfd102020-04-07 19:27:00 +00002160}
dan sinclair46e959d2020-06-01 13:43:22 +00002161
2162TEST_P(Intrinsic_FloatMethod, Scalar) {
2163 auto name = GetParam();
dan sinclair8dcfd102020-04-07 19:27:00 +00002164
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002165 ast::type::F32 f32;
dan sinclair8dcfd102020-04-07 19:27:00 +00002166
Ben Clayton321e5a92020-12-07 21:08:07 +00002167 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002168 create<ast::Variable>(Source{}, // source
2169 "my_var", // name
2170 ast::StorageClass::kNone, // storage_class
2171 &f32, // type
2172 false, // is_const
2173 nullptr, // constructor
2174 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002175 mod->AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00002176
dan sinclair46e959d2020-06-01 13:43:22 +00002177 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002178 call_params.push_back(create<ast::IdentifierExpression>(
2179 mod->RegisterSymbol("my_var"), "my_var"));
dan sinclair8dcfd102020-04-07 19:27:00 +00002180
dan sinclair6b59bf42020-12-11 19:16:13 +00002181 ast::CallExpression expr(
2182 create<ast::IdentifierExpression>(mod->RegisterSymbol(name), name),
2183 call_params);
dan sinclair8dcfd102020-04-07 19:27:00 +00002184
dan sinclair8dcfd102020-04-07 19:27:00 +00002185 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00002186 EXPECT_TRUE(td()->Determine());
dan sinclair46e959d2020-06-01 13:43:22 +00002187 EXPECT_TRUE(td()->DetermineResultType(&expr));
2188 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002189 EXPECT_TRUE(expr.result_type()->Is<ast::type::Bool>());
dan sinclair8dcfd102020-04-07 19:27:00 +00002190}
dan sinclair8dcfd102020-04-07 19:27:00 +00002191
dan sinclair46e959d2020-06-01 13:43:22 +00002192TEST_P(Intrinsic_FloatMethod, MissingParam) {
2193 auto name = GetParam();
2194
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002195 ast::type::F32 f32;
dan sinclair46e959d2020-06-01 13:43:22 +00002196
Ben Clayton321e5a92020-12-07 21:08:07 +00002197 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002198 create<ast::Variable>(Source{}, // source
2199 "my_var", // name
2200 ast::StorageClass::kNone, // storage_class
2201 &f32, // type
2202 false, // is_const
2203 nullptr, // constructor
2204 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002205 mod->AddGlobalVariable(var);
dan sinclair46e959d2020-06-01 13:43:22 +00002206
2207 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002208 ast::CallExpression expr(
2209 create<ast::IdentifierExpression>(mod->RegisterSymbol(name), name),
2210 call_params);
dan sinclair46e959d2020-06-01 13:43:22 +00002211
2212 // Register the variable
2213 EXPECT_TRUE(td()->Determine());
2214 EXPECT_FALSE(td()->DetermineResultType(&expr));
2215 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
2216}
2217
2218TEST_P(Intrinsic_FloatMethod, TooManyParams) {
2219 auto name = GetParam();
2220
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002221 ast::type::F32 f32;
dan sinclair46e959d2020-06-01 13:43:22 +00002222
Ben Clayton321e5a92020-12-07 21:08:07 +00002223 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002224 create<ast::Variable>(Source{}, // source
2225 "my_var", // name
2226 ast::StorageClass::kNone, // storage_class
2227 &f32, // type
2228 false, // is_const
2229 nullptr, // constructor
2230 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002231 mod->AddGlobalVariable(var);
dan sinclair46e959d2020-06-01 13:43:22 +00002232
2233 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002234 call_params.push_back(create<ast::IdentifierExpression>(
2235 mod->RegisterSymbol("my_var"), "my_var"));
2236 call_params.push_back(create<ast::IdentifierExpression>(
2237 mod->RegisterSymbol("my_var"), "my_var"));
dan sinclair46e959d2020-06-01 13:43:22 +00002238
dan sinclair6b59bf42020-12-11 19:16:13 +00002239 ast::CallExpression expr(
2240 create<ast::IdentifierExpression>(mod->RegisterSymbol(name), name),
2241 call_params);
dan sinclair46e959d2020-06-01 13:43:22 +00002242
2243 // Register the variable
2244 EXPECT_TRUE(td()->Determine());
2245 EXPECT_FALSE(td()->DetermineResultType(&expr));
2246 EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name);
2247}
2248INSTANTIATE_TEST_SUITE_P(
2249 TypeDeterminerTest,
2250 Intrinsic_FloatMethod,
Tomek Ponitka4e2d2482020-09-08 16:30:29 +00002251 testing::Values("isInf", "isNan", "isFinite", "isNormal"));
dan sinclair46e959d2020-06-01 13:43:22 +00002252
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002253enum class Texture { kF32, kI32, kU32 };
2254inline std::ostream& operator<<(std::ostream& out, Texture data) {
2255 if (data == Texture::kF32) {
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002256 out << "f32";
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002257 } else if (data == Texture::kI32) {
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002258 out << "i32";
2259 } else {
2260 out << "u32";
2261 }
2262 return out;
2263}
2264
2265struct TextureTestParams {
2266 ast::type::TextureDimension dim;
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002267 Texture type = Texture::kF32;
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002268 ast::type::ImageFormat format = ast::type::ImageFormat::kR16Float;
2269};
2270inline std::ostream& operator<<(std::ostream& out, TextureTestParams data) {
2271 out << data.dim << "_" << data.type;
2272 return out;
2273}
2274
2275class Intrinsic_TextureOperation
2276 : public TypeDeterminerTestWithParam<TextureTestParams> {
2277 public:
2278 std::unique_ptr<ast::type::Type> get_coords_type(
2279 ast::type::TextureDimension dim,
2280 ast::type::Type* type) {
2281 if (dim == ast::type::TextureDimension::k1d) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002282 if (type->Is<ast::type::I32>()) {
2283 return std::make_unique<ast::type::I32>();
2284 } else if (type->Is<ast::type::U32>()) {
2285 return std::make_unique<ast::type::U32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002286 } else {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002287 return std::make_unique<ast::type::F32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002288 }
2289 } else if (dim == ast::type::TextureDimension::k1dArray ||
dan sinclaird3f75ca2020-09-17 03:53:04 +00002290 dim == ast::type::TextureDimension::k2d) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002291 return std::make_unique<ast::type::Vector>(type, 2);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002292 } else if (dim == ast::type::TextureDimension::kCubeArray) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002293 return std::make_unique<ast::type::Vector>(type, 4);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002294 } else {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002295 return std::make_unique<ast::type::Vector>(type, 3);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002296 }
2297 }
2298
2299 void add_call_param(std::string name,
2300 ast::type::Type* type,
2301 ast::ExpressionList* call_params) {
Ben Clayton321e5a92020-12-07 21:08:07 +00002302 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002303 create<ast::Variable>(Source{}, // source
2304 name, // name
2305 ast::StorageClass::kNone, // storage_class
2306 type, // type
2307 false, // is_const
2308 nullptr, // constructor
2309 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002310 mod->AddGlobalVariable(var);
dan sinclair6b59bf42020-12-11 19:16:13 +00002311 call_params->push_back(
2312 create<ast::IdentifierExpression>(mod->RegisterSymbol(name), name));
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002313 }
2314
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002315 std::unique_ptr<ast::type::Type> subtype(Texture type) {
2316 if (type == Texture::kF32) {
2317 return std::make_unique<ast::type::F32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002318 }
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002319 if (type == Texture::kI32) {
2320 return std::make_unique<ast::type::I32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002321 }
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002322 return std::make_unique<ast::type::U32>();
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002323 }
2324};
2325
2326using Intrinsic_StorageTextureOperation = Intrinsic_TextureOperation;
2327TEST_P(Intrinsic_StorageTextureOperation, TextureLoadRo) {
2328 auto dim = GetParam().dim;
2329 auto type = GetParam().type;
2330 auto format = GetParam().format;
2331
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002332 ast::type::I32 i32;
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002333 auto coords_type = get_coords_type(dim, &i32);
2334
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002335 ast::type::Type* texture_type = mod->create<ast::type::StorageTexture>(
Ben Clayton7e4ffa02020-11-23 19:58:55 +00002336 dim, ast::AccessControl::kReadOnly, format);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002337
2338 ast::ExpressionList call_params;
2339
2340 add_call_param("texture", texture_type, &call_params);
2341 add_call_param("coords", coords_type.get(), &call_params);
2342 add_call_param("lod", &i32, &call_params);
2343
dan sinclair6b59bf42020-12-11 19:16:13 +00002344 ast::CallExpression expr(
2345 create<ast::IdentifierExpression>(mod->RegisterSymbol("textureLoad"),
2346 "textureLoad"),
2347 call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002348
2349 EXPECT_TRUE(td()->Determine());
2350 EXPECT_TRUE(td()->DetermineResultType(&expr));
2351
2352 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002353 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
2354 if (type == Texture::kF32) {
Ben Clayton8a083ce2020-11-30 23:30:58 +00002355 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002356 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002357 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002358 ->Is<ast::type::F32>());
2359 } else if (type == Texture::kI32) {
Ben Clayton8a083ce2020-11-30 23:30:58 +00002360 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002361 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002362 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002363 ->Is<ast::type::I32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002364 } else {
Ben Clayton8a083ce2020-11-30 23:30:58 +00002365 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002366 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002367 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002368 ->Is<ast::type::U32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002369 }
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002370 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 4u);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002371}
2372
2373INSTANTIATE_TEST_SUITE_P(
2374 TypeDeterminerTest,
2375 Intrinsic_StorageTextureOperation,
2376 testing::Values(
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002377 TextureTestParams{ast::type::TextureDimension::k1d, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002378 ast::type::ImageFormat::kR16Float},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002379 TextureTestParams{ast::type::TextureDimension::k1d, Texture::kI32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002380 ast::type::ImageFormat::kR16Sint},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002381 TextureTestParams{ast::type::TextureDimension::k1d, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002382 ast::type::ImageFormat::kR8Unorm},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002383 TextureTestParams{ast::type::TextureDimension::k1dArray, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002384 ast::type::ImageFormat::kR16Float},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002385 TextureTestParams{ast::type::TextureDimension::k1dArray, Texture::kI32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002386 ast::type::ImageFormat::kR16Sint},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002387 TextureTestParams{ast::type::TextureDimension::k1dArray, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002388 ast::type::ImageFormat::kR8Unorm},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002389 TextureTestParams{ast::type::TextureDimension::k2d, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002390 ast::type::ImageFormat::kR16Float},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002391 TextureTestParams{ast::type::TextureDimension::k2d, Texture::kI32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002392 ast::type::ImageFormat::kR16Sint},
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002393 TextureTestParams{ast::type::TextureDimension::k2d, Texture::kF32,
2394 ast::type::ImageFormat::kR8Unorm},
2395 TextureTestParams{ast::type::TextureDimension::k2dArray, Texture::kF32,
2396 ast::type::ImageFormat::kR16Float},
2397 TextureTestParams{ast::type::TextureDimension::k2dArray, Texture::kI32,
2398 ast::type::ImageFormat::kR16Sint},
2399 TextureTestParams{ast::type::TextureDimension::k2dArray, Texture::kF32,
2400 ast::type::ImageFormat::kR8Unorm},
2401 TextureTestParams{ast::type::TextureDimension::k3d, Texture::kF32,
2402 ast::type::ImageFormat::kR16Float},
2403 TextureTestParams{ast::type::TextureDimension::k3d, Texture::kI32,
2404 ast::type::ImageFormat::kR16Sint},
2405 TextureTestParams{ast::type::TextureDimension::k3d, Texture::kF32,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002406 ast::type::ImageFormat::kR8Unorm}));
2407
2408using Intrinsic_SampledTextureOperation = Intrinsic_TextureOperation;
2409TEST_P(Intrinsic_SampledTextureOperation, TextureLoadSampled) {
2410 auto dim = GetParam().dim;
2411 auto type = GetParam().type;
2412
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002413 ast::type::I32 i32;
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002414 std::unique_ptr<ast::type::Type> s = subtype(type);
2415 auto coords_type = get_coords_type(dim, &i32);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002416 auto texture_type = std::make_unique<ast::type::SampledTexture>(dim, s.get());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002417
2418 ast::ExpressionList call_params;
2419
2420 add_call_param("texture", texture_type.get(), &call_params);
2421 add_call_param("coords", coords_type.get(), &call_params);
2422 add_call_param("lod", &i32, &call_params);
2423
dan sinclair6b59bf42020-12-11 19:16:13 +00002424 ast::CallExpression expr(
2425 create<ast::IdentifierExpression>(mod->RegisterSymbol("textureLoad"),
2426 "textureLoad"),
2427 call_params);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002428
2429 EXPECT_TRUE(td()->Determine());
2430 EXPECT_TRUE(td()->DetermineResultType(&expr));
2431
2432 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002433 ASSERT_TRUE(expr.result_type()->Is<ast::type::Vector>());
2434 if (type == Texture::kF32) {
Ben Clayton8a083ce2020-11-30 23:30:58 +00002435 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002436 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002437 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002438 ->Is<ast::type::F32>());
2439 } else if (type == Texture::kI32) {
Ben Clayton8a083ce2020-11-30 23:30:58 +00002440 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002441 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002442 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002443 ->Is<ast::type::I32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002444 } else {
Ben Clayton8a083ce2020-11-30 23:30:58 +00002445 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002446 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002447 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002448 ->Is<ast::type::U32>());
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002449 }
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002450 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 4u);
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002451}
2452
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002453INSTANTIATE_TEST_SUITE_P(
2454 TypeDeterminerTest,
2455 Intrinsic_SampledTextureOperation,
Tomek Ponitka1a61fc42020-08-31 15:24:54 +00002456 testing::Values(TextureTestParams{ast::type::TextureDimension::k2d},
2457 TextureTestParams{ast::type::TextureDimension::k2dArray},
2458 TextureTestParams{ast::type::TextureDimension::kCube},
2459 TextureTestParams{
2460 ast::type::TextureDimension::kCubeArray}));
2461
dan sinclair46e959d2020-06-01 13:43:22 +00002462TEST_F(TypeDeterminerTest, Intrinsic_Dot) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002463 ast::type::F32 f32;
2464 ast::type::Vector vec3(&f32, 3);
dan sinclair8dcfd102020-04-07 19:27:00 +00002465
Ben Claytona80511e2020-12-11 13:07:02 +00002466 auto* var =
2467 create<ast::Variable>(Source{}, // source
2468 "my_var", // name
2469 ast::StorageClass::kNone, // storage_class
2470 &vec3, // type
2471 false, // is_const
2472 nullptr, // constructor
2473 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002474 mod->AddGlobalVariable(var);
dan sinclair8dcfd102020-04-07 19:27:00 +00002475
dan sinclair46e959d2020-06-01 13:43:22 +00002476 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002477 call_params.push_back(create<ast::IdentifierExpression>(
2478 mod->RegisterSymbol("my_var"), "my_var"));
2479 call_params.push_back(create<ast::IdentifierExpression>(
2480 mod->RegisterSymbol("my_var"), "my_var"));
dan sinclair8dcfd102020-04-07 19:27:00 +00002481
dan sinclair6b59bf42020-12-11 19:16:13 +00002482 ast::CallExpression expr(
2483 create<ast::IdentifierExpression>(mod->RegisterSymbol("dot"), "dot"),
2484 call_params);
dan sinclair8dcfd102020-04-07 19:27:00 +00002485
dan sinclair8dcfd102020-04-07 19:27:00 +00002486 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00002487 EXPECT_TRUE(td()->Determine());
dan sinclair46e959d2020-06-01 13:43:22 +00002488 EXPECT_TRUE(td()->DetermineResultType(&expr));
2489 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002490 EXPECT_TRUE(expr.result_type()->Is<ast::type::F32>());
dan sinclair8dcfd102020-04-07 19:27:00 +00002491}
2492
dan sinclair16a2ea12020-07-21 17:44:44 +00002493TEST_F(TypeDeterminerTest, Intrinsic_Select) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002494 ast::type::F32 f32;
2495 ast::type::Bool bool_type;
2496 ast::type::Vector vec3(&f32, 3);
2497 ast::type::Vector bool_vec3(&bool_type, 3);
dan sinclair16a2ea12020-07-21 17:44:44 +00002498
Ben Claytona80511e2020-12-11 13:07:02 +00002499 auto* var =
2500 create<ast::Variable>(Source{}, // source
2501 "my_var", // name
2502 ast::StorageClass::kNone, // storage_class
2503 &vec3, // type
2504 false, // is_const
2505 nullptr, // constructor
2506 ast::VariableDecorationList{}); // decorations
2507 auto* bool_var =
2508 create<ast::Variable>(Source{}, // source
2509 "bool_var", // name
2510 ast::StorageClass::kNone, // storage_class
2511 &bool_vec3, // type
2512 false, // is_const
2513 nullptr, // constructor
2514 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002515 mod->AddGlobalVariable(var);
2516 mod->AddGlobalVariable(bool_var);
dan sinclair16a2ea12020-07-21 17:44:44 +00002517
2518 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002519 call_params.push_back(create<ast::IdentifierExpression>(
2520 mod->RegisterSymbol("my_var"), "my_var"));
2521 call_params.push_back(create<ast::IdentifierExpression>(
2522 mod->RegisterSymbol("my_var"), "my_var"));
2523 call_params.push_back(create<ast::IdentifierExpression>(
2524 mod->RegisterSymbol("bool_var"), "bool_var"));
dan sinclair16a2ea12020-07-21 17:44:44 +00002525
dan sinclair6b59bf42020-12-11 19:16:13 +00002526 ast::CallExpression expr(create<ast::IdentifierExpression>(
2527 mod->RegisterSymbol("select"), "select"),
Ben Clayton4bfe4612020-11-16 16:41:47 +00002528 call_params);
dan sinclair16a2ea12020-07-21 17:44:44 +00002529
2530 // Register the variable
2531 EXPECT_TRUE(td()->Determine());
2532 EXPECT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
2533 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002534 EXPECT_TRUE(expr.result_type()->Is<ast::type::Vector>());
2535 EXPECT_EQ(expr.result_type()->As<ast::type::Vector>()->size(), 3u);
Ben Clayton8a083ce2020-11-30 23:30:58 +00002536 EXPECT_TRUE(expr.result_type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002537 ->As<ast::type::Vector>()
Ben Clayton8a083ce2020-11-30 23:30:58 +00002538 ->type()
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002539 ->Is<ast::type::F32>());
dan sinclair16a2ea12020-07-21 17:44:44 +00002540}
2541
2542TEST_F(TypeDeterminerTest, Intrinsic_Select_TooFewParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002543 ast::type::F32 f32;
2544 ast::type::Vector vec3(&f32, 3);
dan sinclair16a2ea12020-07-21 17:44:44 +00002545
Ben Clayton321e5a92020-12-07 21:08:07 +00002546 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002547 create<ast::Variable>(Source{}, // source
2548 "v", // name
2549 ast::StorageClass::kNone, // storage_class
2550 &vec3, // type
2551 false, // is_const
2552 nullptr, // constructor
2553 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002554 mod->AddGlobalVariable(var);
dan sinclair16a2ea12020-07-21 17:44:44 +00002555
2556 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002557 call_params.push_back(
2558 create<ast::IdentifierExpression>(mod->RegisterSymbol("v"), "v"));
dan sinclair16a2ea12020-07-21 17:44:44 +00002559
dan sinclair6b59bf42020-12-11 19:16:13 +00002560 ast::CallExpression expr(create<ast::IdentifierExpression>(
2561 mod->RegisterSymbol("select"), "select"),
Ben Clayton4bfe4612020-11-16 16:41:47 +00002562 call_params);
dan sinclair16a2ea12020-07-21 17:44:44 +00002563
2564 // Register the variable
2565 EXPECT_TRUE(td()->Determine());
2566 EXPECT_FALSE(td()->DetermineResultType(&expr));
2567 EXPECT_EQ(td()->error(),
2568 "incorrect number of parameters for select expected 3 got 1");
2569}
2570
2571TEST_F(TypeDeterminerTest, Intrinsic_Select_TooManyParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002572 ast::type::F32 f32;
2573 ast::type::Vector vec3(&f32, 3);
dan sinclair16a2ea12020-07-21 17:44:44 +00002574
Ben Clayton321e5a92020-12-07 21:08:07 +00002575 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002576 create<ast::Variable>(Source{}, // source
2577 "v", // name
2578 ast::StorageClass::kNone, // storage_class
2579 &vec3, // type
2580 false, // is_const
2581 nullptr, // constructor
2582 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002583 mod->AddGlobalVariable(var);
dan sinclair16a2ea12020-07-21 17:44:44 +00002584
2585 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002586 call_params.push_back(
2587 create<ast::IdentifierExpression>(mod->RegisterSymbol("v"), "v"));
2588 call_params.push_back(
2589 create<ast::IdentifierExpression>(mod->RegisterSymbol("v"), "v"));
2590 call_params.push_back(
2591 create<ast::IdentifierExpression>(mod->RegisterSymbol("v"), "v"));
2592 call_params.push_back(
2593 create<ast::IdentifierExpression>(mod->RegisterSymbol("v"), "v"));
dan sinclair16a2ea12020-07-21 17:44:44 +00002594
dan sinclair6b59bf42020-12-11 19:16:13 +00002595 ast::CallExpression expr(create<ast::IdentifierExpression>(
2596 mod->RegisterSymbol("select"), "select"),
Ben Clayton4bfe4612020-11-16 16:41:47 +00002597 call_params);
dan sinclair16a2ea12020-07-21 17:44:44 +00002598
2599 // Register the variable
2600 EXPECT_TRUE(td()->Determine());
2601 EXPECT_FALSE(td()->DetermineResultType(&expr));
2602 EXPECT_EQ(td()->error(),
2603 "incorrect number of parameters for select expected 3 got 4");
2604}
2605
dan sinclair46e959d2020-06-01 13:43:22 +00002606TEST_F(TypeDeterminerTest, Intrinsic_OuterProduct) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002607 ast::type::F32 f32;
2608 ast::type::Vector vec3(&f32, 3);
2609 ast::type::Vector vec2(&f32, 2);
dan sinclair8dcfd102020-04-07 19:27:00 +00002610
Ben Clayton321e5a92020-12-07 21:08:07 +00002611 auto* var1 =
Ben Claytona80511e2020-12-11 13:07:02 +00002612 create<ast::Variable>(Source{}, // source
2613 "v3", // name
2614 ast::StorageClass::kNone, // storage_class
2615 &vec3, // type
2616 false, // is_const
2617 nullptr, // constructor
2618 ast::VariableDecorationList{}); // decorations
Ben Clayton321e5a92020-12-07 21:08:07 +00002619 auto* var2 =
Ben Claytona80511e2020-12-11 13:07:02 +00002620 create<ast::Variable>(Source{}, // source
2621 "v2", // name
2622 ast::StorageClass::kNone, // storage_class
2623 &vec2, // type
2624 false, // is_const
2625 nullptr, // constructor
2626 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002627 mod->AddGlobalVariable(var1);
2628 mod->AddGlobalVariable(var2);
dan sinclair8dcfd102020-04-07 19:27:00 +00002629
dan sinclair46e959d2020-06-01 13:43:22 +00002630 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002631 call_params.push_back(
2632 create<ast::IdentifierExpression>(mod->RegisterSymbol("v3"), "v3"));
2633 call_params.push_back(
2634 create<ast::IdentifierExpression>(mod->RegisterSymbol("v2"), "v2"));
dan sinclair8dcfd102020-04-07 19:27:00 +00002635
dan sinclair6b59bf42020-12-11 19:16:13 +00002636 ast::CallExpression expr(
2637 create<ast::IdentifierExpression>(mod->RegisterSymbol("outerProduct"),
2638 "outerProduct"),
2639 call_params);
dan sinclair8dcfd102020-04-07 19:27:00 +00002640
dan sinclair8dcfd102020-04-07 19:27:00 +00002641 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00002642 EXPECT_TRUE(td()->Determine());
dan sinclair46e959d2020-06-01 13:43:22 +00002643 EXPECT_TRUE(td()->DetermineResultType(&expr));
dan sinclair8dcfd102020-04-07 19:27:00 +00002644
dan sinclair46e959d2020-06-01 13:43:22 +00002645 ASSERT_NE(expr.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002646 ASSERT_TRUE(expr.result_type()->Is<ast::type::Matrix>());
dan sinclair46e959d2020-06-01 13:43:22 +00002647
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002648 auto* mat = expr.result_type()->As<ast::type::Matrix>();
2649 EXPECT_TRUE(mat->type()->Is<ast::type::F32>());
Ryan Harrison0a196c12020-04-17 13:18:20 +00002650 EXPECT_EQ(mat->rows(), 3u);
2651 EXPECT_EQ(mat->columns(), 2u);
dan sinclair8dcfd102020-04-07 19:27:00 +00002652}
2653
dan sinclair46e959d2020-06-01 13:43:22 +00002654TEST_F(TypeDeterminerTest, Intrinsic_OuterProduct_TooFewParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002655 ast::type::F32 f32;
2656 ast::type::Vector vec3(&f32, 3);
2657 ast::type::Vector vec2(&f32, 2);
dan sinclair46e959d2020-06-01 13:43:22 +00002658
Ben Clayton321e5a92020-12-07 21:08:07 +00002659 auto* var2 =
Ben Claytona80511e2020-12-11 13:07:02 +00002660 create<ast::Variable>(Source{}, // source
2661 "v2", // name
2662 ast::StorageClass::kNone, // storage_class
2663 &vec2, // type
2664 false, // is_const
2665 nullptr, // constructor
2666 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002667 mod->AddGlobalVariable(var2);
dan sinclair46e959d2020-06-01 13:43:22 +00002668
2669 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002670 call_params.push_back(
2671 create<ast::IdentifierExpression>(mod->RegisterSymbol("v2"), "v2"));
dan sinclair46e959d2020-06-01 13:43:22 +00002672
dan sinclair6b59bf42020-12-11 19:16:13 +00002673 ast::CallExpression expr(
2674 create<ast::IdentifierExpression>(mod->RegisterSymbol("outerProduct"),
2675 "outerProduct"),
2676 call_params);
dan sinclair46e959d2020-06-01 13:43:22 +00002677
2678 // Register the variable
2679 EXPECT_TRUE(td()->Determine());
2680 EXPECT_FALSE(td()->DetermineResultType(&expr));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002681 EXPECT_EQ(td()->error(), "incorrect number of parameters for outerProduct");
dan sinclair46e959d2020-06-01 13:43:22 +00002682}
2683
2684TEST_F(TypeDeterminerTest, Intrinsic_OuterProduct_TooManyParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002685 ast::type::F32 f32;
2686 ast::type::Vector vec3(&f32, 3);
2687 ast::type::Vector vec2(&f32, 2);
dan sinclair46e959d2020-06-01 13:43:22 +00002688
Ben Clayton321e5a92020-12-07 21:08:07 +00002689 auto* var2 =
Ben Claytona80511e2020-12-11 13:07:02 +00002690 create<ast::Variable>(Source{}, // source
2691 "v2", // name
2692 ast::StorageClass::kNone, // storage_class
2693 &vec2, // type
2694 false, // is_const
2695 nullptr, // constructor
2696 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002697 mod->AddGlobalVariable(var2);
dan sinclair46e959d2020-06-01 13:43:22 +00002698
2699 ast::ExpressionList call_params;
dan sinclair6b59bf42020-12-11 19:16:13 +00002700 call_params.push_back(
2701 create<ast::IdentifierExpression>(mod->RegisterSymbol("v2"), "v2"));
2702 call_params.push_back(
2703 create<ast::IdentifierExpression>(mod->RegisterSymbol("v2"), "v2"));
2704 call_params.push_back(
2705 create<ast::IdentifierExpression>(mod->RegisterSymbol("v2"), "v2"));
dan sinclair46e959d2020-06-01 13:43:22 +00002706
dan sinclair6b59bf42020-12-11 19:16:13 +00002707 ast::CallExpression expr(
2708 create<ast::IdentifierExpression>(mod->RegisterSymbol("outerProduct"),
2709 "outerProduct"),
2710 call_params);
dan sinclair46e959d2020-06-01 13:43:22 +00002711
2712 // Register the variable
2713 EXPECT_TRUE(td()->Determine());
2714 EXPECT_FALSE(td()->DetermineResultType(&expr));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002715 EXPECT_EQ(td()->error(), "incorrect number of parameters for outerProduct");
dan sinclair46e959d2020-06-01 13:43:22 +00002716}
2717
dan sinclaircd077b02020-04-20 14:19:04 +00002718using UnaryOpExpressionTest = TypeDeterminerTestWithParam<ast::UnaryOp>;
dan sinclair0e257622020-04-07 19:27:11 +00002719TEST_P(UnaryOpExpressionTest, Expr_UnaryOp) {
2720 auto op = GetParam();
2721
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002722 ast::type::F32 f32;
dan sinclair0e257622020-04-07 19:27:11 +00002723
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002724 ast::type::Vector vec4(&f32, 4);
dan sinclair0e257622020-04-07 19:27:11 +00002725
Ben Clayton321e5a92020-12-07 21:08:07 +00002726 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002727 create<ast::Variable>(Source{}, // source
2728 "ident", // name
2729 ast::StorageClass::kNone, // storage_class
2730 &vec4, // type
2731 false, // is_const
2732 nullptr, // constructor
2733 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00002734 mod->AddGlobalVariable(var);
dan sinclair0e257622020-04-07 19:27:11 +00002735
2736 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00002737 EXPECT_TRUE(td()->Determine());
dan sinclair0e257622020-04-07 19:27:11 +00002738
dan sinclair6b59bf42020-12-11 19:16:13 +00002739 ast::UnaryOpExpression der(op, create<ast::IdentifierExpression>(
2740 mod->RegisterSymbol("ident"), "ident"));
dan sinclaircd077b02020-04-20 14:19:04 +00002741 EXPECT_TRUE(td()->DetermineResultType(&der));
dan sinclair0e257622020-04-07 19:27:11 +00002742 ASSERT_NE(der.result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002743 ASSERT_TRUE(der.result_type()->Is<ast::type::Vector>());
2744 EXPECT_TRUE(
2745 der.result_type()->As<ast::type::Vector>()->type()->Is<ast::type::F32>());
2746 EXPECT_EQ(der.result_type()->As<ast::type::Vector>()->size(), 4u);
dan sinclair0e257622020-04-07 19:27:11 +00002747}
2748INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
2749 UnaryOpExpressionTest,
2750 testing::Values(ast::UnaryOp::kNegation,
2751 ast::UnaryOp::kNot));
2752
dan sinclairee8ae042020-04-08 19:58:20 +00002753TEST_F(TypeDeterminerTest, StorageClass_SetsIfMissing) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002754 ast::type::I32 i32;
dan sinclairee8ae042020-04-08 19:58:20 +00002755
Ben Clayton321e5a92020-12-07 21:08:07 +00002756 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002757 create<ast::Variable>(Source{}, // source
2758 "var", // name
2759 ast::StorageClass::kNone, // storage_class
2760 &i32, // type
2761 false, // is_const
2762 nullptr, // constructor
2763 ast::VariableDecorationList{}); // decorations
Ben Clayton4bfe4612020-11-16 16:41:47 +00002764 auto* stmt = create<ast::VariableDeclStatement>(var);
dan sinclairee8ae042020-04-08 19:58:20 +00002765
Ben Claytonb053acf2020-11-16 16:31:07 +00002766 auto* body = create<ast::BlockStatement>();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002767 body->append(stmt);
dan sinclaira41132f2020-12-11 18:24:53 +00002768 auto* func = create<ast::Function>(Source{}, mod->RegisterSymbol("func"),
2769 "func", ast::VariableList{}, &i32, body,
2770 ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00002771
Ben Clayton3ea3c992020-11-18 21:19:22 +00002772 mod->AddFunction(func);
dan sinclairee8ae042020-04-08 19:58:20 +00002773
dan sinclairb950e802020-04-20 14:20:01 +00002774 EXPECT_TRUE(td()->Determine()) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002775 EXPECT_EQ(var->storage_class(), ast::StorageClass::kFunction);
dan sinclairee8ae042020-04-08 19:58:20 +00002776}
2777
2778TEST_F(TypeDeterminerTest, StorageClass_DoesNotSetOnConst) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002779 ast::type::I32 i32;
dan sinclairee8ae042020-04-08 19:58:20 +00002780
Ben Clayton321e5a92020-12-07 21:08:07 +00002781 auto* var =
Ben Claytona80511e2020-12-11 13:07:02 +00002782 create<ast::Variable>(Source{}, // source
2783 "var", // name
2784 ast::StorageClass::kNone, // storage_class
2785 &i32, // type
2786 true, // is_const
2787 nullptr, // constructor
2788 ast::VariableDecorationList{}); // decorations
Ben Clayton4bfe4612020-11-16 16:41:47 +00002789 auto* stmt = create<ast::VariableDeclStatement>(var);
dan sinclairee8ae042020-04-08 19:58:20 +00002790
Ben Claytonb053acf2020-11-16 16:31:07 +00002791 auto* body = create<ast::BlockStatement>();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002792 body->append(stmt);
dan sinclaira41132f2020-12-11 18:24:53 +00002793 auto* func = create<ast::Function>(Source{}, mod->RegisterSymbol("func"),
2794 "func", ast::VariableList{}, &i32, body,
2795 ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00002796
Ben Clayton3ea3c992020-11-18 21:19:22 +00002797 mod->AddFunction(func);
dan sinclairee8ae042020-04-08 19:58:20 +00002798
dan sinclairb950e802020-04-20 14:20:01 +00002799 EXPECT_TRUE(td()->Determine()) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002800 EXPECT_EQ(var->storage_class(), ast::StorageClass::kNone);
dan sinclairee8ae042020-04-08 19:58:20 +00002801}
2802
2803TEST_F(TypeDeterminerTest, StorageClass_NonFunctionClassError) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002804 ast::type::I32 i32;
dan sinclairee8ae042020-04-08 19:58:20 +00002805
Ben Claytona80511e2020-12-11 13:07:02 +00002806 auto* var =
2807 create<ast::Variable>(Source{}, // source
2808 "var", // name
2809 ast::StorageClass::kWorkgroup, // storage_class
2810 &i32, // type
2811 false, // is_const
2812 nullptr, // constructor
2813 ast::VariableDecorationList{}); // decorations
Ben Clayton4bfe4612020-11-16 16:41:47 +00002814 auto* stmt = create<ast::VariableDeclStatement>(var);
dan sinclairee8ae042020-04-08 19:58:20 +00002815
Ben Claytonb053acf2020-11-16 16:31:07 +00002816 auto* body = create<ast::BlockStatement>();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002817 body->append(stmt);
dan sinclaira41132f2020-12-11 18:24:53 +00002818 auto* func = create<ast::Function>(Source{}, mod->RegisterSymbol("func"),
2819 "func", ast::VariableList{}, &i32, body,
2820 ast::FunctionDecorationList{});
dan sinclairee8ae042020-04-08 19:58:20 +00002821
Ben Clayton3ea3c992020-11-18 21:19:22 +00002822 mod->AddFunction(func);
dan sinclairee8ae042020-04-08 19:58:20 +00002823
dan sinclairb950e802020-04-20 14:20:01 +00002824 EXPECT_FALSE(td()->Determine());
dan sinclairee8ae042020-04-08 19:58:20 +00002825 EXPECT_EQ(td()->error(),
2826 "function variable has a non-function storage class");
2827}
2828
dan sinclairb4fee2f2020-09-22 19:42:13 +00002829struct IntrinsicData {
dan sinclairca1723e2020-04-20 15:47:55 +00002830 const char* name;
dan sinclairb4fee2f2020-09-22 19:42:13 +00002831 ast::Intrinsic intrinsic;
dan sinclairca1723e2020-04-20 15:47:55 +00002832};
dan sinclairb4fee2f2020-09-22 19:42:13 +00002833inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
dan sinclairca1723e2020-04-20 15:47:55 +00002834 out << data.name;
2835 return out;
2836}
dan sinclairb4fee2f2020-09-22 19:42:13 +00002837using IntrinsicDataTest = TypeDeterminerTestWithParam<IntrinsicData>;
2838TEST_P(IntrinsicDataTest, Lookup) {
2839 auto param = GetParam();
dan sinclairca1723e2020-04-20 15:47:55 +00002840
dan sinclair6b59bf42020-12-11 19:16:13 +00002841 ast::IdentifierExpression ident(mod->RegisterSymbol(param.name), param.name);
dan sinclairff267ca2020-10-14 18:26:31 +00002842 EXPECT_TRUE(td()->SetIntrinsicIfNeeded(&ident));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002843 EXPECT_EQ(ident.intrinsic(), param.intrinsic);
2844 EXPECT_TRUE(ident.IsIntrinsic());
2845}
2846INSTANTIATE_TEST_SUITE_P(
2847 TypeDeterminerTest,
2848 IntrinsicDataTest,
2849 testing::Values(
2850 IntrinsicData{"abs", ast::Intrinsic::kAbs},
2851 IntrinsicData{"acos", ast::Intrinsic::kAcos},
2852 IntrinsicData{"all", ast::Intrinsic::kAll},
2853 IntrinsicData{"any", ast::Intrinsic::kAny},
dan sinclair007dc422020-10-08 17:01:55 +00002854 IntrinsicData{"arrayLength", ast::Intrinsic::kArrayLength},
dan sinclairb4fee2f2020-09-22 19:42:13 +00002855 IntrinsicData{"asin", ast::Intrinsic::kAsin},
2856 IntrinsicData{"atan", ast::Intrinsic::kAtan},
2857 IntrinsicData{"atan2", ast::Intrinsic::kAtan2},
2858 IntrinsicData{"ceil", ast::Intrinsic::kCeil},
2859 IntrinsicData{"clamp", ast::Intrinsic::kClamp},
2860 IntrinsicData{"cos", ast::Intrinsic::kCos},
2861 IntrinsicData{"cosh", ast::Intrinsic::kCosh},
2862 IntrinsicData{"countOneBits", ast::Intrinsic::kCountOneBits},
2863 IntrinsicData{"cross", ast::Intrinsic::kCross},
2864 IntrinsicData{"determinant", ast::Intrinsic::kDeterminant},
2865 IntrinsicData{"distance", ast::Intrinsic::kDistance},
2866 IntrinsicData{"dot", ast::Intrinsic::kDot},
2867 IntrinsicData{"dpdx", ast::Intrinsic::kDpdx},
2868 IntrinsicData{"dpdxCoarse", ast::Intrinsic::kDpdxCoarse},
2869 IntrinsicData{"dpdxFine", ast::Intrinsic::kDpdxFine},
2870 IntrinsicData{"dpdy", ast::Intrinsic::kDpdy},
2871 IntrinsicData{"dpdyCoarse", ast::Intrinsic::kDpdyCoarse},
2872 IntrinsicData{"dpdyFine", ast::Intrinsic::kDpdyFine},
2873 IntrinsicData{"exp", ast::Intrinsic::kExp},
2874 IntrinsicData{"exp2", ast::Intrinsic::kExp2},
2875 IntrinsicData{"faceForward", ast::Intrinsic::kFaceForward},
2876 IntrinsicData{"floor", ast::Intrinsic::kFloor},
2877 IntrinsicData{"fma", ast::Intrinsic::kFma},
2878 IntrinsicData{"fract", ast::Intrinsic::kFract},
2879 IntrinsicData{"frexp", ast::Intrinsic::kFrexp},
2880 IntrinsicData{"fwidth", ast::Intrinsic::kFwidth},
2881 IntrinsicData{"fwidthCoarse", ast::Intrinsic::kFwidthCoarse},
2882 IntrinsicData{"fwidthFine", ast::Intrinsic::kFwidthFine},
2883 IntrinsicData{"inverseSqrt", ast::Intrinsic::kInverseSqrt},
2884 IntrinsicData{"isFinite", ast::Intrinsic::kIsFinite},
2885 IntrinsicData{"isInf", ast::Intrinsic::kIsInf},
2886 IntrinsicData{"isNan", ast::Intrinsic::kIsNan},
2887 IntrinsicData{"isNormal", ast::Intrinsic::kIsNormal},
2888 IntrinsicData{"ldexp", ast::Intrinsic::kLdexp},
2889 IntrinsicData{"length", ast::Intrinsic::kLength},
2890 IntrinsicData{"log", ast::Intrinsic::kLog},
2891 IntrinsicData{"log2", ast::Intrinsic::kLog2},
2892 IntrinsicData{"max", ast::Intrinsic::kMax},
2893 IntrinsicData{"min", ast::Intrinsic::kMin},
2894 IntrinsicData{"mix", ast::Intrinsic::kMix},
2895 IntrinsicData{"modf", ast::Intrinsic::kModf},
2896 IntrinsicData{"normalize", ast::Intrinsic::kNormalize},
2897 IntrinsicData{"outerProduct", ast::Intrinsic::kOuterProduct},
2898 IntrinsicData{"pow", ast::Intrinsic::kPow},
2899 IntrinsicData{"reflect", ast::Intrinsic::kReflect},
2900 IntrinsicData{"reverseBits", ast::Intrinsic::kReverseBits},
2901 IntrinsicData{"round", ast::Intrinsic::kRound},
2902 IntrinsicData{"select", ast::Intrinsic::kSelect},
2903 IntrinsicData{"sign", ast::Intrinsic::kSign},
2904 IntrinsicData{"sin", ast::Intrinsic::kSin},
2905 IntrinsicData{"sinh", ast::Intrinsic::kSinh},
2906 IntrinsicData{"smoothStep", ast::Intrinsic::kSmoothStep},
2907 IntrinsicData{"sqrt", ast::Intrinsic::kSqrt},
2908 IntrinsicData{"step", ast::Intrinsic::kStep},
2909 IntrinsicData{"tan", ast::Intrinsic::kTan},
2910 IntrinsicData{"tanh", ast::Intrinsic::kTanh},
2911 IntrinsicData{"textureLoad", ast::Intrinsic::kTextureLoad},
2912 IntrinsicData{"textureSample", ast::Intrinsic::kTextureSample},
2913 IntrinsicData{"textureSampleBias", ast::Intrinsic::kTextureSampleBias},
2914 IntrinsicData{"textureSampleCompare",
2915 ast::Intrinsic::kTextureSampleCompare},
Ben Clayton3ea3c992020-11-18 21:19:22 +00002916 IntrinsicData{"textureSampleGrad", ast::Intrinsic::kTextureSampleGrad},
dan sinclairb4fee2f2020-09-22 19:42:13 +00002917 IntrinsicData{"textureSampleLevel",
2918 ast::Intrinsic::kTextureSampleLevel},
2919 IntrinsicData{"trunc", ast::Intrinsic::kTrunc}));
2920
2921TEST_F(TypeDeterminerTest, IntrinsicNotSetIfNotMatched) {
dan sinclair6b59bf42020-12-11 19:16:13 +00002922 ast::IdentifierExpression ident(mod->RegisterSymbol("not_intrinsic"),
2923 "not_intrinsic");
dan sinclairff267ca2020-10-14 18:26:31 +00002924 EXPECT_FALSE(td()->SetIntrinsicIfNeeded(&ident));
dan sinclairb4fee2f2020-09-22 19:42:13 +00002925 EXPECT_EQ(ident.intrinsic(), ast::Intrinsic::kNone);
2926 EXPECT_FALSE(ident.IsIntrinsic());
2927}
2928
2929using ImportData_SingleParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair37d62c92020-04-21 12:55:06 +00002930TEST_P(ImportData_SingleParamTest, Scalar) {
dan sinclairca1723e2020-04-20 15:47:55 +00002931 auto param = GetParam();
2932
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002933 ast::type::F32 f32;
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002934
2935 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00002936 params.push_back(create<ast::ScalarConstructorExpression>(
2937 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002938
dan sinclair6b59bf42020-12-11 19:16:13 +00002939 auto* ident = create<ast::IdentifierExpression>(
2940 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00002941
2942 ast::CallExpression call(ident, params);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002943
dan sinclairb4fee2f2020-09-22 19:42:13 +00002944 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002945 ASSERT_NE(ident->result_type(), nullptr);
2946 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002947}
2948
dan sinclair37d62c92020-04-21 12:55:06 +00002949TEST_P(ImportData_SingleParamTest, Vector) {
dan sinclairca1723e2020-04-20 15:47:55 +00002950 auto param = GetParam();
2951
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002952 ast::type::F32 f32;
2953 ast::type::Vector vec(&f32, 3);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002954
2955 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00002956 vals.push_back(create<ast::ScalarConstructorExpression>(
2957 create<ast::FloatLiteral>(&f32, 1.0f)));
2958 vals.push_back(create<ast::ScalarConstructorExpression>(
2959 create<ast::FloatLiteral>(&f32, 1.0f)));
2960 vals.push_back(create<ast::ScalarConstructorExpression>(
2961 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002962
2963 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00002964 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals));
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002965
dan sinclair6b59bf42020-12-11 19:16:13 +00002966 auto* ident = create<ast::IdentifierExpression>(
2967 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00002968
2969 ast::CallExpression call(ident, params);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002970
dan sinclairb4fee2f2020-09-22 19:42:13 +00002971 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00002972 ASSERT_NE(ident->result_type(), nullptr);
2973 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002974 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002975}
2976
dan sinclair37d62c92020-04-21 12:55:06 +00002977TEST_P(ImportData_SingleParamTest, Error_Integer) {
dan sinclairca1723e2020-04-20 15:47:55 +00002978 auto param = GetParam();
2979
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00002980 ast::type::I32 i32;
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002981
2982 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00002983 params.push_back(create<ast::ScalarConstructorExpression>(
2984 create<ast::SintLiteral>(&i32, 1)));
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002985
dan sinclair6b59bf42020-12-11 19:16:13 +00002986 auto* ident = create<ast::IdentifierExpression>(
2987 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00002988 ast::CallExpression call(ident, params);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002989
dan sinclairb4fee2f2020-09-22 19:42:13 +00002990 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair53352042020-06-08 18:49:31 +00002991 EXPECT_EQ(td()->error(),
2992 std::string("incorrect type for ") + param.name +
2993 ". Requires float scalar or float vector values");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002994}
2995
dan sinclair37d62c92020-04-21 12:55:06 +00002996TEST_P(ImportData_SingleParamTest, Error_NoParams) {
dan sinclairca1723e2020-04-20 15:47:55 +00002997 auto param = GetParam();
2998
dan sinclairfd5d4ca2020-04-20 15:46:18 +00002999 ast::ExpressionList params;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003000
dan sinclair6b59bf42020-12-11 19:16:13 +00003001 auto* ident = create<ast::IdentifierExpression>(
3002 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003003 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003004
3005 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclairca1723e2020-04-20 15:47:55 +00003006 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
3007 param.name + ". Expected 1 got 0");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003008}
3009
dan sinclair37d62c92020-04-21 12:55:06 +00003010TEST_P(ImportData_SingleParamTest, Error_MultipleParams) {
dan sinclairca1723e2020-04-20 15:47:55 +00003011 auto param = GetParam();
3012
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003013 ast::type::F32 f32;
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003014 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003015 params.push_back(create<ast::ScalarConstructorExpression>(
3016 create<ast::FloatLiteral>(&f32, 1.f)));
3017 params.push_back(create<ast::ScalarConstructorExpression>(
3018 create<ast::FloatLiteral>(&f32, 1.f)));
3019 params.push_back(create<ast::ScalarConstructorExpression>(
3020 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003021
dan sinclair6b59bf42020-12-11 19:16:13 +00003022 auto* ident = create<ast::IdentifierExpression>(
3023 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003024 ast::CallExpression call(ident, params);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003025
dan sinclairb4fee2f2020-09-22 19:42:13 +00003026 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclairca1723e2020-04-20 15:47:55 +00003027 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
3028 param.name + ". Expected 1 got 3");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00003029}
3030
dan sinclaira49328f2020-04-20 15:49:50 +00003031INSTANTIATE_TEST_SUITE_P(
3032 TypeDeterminerTest,
dan sinclair37d62c92020-04-21 12:55:06 +00003033 ImportData_SingleParamTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00003034 testing::Values(IntrinsicData{"acos", ast::Intrinsic::kAcos},
3035 IntrinsicData{"asin", ast::Intrinsic::kAsin},
3036 IntrinsicData{"atan", ast::Intrinsic::kAtan},
3037 IntrinsicData{"ceil", ast::Intrinsic::kCeil},
3038 IntrinsicData{"cos", ast::Intrinsic::kCos},
3039 IntrinsicData{"cosh", ast::Intrinsic::kCosh},
3040 IntrinsicData{"exp", ast::Intrinsic::kExp},
3041 IntrinsicData{"exp2", ast::Intrinsic::kExp2},
3042 IntrinsicData{"floor", ast::Intrinsic::kFloor},
3043 IntrinsicData{"fract", ast::Intrinsic::kFract},
3044 IntrinsicData{"inverseSqrt", ast::Intrinsic::kInverseSqrt},
3045 IntrinsicData{"log", ast::Intrinsic::kLog},
3046 IntrinsicData{"log2", ast::Intrinsic::kLog2},
3047 IntrinsicData{"normalize", ast::Intrinsic::kNormalize},
3048 IntrinsicData{"round", ast::Intrinsic::kRound},
3049 IntrinsicData{"sign", ast::Intrinsic::kSign},
3050 IntrinsicData{"sin", ast::Intrinsic::kSin},
3051 IntrinsicData{"sinh", ast::Intrinsic::kSinh},
3052 IntrinsicData{"sqrt", ast::Intrinsic::kSqrt},
3053 IntrinsicData{"tan", ast::Intrinsic::kTan},
3054 IntrinsicData{"tanh", ast::Intrinsic::kTanh},
3055 IntrinsicData{"trunc", ast::Intrinsic::kTrunc}));
3056
3057using ImportData_SingleParam_FloatOrInt_Test =
3058 TypeDeterminerTestWithParam<IntrinsicData>;
3059TEST_P(ImportData_SingleParam_FloatOrInt_Test, Float_Scalar) {
3060 auto param = GetParam();
3061
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003062 ast::type::F32 f32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003063
3064 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003065 params.push_back(create<ast::ScalarConstructorExpression>(
3066 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003067
dan sinclair6b59bf42020-12-11 19:16:13 +00003068 auto* ident = create<ast::IdentifierExpression>(
3069 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003070
3071 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003072
3073 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003074 ASSERT_NE(ident->result_type(), nullptr);
3075 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclairb4fee2f2020-09-22 19:42:13 +00003076}
3077
3078TEST_P(ImportData_SingleParam_FloatOrInt_Test, Float_Vector) {
3079 auto param = GetParam();
3080
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003081 ast::type::F32 f32;
3082 ast::type::Vector vec(&f32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003083
3084 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00003085 vals.push_back(create<ast::ScalarConstructorExpression>(
3086 create<ast::FloatLiteral>(&f32, 1.0f)));
3087 vals.push_back(create<ast::ScalarConstructorExpression>(
3088 create<ast::FloatLiteral>(&f32, 1.0f)));
3089 vals.push_back(create<ast::ScalarConstructorExpression>(
3090 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003091
3092 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00003093 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003094
dan sinclair6b59bf42020-12-11 19:16:13 +00003095 auto* ident = create<ast::IdentifierExpression>(
3096 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003097
3098 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003099
3100 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003101 ASSERT_NE(ident->result_type(), nullptr);
3102 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003103 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003104}
3105
3106TEST_P(ImportData_SingleParam_FloatOrInt_Test, Sint_Scalar) {
3107 auto param = GetParam();
3108
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003109 ast::type::I32 i32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003110
3111 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003112 params.push_back(create<ast::ScalarConstructorExpression>(
3113 create<ast::SintLiteral>(&i32, -11)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003114
dan sinclair6b59bf42020-12-11 19:16:13 +00003115 auto* ident = create<ast::IdentifierExpression>(
3116 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003117
3118 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003119
3120 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003121 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003122 EXPECT_TRUE(ident->result_type()->Is<ast::type::I32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00003123}
3124
3125TEST_P(ImportData_SingleParam_FloatOrInt_Test, Sint_Vector) {
3126 auto param = GetParam();
3127
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003128 ast::type::I32 i32;
3129 ast::type::Vector vec(&i32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003130
3131 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00003132 vals.push_back(create<ast::ScalarConstructorExpression>(
3133 create<ast::SintLiteral>(&i32, 1)));
3134 vals.push_back(create<ast::ScalarConstructorExpression>(
3135 create<ast::SintLiteral>(&i32, 1)));
3136 vals.push_back(create<ast::ScalarConstructorExpression>(
3137 create<ast::SintLiteral>(&i32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003138
3139 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00003140 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003141
dan sinclair6b59bf42020-12-11 19:16:13 +00003142 auto* ident = create<ast::IdentifierExpression>(
3143 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003144
3145 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003146
3147 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003148 ASSERT_NE(ident->result_type(), nullptr);
3149 EXPECT_TRUE(ident->result_type()->is_signed_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003150 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003151}
3152
3153TEST_P(ImportData_SingleParam_FloatOrInt_Test, Uint_Scalar) {
3154 auto param = GetParam();
3155
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003156 ast::type::U32 u32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003157
3158 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003159 params.push_back(create<ast::ScalarConstructorExpression>(
3160 create<ast::UintLiteral>(&u32, 1)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003161
dan sinclair6b59bf42020-12-11 19:16:13 +00003162 auto* ident = create<ast::IdentifierExpression>(
3163 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003164
3165 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003166
3167 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003168 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003169 EXPECT_TRUE(ident->result_type()->Is<ast::type::U32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00003170}
3171
3172TEST_P(ImportData_SingleParam_FloatOrInt_Test, Uint_Vector) {
3173 auto param = GetParam();
3174
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003175 ast::type::U32 u32;
3176 ast::type::Vector vec(&u32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003177
3178 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00003179 vals.push_back(create<ast::ScalarConstructorExpression>(
3180 create<ast::UintLiteral>(&u32, 1.0f)));
3181 vals.push_back(create<ast::ScalarConstructorExpression>(
3182 create<ast::UintLiteral>(&u32, 1.0f)));
3183 vals.push_back(create<ast::ScalarConstructorExpression>(
3184 create<ast::UintLiteral>(&u32, 3.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003185
3186 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00003187 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003188
dan sinclair6b59bf42020-12-11 19:16:13 +00003189 auto* ident = create<ast::IdentifierExpression>(
3190 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003191
3192 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003193
3194 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003195 ASSERT_NE(ident->result_type(), nullptr);
3196 EXPECT_TRUE(ident->result_type()->is_unsigned_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003197 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003198}
3199
3200TEST_P(ImportData_SingleParam_FloatOrInt_Test, Error_Bool) {
3201 auto param = GetParam();
3202
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003203 ast::type::Bool bool_type;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003204
3205 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003206 params.push_back(create<ast::ScalarConstructorExpression>(
3207 create<ast::BoolLiteral>(&bool_type, false)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003208
dan sinclair6b59bf42020-12-11 19:16:13 +00003209 auto* ident = create<ast::IdentifierExpression>(
3210 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003211 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003212
3213 EXPECT_FALSE(td()->DetermineResultType(&call));
3214 EXPECT_EQ(td()->error(),
3215 std::string("incorrect type for ") + param.name +
3216 ". Requires float or int, scalar or vector values");
3217}
3218
3219TEST_P(ImportData_SingleParam_FloatOrInt_Test, Error_NoParams) {
3220 auto param = GetParam();
3221
3222 ast::ExpressionList params;
3223
dan sinclair6b59bf42020-12-11 19:16:13 +00003224 auto* ident = create<ast::IdentifierExpression>(
3225 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003226 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003227
3228 EXPECT_FALSE(td()->DetermineResultType(&call));
3229 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
3230 param.name + ". Expected 1 got 0");
3231}
3232
3233TEST_P(ImportData_SingleParam_FloatOrInt_Test, Error_MultipleParams) {
3234 auto param = GetParam();
3235
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003236 ast::type::F32 f32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003237 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003238 params.push_back(create<ast::ScalarConstructorExpression>(
3239 create<ast::FloatLiteral>(&f32, 1.f)));
3240 params.push_back(create<ast::ScalarConstructorExpression>(
3241 create<ast::FloatLiteral>(&f32, 1.f)));
3242 params.push_back(create<ast::ScalarConstructorExpression>(
3243 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00003244
dan sinclair6b59bf42020-12-11 19:16:13 +00003245 auto* ident = create<ast::IdentifierExpression>(
3246 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003247 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003248
3249 EXPECT_FALSE(td()->DetermineResultType(&call));
3250 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
3251 param.name + ". Expected 1 got 3");
3252}
3253
3254INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
3255 ImportData_SingleParam_FloatOrInt_Test,
3256 testing::Values(IntrinsicData{"abs",
3257 ast::Intrinsic::kAbs}));
dan sinclairca1723e2020-04-20 15:47:55 +00003258
dan sinclair652a4b92020-04-20 21:09:14 +00003259TEST_F(TypeDeterminerTest, ImportData_Length_Scalar) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003260 ast::type::F32 f32;
dan sinclair652a4b92020-04-20 21:09:14 +00003261
3262 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003263 params.push_back(create<ast::ScalarConstructorExpression>(
3264 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclair652a4b92020-04-20 21:09:14 +00003265
3266 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
3267
dan sinclair6b59bf42020-12-11 19:16:13 +00003268 auto* ident = create<ast::IdentifierExpression>(mod->RegisterSymbol("length"),
3269 "length");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003270
3271 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003272
3273 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003274 ASSERT_NE(ident->result_type(), nullptr);
3275 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair652a4b92020-04-20 21:09:14 +00003276}
3277
3278TEST_F(TypeDeterminerTest, ImportData_Length_FloatVector) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003279 ast::type::F32 f32;
3280 ast::type::Vector vec(&f32, 3);
dan sinclair652a4b92020-04-20 21:09:14 +00003281
3282 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00003283 vals.push_back(create<ast::ScalarConstructorExpression>(
3284 create<ast::FloatLiteral>(&f32, 1.0f)));
3285 vals.push_back(create<ast::ScalarConstructorExpression>(
3286 create<ast::FloatLiteral>(&f32, 1.0f)));
3287 vals.push_back(create<ast::ScalarConstructorExpression>(
3288 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclair652a4b92020-04-20 21:09:14 +00003289
3290 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00003291 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals));
dan sinclair652a4b92020-04-20 21:09:14 +00003292
dan sinclair6b59bf42020-12-11 19:16:13 +00003293 auto* ident = create<ast::IdentifierExpression>(mod->RegisterSymbol("length"),
3294 "length");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003295
3296 ast::CallExpression call(ident, params);
dan sinclair652a4b92020-04-20 21:09:14 +00003297
dan sinclairb4fee2f2020-09-22 19:42:13 +00003298 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003299 ASSERT_NE(ident->result_type(), nullptr);
3300 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair652a4b92020-04-20 21:09:14 +00003301}
3302
3303TEST_F(TypeDeterminerTest, ImportData_Length_Error_Integer) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003304 ast::type::I32 i32;
dan sinclair652a4b92020-04-20 21:09:14 +00003305
3306 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003307 params.push_back(create<ast::ScalarConstructorExpression>(
3308 create<ast::SintLiteral>(&i32, 1)));
dan sinclair652a4b92020-04-20 21:09:14 +00003309
dan sinclair6b59bf42020-12-11 19:16:13 +00003310 auto* ident = create<ast::IdentifierExpression>(mod->RegisterSymbol("length"),
3311 "length");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003312 ast::CallExpression call(ident, params);
dan sinclair652a4b92020-04-20 21:09:14 +00003313
dan sinclairb4fee2f2020-09-22 19:42:13 +00003314 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair53352042020-06-08 18:49:31 +00003315 EXPECT_EQ(td()->error(),
3316 "incorrect type for length. Requires float scalar or float vector "
3317 "values");
dan sinclair652a4b92020-04-20 21:09:14 +00003318}
3319
3320TEST_F(TypeDeterminerTest, ImportData_Length_Error_NoParams) {
3321 ast::ExpressionList params;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003322
dan sinclair6b59bf42020-12-11 19:16:13 +00003323 auto* ident = create<ast::IdentifierExpression>(mod->RegisterSymbol("length"),
3324 "length");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003325 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003326
3327 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair652a4b92020-04-20 21:09:14 +00003328 EXPECT_EQ(td()->error(),
3329 "incorrect number of parameters for length. Expected 1 got 0");
3330}
3331
3332TEST_F(TypeDeterminerTest, ImportData_Length_Error_MultipleParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003333 ast::type::F32 f32;
dan sinclair652a4b92020-04-20 21:09:14 +00003334 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003335 params.push_back(create<ast::ScalarConstructorExpression>(
3336 create<ast::FloatLiteral>(&f32, 1.f)));
3337 params.push_back(create<ast::ScalarConstructorExpression>(
3338 create<ast::FloatLiteral>(&f32, 1.f)));
3339 params.push_back(create<ast::ScalarConstructorExpression>(
3340 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclair652a4b92020-04-20 21:09:14 +00003341
dan sinclair6b59bf42020-12-11 19:16:13 +00003342 auto* ident = create<ast::IdentifierExpression>(mod->RegisterSymbol("length"),
3343 "length");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003344 ast::CallExpression call(ident, params);
dan sinclair652a4b92020-04-20 21:09:14 +00003345
dan sinclairb4fee2f2020-09-22 19:42:13 +00003346 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair652a4b92020-04-20 21:09:14 +00003347 EXPECT_EQ(td()->error(),
3348 "incorrect number of parameters for length. Expected 1 got 3");
3349}
3350
dan sinclairb4fee2f2020-09-22 19:42:13 +00003351using ImportData_TwoParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair37d62c92020-04-21 12:55:06 +00003352TEST_P(ImportData_TwoParamTest, Scalar) {
3353 auto param = GetParam();
3354
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003355 ast::type::F32 f32;
dan sinclair37d62c92020-04-21 12:55:06 +00003356
3357 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003358 params.push_back(create<ast::ScalarConstructorExpression>(
3359 create<ast::FloatLiteral>(&f32, 1.f)));
3360 params.push_back(create<ast::ScalarConstructorExpression>(
3361 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclair37d62c92020-04-21 12:55:06 +00003362
dan sinclair6b59bf42020-12-11 19:16:13 +00003363 auto* ident = create<ast::IdentifierExpression>(
3364 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003365
3366 ast::CallExpression call(ident, params);
dan sinclair37d62c92020-04-21 12:55:06 +00003367
dan sinclairb4fee2f2020-09-22 19:42:13 +00003368 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003369 ASSERT_NE(ident->result_type(), nullptr);
3370 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair37d62c92020-04-21 12:55:06 +00003371}
3372
3373TEST_P(ImportData_TwoParamTest, Vector) {
3374 auto param = GetParam();
3375
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003376 ast::type::F32 f32;
3377 ast::type::Vector vec(&f32, 3);
dan sinclair37d62c92020-04-21 12:55:06 +00003378
3379 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00003380 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3381 create<ast::FloatLiteral>(&f32, 1.0f)));
3382 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3383 create<ast::FloatLiteral>(&f32, 1.0f)));
3384 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3385 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclair37d62c92020-04-21 12:55:06 +00003386
3387 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00003388 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3389 create<ast::FloatLiteral>(&f32, 1.0f)));
3390 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3391 create<ast::FloatLiteral>(&f32, 1.0f)));
3392 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3393 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclair37d62c92020-04-21 12:55:06 +00003394
3395 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00003396 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_1));
3397 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_2));
dan sinclair37d62c92020-04-21 12:55:06 +00003398
dan sinclair6b59bf42020-12-11 19:16:13 +00003399 auto* ident = create<ast::IdentifierExpression>(
3400 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003401
3402 ast::CallExpression call(ident, params);
dan sinclair37d62c92020-04-21 12:55:06 +00003403
dan sinclairb4fee2f2020-09-22 19:42:13 +00003404 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003405 ASSERT_NE(ident->result_type(), nullptr);
3406 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003407 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair37d62c92020-04-21 12:55:06 +00003408}
3409
3410TEST_P(ImportData_TwoParamTest, Error_Integer) {
3411 auto param = GetParam();
3412
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003413 ast::type::I32 i32;
dan sinclair37d62c92020-04-21 12:55:06 +00003414
3415 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003416 params.push_back(create<ast::ScalarConstructorExpression>(
3417 create<ast::SintLiteral>(&i32, 1)));
3418 params.push_back(create<ast::ScalarConstructorExpression>(
3419 create<ast::SintLiteral>(&i32, 2)));
dan sinclair37d62c92020-04-21 12:55:06 +00003420
dan sinclair6b59bf42020-12-11 19:16:13 +00003421 auto* ident = create<ast::IdentifierExpression>(
3422 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003423 ast::CallExpression call(ident, params);
dan sinclair37d62c92020-04-21 12:55:06 +00003424
dan sinclairb4fee2f2020-09-22 19:42:13 +00003425 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair37d62c92020-04-21 12:55:06 +00003426 EXPECT_EQ(td()->error(),
3427 std::string("incorrect type for ") + param.name +
dan sinclair53352042020-06-08 18:49:31 +00003428 ". Requires float scalar or float vector values");
dan sinclair37d62c92020-04-21 12:55:06 +00003429}
3430
3431TEST_P(ImportData_TwoParamTest, Error_NoParams) {
3432 auto param = GetParam();
3433
3434 ast::ExpressionList params;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003435
dan sinclair6b59bf42020-12-11 19:16:13 +00003436 auto* ident = create<ast::IdentifierExpression>(
3437 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003438 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003439
3440 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair37d62c92020-04-21 12:55:06 +00003441 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
3442 param.name + ". Expected 2 got 0");
3443}
3444
3445TEST_P(ImportData_TwoParamTest, Error_OneParam) {
3446 auto param = GetParam();
3447
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003448 ast::type::F32 f32;
dan sinclair37d62c92020-04-21 12:55:06 +00003449 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003450 params.push_back(create<ast::ScalarConstructorExpression>(
3451 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclair37d62c92020-04-21 12:55:06 +00003452
dan sinclair6b59bf42020-12-11 19:16:13 +00003453 auto* ident = create<ast::IdentifierExpression>(
3454 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003455 ast::CallExpression call(ident, params);
dan sinclair37d62c92020-04-21 12:55:06 +00003456
dan sinclairb4fee2f2020-09-22 19:42:13 +00003457 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair37d62c92020-04-21 12:55:06 +00003458 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
3459 param.name + ". Expected 2 got 1");
3460}
3461
3462TEST_P(ImportData_TwoParamTest, Error_MismatchedParamCount) {
3463 auto param = GetParam();
3464
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003465 ast::type::F32 f32;
3466 ast::type::Vector vec2(&f32, 2);
3467 ast::type::Vector vec3(&f32, 3);
dan sinclair37d62c92020-04-21 12:55:06 +00003468
3469 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00003470 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3471 create<ast::FloatLiteral>(&f32, 1.0f)));
3472 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3473 create<ast::FloatLiteral>(&f32, 1.0f)));
dan sinclair37d62c92020-04-21 12:55:06 +00003474
3475 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00003476 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3477 create<ast::FloatLiteral>(&f32, 1.0f)));
3478 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3479 create<ast::FloatLiteral>(&f32, 1.0f)));
3480 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3481 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclair37d62c92020-04-21 12:55:06 +00003482
3483 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00003484 params.push_back(create<ast::TypeConstructorExpression>(&vec2, vals_1));
3485 params.push_back(create<ast::TypeConstructorExpression>(&vec3, vals_2));
dan sinclair37d62c92020-04-21 12:55:06 +00003486
dan sinclair6b59bf42020-12-11 19:16:13 +00003487 auto* ident = create<ast::IdentifierExpression>(
3488 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003489 ast::CallExpression call(ident, params);
dan sinclair37d62c92020-04-21 12:55:06 +00003490
dan sinclairb4fee2f2020-09-22 19:42:13 +00003491 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair37d62c92020-04-21 12:55:06 +00003492 EXPECT_EQ(td()->error(),
3493 std::string("mismatched parameter types for ") + param.name);
3494}
3495
3496TEST_P(ImportData_TwoParamTest, Error_MismatchedParamType) {
3497 auto param = GetParam();
3498
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003499 ast::type::F32 f32;
3500 ast::type::Vector vec(&f32, 3);
dan sinclair37d62c92020-04-21 12:55:06 +00003501
3502 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00003503 vals.push_back(create<ast::ScalarConstructorExpression>(
3504 create<ast::FloatLiteral>(&f32, 1.0f)));
3505 vals.push_back(create<ast::ScalarConstructorExpression>(
3506 create<ast::FloatLiteral>(&f32, 1.0f)));
3507 vals.push_back(create<ast::ScalarConstructorExpression>(
3508 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclair37d62c92020-04-21 12:55:06 +00003509
3510 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003511 params.push_back(create<ast::ScalarConstructorExpression>(
3512 create<ast::FloatLiteral>(&f32, 1.0f)));
Ben Clayton4bfe4612020-11-16 16:41:47 +00003513 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals));
dan sinclair37d62c92020-04-21 12:55:06 +00003514
dan sinclair6b59bf42020-12-11 19:16:13 +00003515 auto* ident = create<ast::IdentifierExpression>(
3516 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003517 ast::CallExpression call(ident, params);
dan sinclair37d62c92020-04-21 12:55:06 +00003518
dan sinclairb4fee2f2020-09-22 19:42:13 +00003519 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair37d62c92020-04-21 12:55:06 +00003520 EXPECT_EQ(td()->error(),
3521 std::string("mismatched parameter types for ") + param.name);
3522}
3523
3524TEST_P(ImportData_TwoParamTest, Error_TooManyParams) {
3525 auto param = GetParam();
3526
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003527 ast::type::F32 f32;
dan sinclair37d62c92020-04-21 12:55:06 +00003528 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003529 params.push_back(create<ast::ScalarConstructorExpression>(
3530 create<ast::FloatLiteral>(&f32, 1.f)));
3531 params.push_back(create<ast::ScalarConstructorExpression>(
3532 create<ast::FloatLiteral>(&f32, 1.f)));
3533 params.push_back(create<ast::ScalarConstructorExpression>(
3534 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclair37d62c92020-04-21 12:55:06 +00003535
dan sinclair6b59bf42020-12-11 19:16:13 +00003536 auto* ident = create<ast::IdentifierExpression>(
3537 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003538 ast::CallExpression call(ident, params);
dan sinclair37d62c92020-04-21 12:55:06 +00003539
dan sinclairb4fee2f2020-09-22 19:42:13 +00003540 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair37d62c92020-04-21 12:55:06 +00003541 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
3542 param.name + ". Expected 2 got 3");
3543}
3544
dan sinclairb4fee2f2020-09-22 19:42:13 +00003545INSTANTIATE_TEST_SUITE_P(
3546 TypeDeterminerTest,
3547 ImportData_TwoParamTest,
3548 testing::Values(IntrinsicData{"atan2", ast::Intrinsic::kAtan2},
3549 IntrinsicData{"pow", ast::Intrinsic::kPow},
3550 IntrinsicData{"step", ast::Intrinsic::kStep},
3551 IntrinsicData{"reflect", ast::Intrinsic::kReflect}));
dan sinclair37d62c92020-04-21 12:55:06 +00003552
dan sinclair54444382020-04-21 13:04:15 +00003553TEST_F(TypeDeterminerTest, ImportData_Distance_Scalar) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003554 ast::type::F32 f32;
dan sinclair54444382020-04-21 13:04:15 +00003555
3556 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003557 params.push_back(create<ast::ScalarConstructorExpression>(
3558 create<ast::FloatLiteral>(&f32, 1.f)));
3559 params.push_back(create<ast::ScalarConstructorExpression>(
3560 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclair54444382020-04-21 13:04:15 +00003561
dan sinclair6b59bf42020-12-11 19:16:13 +00003562 auto* ident = create<ast::IdentifierExpression>(
3563 mod->RegisterSymbol("distance"), "distance");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003564
3565 ast::CallExpression call(ident, params);
dan sinclair54444382020-04-21 13:04:15 +00003566
dan sinclairb4fee2f2020-09-22 19:42:13 +00003567 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003568 ASSERT_NE(ident->result_type(), nullptr);
3569 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair54444382020-04-21 13:04:15 +00003570}
3571
3572TEST_F(TypeDeterminerTest, ImportData_Distance_Vector) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003573 ast::type::F32 f32;
3574 ast::type::Vector vec(&f32, 3);
dan sinclair54444382020-04-21 13:04:15 +00003575
3576 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00003577 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3578 create<ast::FloatLiteral>(&f32, 1.0f)));
3579 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3580 create<ast::FloatLiteral>(&f32, 1.0f)));
3581 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3582 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclair54444382020-04-21 13:04:15 +00003583
3584 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00003585 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3586 create<ast::FloatLiteral>(&f32, 1.0f)));
3587 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3588 create<ast::FloatLiteral>(&f32, 1.0f)));
3589 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3590 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclair54444382020-04-21 13:04:15 +00003591
3592 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00003593 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_1));
3594 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_2));
dan sinclair54444382020-04-21 13:04:15 +00003595
dan sinclair6b59bf42020-12-11 19:16:13 +00003596 auto* ident = create<ast::IdentifierExpression>(
3597 mod->RegisterSymbol("distance"), "distance");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003598
3599 ast::CallExpression call(ident, params);
dan sinclair54444382020-04-21 13:04:15 +00003600
dan sinclairb4fee2f2020-09-22 19:42:13 +00003601 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003602 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003603 EXPECT_TRUE(ident->result_type()->Is<ast::type::F32>());
dan sinclair54444382020-04-21 13:04:15 +00003604}
3605
3606TEST_F(TypeDeterminerTest, ImportData_Distance_Error_Integer) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003607 ast::type::I32 i32;
dan sinclair54444382020-04-21 13:04:15 +00003608
3609 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003610 params.push_back(create<ast::ScalarConstructorExpression>(
3611 create<ast::SintLiteral>(&i32, 1)));
3612 params.push_back(create<ast::ScalarConstructorExpression>(
3613 create<ast::SintLiteral>(&i32, 2)));
dan sinclair54444382020-04-21 13:04:15 +00003614
dan sinclair6b59bf42020-12-11 19:16:13 +00003615 auto* ident = create<ast::IdentifierExpression>(
3616 mod->RegisterSymbol("distance"), "distance");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003617 ast::CallExpression call(ident, params);
dan sinclair54444382020-04-21 13:04:15 +00003618
dan sinclairb4fee2f2020-09-22 19:42:13 +00003619 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair54444382020-04-21 13:04:15 +00003620 EXPECT_EQ(td()->error(),
dan sinclair53352042020-06-08 18:49:31 +00003621 "incorrect type for distance. Requires float scalar or float "
dan sinclair54444382020-04-21 13:04:15 +00003622 "vector values");
3623}
3624
3625TEST_F(TypeDeterminerTest, ImportData_Distance_Error_NoParams) {
3626 ast::ExpressionList params;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003627
dan sinclair6b59bf42020-12-11 19:16:13 +00003628 auto* ident = create<ast::IdentifierExpression>(
3629 mod->RegisterSymbol("distance"), "distance");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003630 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003631
3632 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair54444382020-04-21 13:04:15 +00003633 EXPECT_EQ(td()->error(),
3634 "incorrect number of parameters for distance. Expected 2 got 0");
3635}
3636
3637TEST_F(TypeDeterminerTest, ImportData_Distance_Error_OneParam) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003638 ast::type::F32 f32;
dan sinclair54444382020-04-21 13:04:15 +00003639 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003640 params.push_back(create<ast::ScalarConstructorExpression>(
3641 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclair54444382020-04-21 13:04:15 +00003642
dan sinclair6b59bf42020-12-11 19:16:13 +00003643 auto* ident = create<ast::IdentifierExpression>(
3644 mod->RegisterSymbol("distance"), "distance");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003645 ast::CallExpression call(ident, params);
dan sinclair54444382020-04-21 13:04:15 +00003646
dan sinclairb4fee2f2020-09-22 19:42:13 +00003647 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair54444382020-04-21 13:04:15 +00003648 EXPECT_EQ(td()->error(),
3649 "incorrect number of parameters for distance. Expected 2 got 1");
3650}
3651
3652TEST_F(TypeDeterminerTest, ImportData_Distance_Error_MismatchedParamCount) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003653 ast::type::F32 f32;
3654 ast::type::Vector vec2(&f32, 2);
3655 ast::type::Vector vec3(&f32, 3);
dan sinclair54444382020-04-21 13:04:15 +00003656
3657 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00003658 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3659 create<ast::FloatLiteral>(&f32, 1.0f)));
3660 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3661 create<ast::FloatLiteral>(&f32, 1.0f)));
dan sinclair54444382020-04-21 13:04:15 +00003662
3663 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00003664 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3665 create<ast::FloatLiteral>(&f32, 1.0f)));
3666 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3667 create<ast::FloatLiteral>(&f32, 1.0f)));
3668 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3669 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclair54444382020-04-21 13:04:15 +00003670
3671 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00003672 params.push_back(create<ast::TypeConstructorExpression>(&vec2, vals_1));
3673 params.push_back(create<ast::TypeConstructorExpression>(&vec3, vals_2));
dan sinclair54444382020-04-21 13:04:15 +00003674
dan sinclair6b59bf42020-12-11 19:16:13 +00003675 auto* ident = create<ast::IdentifierExpression>(
3676 mod->RegisterSymbol("distance"), "distance");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003677 ast::CallExpression call(ident, params);
dan sinclair54444382020-04-21 13:04:15 +00003678
dan sinclairb4fee2f2020-09-22 19:42:13 +00003679 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair54444382020-04-21 13:04:15 +00003680 EXPECT_EQ(td()->error(), "mismatched parameter types for distance");
3681}
3682
3683TEST_F(TypeDeterminerTest, ImportData_Distance_Error_MismatchedParamType) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003684 ast::type::F32 f32;
3685 ast::type::Vector vec(&f32, 3);
dan sinclair54444382020-04-21 13:04:15 +00003686
3687 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00003688 vals.push_back(create<ast::ScalarConstructorExpression>(
3689 create<ast::FloatLiteral>(&f32, 1.0f)));
3690 vals.push_back(create<ast::ScalarConstructorExpression>(
3691 create<ast::FloatLiteral>(&f32, 1.0f)));
3692 vals.push_back(create<ast::ScalarConstructorExpression>(
3693 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclair54444382020-04-21 13:04:15 +00003694
3695 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003696 params.push_back(create<ast::ScalarConstructorExpression>(
3697 create<ast::FloatLiteral>(&f32, 1.0f)));
Ben Clayton4bfe4612020-11-16 16:41:47 +00003698 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals));
dan sinclair54444382020-04-21 13:04:15 +00003699
dan sinclair6b59bf42020-12-11 19:16:13 +00003700 auto* ident = create<ast::IdentifierExpression>(
3701 mod->RegisterSymbol("distance"), "distance");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003702 ast::CallExpression call(ident, params);
dan sinclair54444382020-04-21 13:04:15 +00003703
dan sinclairb4fee2f2020-09-22 19:42:13 +00003704 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair54444382020-04-21 13:04:15 +00003705 EXPECT_EQ(td()->error(), "mismatched parameter types for distance");
3706}
3707
3708TEST_F(TypeDeterminerTest, ImportData_Distance_Error_TooManyParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003709 ast::type::F32 f32;
dan sinclair54444382020-04-21 13:04:15 +00003710 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003711 params.push_back(create<ast::ScalarConstructorExpression>(
3712 create<ast::FloatLiteral>(&f32, 1.f)));
3713 params.push_back(create<ast::ScalarConstructorExpression>(
3714 create<ast::FloatLiteral>(&f32, 1.f)));
3715 params.push_back(create<ast::ScalarConstructorExpression>(
3716 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclair54444382020-04-21 13:04:15 +00003717
dan sinclair6b59bf42020-12-11 19:16:13 +00003718 auto* ident = create<ast::IdentifierExpression>(
3719 mod->RegisterSymbol("distance"), "distance");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003720 ast::CallExpression call(ident, params);
dan sinclair54444382020-04-21 13:04:15 +00003721
dan sinclairb4fee2f2020-09-22 19:42:13 +00003722 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair54444382020-04-21 13:04:15 +00003723 EXPECT_EQ(td()->error(),
3724 "incorrect number of parameters for distance. Expected 2 got 3");
3725}
3726
dan sinclairee392252020-06-08 23:48:15 +00003727TEST_F(TypeDeterminerTest, ImportData_Cross) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003728 ast::type::F32 f32;
3729 ast::type::Vector vec(&f32, 3);
dan sinclair2287d012020-04-22 00:23:57 +00003730
dan sinclairee392252020-06-08 23:48:15 +00003731 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00003732 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3733 create<ast::FloatLiteral>(&f32, 1.0f)));
3734 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3735 create<ast::FloatLiteral>(&f32, 1.0f)));
3736 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3737 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclairee392252020-06-08 23:48:15 +00003738
3739 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00003740 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3741 create<ast::FloatLiteral>(&f32, 1.0f)));
3742 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3743 create<ast::FloatLiteral>(&f32, 1.0f)));
3744 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3745 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclairee392252020-06-08 23:48:15 +00003746
3747 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00003748 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_1));
3749 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_2));
dan sinclairee392252020-06-08 23:48:15 +00003750
dan sinclair6b59bf42020-12-11 19:16:13 +00003751 auto* ident =
3752 create<ast::IdentifierExpression>(mod->RegisterSymbol("cross"), "cross");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003753
3754 ast::CallExpression call(ident, params);
dan sinclairee392252020-06-08 23:48:15 +00003755
dan sinclairb4fee2f2020-09-22 19:42:13 +00003756 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003757 ASSERT_NE(ident->result_type(), nullptr);
3758 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003759 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairee392252020-06-08 23:48:15 +00003760}
3761
3762TEST_F(TypeDeterminerTest, ImportData_Cross_Error_Scalar) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003763 ast::type::F32 f32;
dan sinclairee392252020-06-08 23:48:15 +00003764
3765 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003766 params.push_back(create<ast::ScalarConstructorExpression>(
3767 create<ast::FloatLiteral>(&f32, 1.0f)));
3768 params.push_back(create<ast::ScalarConstructorExpression>(
3769 create<ast::FloatLiteral>(&f32, 1.0f)));
dan sinclairee392252020-06-08 23:48:15 +00003770
dan sinclair6b59bf42020-12-11 19:16:13 +00003771 auto* ident =
3772 create<ast::IdentifierExpression>(mod->RegisterSymbol("cross"), "cross");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003773 ast::CallExpression call(ident, params);
dan sinclairee392252020-06-08 23:48:15 +00003774
dan sinclairb4fee2f2020-09-22 19:42:13 +00003775 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclairee392252020-06-08 23:48:15 +00003776 EXPECT_EQ(td()->error(),
3777 "incorrect type for cross. Requires float vector values");
3778}
3779
3780TEST_F(TypeDeterminerTest, ImportData_Cross_Error_IntType) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003781 ast::type::I32 i32;
3782 ast::type::Vector vec(&i32, 3);
dan sinclairee392252020-06-08 23:48:15 +00003783
3784 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00003785 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3786 create<ast::SintLiteral>(&i32, 1)));
3787 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3788 create<ast::SintLiteral>(&i32, 1)));
3789 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3790 create<ast::SintLiteral>(&i32, 3)));
dan sinclairee392252020-06-08 23:48:15 +00003791
3792 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00003793 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3794 create<ast::SintLiteral>(&i32, 1)));
3795 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3796 create<ast::SintLiteral>(&i32, 1)));
3797 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3798 create<ast::SintLiteral>(&i32, 3)));
dan sinclairee392252020-06-08 23:48:15 +00003799
3800 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00003801 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_1));
3802 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_2));
dan sinclairee392252020-06-08 23:48:15 +00003803
dan sinclair6b59bf42020-12-11 19:16:13 +00003804 auto* ident =
3805 create<ast::IdentifierExpression>(mod->RegisterSymbol("cross"), "cross");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003806 ast::CallExpression call(ident, params);
dan sinclairee392252020-06-08 23:48:15 +00003807
dan sinclairb4fee2f2020-09-22 19:42:13 +00003808 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclairee392252020-06-08 23:48:15 +00003809 EXPECT_EQ(td()->error(),
3810 "incorrect type for cross. Requires float vector values");
3811}
3812
3813TEST_F(TypeDeterminerTest, ImportData_Cross_Error_MissingParams) {
dan sinclairee392252020-06-08 23:48:15 +00003814 ast::ExpressionList params;
dan sinclair6b59bf42020-12-11 19:16:13 +00003815 auto* ident =
3816 create<ast::IdentifierExpression>(mod->RegisterSymbol("cross"), "cross");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003817 ast::CallExpression call(ident, params);
dan sinclairee392252020-06-08 23:48:15 +00003818
dan sinclairb4fee2f2020-09-22 19:42:13 +00003819 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclairee392252020-06-08 23:48:15 +00003820 EXPECT_EQ(td()->error(),
3821 "incorrect number of parameters for cross. Expected 2 got 0");
3822}
3823
3824TEST_F(TypeDeterminerTest, ImportData_Cross_Error_TooFewParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003825 ast::type::F32 f32;
3826 ast::type::Vector vec(&f32, 3);
dan sinclairee392252020-06-08 23:48:15 +00003827
3828 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00003829 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3830 create<ast::FloatLiteral>(&f32, 1.0f)));
3831 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3832 create<ast::FloatLiteral>(&f32, 1.0f)));
3833 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3834 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclairee392252020-06-08 23:48:15 +00003835
3836 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00003837 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_1));
dan sinclairee392252020-06-08 23:48:15 +00003838
dan sinclair6b59bf42020-12-11 19:16:13 +00003839 auto* ident =
3840 create<ast::IdentifierExpression>(mod->RegisterSymbol("cross"), "cross");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003841 ast::CallExpression call(ident, params);
dan sinclairee392252020-06-08 23:48:15 +00003842
dan sinclairb4fee2f2020-09-22 19:42:13 +00003843 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclairee392252020-06-08 23:48:15 +00003844 EXPECT_EQ(td()->error(),
3845 "incorrect number of parameters for cross. Expected 2 got 1");
3846}
3847
3848TEST_F(TypeDeterminerTest, ImportData_Cross_Error_TooManyParams) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003849 ast::type::F32 f32;
3850 ast::type::Vector vec(&f32, 3);
dan sinclairee392252020-06-08 23:48:15 +00003851
3852 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00003853 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3854 create<ast::FloatLiteral>(&f32, 1.0f)));
3855 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3856 create<ast::FloatLiteral>(&f32, 1.0f)));
3857 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3858 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclairee392252020-06-08 23:48:15 +00003859
3860 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00003861 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3862 create<ast::FloatLiteral>(&f32, 1.0f)));
3863 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3864 create<ast::FloatLiteral>(&f32, 1.0f)));
3865 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3866 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclairee392252020-06-08 23:48:15 +00003867
3868 ast::ExpressionList vals_3;
Ben Clayton62625922020-11-13 22:09:38 +00003869 vals_3.push_back(create<ast::ScalarConstructorExpression>(
3870 create<ast::FloatLiteral>(&f32, 1.0f)));
3871 vals_3.push_back(create<ast::ScalarConstructorExpression>(
3872 create<ast::FloatLiteral>(&f32, 1.0f)));
3873 vals_3.push_back(create<ast::ScalarConstructorExpression>(
3874 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclairee392252020-06-08 23:48:15 +00003875
3876 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00003877 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_1));
3878 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_2));
3879 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_3));
dan sinclairee392252020-06-08 23:48:15 +00003880
dan sinclair6b59bf42020-12-11 19:16:13 +00003881 auto* ident =
3882 create<ast::IdentifierExpression>(mod->RegisterSymbol("cross"), "cross");
Ben Clayton4bfe4612020-11-16 16:41:47 +00003883 ast::CallExpression call(ident, params);
dan sinclairee392252020-06-08 23:48:15 +00003884
dan sinclairb4fee2f2020-09-22 19:42:13 +00003885 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclairee392252020-06-08 23:48:15 +00003886 EXPECT_EQ(td()->error(),
3887 "incorrect number of parameters for cross. Expected 2 got 3");
3888}
3889
dan sinclairb4fee2f2020-09-22 19:42:13 +00003890using ImportData_ThreeParamTest = TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair2287d012020-04-22 00:23:57 +00003891TEST_P(ImportData_ThreeParamTest, Scalar) {
3892 auto param = GetParam();
3893
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003894 ast::type::F32 f32;
dan sinclair2287d012020-04-22 00:23:57 +00003895
3896 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003897 params.push_back(create<ast::ScalarConstructorExpression>(
3898 create<ast::FloatLiteral>(&f32, 1.f)));
3899 params.push_back(create<ast::ScalarConstructorExpression>(
3900 create<ast::FloatLiteral>(&f32, 1.f)));
3901 params.push_back(create<ast::ScalarConstructorExpression>(
3902 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclair2287d012020-04-22 00:23:57 +00003903
dan sinclair6b59bf42020-12-11 19:16:13 +00003904 auto* ident = create<ast::IdentifierExpression>(
3905 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003906
3907 ast::CallExpression call(ident, params);
dan sinclair2287d012020-04-22 00:23:57 +00003908
dan sinclairb4fee2f2020-09-22 19:42:13 +00003909 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003910 ASSERT_NE(ident->result_type(), nullptr);
3911 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclair2287d012020-04-22 00:23:57 +00003912}
3913
3914TEST_P(ImportData_ThreeParamTest, Vector) {
3915 auto param = GetParam();
3916
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003917 ast::type::F32 f32;
3918 ast::type::Vector vec(&f32, 3);
dan sinclair2287d012020-04-22 00:23:57 +00003919
3920 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00003921 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3922 create<ast::FloatLiteral>(&f32, 1.0f)));
3923 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3924 create<ast::FloatLiteral>(&f32, 1.0f)));
3925 vals_1.push_back(create<ast::ScalarConstructorExpression>(
3926 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclair2287d012020-04-22 00:23:57 +00003927
3928 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00003929 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3930 create<ast::FloatLiteral>(&f32, 1.0f)));
3931 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3932 create<ast::FloatLiteral>(&f32, 1.0f)));
3933 vals_2.push_back(create<ast::ScalarConstructorExpression>(
3934 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclair2287d012020-04-22 00:23:57 +00003935
3936 ast::ExpressionList vals_3;
Ben Clayton62625922020-11-13 22:09:38 +00003937 vals_3.push_back(create<ast::ScalarConstructorExpression>(
3938 create<ast::FloatLiteral>(&f32, 1.0f)));
3939 vals_3.push_back(create<ast::ScalarConstructorExpression>(
3940 create<ast::FloatLiteral>(&f32, 1.0f)));
3941 vals_3.push_back(create<ast::ScalarConstructorExpression>(
3942 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclair2287d012020-04-22 00:23:57 +00003943
3944 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00003945 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_1));
3946 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_2));
3947 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_3));
dan sinclair2287d012020-04-22 00:23:57 +00003948
dan sinclair6b59bf42020-12-11 19:16:13 +00003949 auto* ident = create<ast::IdentifierExpression>(
3950 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003951
3952 ast::CallExpression call(ident, params);
dan sinclair2287d012020-04-22 00:23:57 +00003953
dan sinclairb4fee2f2020-09-22 19:42:13 +00003954 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00003955 ASSERT_NE(ident->result_type(), nullptr);
3956 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003957 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair2287d012020-04-22 00:23:57 +00003958}
3959
3960TEST_P(ImportData_ThreeParamTest, Error_Integer) {
3961 auto param = GetParam();
3962
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00003963 ast::type::I32 i32;
dan sinclair2287d012020-04-22 00:23:57 +00003964
3965 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00003966 params.push_back(create<ast::ScalarConstructorExpression>(
3967 create<ast::SintLiteral>(&i32, 1)));
3968 params.push_back(create<ast::ScalarConstructorExpression>(
3969 create<ast::SintLiteral>(&i32, 2)));
3970 params.push_back(create<ast::ScalarConstructorExpression>(
3971 create<ast::SintLiteral>(&i32, 3)));
dan sinclair2287d012020-04-22 00:23:57 +00003972
dan sinclair6b59bf42020-12-11 19:16:13 +00003973 auto* ident = create<ast::IdentifierExpression>(
3974 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003975 ast::CallExpression call(ident, params);
dan sinclair2287d012020-04-22 00:23:57 +00003976
dan sinclairb4fee2f2020-09-22 19:42:13 +00003977 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair2287d012020-04-22 00:23:57 +00003978 EXPECT_EQ(td()->error(),
3979 std::string("incorrect type for ") + param.name +
dan sinclair53352042020-06-08 18:49:31 +00003980 ". Requires float scalar or float vector values");
dan sinclair2287d012020-04-22 00:23:57 +00003981}
3982
3983TEST_P(ImportData_ThreeParamTest, Error_NoParams) {
3984 auto param = GetParam();
3985
3986 ast::ExpressionList params;
dan sinclairb4fee2f2020-09-22 19:42:13 +00003987
dan sinclair6b59bf42020-12-11 19:16:13 +00003988 auto* ident = create<ast::IdentifierExpression>(
3989 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00003990 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00003991
3992 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair2287d012020-04-22 00:23:57 +00003993 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
3994 param.name + ". Expected 3 got 0");
3995}
3996
3997TEST_P(ImportData_ThreeParamTest, Error_OneParam) {
3998 auto param = GetParam();
3999
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004000 ast::type::F32 f32;
dan sinclair2287d012020-04-22 00:23:57 +00004001 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004002 params.push_back(create<ast::ScalarConstructorExpression>(
4003 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclair2287d012020-04-22 00:23:57 +00004004
dan sinclair6b59bf42020-12-11 19:16:13 +00004005 auto* ident = create<ast::IdentifierExpression>(
4006 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004007 ast::CallExpression call(ident, params);
dan sinclair2287d012020-04-22 00:23:57 +00004008
dan sinclairb4fee2f2020-09-22 19:42:13 +00004009 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair2287d012020-04-22 00:23:57 +00004010 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4011 param.name + ". Expected 3 got 1");
4012}
4013
4014TEST_P(ImportData_ThreeParamTest, Error_TwoParams) {
4015 auto param = GetParam();
4016
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004017 ast::type::F32 f32;
dan sinclair2287d012020-04-22 00:23:57 +00004018 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004019 params.push_back(create<ast::ScalarConstructorExpression>(
4020 create<ast::FloatLiteral>(&f32, 1.f)));
4021 params.push_back(create<ast::ScalarConstructorExpression>(
4022 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclair2287d012020-04-22 00:23:57 +00004023
dan sinclair6b59bf42020-12-11 19:16:13 +00004024 auto* ident = create<ast::IdentifierExpression>(
4025 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004026 ast::CallExpression call(ident, params);
dan sinclair2287d012020-04-22 00:23:57 +00004027
dan sinclairb4fee2f2020-09-22 19:42:13 +00004028 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair2287d012020-04-22 00:23:57 +00004029 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4030 param.name + ". Expected 3 got 2");
4031}
4032
4033TEST_P(ImportData_ThreeParamTest, Error_MismatchedParamCount) {
4034 auto param = GetParam();
4035
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004036 ast::type::F32 f32;
4037 ast::type::Vector vec2(&f32, 2);
4038 ast::type::Vector vec3(&f32, 3);
dan sinclair2287d012020-04-22 00:23:57 +00004039
4040 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004041 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4042 create<ast::FloatLiteral>(&f32, 1.0f)));
4043 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4044 create<ast::FloatLiteral>(&f32, 1.0f)));
dan sinclair2287d012020-04-22 00:23:57 +00004045
4046 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004047 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4048 create<ast::FloatLiteral>(&f32, 1.0f)));
4049 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4050 create<ast::FloatLiteral>(&f32, 1.0f)));
4051 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4052 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclair2287d012020-04-22 00:23:57 +00004053
4054 ast::ExpressionList vals_3;
Ben Clayton62625922020-11-13 22:09:38 +00004055 vals_3.push_back(create<ast::ScalarConstructorExpression>(
4056 create<ast::FloatLiteral>(&f32, 1.0f)));
4057 vals_3.push_back(create<ast::ScalarConstructorExpression>(
4058 create<ast::FloatLiteral>(&f32, 1.0f)));
4059 vals_3.push_back(create<ast::ScalarConstructorExpression>(
4060 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclair2287d012020-04-22 00:23:57 +00004061
4062 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00004063 params.push_back(create<ast::TypeConstructorExpression>(&vec2, vals_1));
4064 params.push_back(create<ast::TypeConstructorExpression>(&vec3, vals_2));
4065 params.push_back(create<ast::TypeConstructorExpression>(&vec3, vals_3));
dan sinclair2287d012020-04-22 00:23:57 +00004066
dan sinclair6b59bf42020-12-11 19:16:13 +00004067 auto* ident = create<ast::IdentifierExpression>(
4068 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004069 ast::CallExpression call(ident, params);
dan sinclair2287d012020-04-22 00:23:57 +00004070
dan sinclairb4fee2f2020-09-22 19:42:13 +00004071 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair2287d012020-04-22 00:23:57 +00004072 EXPECT_EQ(td()->error(),
4073 std::string("mismatched parameter types for ") + param.name);
4074}
4075
4076TEST_P(ImportData_ThreeParamTest, Error_MismatchedParamType) {
4077 auto param = GetParam();
4078
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004079 ast::type::F32 f32;
4080 ast::type::Vector vec(&f32, 3);
dan sinclair2287d012020-04-22 00:23:57 +00004081
4082 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00004083 vals.push_back(create<ast::ScalarConstructorExpression>(
4084 create<ast::FloatLiteral>(&f32, 1.0f)));
4085 vals.push_back(create<ast::ScalarConstructorExpression>(
4086 create<ast::FloatLiteral>(&f32, 1.0f)));
4087 vals.push_back(create<ast::ScalarConstructorExpression>(
4088 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclair2287d012020-04-22 00:23:57 +00004089
4090 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004091 params.push_back(create<ast::ScalarConstructorExpression>(
4092 create<ast::FloatLiteral>(&f32, 1.0f)));
4093 params.push_back(create<ast::ScalarConstructorExpression>(
4094 create<ast::FloatLiteral>(&f32, 1.0f)));
Ben Clayton4bfe4612020-11-16 16:41:47 +00004095 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals));
dan sinclair2287d012020-04-22 00:23:57 +00004096
dan sinclair6b59bf42020-12-11 19:16:13 +00004097 auto* ident = create<ast::IdentifierExpression>(
4098 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004099 ast::CallExpression call(ident, params);
dan sinclair2287d012020-04-22 00:23:57 +00004100
dan sinclairb4fee2f2020-09-22 19:42:13 +00004101 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair2287d012020-04-22 00:23:57 +00004102 EXPECT_EQ(td()->error(),
4103 std::string("mismatched parameter types for ") + param.name);
4104}
4105
4106TEST_P(ImportData_ThreeParamTest, Error_TooManyParams) {
4107 auto param = GetParam();
4108
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004109 ast::type::F32 f32;
dan sinclair2287d012020-04-22 00:23:57 +00004110 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004111 params.push_back(create<ast::ScalarConstructorExpression>(
4112 create<ast::FloatLiteral>(&f32, 1.f)));
4113 params.push_back(create<ast::ScalarConstructorExpression>(
4114 create<ast::FloatLiteral>(&f32, 1.f)));
4115 params.push_back(create<ast::ScalarConstructorExpression>(
4116 create<ast::FloatLiteral>(&f32, 1.f)));
4117 params.push_back(create<ast::ScalarConstructorExpression>(
4118 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclair2287d012020-04-22 00:23:57 +00004119
dan sinclair6b59bf42020-12-11 19:16:13 +00004120 auto* ident = create<ast::IdentifierExpression>(
4121 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004122 ast::CallExpression call(ident, params);
dan sinclair2287d012020-04-22 00:23:57 +00004123
dan sinclairb4fee2f2020-09-22 19:42:13 +00004124 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair2287d012020-04-22 00:23:57 +00004125 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4126 param.name + ". Expected 3 got 4");
4127}
4128
4129INSTANTIATE_TEST_SUITE_P(
4130 TypeDeterminerTest,
4131 ImportData_ThreeParamTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00004132 testing::Values(IntrinsicData{"mix", ast::Intrinsic::kMix},
4133 IntrinsicData{"smoothStep", ast::Intrinsic::kSmoothStep},
4134 IntrinsicData{"fma", ast::Intrinsic::kFma},
4135 IntrinsicData{"faceForward",
4136 ast::Intrinsic::kFaceForward}));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004137
dan sinclairb4fee2f2020-09-22 19:42:13 +00004138using ImportData_ThreeParam_FloatOrInt_Test =
4139 TypeDeterminerTestWithParam<IntrinsicData>;
4140TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Float_Scalar) {
4141 auto param = GetParam();
4142
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004143 ast::type::F32 f32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004144
4145 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004146 params.push_back(create<ast::ScalarConstructorExpression>(
4147 create<ast::FloatLiteral>(&f32, 1.f)));
4148 params.push_back(create<ast::ScalarConstructorExpression>(
4149 create<ast::FloatLiteral>(&f32, 1.f)));
4150 params.push_back(create<ast::ScalarConstructorExpression>(
4151 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004152
dan sinclair6b59bf42020-12-11 19:16:13 +00004153 auto* ident = create<ast::IdentifierExpression>(
4154 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004155
4156 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004157
4158 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004159 ASSERT_NE(ident->result_type(), nullptr);
4160 EXPECT_TRUE(ident->result_type()->is_float_scalar());
dan sinclairb4fee2f2020-09-22 19:42:13 +00004161}
4162
4163TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Float_Vector) {
4164 auto param = GetParam();
4165
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004166 ast::type::F32 f32;
4167 ast::type::Vector vec(&f32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004168
4169 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004170 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4171 create<ast::FloatLiteral>(&f32, 1.0f)));
4172 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4173 create<ast::FloatLiteral>(&f32, 1.0f)));
4174 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4175 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004176
4177 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004178 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4179 create<ast::FloatLiteral>(&f32, 1.0f)));
4180 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4181 create<ast::FloatLiteral>(&f32, 1.0f)));
4182 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4183 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004184
4185 ast::ExpressionList vals_3;
Ben Clayton62625922020-11-13 22:09:38 +00004186 vals_3.push_back(create<ast::ScalarConstructorExpression>(
4187 create<ast::FloatLiteral>(&f32, 1.0f)));
4188 vals_3.push_back(create<ast::ScalarConstructorExpression>(
4189 create<ast::FloatLiteral>(&f32, 1.0f)));
4190 vals_3.push_back(create<ast::ScalarConstructorExpression>(
4191 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004192
4193 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00004194 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_1));
4195 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_2));
4196 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_3));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004197
dan sinclair6b59bf42020-12-11 19:16:13 +00004198 auto* ident = create<ast::IdentifierExpression>(
4199 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004200
4201 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004202
4203 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004204 ASSERT_NE(ident->result_type(), nullptr);
4205 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004206 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004207}
4208
4209TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Sint_Scalar) {
4210 auto param = GetParam();
4211
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004212 ast::type::I32 i32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004213
4214 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004215 params.push_back(create<ast::ScalarConstructorExpression>(
4216 create<ast::SintLiteral>(&i32, 1)));
4217 params.push_back(create<ast::ScalarConstructorExpression>(
4218 create<ast::SintLiteral>(&i32, 1)));
4219 params.push_back(create<ast::ScalarConstructorExpression>(
4220 create<ast::SintLiteral>(&i32, 1)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004221
dan sinclair6b59bf42020-12-11 19:16:13 +00004222 auto* ident = create<ast::IdentifierExpression>(
4223 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004224
4225 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004226
4227 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004228 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004229 EXPECT_TRUE(ident->result_type()->Is<ast::type::I32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00004230}
4231
4232TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Sint_Vector) {
4233 auto param = GetParam();
4234
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004235 ast::type::I32 i32;
4236 ast::type::Vector vec(&i32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004237
4238 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004239 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4240 create<ast::SintLiteral>(&i32, 1)));
4241 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4242 create<ast::SintLiteral>(&i32, 1)));
4243 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4244 create<ast::SintLiteral>(&i32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004245
4246 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004247 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4248 create<ast::SintLiteral>(&i32, 1)));
4249 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4250 create<ast::SintLiteral>(&i32, 1)));
4251 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4252 create<ast::SintLiteral>(&i32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004253
4254 ast::ExpressionList vals_3;
Ben Clayton62625922020-11-13 22:09:38 +00004255 vals_3.push_back(create<ast::ScalarConstructorExpression>(
4256 create<ast::SintLiteral>(&i32, 1)));
4257 vals_3.push_back(create<ast::ScalarConstructorExpression>(
4258 create<ast::SintLiteral>(&i32, 1)));
4259 vals_3.push_back(create<ast::ScalarConstructorExpression>(
4260 create<ast::SintLiteral>(&i32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004261
4262 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00004263 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_1));
4264 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_2));
4265 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_3));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004266
dan sinclair6b59bf42020-12-11 19:16:13 +00004267 auto* ident = create<ast::IdentifierExpression>(
4268 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004269
4270 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004271
4272 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004273 ASSERT_NE(ident->result_type(), nullptr);
4274 EXPECT_TRUE(ident->result_type()->is_signed_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004275 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004276}
4277
4278TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Uint_Scalar) {
4279 auto param = GetParam();
4280
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004281 ast::type::U32 u32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004282
4283 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004284 params.push_back(create<ast::ScalarConstructorExpression>(
4285 create<ast::UintLiteral>(&u32, 1)));
4286 params.push_back(create<ast::ScalarConstructorExpression>(
4287 create<ast::UintLiteral>(&u32, 1)));
4288 params.push_back(create<ast::ScalarConstructorExpression>(
4289 create<ast::UintLiteral>(&u32, 1)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004290
dan sinclair6b59bf42020-12-11 19:16:13 +00004291 auto* ident = create<ast::IdentifierExpression>(
4292 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004293
4294 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004295
4296 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004297 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004298 EXPECT_TRUE(ident->result_type()->Is<ast::type::U32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00004299}
4300
4301TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Uint_Vector) {
4302 auto param = GetParam();
4303
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004304 ast::type::U32 u32;
4305 ast::type::Vector vec(&u32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004306
4307 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004308 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4309 create<ast::UintLiteral>(&u32, 1)));
4310 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4311 create<ast::UintLiteral>(&u32, 1)));
4312 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4313 create<ast::UintLiteral>(&u32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004314
4315 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004316 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4317 create<ast::UintLiteral>(&u32, 1)));
4318 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4319 create<ast::UintLiteral>(&u32, 1)));
4320 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4321 create<ast::UintLiteral>(&u32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004322
4323 ast::ExpressionList vals_3;
Ben Clayton62625922020-11-13 22:09:38 +00004324 vals_3.push_back(create<ast::ScalarConstructorExpression>(
4325 create<ast::UintLiteral>(&u32, 1)));
4326 vals_3.push_back(create<ast::ScalarConstructorExpression>(
4327 create<ast::UintLiteral>(&u32, 1)));
4328 vals_3.push_back(create<ast::ScalarConstructorExpression>(
4329 create<ast::UintLiteral>(&u32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004330
4331 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00004332 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_1));
4333 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_2));
4334 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_3));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004335
dan sinclair6b59bf42020-12-11 19:16:13 +00004336 auto* ident = create<ast::IdentifierExpression>(
4337 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004338
4339 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004340
4341 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004342 ASSERT_NE(ident->result_type(), nullptr);
4343 EXPECT_TRUE(ident->result_type()->is_unsigned_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004344 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004345}
4346
4347TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_Bool) {
4348 auto param = GetParam();
4349
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004350 ast::type::Bool bool_type;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004351
4352 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004353 params.push_back(create<ast::ScalarConstructorExpression>(
4354 create<ast::BoolLiteral>(&bool_type, true)));
4355 params.push_back(create<ast::ScalarConstructorExpression>(
4356 create<ast::BoolLiteral>(&bool_type, false)));
4357 params.push_back(create<ast::ScalarConstructorExpression>(
4358 create<ast::BoolLiteral>(&bool_type, true)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004359
dan sinclair6b59bf42020-12-11 19:16:13 +00004360 auto* ident = create<ast::IdentifierExpression>(
4361 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004362 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004363
4364 EXPECT_FALSE(td()->DetermineResultType(&call));
4365 EXPECT_EQ(td()->error(),
4366 std::string("incorrect type for ") + param.name +
4367 ". Requires float or int, scalar or vector values");
4368}
4369
4370TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_NoParams) {
4371 auto param = GetParam();
4372
4373 ast::ExpressionList params;
4374
dan sinclair6b59bf42020-12-11 19:16:13 +00004375 auto* ident = create<ast::IdentifierExpression>(
4376 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004377 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004378
4379 EXPECT_FALSE(td()->DetermineResultType(&call));
4380 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4381 param.name + ". Expected 3 got 0");
4382}
4383
4384TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_OneParam) {
4385 auto param = GetParam();
4386
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004387 ast::type::F32 f32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004388 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004389 params.push_back(create<ast::ScalarConstructorExpression>(
4390 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004391
dan sinclair6b59bf42020-12-11 19:16:13 +00004392 auto* ident = create<ast::IdentifierExpression>(
4393 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004394 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004395
4396 EXPECT_FALSE(td()->DetermineResultType(&call));
4397 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4398 param.name + ". Expected 3 got 1");
4399}
4400
4401TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_TwoParams) {
4402 auto param = GetParam();
4403
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004404 ast::type::F32 f32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004405 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004406 params.push_back(create<ast::ScalarConstructorExpression>(
4407 create<ast::FloatLiteral>(&f32, 1.f)));
4408 params.push_back(create<ast::ScalarConstructorExpression>(
4409 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004410
dan sinclair6b59bf42020-12-11 19:16:13 +00004411 auto* ident = create<ast::IdentifierExpression>(
4412 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004413 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004414
4415 EXPECT_FALSE(td()->DetermineResultType(&call));
4416 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4417 param.name + ". Expected 3 got 2");
4418}
4419
4420TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_MismatchedParamCount) {
4421 auto param = GetParam();
4422
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004423 ast::type::F32 f32;
4424 ast::type::Vector vec2(&f32, 2);
4425 ast::type::Vector vec3(&f32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004426
4427 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004428 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4429 create<ast::FloatLiteral>(&f32, 1.0f)));
4430 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4431 create<ast::FloatLiteral>(&f32, 1.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004432
4433 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004434 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4435 create<ast::FloatLiteral>(&f32, 1.0f)));
4436 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4437 create<ast::FloatLiteral>(&f32, 1.0f)));
4438 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4439 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004440
4441 ast::ExpressionList vals_3;
Ben Clayton62625922020-11-13 22:09:38 +00004442 vals_3.push_back(create<ast::ScalarConstructorExpression>(
4443 create<ast::FloatLiteral>(&f32, 1.0f)));
4444 vals_3.push_back(create<ast::ScalarConstructorExpression>(
4445 create<ast::FloatLiteral>(&f32, 1.0f)));
4446 vals_3.push_back(create<ast::ScalarConstructorExpression>(
4447 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004448
4449 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00004450 params.push_back(create<ast::TypeConstructorExpression>(&vec2, vals_1));
4451 params.push_back(create<ast::TypeConstructorExpression>(&vec3, vals_2));
4452 params.push_back(create<ast::TypeConstructorExpression>(&vec3, vals_3));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004453
dan sinclair6b59bf42020-12-11 19:16:13 +00004454 auto* ident = create<ast::IdentifierExpression>(
4455 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004456 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004457
4458 EXPECT_FALSE(td()->DetermineResultType(&call));
4459 EXPECT_EQ(td()->error(),
4460 std::string("mismatched parameter types for ") + param.name);
4461}
4462
4463TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_MismatchedParamType) {
4464 auto param = GetParam();
4465
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004466 ast::type::F32 f32;
4467 ast::type::Vector vec(&f32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004468
4469 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00004470 vals.push_back(create<ast::ScalarConstructorExpression>(
4471 create<ast::FloatLiteral>(&f32, 1.0f)));
4472 vals.push_back(create<ast::ScalarConstructorExpression>(
4473 create<ast::FloatLiteral>(&f32, 1.0f)));
4474 vals.push_back(create<ast::ScalarConstructorExpression>(
4475 create<ast::FloatLiteral>(&f32, 3.0f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004476
4477 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004478 params.push_back(create<ast::ScalarConstructorExpression>(
4479 create<ast::FloatLiteral>(&f32, 1.0f)));
4480 params.push_back(create<ast::ScalarConstructorExpression>(
4481 create<ast::FloatLiteral>(&f32, 1.0f)));
Ben Clayton4bfe4612020-11-16 16:41:47 +00004482 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004483
dan sinclair6b59bf42020-12-11 19:16:13 +00004484 auto* ident = create<ast::IdentifierExpression>(
4485 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004486 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004487
4488 EXPECT_FALSE(td()->DetermineResultType(&call));
4489 EXPECT_EQ(td()->error(),
4490 std::string("mismatched parameter types for ") + param.name);
4491}
4492
4493TEST_P(ImportData_ThreeParam_FloatOrInt_Test, Error_TooManyParams) {
4494 auto param = GetParam();
4495
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004496 ast::type::F32 f32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004497 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004498 params.push_back(create<ast::ScalarConstructorExpression>(
4499 create<ast::FloatLiteral>(&f32, 1.f)));
4500 params.push_back(create<ast::ScalarConstructorExpression>(
4501 create<ast::FloatLiteral>(&f32, 1.f)));
4502 params.push_back(create<ast::ScalarConstructorExpression>(
4503 create<ast::FloatLiteral>(&f32, 1.f)));
4504 params.push_back(create<ast::ScalarConstructorExpression>(
4505 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004506
dan sinclair6b59bf42020-12-11 19:16:13 +00004507 auto* ident = create<ast::IdentifierExpression>(
4508 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004509 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004510
4511 EXPECT_FALSE(td()->DetermineResultType(&call));
4512 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4513 param.name + ". Expected 3 got 4");
4514}
4515
4516INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
4517 ImportData_ThreeParam_FloatOrInt_Test,
4518 testing::Values(IntrinsicData{
4519 "clamp", ast::Intrinsic::kClamp}));
4520
4521using ImportData_Int_SingleParamTest =
4522 TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004523TEST_P(ImportData_Int_SingleParamTest, Scalar) {
4524 auto param = GetParam();
4525
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004526 ast::type::I32 i32;
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004527
4528 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004529 params.push_back(create<ast::ScalarConstructorExpression>(
4530 create<ast::SintLiteral>(&i32, 1)));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004531
dan sinclair6b59bf42020-12-11 19:16:13 +00004532 auto* ident = create<ast::IdentifierExpression>(
4533 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004534
4535 ast::CallExpression call(ident, params);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004536
dan sinclairb4fee2f2020-09-22 19:42:13 +00004537 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004538 ASSERT_NE(ident->result_type(), nullptr);
4539 EXPECT_TRUE(ident->result_type()->is_integer_scalar());
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004540}
4541
4542TEST_P(ImportData_Int_SingleParamTest, Vector) {
4543 auto param = GetParam();
4544
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004545 ast::type::I32 i32;
4546 ast::type::Vector vec(&i32, 3);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004547
4548 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00004549 vals.push_back(create<ast::ScalarConstructorExpression>(
4550 create<ast::SintLiteral>(&i32, 1)));
4551 vals.push_back(create<ast::ScalarConstructorExpression>(
4552 create<ast::SintLiteral>(&i32, 1)));
4553 vals.push_back(create<ast::ScalarConstructorExpression>(
4554 create<ast::SintLiteral>(&i32, 3)));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004555
4556 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00004557 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004558
dan sinclair6b59bf42020-12-11 19:16:13 +00004559 auto* ident = create<ast::IdentifierExpression>(
4560 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004561
4562 ast::CallExpression call(ident, params);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004563
dan sinclairb4fee2f2020-09-22 19:42:13 +00004564 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004565 ASSERT_NE(ident->result_type(), nullptr);
4566 EXPECT_TRUE(ident->result_type()->is_signed_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004567 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004568}
4569
4570TEST_P(ImportData_Int_SingleParamTest, Error_Float) {
4571 auto param = GetParam();
4572
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004573 ast::type::F32 f32;
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004574
4575 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004576 params.push_back(create<ast::ScalarConstructorExpression>(
4577 create<ast::FloatLiteral>(&f32, 1.f)));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004578
dan sinclair6b59bf42020-12-11 19:16:13 +00004579 auto* ident = create<ast::IdentifierExpression>(
4580 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004581 ast::CallExpression call(ident, params);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004582
dan sinclairb4fee2f2020-09-22 19:42:13 +00004583 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004584 EXPECT_EQ(td()->error(),
4585 std::string("incorrect type for ") + param.name +
4586 ". Requires integer scalar or integer vector values");
4587}
4588
4589TEST_P(ImportData_Int_SingleParamTest, Error_NoParams) {
4590 auto param = GetParam();
4591
4592 ast::ExpressionList params;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004593
dan sinclair6b59bf42020-12-11 19:16:13 +00004594 auto* ident = create<ast::IdentifierExpression>(
4595 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004596 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004597
4598 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004599 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4600 param.name + ". Expected 1 got 0");
4601}
4602
4603TEST_P(ImportData_Int_SingleParamTest, Error_MultipleParams) {
4604 auto param = GetParam();
4605
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004606 ast::type::I32 i32;
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004607 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004608 params.push_back(create<ast::ScalarConstructorExpression>(
4609 create<ast::SintLiteral>(&i32, 1)));
4610 params.push_back(create<ast::ScalarConstructorExpression>(
4611 create<ast::SintLiteral>(&i32, 1)));
4612 params.push_back(create<ast::ScalarConstructorExpression>(
4613 create<ast::SintLiteral>(&i32, 1)));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004614
dan sinclair6b59bf42020-12-11 19:16:13 +00004615 auto* ident = create<ast::IdentifierExpression>(
4616 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004617 ast::CallExpression call(ident, params);
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004618
dan sinclairb4fee2f2020-09-22 19:42:13 +00004619 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004620 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4621 param.name + ". Expected 1 got 3");
4622}
4623
dan sinclairaf5df702020-06-08 23:48:26 +00004624INSTANTIATE_TEST_SUITE_P(
4625 TypeDeterminerTest,
4626 ImportData_Int_SingleParamTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00004627 testing::Values(
4628 IntrinsicData{"countOneBits", ast::Intrinsic::kCountOneBits},
4629 IntrinsicData{"reverseBits", ast::Intrinsic::kReverseBits}));
dan sinclair5e5fb9c2020-06-08 19:01:07 +00004630
dan sinclairb4fee2f2020-09-22 19:42:13 +00004631using ImportData_FloatOrInt_TwoParamTest =
4632 TypeDeterminerTestWithParam<IntrinsicData>;
4633TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Signed) {
dan sinclair92bb5572020-06-08 23:48:07 +00004634 auto param = GetParam();
4635
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004636 ast::type::I32 i32;
dan sinclair92bb5572020-06-08 23:48:07 +00004637
4638 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004639 params.push_back(create<ast::ScalarConstructorExpression>(
4640 create<ast::SintLiteral>(&i32, 1)));
4641 params.push_back(create<ast::ScalarConstructorExpression>(
4642 create<ast::SintLiteral>(&i32, 1)));
dan sinclair92bb5572020-06-08 23:48:07 +00004643
dan sinclair6b59bf42020-12-11 19:16:13 +00004644 auto* ident = create<ast::IdentifierExpression>(
4645 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004646
4647 ast::CallExpression call(ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00004648
dan sinclairb4fee2f2020-09-22 19:42:13 +00004649 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004650 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004651 EXPECT_TRUE(ident->result_type()->Is<ast::type::I32>());
dan sinclair92bb5572020-06-08 23:48:07 +00004652}
4653
dan sinclairb4fee2f2020-09-22 19:42:13 +00004654TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Unsigned) {
dan sinclair92bb5572020-06-08 23:48:07 +00004655 auto param = GetParam();
4656
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004657 ast::type::U32 u32;
dan sinclair92bb5572020-06-08 23:48:07 +00004658
4659 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004660 params.push_back(create<ast::ScalarConstructorExpression>(
4661 create<ast::UintLiteral>(&u32, 1)));
4662 params.push_back(create<ast::ScalarConstructorExpression>(
4663 create<ast::UintLiteral>(&u32, 1)));
dan sinclair92bb5572020-06-08 23:48:07 +00004664
dan sinclair6b59bf42020-12-11 19:16:13 +00004665 auto* ident = create<ast::IdentifierExpression>(
4666 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004667
4668 ast::CallExpression call(ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00004669
dan sinclairb4fee2f2020-09-22 19:42:13 +00004670 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004671 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004672 EXPECT_TRUE(ident->result_type()->Is<ast::type::U32>());
dan sinclair92bb5572020-06-08 23:48:07 +00004673}
4674
dan sinclairb4fee2f2020-09-22 19:42:13 +00004675TEST_P(ImportData_FloatOrInt_TwoParamTest, Scalar_Float) {
4676 auto param = GetParam();
4677
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004678 ast::type::F32 f32;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004679
4680 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004681 params.push_back(create<ast::ScalarConstructorExpression>(
4682 create<ast::FloatLiteral>(&f32, 1)));
4683 params.push_back(create<ast::ScalarConstructorExpression>(
4684 create<ast::FloatLiteral>(&f32, 1)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004685
dan sinclair6b59bf42020-12-11 19:16:13 +00004686 auto* ident = create<ast::IdentifierExpression>(
4687 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004688
4689 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004690
4691 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004692 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004693 EXPECT_TRUE(ident->result_type()->Is<ast::type::F32>());
dan sinclairb4fee2f2020-09-22 19:42:13 +00004694}
4695
4696TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Signed) {
dan sinclair92bb5572020-06-08 23:48:07 +00004697 auto param = GetParam();
4698
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004699 ast::type::I32 i32;
4700 ast::type::Vector vec(&i32, 3);
dan sinclair92bb5572020-06-08 23:48:07 +00004701
4702 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004703 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4704 create<ast::SintLiteral>(&i32, 1)));
4705 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4706 create<ast::SintLiteral>(&i32, 1)));
4707 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4708 create<ast::SintLiteral>(&i32, 3)));
dan sinclair92bb5572020-06-08 23:48:07 +00004709
4710 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004711 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4712 create<ast::SintLiteral>(&i32, 1)));
4713 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4714 create<ast::SintLiteral>(&i32, 1)));
4715 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4716 create<ast::SintLiteral>(&i32, 3)));
dan sinclair92bb5572020-06-08 23:48:07 +00004717
4718 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00004719 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_1));
4720 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_2));
dan sinclair92bb5572020-06-08 23:48:07 +00004721
dan sinclair6b59bf42020-12-11 19:16:13 +00004722 auto* ident = create<ast::IdentifierExpression>(
4723 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004724
4725 ast::CallExpression call(ident, params);
dan sinclair92bb5572020-06-08 23:48: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_signed_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004730 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair92bb5572020-06-08 23:48:07 +00004731}
4732
dan sinclairb4fee2f2020-09-22 19:42:13 +00004733TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Unsigned) {
dan sinclair92bb5572020-06-08 23:48:07 +00004734 auto param = GetParam();
4735
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004736 ast::type::U32 u32;
4737 ast::type::Vector vec(&u32, 3);
dan sinclair92bb5572020-06-08 23:48:07 +00004738
4739 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004740 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4741 create<ast::UintLiteral>(&u32, 1)));
4742 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4743 create<ast::UintLiteral>(&u32, 1)));
4744 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4745 create<ast::UintLiteral>(&u32, 3)));
dan sinclair92bb5572020-06-08 23:48:07 +00004746
4747 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004748 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4749 create<ast::UintLiteral>(&u32, 1)));
4750 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4751 create<ast::UintLiteral>(&u32, 1)));
4752 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4753 create<ast::UintLiteral>(&u32, 3)));
dan sinclair92bb5572020-06-08 23:48:07 +00004754
4755 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00004756 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_1));
4757 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_2));
dan sinclair92bb5572020-06-08 23:48:07 +00004758
dan sinclair6b59bf42020-12-11 19:16:13 +00004759 auto* ident = create<ast::IdentifierExpression>(
4760 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004761
4762 ast::CallExpression call(ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00004763
dan sinclairb4fee2f2020-09-22 19:42:13 +00004764 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004765 ASSERT_NE(ident->result_type(), nullptr);
4766 EXPECT_TRUE(ident->result_type()->is_unsigned_integer_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004767 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclair92bb5572020-06-08 23:48:07 +00004768}
4769
dan sinclairb4fee2f2020-09-22 19:42:13 +00004770TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Float) {
dan sinclair92bb5572020-06-08 23:48:07 +00004771 auto param = GetParam();
4772
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004773 ast::type::F32 f32;
4774 ast::type::Vector vec(&f32, 3);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004775
4776 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004777 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4778 create<ast::FloatLiteral>(&f32, 1)));
4779 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4780 create<ast::FloatLiteral>(&f32, 1)));
4781 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4782 create<ast::FloatLiteral>(&f32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004783
4784 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004785 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4786 create<ast::FloatLiteral>(&f32, 1)));
4787 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4788 create<ast::FloatLiteral>(&f32, 1)));
4789 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4790 create<ast::FloatLiteral>(&f32, 3)));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004791
4792 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00004793 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_1));
4794 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals_2));
dan sinclairb4fee2f2020-09-22 19:42:13 +00004795
dan sinclair6b59bf42020-12-11 19:16:13 +00004796 auto* ident = create<ast::IdentifierExpression>(
4797 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004798
4799 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004800
4801 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004802 ASSERT_NE(ident->result_type(), nullptr);
4803 EXPECT_TRUE(ident->result_type()->is_float_vector());
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004804 EXPECT_EQ(ident->result_type()->As<ast::type::Vector>()->size(), 3u);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004805}
4806
4807TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_Bool) {
4808 auto param = GetParam();
4809
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004810 ast::type::Bool bool_type;
dan sinclair92bb5572020-06-08 23:48:07 +00004811
4812 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004813 params.push_back(create<ast::ScalarConstructorExpression>(
4814 create<ast::BoolLiteral>(&bool_type, true)));
4815 params.push_back(create<ast::ScalarConstructorExpression>(
4816 create<ast::BoolLiteral>(&bool_type, false)));
dan sinclair92bb5572020-06-08 23:48:07 +00004817
dan sinclair6b59bf42020-12-11 19:16:13 +00004818 auto* ident = create<ast::IdentifierExpression>(
4819 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004820 ast::CallExpression call(ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00004821
dan sinclairb4fee2f2020-09-22 19:42:13 +00004822 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair92bb5572020-06-08 23:48:07 +00004823 EXPECT_EQ(td()->error(),
4824 std::string("incorrect type for ") + param.name +
dan sinclairb4fee2f2020-09-22 19:42:13 +00004825 ". Requires float or int, scalar or vector values");
dan sinclair92bb5572020-06-08 23:48:07 +00004826}
4827
dan sinclairb4fee2f2020-09-22 19:42:13 +00004828TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_NoParams) {
dan sinclair92bb5572020-06-08 23:48:07 +00004829 auto param = GetParam();
4830
4831 ast::ExpressionList params;
dan sinclairb4fee2f2020-09-22 19:42:13 +00004832
dan sinclair6b59bf42020-12-11 19:16:13 +00004833 auto* ident = create<ast::IdentifierExpression>(
4834 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004835 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00004836
4837 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair92bb5572020-06-08 23:48:07 +00004838 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4839 param.name + ". Expected 2 got 0");
4840}
4841
dan sinclairb4fee2f2020-09-22 19:42:13 +00004842TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_OneParam) {
dan sinclair92bb5572020-06-08 23:48:07 +00004843 auto param = GetParam();
4844
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004845 ast::type::I32 i32;
dan sinclair92bb5572020-06-08 23:48:07 +00004846 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004847 params.push_back(create<ast::ScalarConstructorExpression>(
4848 create<ast::SintLiteral>(&i32, 1)));
dan sinclair92bb5572020-06-08 23:48:07 +00004849
dan sinclair6b59bf42020-12-11 19:16:13 +00004850 auto* ident = create<ast::IdentifierExpression>(
4851 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004852 ast::CallExpression call(ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00004853
dan sinclairb4fee2f2020-09-22 19:42:13 +00004854 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair92bb5572020-06-08 23:48:07 +00004855 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4856 param.name + ". Expected 2 got 1");
4857}
4858
dan sinclairb4fee2f2020-09-22 19:42:13 +00004859TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_MismatchedParamCount) {
dan sinclair92bb5572020-06-08 23:48:07 +00004860 auto param = GetParam();
4861
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004862 ast::type::I32 i32;
4863 ast::type::Vector vec2(&i32, 2);
4864 ast::type::Vector vec3(&i32, 3);
dan sinclair92bb5572020-06-08 23:48:07 +00004865
4866 ast::ExpressionList vals_1;
Ben Clayton62625922020-11-13 22:09:38 +00004867 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4868 create<ast::SintLiteral>(&i32, 1)));
4869 vals_1.push_back(create<ast::ScalarConstructorExpression>(
4870 create<ast::SintLiteral>(&i32, 1)));
dan sinclair92bb5572020-06-08 23:48:07 +00004871
4872 ast::ExpressionList vals_2;
Ben Clayton62625922020-11-13 22:09:38 +00004873 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4874 create<ast::SintLiteral>(&i32, 1)));
4875 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4876 create<ast::SintLiteral>(&i32, 1)));
4877 vals_2.push_back(create<ast::ScalarConstructorExpression>(
4878 create<ast::SintLiteral>(&i32, 3)));
dan sinclair92bb5572020-06-08 23:48:07 +00004879
4880 ast::ExpressionList params;
Ben Clayton4bfe4612020-11-16 16:41:47 +00004881 params.push_back(create<ast::TypeConstructorExpression>(&vec2, vals_1));
4882 params.push_back(create<ast::TypeConstructorExpression>(&vec3, vals_2));
dan sinclair92bb5572020-06-08 23:48:07 +00004883
dan sinclair6b59bf42020-12-11 19:16:13 +00004884 auto* ident = create<ast::IdentifierExpression>(
4885 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004886 ast::CallExpression call(ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00004887
dan sinclairb4fee2f2020-09-22 19:42:13 +00004888 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair92bb5572020-06-08 23:48:07 +00004889 EXPECT_EQ(td()->error(),
4890 std::string("mismatched parameter types for ") + param.name);
4891}
4892
dan sinclairb4fee2f2020-09-22 19:42:13 +00004893TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_MismatchedParamType) {
dan sinclair92bb5572020-06-08 23:48:07 +00004894 auto param = GetParam();
4895
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004896 ast::type::I32 i32;
4897 ast::type::Vector vec(&i32, 3);
dan sinclair92bb5572020-06-08 23:48:07 +00004898
4899 ast::ExpressionList vals;
Ben Clayton62625922020-11-13 22:09:38 +00004900 vals.push_back(create<ast::ScalarConstructorExpression>(
4901 create<ast::SintLiteral>(&i32, 1)));
4902 vals.push_back(create<ast::ScalarConstructorExpression>(
4903 create<ast::SintLiteral>(&i32, 1)));
4904 vals.push_back(create<ast::ScalarConstructorExpression>(
4905 create<ast::SintLiteral>(&i32, 3)));
dan sinclair92bb5572020-06-08 23:48:07 +00004906
4907 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004908 params.push_back(create<ast::ScalarConstructorExpression>(
4909 create<ast::SintLiteral>(&i32, 1)));
Ben Clayton4bfe4612020-11-16 16:41:47 +00004910 params.push_back(create<ast::TypeConstructorExpression>(&vec, vals));
dan sinclair92bb5572020-06-08 23:48:07 +00004911
dan sinclair6b59bf42020-12-11 19:16:13 +00004912 auto* ident = create<ast::IdentifierExpression>(
4913 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004914 ast::CallExpression call(ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00004915
dan sinclairb4fee2f2020-09-22 19:42:13 +00004916 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair92bb5572020-06-08 23:48:07 +00004917 EXPECT_EQ(td()->error(),
4918 std::string("mismatched parameter types for ") + param.name);
4919}
4920
dan sinclairb4fee2f2020-09-22 19:42:13 +00004921TEST_P(ImportData_FloatOrInt_TwoParamTest, Error_TooManyParams) {
dan sinclair92bb5572020-06-08 23:48:07 +00004922 auto param = GetParam();
4923
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004924 ast::type::I32 i32;
dan sinclair92bb5572020-06-08 23:48:07 +00004925 ast::ExpressionList params;
Ben Clayton62625922020-11-13 22:09:38 +00004926 params.push_back(create<ast::ScalarConstructorExpression>(
4927 create<ast::SintLiteral>(&i32, 1)));
4928 params.push_back(create<ast::ScalarConstructorExpression>(
4929 create<ast::SintLiteral>(&i32, 1)));
4930 params.push_back(create<ast::ScalarConstructorExpression>(
4931 create<ast::SintLiteral>(&i32, 1)));
dan sinclair92bb5572020-06-08 23:48:07 +00004932
dan sinclair6b59bf42020-12-11 19:16:13 +00004933 auto* ident = create<ast::IdentifierExpression>(
4934 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00004935 ast::CallExpression call(ident, params);
dan sinclair92bb5572020-06-08 23:48:07 +00004936
dan sinclairb4fee2f2020-09-22 19:42:13 +00004937 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair92bb5572020-06-08 23:48:07 +00004938 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
4939 param.name + ". Expected 2 got 3");
4940}
4941
dan sinclairb4fee2f2020-09-22 19:42:13 +00004942INSTANTIATE_TEST_SUITE_P(
4943 TypeDeterminerTest,
4944 ImportData_FloatOrInt_TwoParamTest,
4945 testing::Values(IntrinsicData{"min", ast::Intrinsic::kMin},
4946 IntrinsicData{"max", ast::Intrinsic::kMax}));
dan sinclair92bb5572020-06-08 23:48:07 +00004947
dan sinclair3238eaa2020-06-17 20:22:08 +00004948TEST_F(TypeDeterminerTest, ImportData_GLSL_Determinant) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004949 ast::type::F32 f32;
4950 ast::type::Matrix mat(&f32, 3, 3);
dan sinclair3819c262020-06-17 18:39:17 +00004951
Ben Claytona80511e2020-12-11 13:07:02 +00004952 auto* var =
4953 create<ast::Variable>(Source{}, // source
4954 "var", // name
4955 ast::StorageClass::kFunction, // storage_class
4956 &mat, // type
4957 false, // is_const
4958 nullptr, // constructor
4959 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00004960 mod->AddGlobalVariable(var);
dan sinclair3819c262020-06-17 18:39:17 +00004961
4962 // Register the global
4963 ASSERT_TRUE(td()->Determine()) << td()->error();
4964
4965 ast::ExpressionList params;
dan sinclair6b59bf42020-12-11 19:16:13 +00004966 params.push_back(
4967 create<ast::IdentifierExpression>(mod->RegisterSymbol("var"), "var"));
dan sinclair3819c262020-06-17 18:39:17 +00004968
dan sinclair6b59bf42020-12-11 19:16:13 +00004969 auto* ident = create<ast::IdentifierExpression>(
4970 mod->RegisterSymbol("determinant"), "determinant");
Ben Clayton4bfe4612020-11-16 16:41:47 +00004971
4972 ast::CallExpression call(ident, params);
dan sinclair3819c262020-06-17 18:39:17 +00004973
dan sinclairb4fee2f2020-09-22 19:42:13 +00004974 EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton4bfe4612020-11-16 16:41:47 +00004975 ASSERT_NE(ident->result_type(), nullptr);
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004976 EXPECT_TRUE(ident->result_type()->Is<ast::type::F32>());
dan sinclair3819c262020-06-17 18:39:17 +00004977}
4978
dan sinclairb4fee2f2020-09-22 19:42:13 +00004979using ImportData_Matrix_OneParam_Test =
4980 TypeDeterminerTestWithParam<IntrinsicData>;
dan sinclair3238eaa2020-06-17 20:22:08 +00004981TEST_P(ImportData_Matrix_OneParam_Test, Error_Float) {
4982 auto param = GetParam();
4983
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00004984 ast::type::F32 f32;
dan sinclair3819c262020-06-17 18:39:17 +00004985
Ben Claytona80511e2020-12-11 13:07:02 +00004986 auto* var =
4987 create<ast::Variable>(Source{}, // source
4988 "var", // name
4989 ast::StorageClass::kFunction, // storage_class
4990 &f32, // type
4991 false, // is_const
4992 nullptr, // constructor
4993 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00004994 mod->AddGlobalVariable(var);
dan sinclair3819c262020-06-17 18:39:17 +00004995
4996 // Register the global
4997 ASSERT_TRUE(td()->Determine()) << td()->error();
4998
4999 ast::ExpressionList params;
dan sinclair6b59bf42020-12-11 19:16:13 +00005000 params.push_back(
5001 create<ast::IdentifierExpression>(mod->RegisterSymbol("var"), "var"));
dan sinclair3819c262020-06-17 18:39:17 +00005002
dan sinclair6b59bf42020-12-11 19:16:13 +00005003 auto* ident = create<ast::IdentifierExpression>(
5004 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00005005 ast::CallExpression call(ident, params);
dan sinclair3819c262020-06-17 18:39:17 +00005006
dan sinclairb4fee2f2020-09-22 19:42:13 +00005007 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair3238eaa2020-06-17 20:22:08 +00005008 EXPECT_EQ(td()->error(), std::string("incorrect type for ") + param.name +
5009 ". Requires matrix value");
dan sinclair3819c262020-06-17 18:39:17 +00005010}
5011
dan sinclair3238eaa2020-06-17 20:22:08 +00005012TEST_P(ImportData_Matrix_OneParam_Test, NoParams) {
5013 auto param = GetParam();
5014
dan sinclair3819c262020-06-17 18:39:17 +00005015 ast::ExpressionList params;
5016
dan sinclair6b59bf42020-12-11 19:16:13 +00005017 auto* ident = create<ast::IdentifierExpression>(
5018 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00005019 ast::CallExpression call(ident, params);
dan sinclairb4fee2f2020-09-22 19:42:13 +00005020
5021 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair3238eaa2020-06-17 20:22:08 +00005022 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
5023 param.name + ". Expected 1 got 0");
dan sinclair3819c262020-06-17 18:39:17 +00005024}
5025
dan sinclair3238eaa2020-06-17 20:22:08 +00005026TEST_P(ImportData_Matrix_OneParam_Test, TooManyParams) {
5027 auto param = GetParam();
5028
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00005029 ast::type::F32 f32;
5030 ast::type::Matrix mat(&f32, 3, 3);
dan sinclair3819c262020-06-17 18:39:17 +00005031
Ben Claytona80511e2020-12-11 13:07:02 +00005032 auto* var =
5033 create<ast::Variable>(Source{}, // source
5034 "var", // name
5035 ast::StorageClass::kFunction, // storage_class
5036 &mat, // type
5037 false, // is_const
5038 nullptr, // constructor
5039 ast::VariableDecorationList{}); // decorations
Ben Clayton3ea3c992020-11-18 21:19:22 +00005040 mod->AddGlobalVariable(var);
dan sinclair3819c262020-06-17 18:39:17 +00005041
5042 // Register the global
5043 ASSERT_TRUE(td()->Determine()) << td()->error();
5044
5045 ast::ExpressionList params;
dan sinclair6b59bf42020-12-11 19:16:13 +00005046 params.push_back(
5047 create<ast::IdentifierExpression>(mod->RegisterSymbol("var"), "var"));
5048 params.push_back(
5049 create<ast::IdentifierExpression>(mod->RegisterSymbol("var"), "var"));
dan sinclair3819c262020-06-17 18:39:17 +00005050
dan sinclair6b59bf42020-12-11 19:16:13 +00005051 auto* ident = create<ast::IdentifierExpression>(
5052 mod->RegisterSymbol(param.name), param.name);
Ben Clayton4bfe4612020-11-16 16:41:47 +00005053 ast::CallExpression call(ident, params);
dan sinclair3819c262020-06-17 18:39:17 +00005054
dan sinclairb4fee2f2020-09-22 19:42:13 +00005055 EXPECT_FALSE(td()->DetermineResultType(&call));
dan sinclair3238eaa2020-06-17 20:22:08 +00005056 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
5057 param.name + ". Expected 1 got 2");
dan sinclair3819c262020-06-17 18:39:17 +00005058}
dan sinclaire9598d62020-06-18 18:03:00 +00005059INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclairb4fee2f2020-09-22 19:42:13 +00005060 ImportData_Matrix_OneParam_Test,
5061 testing::Values(IntrinsicData{
5062 "determinant", ast::Intrinsic::kDeterminant}));
dan sinclaire9598d62020-06-18 18:03:00 +00005063
dan sinclair05926432020-09-21 17:51:31 +00005064TEST_F(TypeDeterminerTest, Function_EntryPoints_StageDecoration) {
Ben Claytonf1b0e1e2020-11-30 23:30:58 +00005065 ast::type::F32 f32;
dan sinclair05926432020-09-21 17:51:31 +00005066
5067 // fn b() {}
5068 // fn c() { b(); }
5069 // fn a() { c(); }
5070 // fn ep_1() { a(); b(); }
5071 // fn ep_2() { c();}
5072 //
5073 // c -> {ep_1, ep_2}
5074 // a -> {ep_1}
5075 // b -> {ep_1, ep_2}
5076 // ep_1 -> {}
5077 // ep_2 -> {}
5078
5079 ast::VariableList params;
Ben Claytonb053acf2020-11-16 16:31:07 +00005080 auto* body = create<ast::BlockStatement>();
dan sinclaira41132f2020-12-11 18:24:53 +00005081 auto* func_b =
5082 create<ast::Function>(Source{}, mod->RegisterSymbol("b"), "b", params,
5083 &f32, body, ast::FunctionDecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00005084
Ben Clayton62625922020-11-13 22:09:38 +00005085 body = create<ast::BlockStatement>();
5086 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +00005087 create<ast::IdentifierExpression>(mod->RegisterSymbol("second"),
5088 "second"),
5089 create<ast::CallExpression>(
5090 create<ast::IdentifierExpression>(mod->RegisterSymbol("b"), "b"),
5091 ast::ExpressionList{})));
dan sinclaira41132f2020-12-11 18:24:53 +00005092 auto* func_c =
5093 create<ast::Function>(Source{}, mod->RegisterSymbol("c"), "c", params,
5094 &f32, body, ast::FunctionDecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00005095
Ben Clayton62625922020-11-13 22:09:38 +00005096 body = create<ast::BlockStatement>();
5097 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +00005098 create<ast::IdentifierExpression>(mod->RegisterSymbol("first"), "first"),
5099 create<ast::CallExpression>(
5100 create<ast::IdentifierExpression>(mod->RegisterSymbol("c"), "c"),
5101 ast::ExpressionList{})));
dan sinclaira41132f2020-12-11 18:24:53 +00005102 auto* func_a =
5103 create<ast::Function>(Source{}, mod->RegisterSymbol("a"), "a", params,
5104 &f32, body, ast::FunctionDecorationList{});
dan sinclair05926432020-09-21 17:51:31 +00005105
Ben Clayton62625922020-11-13 22:09:38 +00005106 body = create<ast::BlockStatement>();
5107 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +00005108 create<ast::IdentifierExpression>(mod->RegisterSymbol("call_a"),
5109 "call_a"),
5110 create<ast::CallExpression>(
5111 create<ast::IdentifierExpression>(mod->RegisterSymbol("a"), "a"),
5112 ast::ExpressionList{})));
Ben Clayton62625922020-11-13 22:09:38 +00005113 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +00005114 create<ast::IdentifierExpression>(mod->RegisterSymbol("call_b"),
5115 "call_b"),
5116 create<ast::CallExpression>(
5117 create<ast::IdentifierExpression>(mod->RegisterSymbol("b"), "b"),
5118 ast::ExpressionList{})));
Ben Clayton234b7de2020-12-07 20:45:14 +00005119 auto* ep_1 = create<ast::Function>(
dan sinclaira41132f2020-12-11 18:24:53 +00005120 Source{}, mod->RegisterSymbol("ep_1"), "ep_1", params, &f32, body,
Ben Clayton234b7de2020-12-07 20:45:14 +00005121 ast::FunctionDecorationList{
5122 create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}),
5123 });
dan sinclair05926432020-09-21 17:51:31 +00005124
Ben Clayton62625922020-11-13 22:09:38 +00005125 body = create<ast::BlockStatement>();
5126 body->append(create<ast::AssignmentStatement>(
dan sinclair6b59bf42020-12-11 19:16:13 +00005127 create<ast::IdentifierExpression>(mod->RegisterSymbol("call_c"),
5128 "call_c"),
5129 create<ast::CallExpression>(
5130 create<ast::IdentifierExpression>(mod->RegisterSymbol("c"), "c"),
5131 ast::ExpressionList{})));
Ben Clayton234b7de2020-12-07 20:45:14 +00005132 auto* ep_2 = create<ast::Function>(
dan sinclaira41132f2020-12-11 18:24:53 +00005133 Source{}, mod->RegisterSymbol("ep_2"), "ep_2", params, &f32, body,
Ben Clayton234b7de2020-12-07 20:45:14 +00005134 ast::FunctionDecorationList{
5135 create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}),
5136 });
dan sinclair05926432020-09-21 17:51:31 +00005137
Ben Clayton3ea3c992020-11-18 21:19:22 +00005138 mod->AddFunction(func_b);
5139 mod->AddFunction(func_c);
5140 mod->AddFunction(func_a);
5141 mod->AddFunction(ep_1);
5142 mod->AddFunction(ep_2);
dan sinclair05926432020-09-21 17:51:31 +00005143
Ben Claytona80511e2020-12-11 13:07:02 +00005144 mod->AddGlobalVariable(
5145 create<ast::Variable>(Source{}, // source
5146 "first", // name
5147 ast::StorageClass::kPrivate, // storage_class
5148 &f32, // type
5149 false, // is_const
5150 nullptr, // constructor
5151 ast::VariableDecorationList{})); // decorations
5152 mod->AddGlobalVariable(
5153 create<ast::Variable>(Source{}, // source
5154 "second", // name
5155 ast::StorageClass::kPrivate, // storage_class
5156 &f32, // type
5157 false, // is_const
5158 nullptr, // constructor
5159 ast::VariableDecorationList{})); // decorations
5160 mod->AddGlobalVariable(
5161 create<ast::Variable>(Source{}, // source
5162 "call_a", // name
5163 ast::StorageClass::kPrivate, // storage_class
5164 &f32, // type
5165 false, // is_const
5166 nullptr, // constructor
5167 ast::VariableDecorationList{})); // decorations
5168 mod->AddGlobalVariable(
5169 create<ast::Variable>(Source{}, // source
5170 "call_b", // name
5171 ast::StorageClass::kPrivate, // storage_class
5172 &f32, // type
5173 false, // is_const
5174 nullptr, // constructor
5175 ast::VariableDecorationList{})); // decorations
5176 mod->AddGlobalVariable(
5177 create<ast::Variable>(Source{}, // source
5178 "call_c", // name
5179 ast::StorageClass::kPrivate, // storage_class
5180 &f32, // type
5181 false, // is_const
5182 nullptr, // constructor
5183 ast::VariableDecorationList{})); // decorations
dan sinclairff267ca2020-10-14 18:26:31 +00005184
dan sinclair05926432020-09-21 17:51:31 +00005185 // Register the functions and calculate the callers
5186 ASSERT_TRUE(td()->Determine()) << td()->error();
5187
Ben Clayton4bfe4612020-11-16 16:41:47 +00005188 const auto& b_eps = func_b->ancestor_entry_points();
dan sinclair05926432020-09-21 17:51:31 +00005189 ASSERT_EQ(2u, b_eps.size());
dan sinclaira41132f2020-12-11 18:24:53 +00005190 EXPECT_EQ(mod->RegisterSymbol("ep_1"), b_eps[0]);
5191 EXPECT_EQ(mod->RegisterSymbol("ep_2"), b_eps[1]);
dan sinclair05926432020-09-21 17:51:31 +00005192
Ben Clayton4bfe4612020-11-16 16:41:47 +00005193 const auto& a_eps = func_a->ancestor_entry_points();
dan sinclair05926432020-09-21 17:51:31 +00005194 ASSERT_EQ(1u, a_eps.size());
dan sinclaira41132f2020-12-11 18:24:53 +00005195 EXPECT_EQ(mod->RegisterSymbol("ep_1"), a_eps[0]);
dan sinclair05926432020-09-21 17:51:31 +00005196
Ben Clayton4bfe4612020-11-16 16:41:47 +00005197 const auto& c_eps = func_c->ancestor_entry_points();
dan sinclair05926432020-09-21 17:51:31 +00005198 ASSERT_EQ(2u, c_eps.size());
dan sinclaira41132f2020-12-11 18:24:53 +00005199 EXPECT_EQ(mod->RegisterSymbol("ep_1"), c_eps[0]);
5200 EXPECT_EQ(mod->RegisterSymbol("ep_2"), c_eps[1]);
dan sinclair05926432020-09-21 17:51:31 +00005201
Ben Clayton4bfe4612020-11-16 16:41:47 +00005202 EXPECT_TRUE(ep_1->ancestor_entry_points().empty());
5203 EXPECT_TRUE(ep_2->ancestor_entry_points().empty());
dan sinclair05926432020-09-21 17:51:31 +00005204}
5205
Ben Clayton3ea3c992020-11-18 21:19:22 +00005206using TypeDeterminerTextureIntrinsicTest =
5207 TypeDeterminerTestWithParam<ast::intrinsic::test::TextureOverloadCase>;
5208
5209INSTANTIATE_TEST_SUITE_P(
5210 TypeDeterminerTest,
5211 TypeDeterminerTextureIntrinsicTest,
5212 testing::ValuesIn(ast::intrinsic::test::TextureOverloadCase::ValidCases()));
5213
5214std::string to_str(const std::string& function,
5215 const ast::intrinsic::TextureSignature* sig) {
5216 struct Parameter {
5217 size_t idx;
5218 std::string name;
5219 };
5220 std::vector<Parameter> params;
5221 auto maybe_add_param = [&params](size_t idx, const char* name) {
5222 if (idx != ast::intrinsic::TextureSignature::Parameters::kNotUsed) {
5223 params.emplace_back(Parameter{idx, name});
5224 }
5225 };
5226 maybe_add_param(sig->params.idx.array_index, "array_index");
5227 maybe_add_param(sig->params.idx.bias, "bias");
5228 maybe_add_param(sig->params.idx.coords, "coords");
5229 maybe_add_param(sig->params.idx.depth_ref, "depth_ref");
5230 maybe_add_param(sig->params.idx.ddx, "ddx");
5231 maybe_add_param(sig->params.idx.ddy, "ddy");
5232 maybe_add_param(sig->params.idx.level, "level");
5233 maybe_add_param(sig->params.idx.offset, "offset");
5234 maybe_add_param(sig->params.idx.sampler, "sampler");
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005235 maybe_add_param(sig->params.idx.sample_index, "sample_index");
Ben Clayton3ea3c992020-11-18 21:19:22 +00005236 maybe_add_param(sig->params.idx.texture, "texture");
Ben Clayton591268d2020-12-10 18:39:41 +00005237 maybe_add_param(sig->params.idx.value, "value");
Ben Clayton3ea3c992020-11-18 21:19:22 +00005238 std::sort(
5239 params.begin(), params.end(),
5240 [](const Parameter& a, const Parameter& b) { return a.idx < b.idx; });
5241
5242 std::stringstream out;
5243 out << function << "(";
5244 bool first = true;
5245 for (auto& param : params) {
5246 if (!first) {
5247 out << ", ";
5248 }
5249 out << param.name;
5250 first = false;
5251 }
5252 out << ")";
5253 return out.str();
5254}
5255
5256const char* expected_texture_overload(
5257 ast::intrinsic::test::ValidTextureOverload overload) {
5258 using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
5259 switch (overload) {
5260 case ValidTextureOverload::kSample1dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005261 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005262 case ValidTextureOverload::kSample1dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005263 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005264 case ValidTextureOverload::kSample2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005265 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005266 case ValidTextureOverload::kSample2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005267 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005268 case ValidTextureOverload::kSample2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005269 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005270 case ValidTextureOverload::kSample2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005271 return R"(textureSample(texture, sampler, coords, array_index, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005272 case ValidTextureOverload::kSample3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005273 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005274 case ValidTextureOverload::kSample3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005275 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005276 case ValidTextureOverload::kSampleCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005277 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005278 case ValidTextureOverload::kSampleCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005279 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005280 case ValidTextureOverload::kSampleDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005281 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005282 case ValidTextureOverload::kSampleDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005283 return R"(textureSample(texture, sampler, coords, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005284 case ValidTextureOverload::kSampleDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005285 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005286 case ValidTextureOverload::kSampleDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005287 return R"(textureSample(texture, sampler, coords, array_index, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005288 case ValidTextureOverload::kSampleDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005289 return R"(textureSample(texture, sampler, coords))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005290 case ValidTextureOverload::kSampleDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005291 return R"(textureSample(texture, sampler, coords, array_index))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005292 case ValidTextureOverload::kSampleBias2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005293 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005294 case ValidTextureOverload::kSampleBias2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005295 return R"(textureSampleBias(texture, sampler, coords, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005296 case ValidTextureOverload::kSampleBias2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005297 return R"(textureSampleBias(texture, sampler, coords, array_index, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005298 case ValidTextureOverload::kSampleBias2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005299 return R"(textureSampleBias(texture, sampler, coords, array_index, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005300 case ValidTextureOverload::kSampleBias3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005301 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005302 case ValidTextureOverload::kSampleBias3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005303 return R"(textureSampleBias(texture, sampler, coords, bias, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005304 case ValidTextureOverload::kSampleBiasCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005305 return R"(textureSampleBias(texture, sampler, coords, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005306 case ValidTextureOverload::kSampleBiasCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005307 return R"(textureSampleBias(texture, sampler, coords, array_index, bias))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005308 case ValidTextureOverload::kSampleLevel2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005309 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005310 case ValidTextureOverload::kSampleLevel2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005311 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005312 case ValidTextureOverload::kSampleLevel2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005313 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005314 case ValidTextureOverload::kSampleLevel2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005315 return R"(textureSampleLevel(texture, sampler, coords, array_index, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005316 case ValidTextureOverload::kSampleLevel3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005317 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005318 case ValidTextureOverload::kSampleLevel3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005319 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005320 case ValidTextureOverload::kSampleLevelCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005321 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005322 case ValidTextureOverload::kSampleLevelCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005323 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005324 case ValidTextureOverload::kSampleLevelDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005325 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005326 case ValidTextureOverload::kSampleLevelDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005327 return R"(textureSampleLevel(texture, sampler, coords, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005328 case ValidTextureOverload::kSampleLevelDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005329 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005330 case ValidTextureOverload::kSampleLevelDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005331 return R"(textureSampleLevel(texture, sampler, coords, array_index, level, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005332 case ValidTextureOverload::kSampleLevelDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005333 return R"(textureSampleLevel(texture, sampler, coords, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005334 case ValidTextureOverload::kSampleLevelDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005335 return R"(textureSampleLevel(texture, sampler, coords, array_index, level))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005336 case ValidTextureOverload::kSampleGrad2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005337 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005338 case ValidTextureOverload::kSampleGrad2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005339 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005340 case ValidTextureOverload::kSampleGrad2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005341 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005342 case ValidTextureOverload::kSampleGrad2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005343 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005344 case ValidTextureOverload::kSampleGrad3dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005345 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005346 case ValidTextureOverload::kSampleGrad3dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005347 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005348 case ValidTextureOverload::kSampleGradCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005349 return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005350 case ValidTextureOverload::kSampleGradCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005351 return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005352 case ValidTextureOverload::kSampleGradDepth2dF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005353 return R"(textureSampleCompare(texture, sampler, coords, depth_ref))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005354 case ValidTextureOverload::kSampleGradDepth2dOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005355 return R"(textureSampleCompare(texture, sampler, coords, depth_ref, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005356 case ValidTextureOverload::kSampleGradDepth2dArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005357 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005358 case ValidTextureOverload::kSampleGradDepth2dArrayOffsetF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005359 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref, offset))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005360 case ValidTextureOverload::kSampleGradDepthCubeF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005361 return R"(textureSampleCompare(texture, sampler, coords, depth_ref))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005362 case ValidTextureOverload::kSampleGradDepthCubeArrayF32:
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005363 return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref))";
5364 case ValidTextureOverload::kLoad1dF32:
5365 return R"(textureLoad(texture, coords))";
5366 case ValidTextureOverload::kLoad1dU32:
5367 return R"(textureLoad(texture, coords))";
5368 case ValidTextureOverload::kLoad1dI32:
5369 return R"(textureLoad(texture, coords))";
5370 case ValidTextureOverload::kLoad1dArrayF32:
5371 return R"(textureLoad(texture, coords, array_index))";
5372 case ValidTextureOverload::kLoad1dArrayU32:
5373 return R"(textureLoad(texture, coords, array_index))";
5374 case ValidTextureOverload::kLoad1dArrayI32:
5375 return R"(textureLoad(texture, coords, array_index))";
5376 case ValidTextureOverload::kLoad2dF32:
5377 return R"(textureLoad(texture, coords))";
5378 case ValidTextureOverload::kLoad2dU32:
5379 return R"(textureLoad(texture, coords))";
5380 case ValidTextureOverload::kLoad2dI32:
5381 return R"(textureLoad(texture, coords))";
5382 case ValidTextureOverload::kLoad2dLevelF32:
5383 return R"(textureLoad(texture, coords, level))";
5384 case ValidTextureOverload::kLoad2dLevelU32:
5385 return R"(textureLoad(texture, coords, level))";
5386 case ValidTextureOverload::kLoad2dLevelI32:
5387 return R"(textureLoad(texture, coords, level))";
5388 case ValidTextureOverload::kLoad2dArrayF32:
5389 return R"(textureLoad(texture, coords, array_index))";
5390 case ValidTextureOverload::kLoad2dArrayU32:
5391 return R"(textureLoad(texture, coords, array_index))";
5392 case ValidTextureOverload::kLoad2dArrayI32:
5393 return R"(textureLoad(texture, coords, array_index))";
5394 case ValidTextureOverload::kLoad2dArrayLevelF32:
5395 return R"(textureLoad(texture, coords, array_index, level))";
5396 case ValidTextureOverload::kLoad2dArrayLevelU32:
5397 return R"(textureLoad(texture, coords, array_index, level))";
5398 case ValidTextureOverload::kLoad2dArrayLevelI32:
5399 return R"(textureLoad(texture, coords, array_index, level))";
5400 case ValidTextureOverload::kLoad3dF32:
5401 return R"(textureLoad(texture, coords))";
5402 case ValidTextureOverload::kLoad3dU32:
5403 return R"(textureLoad(texture, coords))";
5404 case ValidTextureOverload::kLoad3dI32:
5405 return R"(textureLoad(texture, coords))";
5406 case ValidTextureOverload::kLoad3dLevelF32:
5407 return R"(textureLoad(texture, coords, level))";
5408 case ValidTextureOverload::kLoad3dLevelU32:
5409 return R"(textureLoad(texture, coords, level))";
5410 case ValidTextureOverload::kLoad3dLevelI32:
5411 return R"(textureLoad(texture, coords, level))";
5412 case ValidTextureOverload::kLoadMultisampled2dF32:
5413 return R"(textureLoad(texture, coords, sample_index))";
5414 case ValidTextureOverload::kLoadMultisampled2dU32:
5415 return R"(textureLoad(texture, coords, sample_index))";
5416 case ValidTextureOverload::kLoadMultisampled2dI32:
5417 return R"(textureLoad(texture, coords, sample_index))";
5418 case ValidTextureOverload::kLoadMultisampled2dArrayF32:
5419 return R"(textureLoad(texture, coords, array_index, sample_index))";
5420 case ValidTextureOverload::kLoadMultisampled2dArrayU32:
5421 return R"(textureLoad(texture, coords, array_index, sample_index))";
5422 case ValidTextureOverload::kLoadMultisampled2dArrayI32:
5423 return R"(textureLoad(texture, coords, array_index, sample_index))";
5424 case ValidTextureOverload::kLoadDepth2dF32:
5425 return R"(textureLoad(texture, coords))";
5426 case ValidTextureOverload::kLoadDepth2dLevelF32:
5427 return R"(textureLoad(texture, coords, level))";
5428 case ValidTextureOverload::kLoadDepth2dArrayF32:
5429 return R"(textureLoad(texture, coords, array_index))";
5430 case ValidTextureOverload::kLoadDepth2dArrayLevelF32:
5431 return R"(textureLoad(texture, coords, array_index, level))";
5432 case ValidTextureOverload::kLoadStorageRO1dRgba32float:
5433 return R"(textureLoad(texture, coords))";
5434 case ValidTextureOverload::kLoadStorageRO1dArrayRgba32float:
5435 return R"(textureLoad(texture, coords, array_index))";
5436 case ValidTextureOverload::kLoadStorageRO2dRgba8unorm:
5437 case ValidTextureOverload::kLoadStorageRO2dRgba8snorm:
5438 case ValidTextureOverload::kLoadStorageRO2dRgba8uint:
5439 case ValidTextureOverload::kLoadStorageRO2dRgba8sint:
5440 case ValidTextureOverload::kLoadStorageRO2dRgba16uint:
5441 case ValidTextureOverload::kLoadStorageRO2dRgba16sint:
5442 case ValidTextureOverload::kLoadStorageRO2dRgba16float:
5443 case ValidTextureOverload::kLoadStorageRO2dR32uint:
5444 case ValidTextureOverload::kLoadStorageRO2dR32sint:
5445 case ValidTextureOverload::kLoadStorageRO2dR32float:
5446 case ValidTextureOverload::kLoadStorageRO2dRg32uint:
5447 case ValidTextureOverload::kLoadStorageRO2dRg32sint:
5448 case ValidTextureOverload::kLoadStorageRO2dRg32float:
5449 case ValidTextureOverload::kLoadStorageRO2dRgba32uint:
5450 case ValidTextureOverload::kLoadStorageRO2dRgba32sint:
5451 case ValidTextureOverload::kLoadStorageRO2dRgba32float:
5452 return R"(textureLoad(texture, coords))";
5453 case ValidTextureOverload::kLoadStorageRO2dArrayRgba32float:
5454 return R"(textureLoad(texture, coords, array_index))";
5455 case ValidTextureOverload::kLoadStorageRO3dRgba32float:
5456 return R"(textureLoad(texture, coords))";
Ben Clayton591268d2020-12-10 18:39:41 +00005457 case ValidTextureOverload::kStoreWO1dRgba32float:
5458 return R"(textureStore(texture, coords, value))";
5459 case ValidTextureOverload::kStoreWO1dArrayRgba32float:
5460 return R"(textureStore(texture, coords, array_index, value))";
5461 case ValidTextureOverload::kStoreWO2dRgba32float:
5462 return R"(textureStore(texture, coords, value))";
5463 case ValidTextureOverload::kStoreWO2dArrayRgba32float:
5464 return R"(textureStore(texture, coords, array_index, value))";
5465 case ValidTextureOverload::kStoreWO3dRgba32float:
5466 return R"(textureStore(texture, coords, value))";
Ben Clayton3ea3c992020-11-18 21:19:22 +00005467 }
5468 return "<unmatched texture overload>";
5469}
5470
5471TEST_P(TypeDeterminerTextureIntrinsicTest, Call) {
5472 auto param = GetParam();
5473
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005474 param.buildTextureVariable(this);
5475 param.buildSamplerVariable(this);
Ben Clayton3ea3c992020-11-18 21:19:22 +00005476
5477 auto* ident = Expr(param.function);
5478 ast::CallExpression call{ident, param.args(this)};
5479
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005480 ASSERT_TRUE(td()->Determine()) << td()->error();
5481 ASSERT_TRUE(td()->DetermineResultType(&call)) << td()->error();
Ben Clayton3ea3c992020-11-18 21:19:22 +00005482
Ben Clayton591268d2020-12-10 18:39:41 +00005483 if (std::string(param.function) == "textureStore") {
5484 EXPECT_EQ(call.result_type(), ty.void_);
5485 } else {
5486 switch (param.texture_kind) {
5487 case ast::intrinsic::test::TextureKind::kRegular:
5488 case ast::intrinsic::test::TextureKind::kMultisampled:
5489 case ast::intrinsic::test::TextureKind::kStorage: {
5490 auto* datatype = param.resultVectorComponentType(this);
5491 ASSERT_TRUE(call.result_type()->Is<ast::type::Vector>());
5492 EXPECT_EQ(call.result_type()->As<ast::type::Vector>()->type(),
5493 datatype);
5494 break;
5495 }
5496 case ast::intrinsic::test::TextureKind::kDepth: {
5497 EXPECT_EQ(call.result_type(), ty.f32);
5498 break;
5499 }
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005500 }
Ben Clayton3ea3c992020-11-18 21:19:22 +00005501 }
5502
5503 auto* sig = static_cast<const ast::intrinsic::TextureSignature*>(
5504 ident->intrinsic_signature());
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005505 ASSERT_NE(sig, nullptr);
Ben Clayton3ea3c992020-11-18 21:19:22 +00005506
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005507 auto got = to_str(param.function, sig);
Ben Clayton3ea3c992020-11-18 21:19:22 +00005508 auto* expected = expected_texture_overload(param.overload);
Ben Clayton7f04e5c2020-12-09 15:57:00 +00005509 EXPECT_EQ(got, expected);
Ben Clayton3ea3c992020-11-18 21:19:22 +00005510}
5511
dan sinclairb7edc4c2020-04-07 12:46:30 +00005512} // namespace
5513} // namespace tint