blob: b1c6cd880a6c56f00a31a3f1e70ddfed770a7e80 [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
17#include <memory>
18#include <utility>
dan sinclairfd5d4ca2020-04-20 15:46:18 +000019#include <vector>
dan sinclairb7edc4c2020-04-07 12:46:30 +000020
21#include "gtest/gtest.h"
dan sinclairfd5d4ca2020-04-20 15:46:18 +000022#include "spirv/unified1/GLSL.std.450.h"
dan sinclair973bd6a2020-04-07 12:57:42 +000023#include "src/ast/array_accessor_expression.h"
dan sinclaira01777c2020-04-07 12:57:52 +000024#include "src/ast/as_expression.h"
dan sinclair6c498fc2020-04-07 12:47:23 +000025#include "src/ast/assignment_statement.h"
dan sinclair1c9b4862020-04-07 19:27:41 +000026#include "src/ast/binary_expression.h"
dan sinclairb7ea6e22020-04-07 12:54:10 +000027#include "src/ast/break_statement.h"
dan sinclair3ca87462020-04-07 16:41:10 +000028#include "src/ast/call_expression.h"
dan sinclair6010b292020-04-07 12:54:20 +000029#include "src/ast/case_statement.h"
dan sinclair4e807952020-04-07 16:41:23 +000030#include "src/ast/cast_expression.h"
dan sinclairaec965e2020-04-07 12:54:29 +000031#include "src/ast/continue_statement.h"
dan sinclair0cf685f2020-04-07 12:54:37 +000032#include "src/ast/else_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000033#include "src/ast/float_literal.h"
dan sinclaircab0e732020-04-07 12:57:27 +000034#include "src/ast/identifier_expression.h"
dan sinclair91c44a52020-04-07 12:55:25 +000035#include "src/ast/if_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000036#include "src/ast/int_literal.h"
dan sinclairbc71eda2020-04-07 12:55:51 +000037#include "src/ast/loop_statement.h"
dan sinclair8ee1d222020-04-07 16:41:33 +000038#include "src/ast/member_accessor_expression.h"
dan sinclairbf0fff82020-04-07 12:56:24 +000039#include "src/ast/return_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000040#include "src/ast/scalar_constructor_expression.h"
dan sinclair8ee1d222020-04-07 16:41:33 +000041#include "src/ast/struct.h"
42#include "src/ast/struct_member.h"
dan sinclair18b32852020-04-07 12:56:45 +000043#include "src/ast/switch_statement.h"
dan sinclair973bd6a2020-04-07 12:57:42 +000044#include "src/ast/type/array_type.h"
dan sinclair9b978022020-04-07 19:26:39 +000045#include "src/ast/type/bool_type.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000046#include "src/ast/type/f32_type.h"
dan sinclair6c498fc2020-04-07 12:47:23 +000047#include "src/ast/type/i32_type.h"
dan sinclair973bd6a2020-04-07 12:57:42 +000048#include "src/ast/type/matrix_type.h"
dan sinclair8ee1d222020-04-07 16:41:33 +000049#include "src/ast/type/struct_type.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000050#include "src/ast/type/vector_type.h"
51#include "src/ast/type_constructor_expression.h"
dan sinclairb1730562020-04-07 19:26:49 +000052#include "src/ast/unary_derivative_expression.h"
dan sinclair8dcfd102020-04-07 19:27:00 +000053#include "src/ast/unary_method_expression.h"
dan sinclair327ed1b2020-04-07 19:27:21 +000054#include "src/ast/unary_op_expression.h"
dan sinclair9a84e5e2020-04-07 12:56:57 +000055#include "src/ast/unless_statement.h"
dan sinclairca893e32020-04-07 12:57:12 +000056#include "src/ast/variable_decl_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000057
58namespace tint {
59namespace {
60
dan sinclair7456f422020-04-08 19:58:35 +000061class FakeStmt : public ast::Statement {
62 public:
63 bool IsValid() const override { return true; }
64 void to_str(std::ostream&, size_t) const override {}
65};
66
67class FakeExpr : public ast::Expression {
68 public:
69 bool IsValid() const override { return true; }
70 void to_str(std::ostream&, size_t) const override {}
71};
72
dan sinclaircd077b02020-04-20 14:19:04 +000073class TypeDeterminerHelper {
dan sinclairb7edc4c2020-04-07 12:46:30 +000074 public:
dan sinclairb950e802020-04-20 14:20:01 +000075 TypeDeterminerHelper()
76 : td_(std::make_unique<TypeDeterminer>(&ctx_, &mod_)) {}
dan sinclairb7edc4c2020-04-07 12:46:30 +000077
78 TypeDeterminer* td() const { return td_.get(); }
dan sinclaircd077b02020-04-20 14:19:04 +000079 ast::Module* mod() { return &mod_; }
dan sinclairb7edc4c2020-04-07 12:46:30 +000080
81 private:
82 Context ctx_;
dan sinclaircd077b02020-04-20 14:19:04 +000083 ast::Module mod_;
dan sinclairb7edc4c2020-04-07 12:46:30 +000084 std::unique_ptr<TypeDeterminer> td_;
85};
86
dan sinclaircd077b02020-04-20 14:19:04 +000087class TypeDeterminerTest : public TypeDeterminerHelper, public testing::Test {};
88
89template <typename T>
90class TypeDeterminerTestWithParam : public TypeDeterminerHelper,
91 public testing::TestWithParam<T> {};
92
dan sinclair7456f422020-04-08 19:58:35 +000093TEST_F(TypeDeterminerTest, Error_WithEmptySource) {
94 FakeStmt s;
95 s.set_source(Source{0, 0});
96
97 EXPECT_FALSE(td()->DetermineResultType(&s));
98 EXPECT_EQ(td()->error(), "unknown statement type for type determination");
99}
100
101TEST_F(TypeDeterminerTest, Stmt_Error_Unknown) {
102 FakeStmt s;
103 s.set_source(Source{2, 30});
104
105 EXPECT_FALSE(td()->DetermineResultType(&s));
106 EXPECT_EQ(td()->error(),
107 "2:30: unknown statement type for type determination");
108}
109
dan sinclair6c498fc2020-04-07 12:47:23 +0000110TEST_F(TypeDeterminerTest, Stmt_Assign) {
111 ast::type::F32Type f32;
112 ast::type::I32Type i32;
113
114 auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
115 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000116 auto* lhs_ptr = lhs.get();
dan sinclair6c498fc2020-04-07 12:47:23 +0000117
118 auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
119 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000120 auto* rhs_ptr = rhs.get();
dan sinclair6c498fc2020-04-07 12:47:23 +0000121
122 ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
123
124 EXPECT_TRUE(td()->DetermineResultType(&assign));
125 ASSERT_NE(lhs_ptr->result_type(), nullptr);
126 ASSERT_NE(rhs_ptr->result_type(), nullptr);
127
128 EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
129 EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
130}
131
dan sinclairb7ea6e22020-04-07 12:54:10 +0000132TEST_F(TypeDeterminerTest, Stmt_Break) {
133 ast::type::I32Type i32;
134
135 auto cond = std::make_unique<ast::ScalarConstructorExpression>(
136 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000137 auto* cond_ptr = cond.get();
dan sinclairb7ea6e22020-04-07 12:54:10 +0000138
139 ast::BreakStatement brk(ast::StatementCondition::kIf, std::move(cond));
140
141 EXPECT_TRUE(td()->DetermineResultType(&brk));
142 ASSERT_NE(cond_ptr->result_type(), nullptr);
143 EXPECT_TRUE(cond_ptr->result_type()->IsI32());
144}
145
dan sinclair327ed1b2020-04-07 19:27:21 +0000146TEST_F(TypeDeterminerTest, Stmt_Break_WithoutCondition) {
147 ast::type::I32Type i32;
148 ast::BreakStatement brk;
149 EXPECT_TRUE(td()->DetermineResultType(&brk));
150}
151
dan sinclair6010b292020-04-07 12:54:20 +0000152TEST_F(TypeDeterminerTest, Stmt_Case) {
153 ast::type::I32Type i32;
154 ast::type::F32Type f32;
155
156 auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
157 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000158 auto* lhs_ptr = lhs.get();
dan sinclair6010b292020-04-07 12:54:20 +0000159
160 auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
161 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000162 auto* rhs_ptr = rhs.get();
dan sinclair6010b292020-04-07 12:54:20 +0000163
164 ast::StatementList body;
165 body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
166 std::move(rhs)));
167
168 ast::CaseStatement cse(std::make_unique<ast::IntLiteral>(&i32, 3),
169 std::move(body));
170
171 EXPECT_TRUE(td()->DetermineResultType(&cse));
172 ASSERT_NE(lhs_ptr->result_type(), nullptr);
173 ASSERT_NE(rhs_ptr->result_type(), nullptr);
174 EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
175 EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
176}
177
dan sinclairaec965e2020-04-07 12:54:29 +0000178TEST_F(TypeDeterminerTest, Stmt_Continue) {
179 ast::type::I32Type i32;
180
181 auto cond = std::make_unique<ast::ScalarConstructorExpression>(
182 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000183 auto* cond_ptr = cond.get();
dan sinclairaec965e2020-04-07 12:54:29 +0000184
185 ast::ContinueStatement stmt(ast::StatementCondition::kIf, std::move(cond));
186
187 EXPECT_TRUE(td()->DetermineResultType(&stmt));
188 ASSERT_NE(cond_ptr->result_type(), nullptr);
189 EXPECT_TRUE(cond_ptr->result_type()->IsI32());
190}
191
dan sinclair327ed1b2020-04-07 19:27:21 +0000192TEST_F(TypeDeterminerTest, Stmt_Continue_WithoutStatement) {
193 ast::type::I32Type i32;
194 ast::ContinueStatement stmt;
195 EXPECT_TRUE(td()->DetermineResultType(&stmt));
196}
197
dan sinclair0cf685f2020-04-07 12:54:37 +0000198TEST_F(TypeDeterminerTest, Stmt_Else) {
199 ast::type::I32Type i32;
200 ast::type::F32Type f32;
201
202 auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
203 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000204 auto* lhs_ptr = lhs.get();
dan sinclair0cf685f2020-04-07 12:54:37 +0000205
206 auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
207 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000208 auto* rhs_ptr = rhs.get();
dan sinclair0cf685f2020-04-07 12:54:37 +0000209
210 ast::StatementList body;
211 body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
212 std::move(rhs)));
213
214 ast::ElseStatement stmt(std::make_unique<ast::ScalarConstructorExpression>(
215 std::make_unique<ast::IntLiteral>(&i32, 3)),
216 std::move(body));
217
218 EXPECT_TRUE(td()->DetermineResultType(&stmt));
219 ASSERT_NE(stmt.condition()->result_type(), nullptr);
220 ASSERT_NE(lhs_ptr->result_type(), nullptr);
221 ASSERT_NE(rhs_ptr->result_type(), nullptr);
222 EXPECT_TRUE(stmt.condition()->result_type()->IsI32());
223 EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
224 EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
225}
226
dan sinclair91c44a52020-04-07 12:55:25 +0000227TEST_F(TypeDeterminerTest, Stmt_If) {
228 ast::type::I32Type i32;
229 ast::type::F32Type f32;
230
231 auto else_lhs = std::make_unique<ast::ScalarConstructorExpression>(
232 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000233 auto* else_lhs_ptr = else_lhs.get();
dan sinclair91c44a52020-04-07 12:55:25 +0000234
235 auto else_rhs = std::make_unique<ast::ScalarConstructorExpression>(
236 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000237 auto* else_rhs_ptr = else_rhs.get();
dan sinclair91c44a52020-04-07 12:55:25 +0000238
239 ast::StatementList else_body;
240 else_body.push_back(std::make_unique<ast::AssignmentStatement>(
241 std::move(else_lhs), std::move(else_rhs)));
242
243 auto else_stmt = std::make_unique<ast::ElseStatement>(
244 std::make_unique<ast::ScalarConstructorExpression>(
245 std::make_unique<ast::IntLiteral>(&i32, 3)),
246 std::move(else_body));
247
248 ast::ElseStatementList else_stmts;
249 else_stmts.push_back(std::move(else_stmt));
250
251 auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
252 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000253 auto* lhs_ptr = lhs.get();
dan sinclair91c44a52020-04-07 12:55:25 +0000254
255 auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
256 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000257 auto* rhs_ptr = rhs.get();
dan sinclair91c44a52020-04-07 12:55:25 +0000258
259 ast::StatementList body;
260 body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
261 std::move(rhs)));
262
263 ast::IfStatement stmt(std::make_unique<ast::ScalarConstructorExpression>(
264 std::make_unique<ast::IntLiteral>(&i32, 3)),
265 std::move(body));
266 stmt.set_else_statements(std::move(else_stmts));
267
268 EXPECT_TRUE(td()->DetermineResultType(&stmt));
269 ASSERT_NE(stmt.condition()->result_type(), nullptr);
270 ASSERT_NE(else_lhs_ptr->result_type(), nullptr);
271 ASSERT_NE(else_rhs_ptr->result_type(), nullptr);
272 ASSERT_NE(lhs_ptr->result_type(), nullptr);
273 ASSERT_NE(rhs_ptr->result_type(), nullptr);
274 EXPECT_TRUE(stmt.condition()->result_type()->IsI32());
275 EXPECT_TRUE(else_lhs_ptr->result_type()->IsI32());
276 EXPECT_TRUE(else_rhs_ptr->result_type()->IsF32());
277 EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
278 EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
279}
280
dan sinclairbc71eda2020-04-07 12:55:51 +0000281TEST_F(TypeDeterminerTest, Stmt_Loop) {
282 ast::type::I32Type i32;
283 ast::type::F32Type f32;
284
285 auto body_lhs = std::make_unique<ast::ScalarConstructorExpression>(
286 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000287 auto* body_lhs_ptr = body_lhs.get();
dan sinclairbc71eda2020-04-07 12:55:51 +0000288
289 auto body_rhs = std::make_unique<ast::ScalarConstructorExpression>(
290 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000291 auto* body_rhs_ptr = body_rhs.get();
dan sinclairbc71eda2020-04-07 12:55:51 +0000292
293 ast::StatementList body;
294 body.push_back(std::make_unique<ast::AssignmentStatement>(
295 std::move(body_lhs), std::move(body_rhs)));
296
297 auto continuing_lhs = std::make_unique<ast::ScalarConstructorExpression>(
298 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000299 auto* continuing_lhs_ptr = continuing_lhs.get();
dan sinclairbc71eda2020-04-07 12:55:51 +0000300
301 auto continuing_rhs = std::make_unique<ast::ScalarConstructorExpression>(
302 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000303 auto* continuing_rhs_ptr = continuing_rhs.get();
dan sinclairbc71eda2020-04-07 12:55:51 +0000304
305 ast::StatementList continuing;
306 continuing.push_back(std::make_unique<ast::AssignmentStatement>(
307 std::move(continuing_lhs), std::move(continuing_rhs)));
308
309 ast::LoopStatement stmt(std::move(body), std::move(continuing));
310
311 EXPECT_TRUE(td()->DetermineResultType(&stmt));
312 ASSERT_NE(body_lhs_ptr->result_type(), nullptr);
313 ASSERT_NE(body_rhs_ptr->result_type(), nullptr);
314 ASSERT_NE(continuing_lhs_ptr->result_type(), nullptr);
315 ASSERT_NE(continuing_rhs_ptr->result_type(), nullptr);
316 EXPECT_TRUE(body_lhs_ptr->result_type()->IsI32());
317 EXPECT_TRUE(body_rhs_ptr->result_type()->IsF32());
318 EXPECT_TRUE(continuing_lhs_ptr->result_type()->IsI32());
319 EXPECT_TRUE(continuing_rhs_ptr->result_type()->IsF32());
320}
321
dan sinclairbf0fff82020-04-07 12:56:24 +0000322TEST_F(TypeDeterminerTest, Stmt_Return) {
323 ast::type::I32Type i32;
324
325 auto cond = std::make_unique<ast::ScalarConstructorExpression>(
326 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000327 auto* cond_ptr = cond.get();
dan sinclairbf0fff82020-04-07 12:56:24 +0000328
329 ast::ReturnStatement ret(std::move(cond));
330
331 EXPECT_TRUE(td()->DetermineResultType(&ret));
332 ASSERT_NE(cond_ptr->result_type(), nullptr);
333 EXPECT_TRUE(cond_ptr->result_type()->IsI32());
334}
335
dan sinclair327ed1b2020-04-07 19:27:21 +0000336TEST_F(TypeDeterminerTest, Stmt_Return_WithoutValue) {
337 ast::type::I32Type i32;
338 ast::ReturnStatement ret;
339 EXPECT_TRUE(td()->DetermineResultType(&ret));
340}
341
dan sinclair18b32852020-04-07 12:56:45 +0000342TEST_F(TypeDeterminerTest, Stmt_Switch) {
343 ast::type::I32Type i32;
344 ast::type::F32Type f32;
345
346 auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
347 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000348 auto* lhs_ptr = lhs.get();
dan sinclair18b32852020-04-07 12:56:45 +0000349
350 auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
351 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000352 auto* rhs_ptr = rhs.get();
dan sinclair18b32852020-04-07 12:56:45 +0000353
354 ast::StatementList body;
355 body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
356 std::move(rhs)));
357
358 ast::CaseStatementList cases;
359 cases.push_back(std::make_unique<ast::CaseStatement>(
360 std::make_unique<ast::IntLiteral>(&i32, 3), std::move(body)));
361
362 ast::SwitchStatement stmt(std::make_unique<ast::ScalarConstructorExpression>(
363 std::make_unique<ast::IntLiteral>(&i32, 2)),
364 std::move(cases));
365
366 EXPECT_TRUE(td()->DetermineResultType(&stmt)) << td()->error();
367 ASSERT_NE(stmt.condition()->result_type(), nullptr);
368 ASSERT_NE(lhs_ptr->result_type(), nullptr);
369 ASSERT_NE(rhs_ptr->result_type(), nullptr);
370
371 EXPECT_TRUE(stmt.condition()->result_type()->IsI32());
372 EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
373 EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
374}
375
dan sinclair9a84e5e2020-04-07 12:56:57 +0000376TEST_F(TypeDeterminerTest, Stmt_Unless) {
377 ast::type::I32Type i32;
378 ast::type::F32Type f32;
379
380 auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
381 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000382 auto* lhs_ptr = lhs.get();
dan sinclair9a84e5e2020-04-07 12:56:57 +0000383
384 auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
385 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000386 auto* rhs_ptr = rhs.get();
dan sinclair9a84e5e2020-04-07 12:56:57 +0000387
388 ast::StatementList body;
389 body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
390 std::move(rhs)));
391
392 ast::UnlessStatement unless(
393 std::make_unique<ast::ScalarConstructorExpression>(
394 std::make_unique<ast::IntLiteral>(&i32, 3)),
395 std::move(body));
396
397 EXPECT_TRUE(td()->DetermineResultType(&unless));
398 ASSERT_NE(unless.condition()->result_type(), nullptr);
399 ASSERT_NE(lhs_ptr->result_type(), nullptr);
400 ASSERT_NE(rhs_ptr->result_type(), nullptr);
401 EXPECT_TRUE(unless.condition()->result_type()->IsI32());
402 EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
403 EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
404}
405
dan sinclairca893e32020-04-07 12:57:12 +0000406TEST_F(TypeDeterminerTest, Stmt_VariableDecl) {
407 ast::type::I32Type i32;
408 auto var =
409 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &i32);
410 var->set_constructor(std::make_unique<ast::ScalarConstructorExpression>(
411 std::make_unique<ast::IntLiteral>(&i32, 2)));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000412 auto* init_ptr = var->constructor();
dan sinclairca893e32020-04-07 12:57:12 +0000413
414 ast::VariableDeclStatement decl(std::move(var));
415
416 EXPECT_TRUE(td()->DetermineResultType(&decl));
417 ASSERT_NE(init_ptr->result_type(), nullptr);
418 EXPECT_TRUE(init_ptr->result_type()->IsI32());
419}
420
dan sinclair7456f422020-04-08 19:58:35 +0000421TEST_F(TypeDeterminerTest, Expr_Error_Unknown) {
422 FakeExpr e;
423 e.set_source(Source{2, 30});
424
425 EXPECT_FALSE(td()->DetermineResultType(&e));
426 EXPECT_EQ(td()->error(), "2:30: unknown expression for type determination");
427}
428
dan sinclair973bd6a2020-04-07 12:57:42 +0000429TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array) {
430 ast::type::I32Type i32;
431 ast::type::F32Type f32;
432 ast::type::ArrayType ary(&f32, 3);
433
434 auto idx = std::make_unique<ast::ScalarConstructorExpression>(
435 std::make_unique<ast::IntLiteral>(&i32, 2));
dan sinclair973bd6a2020-04-07 12:57:42 +0000436 auto var =
437 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &ary);
dan sinclaircd077b02020-04-20 14:19:04 +0000438 mod()->AddGlobalVariable(std::move(var));
dan sinclair973bd6a2020-04-07 12:57:42 +0000439
440 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000441 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000442
443 ast::ArrayAccessorExpression acc(
444 std::make_unique<ast::IdentifierExpression>("my_var"), std::move(idx));
445 EXPECT_TRUE(td()->DetermineResultType(&acc));
446 ASSERT_NE(acc.result_type(), nullptr);
447 EXPECT_TRUE(acc.result_type()->IsF32());
448}
449
450TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix) {
451 ast::type::I32Type i32;
452 ast::type::F32Type f32;
453 ast::type::MatrixType mat(&f32, 3, 2);
454
455 auto idx = std::make_unique<ast::ScalarConstructorExpression>(
456 std::make_unique<ast::IntLiteral>(&i32, 2));
dan sinclair973bd6a2020-04-07 12:57:42 +0000457 auto var =
458 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &mat);
dan sinclaircd077b02020-04-20 14:19:04 +0000459 mod()->AddGlobalVariable(std::move(var));
dan sinclair973bd6a2020-04-07 12:57:42 +0000460
461 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000462 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000463
464 ast::ArrayAccessorExpression acc(
465 std::make_unique<ast::IdentifierExpression>("my_var"), std::move(idx));
466 EXPECT_TRUE(td()->DetermineResultType(&acc));
467 ASSERT_NE(acc.result_type(), nullptr);
468 ASSERT_TRUE(acc.result_type()->IsVector());
Ryan Harrison0a196c12020-04-17 13:18:20 +0000469 EXPECT_EQ(acc.result_type()->AsVector()->size(), 3u);
dan sinclair973bd6a2020-04-07 12:57:42 +0000470}
471
472TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix_BothDimensions) {
473 ast::type::I32Type i32;
474 ast::type::F32Type f32;
475 ast::type::MatrixType mat(&f32, 3, 2);
476
477 auto idx1 = std::make_unique<ast::ScalarConstructorExpression>(
478 std::make_unique<ast::IntLiteral>(&i32, 2));
479 auto idx2 = std::make_unique<ast::ScalarConstructorExpression>(
480 std::make_unique<ast::IntLiteral>(&i32, 1));
dan sinclair973bd6a2020-04-07 12:57:42 +0000481 auto var =
482 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &mat);
dan sinclaircd077b02020-04-20 14:19:04 +0000483 mod()->AddGlobalVariable(std::move(var));
dan sinclair973bd6a2020-04-07 12:57:42 +0000484
485 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000486 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000487
488 ast::ArrayAccessorExpression acc(
489 std::make_unique<ast::ArrayAccessorExpression>(
490 std::make_unique<ast::IdentifierExpression>("my_var"),
491 std::move(idx1)),
492 std::move(idx2));
493
494 EXPECT_TRUE(td()->DetermineResultType(&acc));
495 ASSERT_NE(acc.result_type(), nullptr);
496 EXPECT_TRUE(acc.result_type()->IsF32());
497}
498
499TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Vector) {
500 ast::type::I32Type i32;
501 ast::type::F32Type f32;
502 ast::type::VectorType vec(&f32, 3);
503
504 auto idx = std::make_unique<ast::ScalarConstructorExpression>(
505 std::make_unique<ast::IntLiteral>(&i32, 2));
dan sinclair973bd6a2020-04-07 12:57:42 +0000506 auto var =
507 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &vec);
dan sinclaircd077b02020-04-20 14:19:04 +0000508 mod()->AddGlobalVariable(std::move(var));
dan sinclair973bd6a2020-04-07 12:57:42 +0000509
510 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000511 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000512
513 ast::ArrayAccessorExpression acc(
514 std::make_unique<ast::IdentifierExpression>("my_var"), std::move(idx));
515 EXPECT_TRUE(td()->DetermineResultType(&acc));
516 ASSERT_NE(acc.result_type(), nullptr);
517 EXPECT_TRUE(acc.result_type()->IsF32());
518}
519
dan sinclaira01777c2020-04-07 12:57:52 +0000520TEST_F(TypeDeterminerTest, Expr_As) {
521 ast::type::F32Type f32;
522 ast::AsExpression as(&f32,
523 std::make_unique<ast::IdentifierExpression>("name"));
524
525 EXPECT_TRUE(td()->DetermineResultType(&as));
526 ASSERT_NE(as.result_type(), nullptr);
527 EXPECT_TRUE(as.result_type()->IsF32());
528}
529
dan sinclair3ca87462020-04-07 16:41:10 +0000530TEST_F(TypeDeterminerTest, Expr_Call) {
531 ast::type::F32Type f32;
532
533 ast::VariableList params;
534 auto func =
535 std::make_unique<ast::Function>("my_func", std::move(params), &f32);
dan sinclaircd077b02020-04-20 14:19:04 +0000536 mod()->AddFunction(std::move(func));
dan sinclair3ca87462020-04-07 16:41:10 +0000537
538 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000539 EXPECT_TRUE(td()->Determine());
dan sinclair3ca87462020-04-07 16:41:10 +0000540
541 ast::ExpressionList call_params;
542 ast::CallExpression call(
543 std::make_unique<ast::IdentifierExpression>("my_func"),
544 std::move(call_params));
545 EXPECT_TRUE(td()->DetermineResultType(&call));
546 ASSERT_NE(call.result_type(), nullptr);
547 EXPECT_TRUE(call.result_type()->IsF32());
548}
549
dan sinclairccb52dc2020-04-20 14:18:54 +0000550TEST_F(TypeDeterminerTest, Expr_Call_WithParams) {
551 ast::type::F32Type f32;
552
553 ast::VariableList params;
554 auto func =
555 std::make_unique<ast::Function>("my_func", std::move(params), &f32);
dan sinclaircd077b02020-04-20 14:19:04 +0000556 mod()->AddFunction(std::move(func));
dan sinclairccb52dc2020-04-20 14:18:54 +0000557
558 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000559 EXPECT_TRUE(td()->Determine());
dan sinclairccb52dc2020-04-20 14:18:54 +0000560
561 ast::ExpressionList call_params;
562 call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
563 std::make_unique<ast::FloatLiteral>(&f32, 2.4)));
564
565 auto* param_ptr = call_params.back().get();
566
567 ast::CallExpression call(
568 std::make_unique<ast::IdentifierExpression>("my_func"),
569 std::move(call_params));
570 EXPECT_TRUE(td()->DetermineResultType(&call));
571 ASSERT_NE(param_ptr->result_type(), nullptr);
572 EXPECT_TRUE(param_ptr->result_type()->IsF32());
573}
574
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000575TEST_F(TypeDeterminerTest, Expr_Call_GLSLImport) {
576 ast::type::F32Type f32;
577
578 mod()->AddImport(std::make_unique<ast::Import>("GLSL.std.450", "std"));
579
580 // Register the function
581 EXPECT_TRUE(td()->Determine());
582
583 ast::ExpressionList call_params;
584 call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
585 std::make_unique<ast::FloatLiteral>(&f32, 2.4)));
586
587 std::vector<std::string> name{"std", "round"};
588 ast::CallExpression call(std::make_unique<ast::IdentifierExpression>(name),
589 std::move(call_params));
590
591 EXPECT_TRUE(td()->DetermineResultType(&call));
592 ASSERT_NE(call.result_type(), nullptr);
593 EXPECT_TRUE(call.result_type()->IsF32());
594}
595
dan sinclair4e807952020-04-07 16:41:23 +0000596TEST_F(TypeDeterminerTest, Expr_Cast) {
597 ast::type::F32Type f32;
598 ast::CastExpression cast(&f32,
599 std::make_unique<ast::IdentifierExpression>("name"));
600
601 EXPECT_TRUE(td()->DetermineResultType(&cast));
602 ASSERT_NE(cast.result_type(), nullptr);
603 EXPECT_TRUE(cast.result_type()->IsF32());
604}
605
dan sinclairb7edc4c2020-04-07 12:46:30 +0000606TEST_F(TypeDeterminerTest, Expr_Constructor_Scalar) {
607 ast::type::F32Type f32;
608 ast::ScalarConstructorExpression s(
609 std::make_unique<ast::FloatLiteral>(&f32, 1.0f));
610
611 EXPECT_TRUE(td()->DetermineResultType(&s));
612 ASSERT_NE(s.result_type(), nullptr);
613 EXPECT_TRUE(s.result_type()->IsF32());
614}
615
616TEST_F(TypeDeterminerTest, Expr_Constructor_Type) {
617 ast::type::F32Type f32;
618 ast::type::VectorType vec(&f32, 3);
619
620 ast::ExpressionList vals;
621 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
622 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
623 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
624 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
625 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
626 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
627
628 ast::TypeConstructorExpression tc(&vec, std::move(vals));
629
630 EXPECT_TRUE(td()->DetermineResultType(&tc));
631 ASSERT_NE(tc.result_type(), nullptr);
632 ASSERT_TRUE(tc.result_type()->IsVector());
633 EXPECT_TRUE(tc.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +0000634 EXPECT_EQ(tc.result_type()->AsVector()->size(), 3u);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000635}
636
dan sinclaircab0e732020-04-07 12:57:27 +0000637TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalVariable) {
638 ast::type::F32Type f32;
dan sinclaircab0e732020-04-07 12:57:27 +0000639 auto var =
640 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
dan sinclaircd077b02020-04-20 14:19:04 +0000641 mod()->AddGlobalVariable(std::move(var));
dan sinclaircab0e732020-04-07 12:57:27 +0000642
643 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000644 EXPECT_TRUE(td()->Determine());
dan sinclaircab0e732020-04-07 12:57:27 +0000645
646 ast::IdentifierExpression ident("my_var");
647 EXPECT_TRUE(td()->DetermineResultType(&ident));
648 ASSERT_NE(ident.result_type(), nullptr);
649 EXPECT_TRUE(ident.result_type()->IsF32());
650}
651
652TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable) {
653 ast::type::F32Type f32;
654
655 auto my_var = std::make_unique<ast::IdentifierExpression>("my_var");
Ryan Harrison0a196c12020-04-17 13:18:20 +0000656 auto* my_var_ptr = my_var.get();
dan sinclaircab0e732020-04-07 12:57:27 +0000657
658 ast::StatementList body;
659 body.push_back(std::make_unique<ast::VariableDeclStatement>(
660 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone,
661 &f32)));
662
663 body.push_back(std::make_unique<ast::AssignmentStatement>(
664 std::move(my_var),
665 std::make_unique<ast::IdentifierExpression>("my_var")));
666
667 ast::Function f("my_func", {}, &f32);
668 f.set_body(std::move(body));
669
670 EXPECT_TRUE(td()->DetermineFunction(&f));
671
672 ASSERT_NE(my_var_ptr->result_type(), nullptr);
673 EXPECT_TRUE(my_var_ptr->result_type()->IsF32());
674}
675
676TEST_F(TypeDeterminerTest, Expr_Identifier_Function) {
677 ast::type::F32Type f32;
678
679 ast::VariableList params;
680 auto func =
681 std::make_unique<ast::Function>("my_func", std::move(params), &f32);
dan sinclaircd077b02020-04-20 14:19:04 +0000682 mod()->AddFunction(std::move(func));
dan sinclaircab0e732020-04-07 12:57:27 +0000683
684 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000685 EXPECT_TRUE(td()->Determine());
dan sinclaircab0e732020-04-07 12:57:27 +0000686
687 ast::IdentifierExpression ident("my_func");
688 EXPECT_TRUE(td()->DetermineResultType(&ident));
689 ASSERT_NE(ident.result_type(), nullptr);
690 EXPECT_TRUE(ident.result_type()->IsF32());
691}
692
dan sinclair8ee1d222020-04-07 16:41:33 +0000693TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct) {
694 ast::type::I32Type i32;
695 ast::type::F32Type f32;
696
697 ast::StructMemberDecorationList decos;
698 ast::StructMemberList members;
699 members.push_back(std::make_unique<ast::StructMember>("first_member", &i32,
700 std::move(decos)));
701 members.push_back(std::make_unique<ast::StructMember>("second_member", &f32,
702 std::move(decos)));
703
704 auto strct = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
705 std::move(members));
706
707 ast::type::StructType st(std::move(strct));
708
709 auto var = std::make_unique<ast::Variable>("my_struct",
710 ast::StorageClass::kNone, &st);
711
dan sinclaircd077b02020-04-20 14:19:04 +0000712 mod()->AddGlobalVariable(std::move(var));
dan sinclair8ee1d222020-04-07 16:41:33 +0000713
714 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000715 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +0000716
717 auto ident = std::make_unique<ast::IdentifierExpression>("my_struct");
718 auto mem_ident = std::make_unique<ast::IdentifierExpression>("second_member");
719
720 ast::MemberAccessorExpression mem(std::move(ident), std::move(mem_ident));
721 EXPECT_TRUE(td()->DetermineResultType(&mem));
722 ASSERT_NE(mem.result_type(), nullptr);
723 EXPECT_TRUE(mem.result_type()->IsF32());
724}
725
726TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle) {
727 ast::type::F32Type f32;
728 ast::type::VectorType vec3(&f32, 3);
729
730 auto var = std::make_unique<ast::Variable>("my_vec", ast::StorageClass::kNone,
731 &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +0000732 mod()->AddGlobalVariable(std::move(var));
dan sinclair8ee1d222020-04-07 16:41:33 +0000733
734 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000735 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +0000736
737 auto ident = std::make_unique<ast::IdentifierExpression>("my_vec");
738 auto swizzle = std::make_unique<ast::IdentifierExpression>("xy");
739
740 ast::MemberAccessorExpression mem(std::move(ident), std::move(swizzle));
741 EXPECT_TRUE(td()->DetermineResultType(&mem)) << td()->error();
742 ASSERT_NE(mem.result_type(), nullptr);
743 ASSERT_TRUE(mem.result_type()->IsVector());
744 EXPECT_TRUE(mem.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +0000745 EXPECT_EQ(mem.result_type()->AsVector()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +0000746}
747
748TEST_F(TypeDeterminerTest, Expr_MultiLevel) {
749 // struct b {
750 // vec4<f32> foo
751 // }
752 // struct A {
753 // vec3<struct b> mem
754 // }
755 // var c : A
756 // c.mem[0].foo.yx
757 // -> vec2<f32>
758 //
759 // MemberAccessor{
760 // MemberAccessor{
761 // ArrayAccessor{
762 // MemberAccessor{
763 // Identifier{c}
764 // Identifier{mem}
765 // }
766 // ScalarConstructor{0}
767 // }
768 // Identifier{foo}
769 // }
770 // Identifier{yx}
771 // }
772 //
773 ast::type::I32Type i32;
774 ast::type::F32Type f32;
775
776 ast::type::VectorType vec4(&f32, 4);
777
778 ast::StructMemberDecorationList decos;
779 ast::StructMemberList b_members;
780 b_members.push_back(
781 std::make_unique<ast::StructMember>("foo", &vec4, std::move(decos)));
782
783 auto strctB = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
784 std::move(b_members));
785 ast::type::StructType stB(std::move(strctB));
786
787 ast::type::VectorType vecB(&stB, 3);
788
789 ast::StructMemberList a_members;
790 a_members.push_back(
791 std::make_unique<ast::StructMember>("mem", &vecB, std::move(decos)));
792
793 auto strctA = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
794 std::move(a_members));
795
796 ast::type::StructType stA(std::move(strctA));
797
798 auto var =
799 std::make_unique<ast::Variable>("c", ast::StorageClass::kNone, &stA);
dan sinclaircd077b02020-04-20 14:19:04 +0000800 mod()->AddGlobalVariable(std::move(var));
dan sinclair8ee1d222020-04-07 16:41:33 +0000801
802 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000803 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +0000804
805 auto ident = std::make_unique<ast::IdentifierExpression>("c");
806 auto mem_ident = std::make_unique<ast::IdentifierExpression>("mem");
807 auto foo_ident = std::make_unique<ast::IdentifierExpression>("foo");
808 auto idx = std::make_unique<ast::ScalarConstructorExpression>(
809 std::make_unique<ast::IntLiteral>(&i32, 0));
810 auto swizzle = std::make_unique<ast::IdentifierExpression>("yx");
811
812 ast::MemberAccessorExpression mem(
813 std::make_unique<ast::MemberAccessorExpression>(
814 std::make_unique<ast::ArrayAccessorExpression>(
815 std::make_unique<ast::MemberAccessorExpression>(
816 std::move(ident), std::move(mem_ident)),
817 std::move(idx)),
818 std::move(foo_ident)),
819 std::move(swizzle));
820 EXPECT_TRUE(td()->DetermineResultType(&mem)) << td()->error();
821 ASSERT_NE(mem.result_type(), nullptr);
822 ASSERT_TRUE(mem.result_type()->IsVector());
823 EXPECT_TRUE(mem.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +0000824 EXPECT_EQ(mem.result_type()->AsVector()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +0000825}
826
dan sinclaircd077b02020-04-20 14:19:04 +0000827using Expr_Binary_BitwiseTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +0000828TEST_P(Expr_Binary_BitwiseTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +0000829 auto op = GetParam();
830
831 ast::type::I32Type i32;
832
833 auto var =
834 std::make_unique<ast::Variable>("val", ast::StorageClass::kNone, &i32);
dan sinclaircd077b02020-04-20 14:19:04 +0000835 mod()->AddGlobalVariable(std::move(var));
dan sinclair9b978022020-04-07 19:26:39 +0000836
837 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000838 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000839
dan sinclair1c9b4862020-04-07 19:27:41 +0000840 ast::BinaryExpression expr(
dan sinclair9b978022020-04-07 19:26:39 +0000841 op, std::make_unique<ast::IdentifierExpression>("val"),
842 std::make_unique<ast::IdentifierExpression>("val"));
843
dan sinclaircd077b02020-04-20 14:19:04 +0000844 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000845 ASSERT_NE(expr.result_type(), nullptr);
846 EXPECT_TRUE(expr.result_type()->IsI32());
847}
848
dan sinclair1c9b4862020-04-07 19:27:41 +0000849TEST_P(Expr_Binary_BitwiseTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +0000850 auto op = GetParam();
851
852 ast::type::I32Type i32;
853 ast::type::VectorType vec3(&i32, 3);
854
855 auto var =
856 std::make_unique<ast::Variable>("val", ast::StorageClass::kNone, &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +0000857 mod()->AddGlobalVariable(std::move(var));
dan sinclair9b978022020-04-07 19:26:39 +0000858
859 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000860 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000861
dan sinclair1c9b4862020-04-07 19:27:41 +0000862 ast::BinaryExpression expr(
dan sinclair9b978022020-04-07 19:26:39 +0000863 op, std::make_unique<ast::IdentifierExpression>("val"),
864 std::make_unique<ast::IdentifierExpression>("val"));
865
dan sinclaircd077b02020-04-20 14:19:04 +0000866 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000867 ASSERT_NE(expr.result_type(), nullptr);
868 ASSERT_TRUE(expr.result_type()->IsVector());
869 EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsI32());
Ryan Harrison0a196c12020-04-17 13:18:20 +0000870 EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +0000871}
872INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +0000873 Expr_Binary_BitwiseTest,
874 testing::Values(ast::BinaryOp::kAnd,
875 ast::BinaryOp::kOr,
876 ast::BinaryOp::kXor,
877 ast::BinaryOp::kShiftLeft,
878 ast::BinaryOp::kShiftRight,
879 ast::BinaryOp::kShiftRightArith,
880 ast::BinaryOp::kAdd,
881 ast::BinaryOp::kSubtract,
882 ast::BinaryOp::kDivide,
883 ast::BinaryOp::kModulo));
dan sinclair9b978022020-04-07 19:26:39 +0000884
dan sinclaircd077b02020-04-20 14:19:04 +0000885using Expr_Binary_LogicalTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +0000886TEST_P(Expr_Binary_LogicalTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +0000887 auto op = GetParam();
888
889 ast::type::BoolType bool_type;
890
891 auto var = std::make_unique<ast::Variable>("val", ast::StorageClass::kNone,
892 &bool_type);
dan sinclaircd077b02020-04-20 14:19:04 +0000893 mod()->AddGlobalVariable(std::move(var));
dan sinclair9b978022020-04-07 19:26:39 +0000894
895 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000896 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000897
dan sinclair1c9b4862020-04-07 19:27:41 +0000898 ast::BinaryExpression expr(
dan sinclair9b978022020-04-07 19:26:39 +0000899 op, std::make_unique<ast::IdentifierExpression>("val"),
900 std::make_unique<ast::IdentifierExpression>("val"));
901
dan sinclaircd077b02020-04-20 14:19:04 +0000902 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000903 ASSERT_NE(expr.result_type(), nullptr);
904 EXPECT_TRUE(expr.result_type()->IsBool());
905}
906
dan sinclair1c9b4862020-04-07 19:27:41 +0000907TEST_P(Expr_Binary_LogicalTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +0000908 auto op = GetParam();
909
910 ast::type::BoolType bool_type;
911 ast::type::VectorType vec3(&bool_type, 3);
912
913 auto var =
914 std::make_unique<ast::Variable>("val", ast::StorageClass::kNone, &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +0000915 mod()->AddGlobalVariable(std::move(var));
dan sinclair9b978022020-04-07 19:26:39 +0000916
917 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000918 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000919
dan sinclair1c9b4862020-04-07 19:27:41 +0000920 ast::BinaryExpression expr(
dan sinclair9b978022020-04-07 19:26:39 +0000921 op, std::make_unique<ast::IdentifierExpression>("val"),
922 std::make_unique<ast::IdentifierExpression>("val"));
923
dan sinclaircd077b02020-04-20 14:19:04 +0000924 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000925 ASSERT_NE(expr.result_type(), nullptr);
926 ASSERT_TRUE(expr.result_type()->IsVector());
927 EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsBool());
Ryan Harrison0a196c12020-04-17 13:18:20 +0000928 EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +0000929}
930INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +0000931 Expr_Binary_LogicalTest,
932 testing::Values(ast::BinaryOp::kLogicalAnd,
933 ast::BinaryOp::kLogicalOr));
dan sinclair9b978022020-04-07 19:26:39 +0000934
dan sinclaircd077b02020-04-20 14:19:04 +0000935using Expr_Binary_CompareTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +0000936TEST_P(Expr_Binary_CompareTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +0000937 auto op = GetParam();
938
939 ast::type::I32Type i32;
940
941 auto var =
942 std::make_unique<ast::Variable>("val", ast::StorageClass::kNone, &i32);
dan sinclaircd077b02020-04-20 14:19:04 +0000943 mod()->AddGlobalVariable(std::move(var));
dan sinclair9b978022020-04-07 19:26:39 +0000944
945 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000946 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000947
dan sinclair1c9b4862020-04-07 19:27:41 +0000948 ast::BinaryExpression expr(
dan sinclair9b978022020-04-07 19:26:39 +0000949 op, std::make_unique<ast::IdentifierExpression>("val"),
950 std::make_unique<ast::IdentifierExpression>("val"));
951
dan sinclaircd077b02020-04-20 14:19:04 +0000952 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000953 ASSERT_NE(expr.result_type(), nullptr);
954 EXPECT_TRUE(expr.result_type()->IsBool());
955}
956
dan sinclair1c9b4862020-04-07 19:27:41 +0000957TEST_P(Expr_Binary_CompareTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +0000958 auto op = GetParam();
959
960 ast::type::I32Type i32;
961 ast::type::VectorType vec3(&i32, 3);
962
963 auto var =
964 std::make_unique<ast::Variable>("val", ast::StorageClass::kNone, &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +0000965 mod()->AddGlobalVariable(std::move(var));
dan sinclair9b978022020-04-07 19:26:39 +0000966
967 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000968 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000969
dan sinclair1c9b4862020-04-07 19:27:41 +0000970 ast::BinaryExpression expr(
dan sinclair9b978022020-04-07 19:26:39 +0000971 op, std::make_unique<ast::IdentifierExpression>("val"),
972 std::make_unique<ast::IdentifierExpression>("val"));
973
dan sinclaircd077b02020-04-20 14:19:04 +0000974 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000975 ASSERT_NE(expr.result_type(), nullptr);
976 ASSERT_TRUE(expr.result_type()->IsVector());
977 EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsBool());
Ryan Harrison0a196c12020-04-17 13:18:20 +0000978 EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +0000979}
980INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +0000981 Expr_Binary_CompareTest,
982 testing::Values(ast::BinaryOp::kEqual,
983 ast::BinaryOp::kNotEqual,
984 ast::BinaryOp::kLessThan,
985 ast::BinaryOp::kGreaterThan,
986 ast::BinaryOp::kLessThanEqual,
987 ast::BinaryOp::kGreaterThanEqual));
dan sinclair9b978022020-04-07 19:26:39 +0000988
dan sinclair1c9b4862020-04-07 19:27:41 +0000989TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +0000990 ast::type::I32Type i32;
991
992 auto var =
993 std::make_unique<ast::Variable>("val", ast::StorageClass::kNone, &i32);
dan sinclaircd077b02020-04-20 14:19:04 +0000994 mod()->AddGlobalVariable(std::move(var));
dan sinclair9b978022020-04-07 19:26:39 +0000995
996 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000997 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000998
dan sinclair1c9b4862020-04-07 19:27:41 +0000999 ast::BinaryExpression expr(
1000 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001001 std::make_unique<ast::IdentifierExpression>("val"),
1002 std::make_unique<ast::IdentifierExpression>("val"));
1003
dan sinclaircd077b02020-04-20 14:19:04 +00001004 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001005 ASSERT_NE(expr.result_type(), nullptr);
1006 EXPECT_TRUE(expr.result_type()->IsI32());
1007}
1008
dan sinclair1c9b4862020-04-07 19:27:41 +00001009TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001010 ast::type::F32Type f32;
1011 ast::type::VectorType vec3(&f32, 3);
1012
1013 auto scalar =
1014 std::make_unique<ast::Variable>("scalar", ast::StorageClass::kNone, &f32);
1015 auto vector = std::make_unique<ast::Variable>(
1016 "vector", ast::StorageClass::kNone, &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +00001017 mod()->AddGlobalVariable(std::move(scalar));
1018 mod()->AddGlobalVariable(std::move(vector));
dan sinclair9b978022020-04-07 19:26:39 +00001019
1020 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001021 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001022
dan sinclair1c9b4862020-04-07 19:27:41 +00001023 ast::BinaryExpression expr(
1024 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001025 std::make_unique<ast::IdentifierExpression>("vector"),
1026 std::make_unique<ast::IdentifierExpression>("scalar"));
1027
dan sinclaircd077b02020-04-20 14:19:04 +00001028 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001029 ASSERT_NE(expr.result_type(), nullptr);
1030 ASSERT_TRUE(expr.result_type()->IsVector());
1031 EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001032 EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001033}
1034
dan sinclair1c9b4862020-04-07 19:27:41 +00001035TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001036 ast::type::F32Type f32;
1037 ast::type::VectorType vec3(&f32, 3);
1038
1039 auto scalar =
1040 std::make_unique<ast::Variable>("scalar", ast::StorageClass::kNone, &f32);
1041 auto vector = std::make_unique<ast::Variable>(
1042 "vector", ast::StorageClass::kNone, &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +00001043 mod()->AddGlobalVariable(std::move(scalar));
1044 mod()->AddGlobalVariable(std::move(vector));
dan sinclair9b978022020-04-07 19:26:39 +00001045
1046 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001047 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001048
dan sinclair1c9b4862020-04-07 19:27:41 +00001049 ast::BinaryExpression expr(
1050 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001051 std::make_unique<ast::IdentifierExpression>("scalar"),
1052 std::make_unique<ast::IdentifierExpression>("vector"));
1053
dan sinclaircd077b02020-04-20 14:19:04 +00001054 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001055 ASSERT_NE(expr.result_type(), nullptr);
1056 ASSERT_TRUE(expr.result_type()->IsVector());
1057 EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001058 EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001059}
1060
dan sinclair1c9b4862020-04-07 19:27:41 +00001061TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001062 ast::type::F32Type f32;
1063 ast::type::VectorType vec3(&f32, 3);
1064
1065 auto vector = std::make_unique<ast::Variable>(
1066 "vector", ast::StorageClass::kNone, &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +00001067 mod()->AddGlobalVariable(std::move(vector));
dan sinclair9b978022020-04-07 19:26:39 +00001068
1069 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001070 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001071
dan sinclair1c9b4862020-04-07 19:27:41 +00001072 ast::BinaryExpression expr(
1073 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001074 std::make_unique<ast::IdentifierExpression>("vector"),
1075 std::make_unique<ast::IdentifierExpression>("vector"));
1076
dan sinclaircd077b02020-04-20 14:19:04 +00001077 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001078 ASSERT_NE(expr.result_type(), nullptr);
1079 ASSERT_TRUE(expr.result_type()->IsVector());
1080 EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001081 EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001082}
1083
dan sinclair1c9b4862020-04-07 19:27:41 +00001084TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001085 ast::type::F32Type f32;
1086 ast::type::MatrixType mat3x2(&f32, 3, 2);
1087
1088 auto scalar =
1089 std::make_unique<ast::Variable>("scalar", ast::StorageClass::kNone, &f32);
1090 auto matrix = std::make_unique<ast::Variable>(
1091 "matrix", ast::StorageClass::kNone, &mat3x2);
dan sinclaircd077b02020-04-20 14:19:04 +00001092 mod()->AddGlobalVariable(std::move(scalar));
1093 mod()->AddGlobalVariable(std::move(matrix));
dan sinclair9b978022020-04-07 19:26:39 +00001094
1095 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001096 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001097
dan sinclair1c9b4862020-04-07 19:27:41 +00001098 ast::BinaryExpression expr(
1099 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001100 std::make_unique<ast::IdentifierExpression>("matrix"),
1101 std::make_unique<ast::IdentifierExpression>("scalar"));
1102
dan sinclaircd077b02020-04-20 14:19:04 +00001103 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001104 ASSERT_NE(expr.result_type(), nullptr);
1105 ASSERT_TRUE(expr.result_type()->IsMatrix());
1106
Ryan Harrison0a196c12020-04-17 13:18:20 +00001107 auto* mat = expr.result_type()->AsMatrix();
dan sinclair9b978022020-04-07 19:26:39 +00001108 EXPECT_TRUE(mat->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001109 EXPECT_EQ(mat->rows(), 3u);
1110 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001111}
1112
dan sinclair1c9b4862020-04-07 19:27:41 +00001113TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Matrix) {
dan sinclair9b978022020-04-07 19:26:39 +00001114 ast::type::F32Type f32;
1115 ast::type::MatrixType mat3x2(&f32, 3, 2);
1116
1117 auto scalar =
1118 std::make_unique<ast::Variable>("scalar", ast::StorageClass::kNone, &f32);
1119 auto matrix = std::make_unique<ast::Variable>(
1120 "matrix", ast::StorageClass::kNone, &mat3x2);
dan sinclaircd077b02020-04-20 14:19:04 +00001121 mod()->AddGlobalVariable(std::move(scalar));
1122 mod()->AddGlobalVariable(std::move(matrix));
dan sinclair9b978022020-04-07 19:26:39 +00001123
1124 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001125 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001126
dan sinclair1c9b4862020-04-07 19:27:41 +00001127 ast::BinaryExpression expr(
1128 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001129 std::make_unique<ast::IdentifierExpression>("scalar"),
1130 std::make_unique<ast::IdentifierExpression>("matrix"));
1131
dan sinclaircd077b02020-04-20 14:19:04 +00001132 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001133 ASSERT_NE(expr.result_type(), nullptr);
1134 ASSERT_TRUE(expr.result_type()->IsMatrix());
1135
Ryan Harrison0a196c12020-04-17 13:18:20 +00001136 auto* mat = expr.result_type()->AsMatrix();
dan sinclair9b978022020-04-07 19:26:39 +00001137 EXPECT_TRUE(mat->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001138 EXPECT_EQ(mat->rows(), 3u);
1139 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001140}
1141
dan sinclair1c9b4862020-04-07 19:27:41 +00001142TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001143 ast::type::F32Type f32;
1144 ast::type::VectorType vec3(&f32, 2);
1145 ast::type::MatrixType mat3x2(&f32, 3, 2);
1146
1147 auto vector = std::make_unique<ast::Variable>(
1148 "vector", ast::StorageClass::kNone, &vec3);
1149 auto matrix = std::make_unique<ast::Variable>(
1150 "matrix", ast::StorageClass::kNone, &mat3x2);
dan sinclaircd077b02020-04-20 14:19:04 +00001151 mod()->AddGlobalVariable(std::move(vector));
1152 mod()->AddGlobalVariable(std::move(matrix));
dan sinclair9b978022020-04-07 19:26:39 +00001153
1154 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001155 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001156
dan sinclair1c9b4862020-04-07 19:27:41 +00001157 ast::BinaryExpression expr(
1158 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001159 std::make_unique<ast::IdentifierExpression>("matrix"),
1160 std::make_unique<ast::IdentifierExpression>("vector"));
1161
dan sinclaircd077b02020-04-20 14:19:04 +00001162 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001163 ASSERT_NE(expr.result_type(), nullptr);
1164 ASSERT_TRUE(expr.result_type()->IsVector());
1165 EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001166 EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001167}
1168
dan sinclair1c9b4862020-04-07 19:27:41 +00001169TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Matrix) {
dan sinclair9b978022020-04-07 19:26:39 +00001170 ast::type::F32Type f32;
1171 ast::type::VectorType vec3(&f32, 3);
1172 ast::type::MatrixType mat3x2(&f32, 3, 2);
1173
1174 auto vector = std::make_unique<ast::Variable>(
1175 "vector", ast::StorageClass::kNone, &vec3);
1176 auto matrix = std::make_unique<ast::Variable>(
1177 "matrix", ast::StorageClass::kNone, &mat3x2);
dan sinclaircd077b02020-04-20 14:19:04 +00001178 mod()->AddGlobalVariable(std::move(vector));
1179 mod()->AddGlobalVariable(std::move(matrix));
dan sinclair9b978022020-04-07 19:26:39 +00001180
1181 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001182 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001183
dan sinclair1c9b4862020-04-07 19:27:41 +00001184 ast::BinaryExpression expr(
1185 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001186 std::make_unique<ast::IdentifierExpression>("vector"),
1187 std::make_unique<ast::IdentifierExpression>("matrix"));
1188
dan sinclaircd077b02020-04-20 14:19:04 +00001189 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001190 ASSERT_NE(expr.result_type(), nullptr);
1191 ASSERT_TRUE(expr.result_type()->IsVector());
1192 EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001193 EXPECT_EQ(expr.result_type()->AsVector()->size(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001194}
1195
dan sinclair1c9b4862020-04-07 19:27:41 +00001196TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Matrix) {
dan sinclair9b978022020-04-07 19:26:39 +00001197 ast::type::F32Type f32;
1198 ast::type::MatrixType mat4x3(&f32, 4, 3);
1199 ast::type::MatrixType mat3x4(&f32, 3, 4);
1200
1201 auto matrix1 = std::make_unique<ast::Variable>(
1202 "mat4x3", ast::StorageClass::kNone, &mat4x3);
1203 auto matrix2 = std::make_unique<ast::Variable>(
1204 "mat3x4", ast::StorageClass::kNone, &mat3x4);
dan sinclaircd077b02020-04-20 14:19:04 +00001205 mod()->AddGlobalVariable(std::move(matrix1));
1206 mod()->AddGlobalVariable(std::move(matrix2));
dan sinclair9b978022020-04-07 19:26:39 +00001207
1208 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001209 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001210
dan sinclair1c9b4862020-04-07 19:27:41 +00001211 ast::BinaryExpression expr(
1212 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001213 std::make_unique<ast::IdentifierExpression>("mat4x3"),
1214 std::make_unique<ast::IdentifierExpression>("mat3x4"));
1215
dan sinclaircd077b02020-04-20 14:19:04 +00001216 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001217 ASSERT_NE(expr.result_type(), nullptr);
1218 ASSERT_TRUE(expr.result_type()->IsMatrix());
1219
Ryan Harrison0a196c12020-04-17 13:18:20 +00001220 auto* mat = expr.result_type()->AsMatrix();
dan sinclair9b978022020-04-07 19:26:39 +00001221 EXPECT_TRUE(mat->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001222 EXPECT_EQ(mat->rows(), 4u);
1223 EXPECT_EQ(mat->columns(), 4u);
dan sinclair9b978022020-04-07 19:26:39 +00001224}
1225
dan sinclairb1730562020-04-07 19:26:49 +00001226using UnaryDerivativeExpressionTest =
dan sinclaircd077b02020-04-20 14:19:04 +00001227 TypeDeterminerTestWithParam<ast::UnaryDerivative>;
dan sinclairb1730562020-04-07 19:26:49 +00001228TEST_P(UnaryDerivativeExpressionTest, Expr_UnaryDerivative) {
1229 auto derivative = GetParam();
1230
1231 ast::type::F32Type f32;
1232
1233 ast::type::VectorType vec4(&f32, 4);
1234
1235 auto var =
1236 std::make_unique<ast::Variable>("ident", ast::StorageClass::kNone, &vec4);
dan sinclaircd077b02020-04-20 14:19:04 +00001237 mod()->AddGlobalVariable(std::move(var));
dan sinclairb1730562020-04-07 19:26:49 +00001238
1239 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001240 EXPECT_TRUE(td()->Determine());
dan sinclairb1730562020-04-07 19:26:49 +00001241
1242 ast::UnaryDerivativeExpression der(
1243 derivative, ast::DerivativeModifier::kNone,
1244 std::make_unique<ast::IdentifierExpression>("ident"));
dan sinclaircd077b02020-04-20 14:19:04 +00001245 EXPECT_TRUE(td()->DetermineResultType(&der));
dan sinclairb1730562020-04-07 19:26:49 +00001246 ASSERT_NE(der.result_type(), nullptr);
1247 ASSERT_TRUE(der.result_type()->IsVector());
1248 EXPECT_TRUE(der.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001249 EXPECT_EQ(der.result_type()->AsVector()->size(), 4u);
dan sinclairb1730562020-04-07 19:26:49 +00001250}
1251INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
1252 UnaryDerivativeExpressionTest,
1253 testing::Values(ast::UnaryDerivative::kDpdx,
1254 ast::UnaryDerivative::kDpdy,
1255 ast::UnaryDerivative::kFwidth));
1256
dan sinclaircd077b02020-04-20 14:19:04 +00001257using UnaryMethodExpressionBoolTest =
1258 TypeDeterminerTestWithParam<ast::UnaryMethod>;
dan sinclair8dcfd102020-04-07 19:27:00 +00001259TEST_P(UnaryMethodExpressionBoolTest, Expr_UnaryMethod_Any) {
1260 auto op = GetParam();
1261
1262 ast::type::BoolType bool_type;
1263 ast::type::VectorType vec3(&bool_type, 3);
1264
1265 auto var = std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone,
1266 &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +00001267 mod()->AddGlobalVariable(std::move(var));
dan sinclair8dcfd102020-04-07 19:27:00 +00001268
1269 ast::ExpressionList params;
1270 params.push_back(std::make_unique<ast::IdentifierExpression>("my_var"));
1271
1272 ast::UnaryMethodExpression exp(op, std::move(params));
1273
dan sinclair8dcfd102020-04-07 19:27:00 +00001274 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001275 EXPECT_TRUE(td()->Determine());
dan sinclair8dcfd102020-04-07 19:27:00 +00001276
dan sinclaircd077b02020-04-20 14:19:04 +00001277 EXPECT_TRUE(td()->DetermineResultType(&exp));
dan sinclair8dcfd102020-04-07 19:27:00 +00001278 ASSERT_NE(exp.result_type(), nullptr);
1279 EXPECT_TRUE(exp.result_type()->IsBool());
1280}
1281INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
1282 UnaryMethodExpressionBoolTest,
1283 testing::Values(ast::UnaryMethod::kAny,
1284 ast::UnaryMethod::kAll));
1285
dan sinclaircd077b02020-04-20 14:19:04 +00001286using UnaryMethodExpressionVecTest =
1287 TypeDeterminerTestWithParam<ast::UnaryMethod>;
dan sinclair8dcfd102020-04-07 19:27:00 +00001288TEST_P(UnaryMethodExpressionVecTest, Expr_UnaryMethod_Bool) {
1289 auto op = GetParam();
1290
1291 ast::type::F32Type f32;
1292 ast::type::VectorType vec3(&f32, 3);
1293
1294 auto var = std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone,
1295 &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +00001296 mod()->AddGlobalVariable(std::move(var));
dan sinclair8dcfd102020-04-07 19:27:00 +00001297
1298 ast::ExpressionList params;
1299 params.push_back(std::make_unique<ast::IdentifierExpression>("my_var"));
1300
1301 ast::UnaryMethodExpression exp(op, std::move(params));
1302
dan sinclair8dcfd102020-04-07 19:27:00 +00001303 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001304 EXPECT_TRUE(td()->Determine());
dan sinclair8dcfd102020-04-07 19:27:00 +00001305
dan sinclaircd077b02020-04-20 14:19:04 +00001306 EXPECT_TRUE(td()->DetermineResultType(&exp));
dan sinclair8dcfd102020-04-07 19:27:00 +00001307 ASSERT_NE(exp.result_type(), nullptr);
1308 ASSERT_TRUE(exp.result_type()->IsVector());
1309 EXPECT_TRUE(exp.result_type()->AsVector()->type()->IsBool());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001310 EXPECT_EQ(exp.result_type()->AsVector()->size(), 3u);
dan sinclair8dcfd102020-04-07 19:27:00 +00001311}
1312TEST_P(UnaryMethodExpressionVecTest, Expr_UnaryMethod_Vec) {
1313 auto op = GetParam();
1314
1315 ast::type::F32Type f32;
1316
1317 auto var =
1318 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
dan sinclaircd077b02020-04-20 14:19:04 +00001319 mod()->AddGlobalVariable(std::move(var));
dan sinclair8dcfd102020-04-07 19:27:00 +00001320
1321 ast::ExpressionList params;
1322 params.push_back(std::make_unique<ast::IdentifierExpression>("my_var"));
1323
1324 ast::UnaryMethodExpression exp(op, std::move(params));
1325
dan sinclair8dcfd102020-04-07 19:27:00 +00001326 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001327 EXPECT_TRUE(td()->Determine());
dan sinclair8dcfd102020-04-07 19:27:00 +00001328
dan sinclaircd077b02020-04-20 14:19:04 +00001329 EXPECT_TRUE(td()->DetermineResultType(&exp));
dan sinclair8dcfd102020-04-07 19:27:00 +00001330 ASSERT_NE(exp.result_type(), nullptr);
1331 EXPECT_TRUE(exp.result_type()->IsBool());
1332}
1333INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
1334 UnaryMethodExpressionVecTest,
1335 testing::Values(ast::UnaryMethod::kIsInf,
1336 ast::UnaryMethod::kIsNan,
1337 ast::UnaryMethod::kIsFinite,
1338 ast::UnaryMethod::kIsNormal));
1339
1340TEST_F(TypeDeterminerTest, Expr_UnaryMethod_Dot) {
1341 ast::type::F32Type f32;
1342 ast::type::VectorType vec3(&f32, 3);
1343
1344 auto var = std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone,
1345 &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +00001346 mod()->AddGlobalVariable(std::move(var));
dan sinclair8dcfd102020-04-07 19:27:00 +00001347
1348 ast::ExpressionList params;
1349 params.push_back(std::make_unique<ast::IdentifierExpression>("my_var"));
1350 params.push_back(std::make_unique<ast::IdentifierExpression>("my_var"));
1351
1352 ast::UnaryMethodExpression exp(ast::UnaryMethod::kDot, std::move(params));
1353
dan sinclair8dcfd102020-04-07 19:27:00 +00001354 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001355 EXPECT_TRUE(td()->Determine());
dan sinclair8dcfd102020-04-07 19:27:00 +00001356
dan sinclaircd077b02020-04-20 14:19:04 +00001357 EXPECT_TRUE(td()->DetermineResultType(&exp));
dan sinclair8dcfd102020-04-07 19:27:00 +00001358 ASSERT_NE(exp.result_type(), nullptr);
1359 EXPECT_TRUE(exp.result_type()->IsF32());
1360}
1361
1362TEST_F(TypeDeterminerTest, Expr_UnaryMethod_OuterProduct) {
1363 ast::type::F32Type f32;
1364 ast::type::VectorType vec3(&f32, 3);
1365 ast::type::VectorType vec2(&f32, 2);
1366
1367 auto var1 =
1368 std::make_unique<ast::Variable>("v3", ast::StorageClass::kNone, &vec3);
1369 auto var2 =
1370 std::make_unique<ast::Variable>("v2", ast::StorageClass::kNone, &vec2);
dan sinclaircd077b02020-04-20 14:19:04 +00001371 mod()->AddGlobalVariable(std::move(var1));
1372 mod()->AddGlobalVariable(std::move(var2));
dan sinclair8dcfd102020-04-07 19:27:00 +00001373
1374 ast::ExpressionList params;
1375 params.push_back(std::make_unique<ast::IdentifierExpression>("v3"));
1376 params.push_back(std::make_unique<ast::IdentifierExpression>("v2"));
1377
1378 ast::UnaryMethodExpression exp(ast::UnaryMethod::kOuterProduct,
1379 std::move(params));
1380
dan sinclair8dcfd102020-04-07 19:27:00 +00001381 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001382 EXPECT_TRUE(td()->Determine());
dan sinclair8dcfd102020-04-07 19:27:00 +00001383
dan sinclaircd077b02020-04-20 14:19:04 +00001384 EXPECT_TRUE(td()->DetermineResultType(&exp));
dan sinclair8dcfd102020-04-07 19:27:00 +00001385 ASSERT_NE(exp.result_type(), nullptr);
1386 ASSERT_TRUE(exp.result_type()->IsMatrix());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001387 auto* mat = exp.result_type()->AsMatrix();
dan sinclair8dcfd102020-04-07 19:27:00 +00001388 EXPECT_TRUE(mat->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001389 EXPECT_EQ(mat->rows(), 3u);
1390 EXPECT_EQ(mat->columns(), 2u);
dan sinclair8dcfd102020-04-07 19:27:00 +00001391}
1392
dan sinclaircd077b02020-04-20 14:19:04 +00001393using UnaryOpExpressionTest = TypeDeterminerTestWithParam<ast::UnaryOp>;
dan sinclair0e257622020-04-07 19:27:11 +00001394TEST_P(UnaryOpExpressionTest, Expr_UnaryOp) {
1395 auto op = GetParam();
1396
1397 ast::type::F32Type f32;
1398
1399 ast::type::VectorType vec4(&f32, 4);
1400
1401 auto var =
1402 std::make_unique<ast::Variable>("ident", ast::StorageClass::kNone, &vec4);
dan sinclaircd077b02020-04-20 14:19:04 +00001403 mod()->AddGlobalVariable(std::move(var));
dan sinclair0e257622020-04-07 19:27:11 +00001404
1405 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001406 EXPECT_TRUE(td()->Determine());
dan sinclair0e257622020-04-07 19:27:11 +00001407
1408 ast::UnaryOpExpression der(
1409 op, std::make_unique<ast::IdentifierExpression>("ident"));
dan sinclaircd077b02020-04-20 14:19:04 +00001410 EXPECT_TRUE(td()->DetermineResultType(&der));
dan sinclair0e257622020-04-07 19:27:11 +00001411 ASSERT_NE(der.result_type(), nullptr);
1412 ASSERT_TRUE(der.result_type()->IsVector());
1413 EXPECT_TRUE(der.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001414 EXPECT_EQ(der.result_type()->AsVector()->size(), 4u);
dan sinclair0e257622020-04-07 19:27:11 +00001415}
1416INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
1417 UnaryOpExpressionTest,
1418 testing::Values(ast::UnaryOp::kNegation,
1419 ast::UnaryOp::kNot));
1420
dan sinclairee8ae042020-04-08 19:58:20 +00001421TEST_F(TypeDeterminerTest, StorageClass_SetsIfMissing) {
1422 ast::type::I32Type i32;
1423
1424 auto var =
1425 std::make_unique<ast::Variable>("var", ast::StorageClass::kNone, &i32);
Ryan Harrison0a196c12020-04-17 13:18:20 +00001426 auto* var_ptr = var.get();
dan sinclairee8ae042020-04-08 19:58:20 +00001427 auto stmt = std::make_unique<ast::VariableDeclStatement>(std::move(var));
1428
1429 auto func =
1430 std::make_unique<ast::Function>("func", ast::VariableList{}, &i32);
1431 ast::StatementList stmts;
1432 stmts.push_back(std::move(stmt));
1433 func->set_body(std::move(stmts));
1434
dan sinclaircd077b02020-04-20 14:19:04 +00001435 mod()->AddFunction(std::move(func));
dan sinclairee8ae042020-04-08 19:58:20 +00001436
dan sinclairb950e802020-04-20 14:20:01 +00001437 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclairee8ae042020-04-08 19:58:20 +00001438 EXPECT_EQ(var_ptr->storage_class(), ast::StorageClass::kFunction);
1439}
1440
1441TEST_F(TypeDeterminerTest, StorageClass_DoesNotSetOnConst) {
1442 ast::type::I32Type i32;
1443
1444 auto var =
1445 std::make_unique<ast::Variable>("var", ast::StorageClass::kNone, &i32);
1446 var->set_is_const(true);
Ryan Harrison0a196c12020-04-17 13:18:20 +00001447 auto* var_ptr = var.get();
dan sinclairee8ae042020-04-08 19:58:20 +00001448 auto stmt = std::make_unique<ast::VariableDeclStatement>(std::move(var));
1449
1450 auto func =
1451 std::make_unique<ast::Function>("func", ast::VariableList{}, &i32);
1452 ast::StatementList stmts;
1453 stmts.push_back(std::move(stmt));
1454 func->set_body(std::move(stmts));
1455
dan sinclaircd077b02020-04-20 14:19:04 +00001456 mod()->AddFunction(std::move(func));
dan sinclairee8ae042020-04-08 19:58:20 +00001457
dan sinclairb950e802020-04-20 14:20:01 +00001458 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclairee8ae042020-04-08 19:58:20 +00001459 EXPECT_EQ(var_ptr->storage_class(), ast::StorageClass::kNone);
1460}
1461
1462TEST_F(TypeDeterminerTest, StorageClass_NonFunctionClassError) {
1463 ast::type::I32Type i32;
1464
1465 auto var = std::make_unique<ast::Variable>(
1466 "var", ast::StorageClass::kWorkgroup, &i32);
1467 auto stmt = std::make_unique<ast::VariableDeclStatement>(std::move(var));
1468
1469 auto func =
1470 std::make_unique<ast::Function>("func", ast::VariableList{}, &i32);
1471 ast::StatementList stmts;
1472 stmts.push_back(std::move(stmt));
1473 func->set_body(std::move(stmts));
1474
dan sinclaircd077b02020-04-20 14:19:04 +00001475 mod()->AddFunction(std::move(func));
dan sinclairee8ae042020-04-08 19:58:20 +00001476
dan sinclairb950e802020-04-20 14:20:01 +00001477 EXPECT_FALSE(td()->Determine());
dan sinclairee8ae042020-04-08 19:58:20 +00001478 EXPECT_EQ(td()->error(),
1479 "function variable has a non-function storage class");
1480}
1481
dan sinclairca1723e2020-04-20 15:47:55 +00001482struct GLSLData {
1483 const char* name;
1484 uint32_t value;
1485};
1486inline std::ostream& operator<<(std::ostream& out, GLSLData data) {
1487 out << data.name;
1488 return out;
1489}
dan sinclair37d62c92020-04-21 12:55:06 +00001490using ImportData_SingleParamTest = TypeDeterminerTestWithParam<GLSLData>;
dan sinclairca1723e2020-04-20 15:47:55 +00001491
dan sinclair37d62c92020-04-21 12:55:06 +00001492TEST_P(ImportData_SingleParamTest, Scalar) {
dan sinclairca1723e2020-04-20 15:47:55 +00001493 auto param = GetParam();
1494
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001495 ast::type::F32Type f32;
1496
1497 ast::ExpressionList params;
1498 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
dan sinclair37d62c92020-04-21 12:55:06 +00001499 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001500
1501 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1502
1503 uint32_t id = 0;
dan sinclairca1723e2020-04-20 15:47:55 +00001504 auto* type = td()->GetImportData("GLSL.std.450", param.name, params, &id);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001505 ASSERT_NE(type, nullptr);
1506 EXPECT_TRUE(type->is_float_scalar());
dan sinclairca1723e2020-04-20 15:47:55 +00001507 EXPECT_EQ(id, param.value);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001508}
1509
dan sinclair37d62c92020-04-21 12:55:06 +00001510TEST_P(ImportData_SingleParamTest, Vector) {
dan sinclairca1723e2020-04-20 15:47:55 +00001511 auto param = GetParam();
1512
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001513 ast::type::F32Type f32;
1514 ast::type::VectorType vec(&f32, 3);
1515
1516 ast::ExpressionList vals;
1517 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1518 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1519 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1520 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1521 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1522 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
1523
1524 ast::ExpressionList params;
1525 params.push_back(
1526 std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals)));
1527
1528 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1529
1530 uint32_t id = 0;
dan sinclairca1723e2020-04-20 15:47:55 +00001531 auto* type = td()->GetImportData("GLSL.std.450", param.name, params, &id);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001532 ASSERT_NE(type, nullptr);
1533 EXPECT_TRUE(type->is_float_vector());
1534 EXPECT_EQ(type->AsVector()->size(), 3);
dan sinclairca1723e2020-04-20 15:47:55 +00001535 EXPECT_EQ(id, param.value);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001536}
1537
dan sinclair37d62c92020-04-21 12:55:06 +00001538TEST_P(ImportData_SingleParamTest, Error_Integer) {
dan sinclairca1723e2020-04-20 15:47:55 +00001539 auto param = GetParam();
1540
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001541 ast::type::I32Type i32;
1542
1543 ast::ExpressionList params;
1544 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1545 std::make_unique<ast::IntLiteral>(&i32, 1)));
1546
1547 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1548
1549 uint32_t id = 0;
dan sinclairca1723e2020-04-20 15:47:55 +00001550 auto* type = td()->GetImportData("GLSL.std.450", param.name, params, &id);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001551 ASSERT_EQ(type, nullptr);
dan sinclairca1723e2020-04-20 15:47:55 +00001552 EXPECT_EQ(td()->error(), std::string("incorrect type for ") + param.name +
1553 ". Requires a float scalar or a float vector");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001554}
1555
dan sinclair37d62c92020-04-21 12:55:06 +00001556TEST_P(ImportData_SingleParamTest, Error_NoParams) {
dan sinclairca1723e2020-04-20 15:47:55 +00001557 auto param = GetParam();
1558
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001559 ast::ExpressionList params;
1560 uint32_t id = 0;
dan sinclairca1723e2020-04-20 15:47:55 +00001561 auto* type = td()->GetImportData("GLSL.std.450", param.name, params, &id);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001562 ASSERT_EQ(type, nullptr);
dan sinclairca1723e2020-04-20 15:47:55 +00001563 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
1564 param.name + ". Expected 1 got 0");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001565}
1566
dan sinclair37d62c92020-04-21 12:55:06 +00001567TEST_P(ImportData_SingleParamTest, Error_MultipleParams) {
dan sinclairca1723e2020-04-20 15:47:55 +00001568 auto param = GetParam();
1569
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001570 ast::type::F32Type f32;
1571 ast::ExpressionList params;
1572 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1573 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1574 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1575 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1576 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1577 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1578
1579 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1580
1581 uint32_t id = 0;
dan sinclairca1723e2020-04-20 15:47:55 +00001582 auto* type = td()->GetImportData("GLSL.std.450", param.name, params, &id);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001583 ASSERT_EQ(type, nullptr);
dan sinclairca1723e2020-04-20 15:47:55 +00001584 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
1585 param.name + ". Expected 1 got 3");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001586}
1587
dan sinclaira49328f2020-04-20 15:49:50 +00001588INSTANTIATE_TEST_SUITE_P(
1589 TypeDeterminerTest,
dan sinclair37d62c92020-04-21 12:55:06 +00001590 ImportData_SingleParamTest,
dan sinclaira49328f2020-04-20 15:49:50 +00001591 testing::Values(GLSLData{"round", GLSLstd450Round},
1592 GLSLData{"roundeven", GLSLstd450RoundEven},
1593 GLSLData{"trunc", GLSLstd450Trunc},
1594 GLSLData{"fabs", GLSLstd450FAbs},
1595 GLSLData{"fsign", GLSLstd450FSign},
1596 GLSLData{"floor", GLSLstd450Floor},
1597 GLSLData{"ceil", GLSLstd450Ceil},
1598 GLSLData{"fract", GLSLstd450Fract},
1599 GLSLData{"radians", GLSLstd450Radians},
1600 GLSLData{"degrees", GLSLstd450Degrees},
1601 GLSLData{"sin", GLSLstd450Sin},
1602 GLSLData{"cos", GLSLstd450Cos},
1603 GLSLData{"tan", GLSLstd450Tan},
1604 GLSLData{"asin", GLSLstd450Asin},
1605 GLSLData{"acos", GLSLstd450Acos},
1606 GLSLData{"atan", GLSLstd450Atan},
1607 GLSLData{"sinh", GLSLstd450Sinh},
1608 GLSLData{"cosh", GLSLstd450Cosh},
1609 GLSLData{"tanh", GLSLstd450Tanh},
1610 GLSLData{"asinh", GLSLstd450Asinh},
1611 GLSLData{"acosh", GLSLstd450Acosh},
1612 GLSLData{"atanh", GLSLstd450Atanh},
1613 GLSLData{"exp", GLSLstd450Exp},
1614 GLSLData{"log", GLSLstd450Log},
1615 GLSLData{"exp2", GLSLstd450Exp2},
1616 GLSLData{"log2", GLSLstd450Log2},
1617 GLSLData{"sqrt", GLSLstd450Sqrt},
dan sinclair3df20442020-04-20 15:51:18 +00001618 GLSLData{"inversesqrt", GLSLstd450InverseSqrt},
1619 GLSLData{"normalize", GLSLstd450Normalize}));
dan sinclairca1723e2020-04-20 15:47:55 +00001620
dan sinclair652a4b92020-04-20 21:09:14 +00001621TEST_F(TypeDeterminerTest, ImportData_Length_Scalar) {
1622 ast::type::F32Type f32;
1623
1624 ast::ExpressionList params;
1625 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
dan sinclair37d62c92020-04-21 12:55:06 +00001626 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
dan sinclair652a4b92020-04-20 21:09:14 +00001627
1628 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1629
1630 uint32_t id = 0;
1631 auto* type = td()->GetImportData("GLSL.std.450", "length", params, &id);
1632 ASSERT_NE(type, nullptr);
1633 EXPECT_TRUE(type->is_float_scalar());
1634 EXPECT_EQ(id, GLSLstd450Length);
1635}
1636
1637TEST_F(TypeDeterminerTest, ImportData_Length_FloatVector) {
1638 ast::type::F32Type f32;
1639 ast::type::VectorType vec(&f32, 3);
1640
1641 ast::ExpressionList vals;
1642 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1643 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1644 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1645 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1646 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1647 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
1648
1649 ast::ExpressionList params;
1650 params.push_back(
1651 std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals)));
1652
1653 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1654
1655 uint32_t id = 0;
1656 auto* type = td()->GetImportData("GLSL.std.450", "length", params, &id);
1657 ASSERT_NE(type, nullptr);
1658 EXPECT_TRUE(type->is_float_scalar());
1659 EXPECT_EQ(id, GLSLstd450Length);
1660}
1661
1662TEST_F(TypeDeterminerTest, ImportData_Length_Error_Integer) {
1663 ast::type::I32Type i32;
1664
1665 ast::ExpressionList params;
1666 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1667 std::make_unique<ast::IntLiteral>(&i32, 1)));
1668
1669 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1670
1671 uint32_t id = 0;
1672 auto* type = td()->GetImportData("GLSL.std.450", "length", params, &id);
1673 ASSERT_EQ(type, nullptr);
1674 EXPECT_EQ(
1675 td()->error(),
1676 "incorrect type for length. Requires a float scalar or a float vector");
1677}
1678
1679TEST_F(TypeDeterminerTest, ImportData_Length_Error_NoParams) {
1680 ast::ExpressionList params;
1681 uint32_t id = 0;
1682 auto* type = td()->GetImportData("GLSL.std.450", "length", params, &id);
1683 ASSERT_EQ(type, nullptr);
1684 EXPECT_EQ(td()->error(),
1685 "incorrect number of parameters for length. Expected 1 got 0");
1686}
1687
1688TEST_F(TypeDeterminerTest, ImportData_Length_Error_MultipleParams) {
1689 ast::type::F32Type f32;
1690 ast::ExpressionList params;
1691 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1692 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1693 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1694 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1695 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1696 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1697
1698 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1699
1700 uint32_t id = 0;
1701 auto* type = td()->GetImportData("GLSL.std.450", "length", params, &id);
1702 ASSERT_EQ(type, nullptr);
1703 EXPECT_EQ(td()->error(),
1704 "incorrect number of parameters for length. Expected 1 got 3");
1705}
1706
dan sinclair37d62c92020-04-21 12:55:06 +00001707using ImportData_TwoParamTest = TypeDeterminerTestWithParam<GLSLData>;
1708
1709TEST_P(ImportData_TwoParamTest, Scalar) {
1710 auto param = GetParam();
1711
1712 ast::type::F32Type f32;
1713
1714 ast::ExpressionList params;
1715 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1716 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1717 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1718 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1719
1720 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1721
1722 uint32_t id = 0;
1723 auto* type = td()->GetImportData("GLSL.std.450", param.name, params, &id);
1724 ASSERT_NE(type, nullptr);
1725 EXPECT_TRUE(type->is_float_scalar());
1726 EXPECT_EQ(id, param.value);
1727}
1728
1729TEST_P(ImportData_TwoParamTest, Vector) {
1730 auto param = GetParam();
1731
1732 ast::type::F32Type f32;
1733 ast::type::VectorType vec(&f32, 3);
1734
1735 ast::ExpressionList vals_1;
1736 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1737 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1738 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1739 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1740 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1741 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
1742
1743 ast::ExpressionList vals_2;
1744 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1745 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1746 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1747 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1748 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1749 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
1750
1751 ast::ExpressionList params;
1752 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
1753 &vec, std::move(vals_1)));
1754 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
1755 &vec, std::move(vals_2)));
1756
1757 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1758
1759 uint32_t id = 0;
1760 auto* type = td()->GetImportData("GLSL.std.450", param.name, params, &id);
1761 ASSERT_NE(type, nullptr);
1762 EXPECT_TRUE(type->is_float_vector());
1763 EXPECT_EQ(type->AsVector()->size(), 3);
1764 EXPECT_EQ(id, param.value);
1765}
1766
1767TEST_P(ImportData_TwoParamTest, Error_Integer) {
1768 auto param = GetParam();
1769
1770 ast::type::I32Type i32;
1771
1772 ast::ExpressionList params;
1773 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1774 std::make_unique<ast::IntLiteral>(&i32, 1)));
1775 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1776 std::make_unique<ast::IntLiteral>(&i32, 2)));
1777
1778 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1779
1780 uint32_t id = 0;
1781 auto* type = td()->GetImportData("GLSL.std.450", param.name, params, &id);
1782 ASSERT_EQ(type, nullptr);
1783 EXPECT_EQ(td()->error(),
1784 std::string("incorrect type for ") + param.name +
1785 ". Requires float scalar or a float vector values");
1786}
1787
1788TEST_P(ImportData_TwoParamTest, Error_NoParams) {
1789 auto param = GetParam();
1790
1791 ast::ExpressionList params;
1792 uint32_t id = 0;
1793 auto* type = td()->GetImportData("GLSL.std.450", param.name, params, &id);
1794 ASSERT_EQ(type, nullptr);
1795 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
1796 param.name + ". Expected 2 got 0");
1797}
1798
1799TEST_P(ImportData_TwoParamTest, Error_OneParam) {
1800 auto param = GetParam();
1801
1802 ast::type::F32Type f32;
1803 ast::ExpressionList params;
1804 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1805 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1806
1807 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1808
1809 uint32_t id = 0;
1810 auto* type = td()->GetImportData("GLSL.std.450", param.name, params, &id);
1811 ASSERT_EQ(type, nullptr);
1812 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
1813 param.name + ". Expected 2 got 1");
1814}
1815
1816TEST_P(ImportData_TwoParamTest, Error_MismatchedParamCount) {
1817 auto param = GetParam();
1818
1819 ast::type::F32Type f32;
1820 ast::type::VectorType vec2(&f32, 2);
1821 ast::type::VectorType vec3(&f32, 3);
1822
1823 ast::ExpressionList vals_1;
1824 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1825 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1826 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1827 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1828
1829 ast::ExpressionList vals_2;
1830 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1831 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1832 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1833 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1834 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1835 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
1836
1837 ast::ExpressionList params;
1838 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
1839 &vec2, std::move(vals_1)));
1840 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
1841 &vec3, std::move(vals_2)));
1842
1843 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1844
1845 uint32_t id = 0;
1846 auto* type = td()->GetImportData("GLSL.std.450", param.name, params, &id);
1847 ASSERT_EQ(type, nullptr);
1848 EXPECT_EQ(td()->error(),
1849 std::string("mismatched parameter types for ") + param.name);
1850}
1851
1852TEST_P(ImportData_TwoParamTest, Error_MismatchedParamType) {
1853 auto param = GetParam();
1854
1855 ast::type::F32Type f32;
1856 ast::type::VectorType vec(&f32, 3);
1857
1858 ast::ExpressionList vals;
1859 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1860 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1861 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1862 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1863 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1864 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
1865
1866 ast::ExpressionList params;
1867 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1868 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1869 params.push_back(
1870 std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals)));
1871
1872 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1873
1874 uint32_t id = 0;
1875 auto* type = td()->GetImportData("GLSL.std.450", param.name, params, &id);
1876 ASSERT_EQ(type, nullptr);
1877 EXPECT_EQ(td()->error(),
1878 std::string("mismatched parameter types for ") + param.name);
1879}
1880
1881TEST_P(ImportData_TwoParamTest, Error_TooManyParams) {
1882 auto param = GetParam();
1883
1884 ast::type::F32Type f32;
1885 ast::ExpressionList params;
1886 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1887 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1888 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1889 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1890 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1891 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1892
1893 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1894
1895 uint32_t id = 0;
1896 auto* type = td()->GetImportData("GLSL.std.450", param.name, params, &id);
1897 ASSERT_EQ(type, nullptr);
1898 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
1899 param.name + ". Expected 2 got 3");
1900}
1901
1902INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
1903 ImportData_TwoParamTest,
dan sinclair2ee4a7e2020-04-21 12:58:35 +00001904 testing::Values(GLSLData{"atan2", GLSLstd450Atan2},
1905 GLSLData{"pow", GLSLstd450Pow},
1906 GLSLData{"fmin", GLSLstd450FMin},
1907 GLSLData{"fmax", GLSLstd450FMax},
1908 GLSLData{"step", GLSLstd450Step},
1909 GLSLData{"reflect", GLSLstd450Reflect},
1910 GLSLData{"nmin", GLSLstd450NMin},
1911 GLSLData{"nmax", GLSLstd450NMax}));
dan sinclair37d62c92020-04-21 12:55:06 +00001912
dan sinclair54444382020-04-21 13:04:15 +00001913TEST_F(TypeDeterminerTest, ImportData_Distance_Scalar) {
1914 ast::type::F32Type f32;
1915
1916 ast::ExpressionList params;
1917 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1918 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1919 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1920 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1921
1922 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1923
1924 uint32_t id = 0;
1925 auto* type = td()->GetImportData("GLSL.std.450", "distance", params, &id);
1926 ASSERT_NE(type, nullptr);
1927 EXPECT_TRUE(type->is_float_scalar());
1928 EXPECT_EQ(id, GLSLstd450Distance);
1929}
1930
1931TEST_F(TypeDeterminerTest, ImportData_Distance_Vector) {
1932 ast::type::F32Type f32;
1933 ast::type::VectorType vec(&f32, 3);
1934
1935 ast::ExpressionList vals_1;
1936 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1937 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1938 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1939 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1940 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1941 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
1942
1943 ast::ExpressionList vals_2;
1944 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1945 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1946 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1947 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1948 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1949 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
1950
1951 ast::ExpressionList params;
1952 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
1953 &vec, std::move(vals_1)));
1954 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
1955 &vec, std::move(vals_2)));
1956
1957 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1958
1959 uint32_t id = 0;
1960 auto* type = td()->GetImportData("GLSL.std.450", "distance", params, &id);
1961 ASSERT_NE(type, nullptr);
1962 EXPECT_TRUE(type->IsF32());
1963 EXPECT_EQ(id, GLSLstd450Distance);
1964}
1965
1966TEST_F(TypeDeterminerTest, ImportData_Distance_Error_Integer) {
1967 ast::type::I32Type i32;
1968
1969 ast::ExpressionList params;
1970 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1971 std::make_unique<ast::IntLiteral>(&i32, 1)));
1972 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1973 std::make_unique<ast::IntLiteral>(&i32, 2)));
1974
1975 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1976
1977 uint32_t id = 0;
1978 auto* type = td()->GetImportData("GLSL.std.450", "distance", params, &id);
1979 ASSERT_EQ(type, nullptr);
1980 EXPECT_EQ(td()->error(),
1981 "incorrect type for distance. Requires float scalar or a float "
1982 "vector values");
1983}
1984
1985TEST_F(TypeDeterminerTest, ImportData_Distance_Error_NoParams) {
1986 ast::ExpressionList params;
1987 uint32_t id = 0;
1988 auto* type = td()->GetImportData("GLSL.std.450", "distance", params, &id);
1989 ASSERT_EQ(type, nullptr);
1990 EXPECT_EQ(td()->error(),
1991 "incorrect number of parameters for distance. Expected 2 got 0");
1992}
1993
1994TEST_F(TypeDeterminerTest, ImportData_Distance_Error_OneParam) {
1995 ast::type::F32Type f32;
1996 ast::ExpressionList params;
1997 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1998 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1999
2000 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2001
2002 uint32_t id = 0;
2003 auto* type = td()->GetImportData("GLSL.std.450", "distance", params, &id);
2004 ASSERT_EQ(type, nullptr);
2005 EXPECT_EQ(td()->error(),
2006 "incorrect number of parameters for distance. Expected 2 got 1");
2007}
2008
2009TEST_F(TypeDeterminerTest, ImportData_Distance_Error_MismatchedParamCount) {
2010 ast::type::F32Type f32;
2011 ast::type::VectorType vec2(&f32, 2);
2012 ast::type::VectorType vec3(&f32, 3);
2013
2014 ast::ExpressionList vals_1;
2015 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2016 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2017 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2018 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2019
2020 ast::ExpressionList vals_2;
2021 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2022 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2023 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2024 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2025 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2026 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
2027
2028 ast::ExpressionList params;
2029 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
2030 &vec2, std::move(vals_1)));
2031 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
2032 &vec3, std::move(vals_2)));
2033
2034 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2035
2036 uint32_t id = 0;
2037 auto* type = td()->GetImportData("GLSL.std.450", "distance", params, &id);
2038 ASSERT_EQ(type, nullptr);
2039 EXPECT_EQ(td()->error(), "mismatched parameter types for distance");
2040}
2041
2042TEST_F(TypeDeterminerTest, ImportData_Distance_Error_MismatchedParamType) {
2043 ast::type::F32Type f32;
2044 ast::type::VectorType vec(&f32, 3);
2045
2046 ast::ExpressionList vals;
2047 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2048 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2049 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2050 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2051 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2052 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
2053
2054 ast::ExpressionList params;
2055 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2056 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2057 params.push_back(
2058 std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals)));
2059
2060 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2061
2062 uint32_t id = 0;
2063 auto* type = td()->GetImportData("GLSL.std.450", "distance", params, &id);
2064 ASSERT_EQ(type, nullptr);
2065 EXPECT_EQ(td()->error(), "mismatched parameter types for distance");
2066}
2067
2068TEST_F(TypeDeterminerTest, ImportData_Distance_Error_TooManyParams) {
2069 ast::type::F32Type f32;
2070 ast::ExpressionList params;
2071 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2072 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2073 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2074 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2075 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2076 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2077
2078 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2079
2080 uint32_t id = 0;
2081 auto* type = td()->GetImportData("GLSL.std.450", "distance", params, &id);
2082 ASSERT_EQ(type, nullptr);
2083 EXPECT_EQ(td()->error(),
2084 "incorrect number of parameters for distance. Expected 2 got 3");
2085}
2086
dan sinclairb7edc4c2020-04-07 12:46:30 +00002087} // namespace
2088} // namespace tint