blob: 5e626b4c4d4d493ce01ffce46c40c8624fe372b0 [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 sinclair8eddb782020-04-23 22:26:52 +000049#include "src/ast/type/pointer_type.h"
dan sinclair8ee1d222020-04-07 16:41:33 +000050#include "src/ast/type/struct_type.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000051#include "src/ast/type/vector_type.h"
52#include "src/ast/type_constructor_expression.h"
dan sinclairb1730562020-04-07 19:26:49 +000053#include "src/ast/unary_derivative_expression.h"
dan sinclair8dcfd102020-04-07 19:27:00 +000054#include "src/ast/unary_method_expression.h"
dan sinclair327ed1b2020-04-07 19:27:21 +000055#include "src/ast/unary_op_expression.h"
dan sinclair9a84e5e2020-04-07 12:56:57 +000056#include "src/ast/unless_statement.h"
dan sinclairca893e32020-04-07 12:57:12 +000057#include "src/ast/variable_decl_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000058
59namespace tint {
60namespace {
61
dan sinclair7456f422020-04-08 19:58:35 +000062class FakeStmt : public ast::Statement {
63 public:
64 bool IsValid() const override { return true; }
65 void to_str(std::ostream&, size_t) const override {}
66};
67
68class FakeExpr : public ast::Expression {
69 public:
70 bool IsValid() const override { return true; }
71 void to_str(std::ostream&, size_t) const override {}
72};
73
dan sinclaircd077b02020-04-20 14:19:04 +000074class TypeDeterminerHelper {
dan sinclairb7edc4c2020-04-07 12:46:30 +000075 public:
dan sinclairb950e802020-04-20 14:20:01 +000076 TypeDeterminerHelper()
77 : td_(std::make_unique<TypeDeterminer>(&ctx_, &mod_)) {}
dan sinclairb7edc4c2020-04-07 12:46:30 +000078
79 TypeDeterminer* td() const { return td_.get(); }
dan sinclaircd077b02020-04-20 14:19:04 +000080 ast::Module* mod() { return &mod_; }
dan sinclairb7edc4c2020-04-07 12:46:30 +000081
82 private:
83 Context ctx_;
dan sinclaircd077b02020-04-20 14:19:04 +000084 ast::Module mod_;
dan sinclairb7edc4c2020-04-07 12:46:30 +000085 std::unique_ptr<TypeDeterminer> td_;
86};
87
dan sinclaircd077b02020-04-20 14:19:04 +000088class TypeDeterminerTest : public TypeDeterminerHelper, public testing::Test {};
89
90template <typename T>
91class TypeDeterminerTestWithParam : public TypeDeterminerHelper,
92 public testing::TestWithParam<T> {};
93
dan sinclair7456f422020-04-08 19:58:35 +000094TEST_F(TypeDeterminerTest, Error_WithEmptySource) {
95 FakeStmt s;
96 s.set_source(Source{0, 0});
97
98 EXPECT_FALSE(td()->DetermineResultType(&s));
99 EXPECT_EQ(td()->error(), "unknown statement type for type determination");
100}
101
102TEST_F(TypeDeterminerTest, Stmt_Error_Unknown) {
103 FakeStmt s;
104 s.set_source(Source{2, 30});
105
106 EXPECT_FALSE(td()->DetermineResultType(&s));
107 EXPECT_EQ(td()->error(),
108 "2:30: unknown statement type for type determination");
109}
110
dan sinclair6c498fc2020-04-07 12:47:23 +0000111TEST_F(TypeDeterminerTest, Stmt_Assign) {
112 ast::type::F32Type f32;
113 ast::type::I32Type i32;
114
115 auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
116 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000117 auto* lhs_ptr = lhs.get();
dan sinclair6c498fc2020-04-07 12:47:23 +0000118
119 auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
120 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000121 auto* rhs_ptr = rhs.get();
dan sinclair6c498fc2020-04-07 12:47:23 +0000122
123 ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
124
125 EXPECT_TRUE(td()->DetermineResultType(&assign));
126 ASSERT_NE(lhs_ptr->result_type(), nullptr);
127 ASSERT_NE(rhs_ptr->result_type(), nullptr);
128
129 EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
130 EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
131}
132
dan sinclairb7ea6e22020-04-07 12:54:10 +0000133TEST_F(TypeDeterminerTest, Stmt_Break) {
134 ast::type::I32Type i32;
135
136 auto cond = std::make_unique<ast::ScalarConstructorExpression>(
137 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000138 auto* cond_ptr = cond.get();
dan sinclairb7ea6e22020-04-07 12:54:10 +0000139
140 ast::BreakStatement brk(ast::StatementCondition::kIf, std::move(cond));
141
142 EXPECT_TRUE(td()->DetermineResultType(&brk));
143 ASSERT_NE(cond_ptr->result_type(), nullptr);
144 EXPECT_TRUE(cond_ptr->result_type()->IsI32());
145}
146
dan sinclair327ed1b2020-04-07 19:27:21 +0000147TEST_F(TypeDeterminerTest, Stmt_Break_WithoutCondition) {
148 ast::type::I32Type i32;
149 ast::BreakStatement brk;
150 EXPECT_TRUE(td()->DetermineResultType(&brk));
151}
152
dan sinclair6010b292020-04-07 12:54:20 +0000153TEST_F(TypeDeterminerTest, Stmt_Case) {
154 ast::type::I32Type i32;
155 ast::type::F32Type f32;
156
157 auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
158 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000159 auto* lhs_ptr = lhs.get();
dan sinclair6010b292020-04-07 12:54:20 +0000160
161 auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
162 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000163 auto* rhs_ptr = rhs.get();
dan sinclair6010b292020-04-07 12:54:20 +0000164
165 ast::StatementList body;
166 body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
167 std::move(rhs)));
168
169 ast::CaseStatement cse(std::make_unique<ast::IntLiteral>(&i32, 3),
170 std::move(body));
171
172 EXPECT_TRUE(td()->DetermineResultType(&cse));
173 ASSERT_NE(lhs_ptr->result_type(), nullptr);
174 ASSERT_NE(rhs_ptr->result_type(), nullptr);
175 EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
176 EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
177}
178
dan sinclairaec965e2020-04-07 12:54:29 +0000179TEST_F(TypeDeterminerTest, Stmt_Continue) {
180 ast::type::I32Type i32;
181
182 auto cond = std::make_unique<ast::ScalarConstructorExpression>(
183 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000184 auto* cond_ptr = cond.get();
dan sinclairaec965e2020-04-07 12:54:29 +0000185
186 ast::ContinueStatement stmt(ast::StatementCondition::kIf, std::move(cond));
187
188 EXPECT_TRUE(td()->DetermineResultType(&stmt));
189 ASSERT_NE(cond_ptr->result_type(), nullptr);
190 EXPECT_TRUE(cond_ptr->result_type()->IsI32());
191}
192
dan sinclair327ed1b2020-04-07 19:27:21 +0000193TEST_F(TypeDeterminerTest, Stmt_Continue_WithoutStatement) {
194 ast::type::I32Type i32;
195 ast::ContinueStatement stmt;
196 EXPECT_TRUE(td()->DetermineResultType(&stmt));
197}
198
dan sinclair0cf685f2020-04-07 12:54:37 +0000199TEST_F(TypeDeterminerTest, Stmt_Else) {
200 ast::type::I32Type i32;
201 ast::type::F32Type f32;
202
203 auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
204 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000205 auto* lhs_ptr = lhs.get();
dan sinclair0cf685f2020-04-07 12:54:37 +0000206
207 auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
208 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000209 auto* rhs_ptr = rhs.get();
dan sinclair0cf685f2020-04-07 12:54:37 +0000210
211 ast::StatementList body;
212 body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
213 std::move(rhs)));
214
215 ast::ElseStatement stmt(std::make_unique<ast::ScalarConstructorExpression>(
216 std::make_unique<ast::IntLiteral>(&i32, 3)),
217 std::move(body));
218
219 EXPECT_TRUE(td()->DetermineResultType(&stmt));
220 ASSERT_NE(stmt.condition()->result_type(), nullptr);
221 ASSERT_NE(lhs_ptr->result_type(), nullptr);
222 ASSERT_NE(rhs_ptr->result_type(), nullptr);
223 EXPECT_TRUE(stmt.condition()->result_type()->IsI32());
224 EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
225 EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
226}
227
dan sinclair91c44a52020-04-07 12:55:25 +0000228TEST_F(TypeDeterminerTest, Stmt_If) {
229 ast::type::I32Type i32;
230 ast::type::F32Type f32;
231
232 auto else_lhs = std::make_unique<ast::ScalarConstructorExpression>(
233 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000234 auto* else_lhs_ptr = else_lhs.get();
dan sinclair91c44a52020-04-07 12:55:25 +0000235
236 auto else_rhs = std::make_unique<ast::ScalarConstructorExpression>(
237 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000238 auto* else_rhs_ptr = else_rhs.get();
dan sinclair91c44a52020-04-07 12:55:25 +0000239
240 ast::StatementList else_body;
241 else_body.push_back(std::make_unique<ast::AssignmentStatement>(
242 std::move(else_lhs), std::move(else_rhs)));
243
244 auto else_stmt = std::make_unique<ast::ElseStatement>(
245 std::make_unique<ast::ScalarConstructorExpression>(
246 std::make_unique<ast::IntLiteral>(&i32, 3)),
247 std::move(else_body));
248
249 ast::ElseStatementList else_stmts;
250 else_stmts.push_back(std::move(else_stmt));
251
252 auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
253 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000254 auto* lhs_ptr = lhs.get();
dan sinclair91c44a52020-04-07 12:55:25 +0000255
256 auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
257 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000258 auto* rhs_ptr = rhs.get();
dan sinclair91c44a52020-04-07 12:55:25 +0000259
260 ast::StatementList body;
261 body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
262 std::move(rhs)));
263
264 ast::IfStatement stmt(std::make_unique<ast::ScalarConstructorExpression>(
265 std::make_unique<ast::IntLiteral>(&i32, 3)),
266 std::move(body));
267 stmt.set_else_statements(std::move(else_stmts));
268
269 EXPECT_TRUE(td()->DetermineResultType(&stmt));
270 ASSERT_NE(stmt.condition()->result_type(), nullptr);
271 ASSERT_NE(else_lhs_ptr->result_type(), nullptr);
272 ASSERT_NE(else_rhs_ptr->result_type(), nullptr);
273 ASSERT_NE(lhs_ptr->result_type(), nullptr);
274 ASSERT_NE(rhs_ptr->result_type(), nullptr);
275 EXPECT_TRUE(stmt.condition()->result_type()->IsI32());
276 EXPECT_TRUE(else_lhs_ptr->result_type()->IsI32());
277 EXPECT_TRUE(else_rhs_ptr->result_type()->IsF32());
278 EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
279 EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
280}
281
dan sinclairbc71eda2020-04-07 12:55:51 +0000282TEST_F(TypeDeterminerTest, Stmt_Loop) {
283 ast::type::I32Type i32;
284 ast::type::F32Type f32;
285
286 auto body_lhs = std::make_unique<ast::ScalarConstructorExpression>(
287 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000288 auto* body_lhs_ptr = body_lhs.get();
dan sinclairbc71eda2020-04-07 12:55:51 +0000289
290 auto body_rhs = std::make_unique<ast::ScalarConstructorExpression>(
291 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000292 auto* body_rhs_ptr = body_rhs.get();
dan sinclairbc71eda2020-04-07 12:55:51 +0000293
294 ast::StatementList body;
295 body.push_back(std::make_unique<ast::AssignmentStatement>(
296 std::move(body_lhs), std::move(body_rhs)));
297
298 auto continuing_lhs = std::make_unique<ast::ScalarConstructorExpression>(
299 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000300 auto* continuing_lhs_ptr = continuing_lhs.get();
dan sinclairbc71eda2020-04-07 12:55:51 +0000301
302 auto continuing_rhs = std::make_unique<ast::ScalarConstructorExpression>(
303 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000304 auto* continuing_rhs_ptr = continuing_rhs.get();
dan sinclairbc71eda2020-04-07 12:55:51 +0000305
306 ast::StatementList continuing;
307 continuing.push_back(std::make_unique<ast::AssignmentStatement>(
308 std::move(continuing_lhs), std::move(continuing_rhs)));
309
310 ast::LoopStatement stmt(std::move(body), std::move(continuing));
311
312 EXPECT_TRUE(td()->DetermineResultType(&stmt));
313 ASSERT_NE(body_lhs_ptr->result_type(), nullptr);
314 ASSERT_NE(body_rhs_ptr->result_type(), nullptr);
315 ASSERT_NE(continuing_lhs_ptr->result_type(), nullptr);
316 ASSERT_NE(continuing_rhs_ptr->result_type(), nullptr);
317 EXPECT_TRUE(body_lhs_ptr->result_type()->IsI32());
318 EXPECT_TRUE(body_rhs_ptr->result_type()->IsF32());
319 EXPECT_TRUE(continuing_lhs_ptr->result_type()->IsI32());
320 EXPECT_TRUE(continuing_rhs_ptr->result_type()->IsF32());
321}
322
dan sinclairbf0fff82020-04-07 12:56:24 +0000323TEST_F(TypeDeterminerTest, Stmt_Return) {
324 ast::type::I32Type i32;
325
326 auto cond = std::make_unique<ast::ScalarConstructorExpression>(
327 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000328 auto* cond_ptr = cond.get();
dan sinclairbf0fff82020-04-07 12:56:24 +0000329
330 ast::ReturnStatement ret(std::move(cond));
331
332 EXPECT_TRUE(td()->DetermineResultType(&ret));
333 ASSERT_NE(cond_ptr->result_type(), nullptr);
334 EXPECT_TRUE(cond_ptr->result_type()->IsI32());
335}
336
dan sinclair327ed1b2020-04-07 19:27:21 +0000337TEST_F(TypeDeterminerTest, Stmt_Return_WithoutValue) {
338 ast::type::I32Type i32;
339 ast::ReturnStatement ret;
340 EXPECT_TRUE(td()->DetermineResultType(&ret));
341}
342
dan sinclair18b32852020-04-07 12:56:45 +0000343TEST_F(TypeDeterminerTest, Stmt_Switch) {
344 ast::type::I32Type i32;
345 ast::type::F32Type f32;
346
347 auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
348 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000349 auto* lhs_ptr = lhs.get();
dan sinclair18b32852020-04-07 12:56:45 +0000350
351 auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
352 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000353 auto* rhs_ptr = rhs.get();
dan sinclair18b32852020-04-07 12:56:45 +0000354
355 ast::StatementList body;
356 body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
357 std::move(rhs)));
358
359 ast::CaseStatementList cases;
360 cases.push_back(std::make_unique<ast::CaseStatement>(
361 std::make_unique<ast::IntLiteral>(&i32, 3), std::move(body)));
362
363 ast::SwitchStatement stmt(std::make_unique<ast::ScalarConstructorExpression>(
364 std::make_unique<ast::IntLiteral>(&i32, 2)),
365 std::move(cases));
366
367 EXPECT_TRUE(td()->DetermineResultType(&stmt)) << td()->error();
368 ASSERT_NE(stmt.condition()->result_type(), nullptr);
369 ASSERT_NE(lhs_ptr->result_type(), nullptr);
370 ASSERT_NE(rhs_ptr->result_type(), nullptr);
371
372 EXPECT_TRUE(stmt.condition()->result_type()->IsI32());
373 EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
374 EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
375}
376
dan sinclair9a84e5e2020-04-07 12:56:57 +0000377TEST_F(TypeDeterminerTest, Stmt_Unless) {
378 ast::type::I32Type i32;
379 ast::type::F32Type f32;
380
381 auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
382 std::make_unique<ast::IntLiteral>(&i32, 2));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000383 auto* lhs_ptr = lhs.get();
dan sinclair9a84e5e2020-04-07 12:56:57 +0000384
385 auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
386 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000387 auto* rhs_ptr = rhs.get();
dan sinclair9a84e5e2020-04-07 12:56:57 +0000388
389 ast::StatementList body;
390 body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
391 std::move(rhs)));
392
393 ast::UnlessStatement unless(
394 std::make_unique<ast::ScalarConstructorExpression>(
395 std::make_unique<ast::IntLiteral>(&i32, 3)),
396 std::move(body));
397
398 EXPECT_TRUE(td()->DetermineResultType(&unless));
399 ASSERT_NE(unless.condition()->result_type(), nullptr);
400 ASSERT_NE(lhs_ptr->result_type(), nullptr);
401 ASSERT_NE(rhs_ptr->result_type(), nullptr);
402 EXPECT_TRUE(unless.condition()->result_type()->IsI32());
403 EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
404 EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
405}
406
dan sinclairca893e32020-04-07 12:57:12 +0000407TEST_F(TypeDeterminerTest, Stmt_VariableDecl) {
408 ast::type::I32Type i32;
409 auto var =
410 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &i32);
411 var->set_constructor(std::make_unique<ast::ScalarConstructorExpression>(
412 std::make_unique<ast::IntLiteral>(&i32, 2)));
Ryan Harrison0a196c12020-04-17 13:18:20 +0000413 auto* init_ptr = var->constructor();
dan sinclairca893e32020-04-07 12:57:12 +0000414
415 ast::VariableDeclStatement decl(std::move(var));
416
417 EXPECT_TRUE(td()->DetermineResultType(&decl));
418 ASSERT_NE(init_ptr->result_type(), nullptr);
419 EXPECT_TRUE(init_ptr->result_type()->IsI32());
420}
421
dan sinclair7456f422020-04-08 19:58:35 +0000422TEST_F(TypeDeterminerTest, Expr_Error_Unknown) {
423 FakeExpr e;
424 e.set_source(Source{2, 30});
425
426 EXPECT_FALSE(td()->DetermineResultType(&e));
427 EXPECT_EQ(td()->error(), "2:30: unknown expression for type determination");
428}
429
dan sinclair973bd6a2020-04-07 12:57:42 +0000430TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array) {
431 ast::type::I32Type i32;
432 ast::type::F32Type f32;
433 ast::type::ArrayType ary(&f32, 3);
434
435 auto idx = std::make_unique<ast::ScalarConstructorExpression>(
436 std::make_unique<ast::IntLiteral>(&i32, 2));
dan sinclair8eddb782020-04-23 22:26:52 +0000437 auto var = std::make_unique<ast::Variable>(
438 "my_var", ast::StorageClass::kFunction, &ary);
439 mod()->AddGlobalVariable(std::move(var));
440
441 // Register the global
442 EXPECT_TRUE(td()->Determine());
443
444 ast::ArrayAccessorExpression acc(
445 std::make_unique<ast::IdentifierExpression>("my_var"), std::move(idx));
446 EXPECT_TRUE(td()->DetermineResultType(&acc));
447 ASSERT_NE(acc.result_type(), nullptr);
448 ASSERT_TRUE(acc.result_type()->IsPointer());
449
450 auto* ptr = acc.result_type()->AsPointer();
451 EXPECT_TRUE(ptr->type()->IsF32());
452}
453
454TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array_Constant) {
455 ast::type::I32Type i32;
456 ast::type::F32Type f32;
457 ast::type::ArrayType ary(&f32, 3);
458
459 auto idx = std::make_unique<ast::ScalarConstructorExpression>(
460 std::make_unique<ast::IntLiteral>(&i32, 2));
461 auto var = std::make_unique<ast::Variable>(
462 "my_var", ast::StorageClass::kFunction, &ary);
463 var->set_is_const(true);
dan sinclaircd077b02020-04-20 14:19:04 +0000464 mod()->AddGlobalVariable(std::move(var));
dan sinclair973bd6a2020-04-07 12:57:42 +0000465
466 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000467 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000468
469 ast::ArrayAccessorExpression acc(
470 std::make_unique<ast::IdentifierExpression>("my_var"), std::move(idx));
471 EXPECT_TRUE(td()->DetermineResultType(&acc));
472 ASSERT_NE(acc.result_type(), nullptr);
473 EXPECT_TRUE(acc.result_type()->IsF32());
474}
475
476TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix) {
477 ast::type::I32Type i32;
478 ast::type::F32Type f32;
479 ast::type::MatrixType mat(&f32, 3, 2);
480
481 auto idx = std::make_unique<ast::ScalarConstructorExpression>(
482 std::make_unique<ast::IntLiteral>(&i32, 2));
dan sinclair973bd6a2020-04-07 12:57:42 +0000483 auto var =
484 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &mat);
dan sinclaircd077b02020-04-20 14:19:04 +0000485 mod()->AddGlobalVariable(std::move(var));
dan sinclair973bd6a2020-04-07 12:57:42 +0000486
487 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000488 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000489
490 ast::ArrayAccessorExpression acc(
491 std::make_unique<ast::IdentifierExpression>("my_var"), std::move(idx));
492 EXPECT_TRUE(td()->DetermineResultType(&acc));
493 ASSERT_NE(acc.result_type(), nullptr);
dan sinclair8eddb782020-04-23 22:26:52 +0000494 ASSERT_TRUE(acc.result_type()->IsPointer());
495
496 auto* ptr = acc.result_type()->AsPointer();
497 ASSERT_TRUE(ptr->type()->IsVector());
498 EXPECT_EQ(ptr->type()->AsVector()->size(), 3u);
dan sinclair973bd6a2020-04-07 12:57:42 +0000499}
500
501TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix_BothDimensions) {
502 ast::type::I32Type i32;
503 ast::type::F32Type f32;
504 ast::type::MatrixType mat(&f32, 3, 2);
505
506 auto idx1 = std::make_unique<ast::ScalarConstructorExpression>(
507 std::make_unique<ast::IntLiteral>(&i32, 2));
508 auto idx2 = std::make_unique<ast::ScalarConstructorExpression>(
509 std::make_unique<ast::IntLiteral>(&i32, 1));
dan sinclair973bd6a2020-04-07 12:57:42 +0000510 auto var =
511 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &mat);
dan sinclaircd077b02020-04-20 14:19:04 +0000512 mod()->AddGlobalVariable(std::move(var));
dan sinclair973bd6a2020-04-07 12:57:42 +0000513
514 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000515 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000516
517 ast::ArrayAccessorExpression acc(
518 std::make_unique<ast::ArrayAccessorExpression>(
519 std::make_unique<ast::IdentifierExpression>("my_var"),
520 std::move(idx1)),
521 std::move(idx2));
522
523 EXPECT_TRUE(td()->DetermineResultType(&acc));
524 ASSERT_NE(acc.result_type(), nullptr);
dan sinclair8eddb782020-04-23 22:26:52 +0000525 ASSERT_TRUE(acc.result_type()->IsPointer());
526
527 auto* ptr = acc.result_type()->AsPointer();
528 EXPECT_TRUE(ptr->type()->IsF32());
dan sinclair973bd6a2020-04-07 12:57:42 +0000529}
530
531TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Vector) {
532 ast::type::I32Type i32;
533 ast::type::F32Type f32;
534 ast::type::VectorType vec(&f32, 3);
535
536 auto idx = std::make_unique<ast::ScalarConstructorExpression>(
537 std::make_unique<ast::IntLiteral>(&i32, 2));
dan sinclair973bd6a2020-04-07 12:57:42 +0000538 auto var =
539 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &vec);
dan sinclaircd077b02020-04-20 14:19:04 +0000540 mod()->AddGlobalVariable(std::move(var));
dan sinclair973bd6a2020-04-07 12:57:42 +0000541
542 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000543 EXPECT_TRUE(td()->Determine());
dan sinclair973bd6a2020-04-07 12:57:42 +0000544
545 ast::ArrayAccessorExpression acc(
546 std::make_unique<ast::IdentifierExpression>("my_var"), std::move(idx));
547 EXPECT_TRUE(td()->DetermineResultType(&acc));
548 ASSERT_NE(acc.result_type(), nullptr);
dan sinclair8eddb782020-04-23 22:26:52 +0000549 ASSERT_TRUE(acc.result_type()->IsPointer());
550
551 auto* ptr = acc.result_type()->AsPointer();
552 EXPECT_TRUE(ptr->type()->IsF32());
dan sinclair973bd6a2020-04-07 12:57:42 +0000553}
554
dan sinclaira01777c2020-04-07 12:57:52 +0000555TEST_F(TypeDeterminerTest, Expr_As) {
556 ast::type::F32Type f32;
557 ast::AsExpression as(&f32,
558 std::make_unique<ast::IdentifierExpression>("name"));
559
560 EXPECT_TRUE(td()->DetermineResultType(&as));
561 ASSERT_NE(as.result_type(), nullptr);
562 EXPECT_TRUE(as.result_type()->IsF32());
563}
564
dan sinclair3ca87462020-04-07 16:41:10 +0000565TEST_F(TypeDeterminerTest, Expr_Call) {
566 ast::type::F32Type f32;
567
568 ast::VariableList params;
569 auto func =
570 std::make_unique<ast::Function>("my_func", std::move(params), &f32);
dan sinclaircd077b02020-04-20 14:19:04 +0000571 mod()->AddFunction(std::move(func));
dan sinclair3ca87462020-04-07 16:41:10 +0000572
573 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000574 EXPECT_TRUE(td()->Determine());
dan sinclair3ca87462020-04-07 16:41:10 +0000575
576 ast::ExpressionList call_params;
577 ast::CallExpression call(
578 std::make_unique<ast::IdentifierExpression>("my_func"),
579 std::move(call_params));
580 EXPECT_TRUE(td()->DetermineResultType(&call));
581 ASSERT_NE(call.result_type(), nullptr);
582 EXPECT_TRUE(call.result_type()->IsF32());
583}
584
dan sinclairccb52dc2020-04-20 14:18:54 +0000585TEST_F(TypeDeterminerTest, Expr_Call_WithParams) {
586 ast::type::F32Type f32;
587
588 ast::VariableList params;
589 auto func =
590 std::make_unique<ast::Function>("my_func", std::move(params), &f32);
dan sinclaircd077b02020-04-20 14:19:04 +0000591 mod()->AddFunction(std::move(func));
dan sinclairccb52dc2020-04-20 14:18:54 +0000592
593 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000594 EXPECT_TRUE(td()->Determine());
dan sinclairccb52dc2020-04-20 14:18:54 +0000595
596 ast::ExpressionList call_params;
597 call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
598 std::make_unique<ast::FloatLiteral>(&f32, 2.4)));
599
600 auto* param_ptr = call_params.back().get();
601
602 ast::CallExpression call(
603 std::make_unique<ast::IdentifierExpression>("my_func"),
604 std::move(call_params));
605 EXPECT_TRUE(td()->DetermineResultType(&call));
606 ASSERT_NE(param_ptr->result_type(), nullptr);
607 EXPECT_TRUE(param_ptr->result_type()->IsF32());
608}
609
dan sinclairfd5d4ca2020-04-20 15:46:18 +0000610TEST_F(TypeDeterminerTest, Expr_Call_GLSLImport) {
611 ast::type::F32Type f32;
612
613 mod()->AddImport(std::make_unique<ast::Import>("GLSL.std.450", "std"));
614
615 // Register the function
616 EXPECT_TRUE(td()->Determine());
617
618 ast::ExpressionList call_params;
619 call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
620 std::make_unique<ast::FloatLiteral>(&f32, 2.4)));
621
622 std::vector<std::string> name{"std", "round"};
623 ast::CallExpression call(std::make_unique<ast::IdentifierExpression>(name),
624 std::move(call_params));
625
626 EXPECT_TRUE(td()->DetermineResultType(&call));
627 ASSERT_NE(call.result_type(), nullptr);
628 EXPECT_TRUE(call.result_type()->IsF32());
629}
630
dan sinclair4e807952020-04-07 16:41:23 +0000631TEST_F(TypeDeterminerTest, Expr_Cast) {
632 ast::type::F32Type f32;
633 ast::CastExpression cast(&f32,
634 std::make_unique<ast::IdentifierExpression>("name"));
635
636 EXPECT_TRUE(td()->DetermineResultType(&cast));
637 ASSERT_NE(cast.result_type(), nullptr);
638 EXPECT_TRUE(cast.result_type()->IsF32());
639}
640
dan sinclairb7edc4c2020-04-07 12:46:30 +0000641TEST_F(TypeDeterminerTest, Expr_Constructor_Scalar) {
642 ast::type::F32Type f32;
643 ast::ScalarConstructorExpression s(
644 std::make_unique<ast::FloatLiteral>(&f32, 1.0f));
645
646 EXPECT_TRUE(td()->DetermineResultType(&s));
647 ASSERT_NE(s.result_type(), nullptr);
648 EXPECT_TRUE(s.result_type()->IsF32());
649}
650
651TEST_F(TypeDeterminerTest, Expr_Constructor_Type) {
652 ast::type::F32Type f32;
653 ast::type::VectorType vec(&f32, 3);
654
655 ast::ExpressionList vals;
656 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
657 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
658 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
659 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
660 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
661 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
662
663 ast::TypeConstructorExpression tc(&vec, std::move(vals));
664
665 EXPECT_TRUE(td()->DetermineResultType(&tc));
666 ASSERT_NE(tc.result_type(), nullptr);
667 ASSERT_TRUE(tc.result_type()->IsVector());
668 EXPECT_TRUE(tc.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +0000669 EXPECT_EQ(tc.result_type()->AsVector()->size(), 3u);
dan sinclairb7edc4c2020-04-07 12:46:30 +0000670}
671
dan sinclaircab0e732020-04-07 12:57:27 +0000672TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalVariable) {
673 ast::type::F32Type f32;
dan sinclaircab0e732020-04-07 12:57:27 +0000674 auto var =
675 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
dan sinclaircd077b02020-04-20 14:19:04 +0000676 mod()->AddGlobalVariable(std::move(var));
dan sinclaircab0e732020-04-07 12:57:27 +0000677
678 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000679 EXPECT_TRUE(td()->Determine());
dan sinclaircab0e732020-04-07 12:57:27 +0000680
681 ast::IdentifierExpression ident("my_var");
682 EXPECT_TRUE(td()->DetermineResultType(&ident));
683 ASSERT_NE(ident.result_type(), nullptr);
dan sinclair8eddb782020-04-23 22:26:52 +0000684 EXPECT_TRUE(ident.result_type()->IsPointer());
685 EXPECT_TRUE(ident.result_type()->AsPointer()->type()->IsF32());
686}
687
688TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalConstant) {
689 ast::type::F32Type f32;
690 auto var =
691 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
692 var->set_is_const(true);
693 mod()->AddGlobalVariable(std::move(var));
694
695 // Register the global
696 EXPECT_TRUE(td()->Determine());
697
698 ast::IdentifierExpression ident("my_var");
699 EXPECT_TRUE(td()->DetermineResultType(&ident));
700 ASSERT_NE(ident.result_type(), nullptr);
dan sinclaircab0e732020-04-07 12:57:27 +0000701 EXPECT_TRUE(ident.result_type()->IsF32());
702}
703
dan sinclair8eddb782020-04-23 22:26:52 +0000704TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable_Const) {
705 ast::type::F32Type f32;
706
707 auto my_var = std::make_unique<ast::IdentifierExpression>("my_var");
708 auto* my_var_ptr = my_var.get();
709
710 auto var =
711 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
712 var->set_is_const(true);
713
714 ast::StatementList body;
715 body.push_back(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
716
717 body.push_back(std::make_unique<ast::AssignmentStatement>(
718 std::move(my_var),
719 std::make_unique<ast::IdentifierExpression>("my_var")));
720
721 ast::Function f("my_func", {}, &f32);
722 f.set_body(std::move(body));
723
724 EXPECT_TRUE(td()->DetermineFunction(&f));
725
726 ASSERT_NE(my_var_ptr->result_type(), nullptr);
727 EXPECT_TRUE(my_var_ptr->result_type()->IsF32());
728}
729
dan sinclaircab0e732020-04-07 12:57:27 +0000730TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable) {
731 ast::type::F32Type f32;
732
733 auto my_var = std::make_unique<ast::IdentifierExpression>("my_var");
Ryan Harrison0a196c12020-04-17 13:18:20 +0000734 auto* my_var_ptr = my_var.get();
dan sinclaircab0e732020-04-07 12:57:27 +0000735
736 ast::StatementList body;
737 body.push_back(std::make_unique<ast::VariableDeclStatement>(
738 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone,
739 &f32)));
740
741 body.push_back(std::make_unique<ast::AssignmentStatement>(
742 std::move(my_var),
743 std::make_unique<ast::IdentifierExpression>("my_var")));
744
745 ast::Function f("my_func", {}, &f32);
746 f.set_body(std::move(body));
747
748 EXPECT_TRUE(td()->DetermineFunction(&f));
749
750 ASSERT_NE(my_var_ptr->result_type(), nullptr);
dan sinclair8eddb782020-04-23 22:26:52 +0000751 EXPECT_TRUE(my_var_ptr->result_type()->IsPointer());
752 EXPECT_TRUE(my_var_ptr->result_type()->AsPointer()->type()->IsF32());
dan sinclaircab0e732020-04-07 12:57:27 +0000753}
754
755TEST_F(TypeDeterminerTest, Expr_Identifier_Function) {
756 ast::type::F32Type f32;
757
758 ast::VariableList params;
759 auto func =
760 std::make_unique<ast::Function>("my_func", std::move(params), &f32);
dan sinclaircd077b02020-04-20 14:19:04 +0000761 mod()->AddFunction(std::move(func));
dan sinclaircab0e732020-04-07 12:57:27 +0000762
763 // Register the function
dan sinclairb950e802020-04-20 14:20:01 +0000764 EXPECT_TRUE(td()->Determine());
dan sinclaircab0e732020-04-07 12:57:27 +0000765
766 ast::IdentifierExpression ident("my_func");
767 EXPECT_TRUE(td()->DetermineResultType(&ident));
768 ASSERT_NE(ident.result_type(), nullptr);
769 EXPECT_TRUE(ident.result_type()->IsF32());
770}
771
dan sinclair8ee1d222020-04-07 16:41:33 +0000772TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct) {
773 ast::type::I32Type i32;
774 ast::type::F32Type f32;
775
776 ast::StructMemberDecorationList decos;
777 ast::StructMemberList members;
778 members.push_back(std::make_unique<ast::StructMember>("first_member", &i32,
779 std::move(decos)));
780 members.push_back(std::make_unique<ast::StructMember>("second_member", &f32,
781 std::move(decos)));
782
783 auto strct = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
784 std::move(members));
785
786 ast::type::StructType st(std::move(strct));
787
788 auto var = std::make_unique<ast::Variable>("my_struct",
789 ast::StorageClass::kNone, &st);
790
dan sinclaircd077b02020-04-20 14:19:04 +0000791 mod()->AddGlobalVariable(std::move(var));
dan sinclair8ee1d222020-04-07 16:41:33 +0000792
793 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000794 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +0000795
796 auto ident = std::make_unique<ast::IdentifierExpression>("my_struct");
797 auto mem_ident = std::make_unique<ast::IdentifierExpression>("second_member");
798
799 ast::MemberAccessorExpression mem(std::move(ident), std::move(mem_ident));
800 EXPECT_TRUE(td()->DetermineResultType(&mem));
801 ASSERT_NE(mem.result_type(), nullptr);
dan sinclair8eddb782020-04-23 22:26:52 +0000802 ASSERT_TRUE(mem.result_type()->IsPointer());
803
804 auto* ptr = mem.result_type()->AsPointer();
805 EXPECT_TRUE(ptr->type()->IsF32());
dan sinclair8ee1d222020-04-07 16:41:33 +0000806}
807
808TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle) {
809 ast::type::F32Type f32;
810 ast::type::VectorType vec3(&f32, 3);
811
812 auto var = std::make_unique<ast::Variable>("my_vec", ast::StorageClass::kNone,
813 &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +0000814 mod()->AddGlobalVariable(std::move(var));
dan sinclair8ee1d222020-04-07 16:41:33 +0000815
816 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000817 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +0000818
819 auto ident = std::make_unique<ast::IdentifierExpression>("my_vec");
820 auto swizzle = std::make_unique<ast::IdentifierExpression>("xy");
821
822 ast::MemberAccessorExpression mem(std::move(ident), std::move(swizzle));
823 EXPECT_TRUE(td()->DetermineResultType(&mem)) << td()->error();
824 ASSERT_NE(mem.result_type(), nullptr);
dan sinclair8eddb782020-04-23 22:26:52 +0000825 ASSERT_TRUE(mem.result_type()->IsPointer());
826
827 auto* ptr = mem.result_type()->AsPointer();
828 ASSERT_TRUE(ptr->type()->IsVector());
829 EXPECT_TRUE(ptr->type()->AsVector()->type()->IsF32());
830 EXPECT_EQ(ptr->type()->AsVector()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +0000831}
832
dan sinclairaac58652020-04-21 13:05:34 +0000833TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle_SingleElement) {
834 ast::type::F32Type f32;
835 ast::type::VectorType vec3(&f32, 3);
836
837 auto var = std::make_unique<ast::Variable>("my_vec", ast::StorageClass::kNone,
838 &vec3);
839 mod()->AddGlobalVariable(std::move(var));
840
841 // Register the global
842 EXPECT_TRUE(td()->Determine());
843
844 auto ident = std::make_unique<ast::IdentifierExpression>("my_vec");
845 auto swizzle = std::make_unique<ast::IdentifierExpression>("x");
846
847 ast::MemberAccessorExpression mem(std::move(ident), std::move(swizzle));
848 EXPECT_TRUE(td()->DetermineResultType(&mem)) << td()->error();
849 ASSERT_NE(mem.result_type(), nullptr);
dan sinclair8eddb782020-04-23 22:26:52 +0000850 ASSERT_TRUE(mem.result_type()->IsPointer());
851
852 auto* ptr = mem.result_type()->AsPointer();
853 ASSERT_TRUE(ptr->type()->IsF32());
dan sinclairaac58652020-04-21 13:05:34 +0000854}
855
dan sinclair8eddb782020-04-23 22:26:52 +0000856TEST_F(TypeDeterminerTest, Expr_Accessor_MultiLevel) {
dan sinclair8ee1d222020-04-07 16:41:33 +0000857 // struct b {
858 // vec4<f32> foo
859 // }
860 // struct A {
861 // vec3<struct b> mem
862 // }
863 // var c : A
864 // c.mem[0].foo.yx
865 // -> vec2<f32>
866 //
867 // MemberAccessor{
868 // MemberAccessor{
869 // ArrayAccessor{
870 // MemberAccessor{
871 // Identifier{c}
872 // Identifier{mem}
873 // }
874 // ScalarConstructor{0}
875 // }
876 // Identifier{foo}
877 // }
878 // Identifier{yx}
879 // }
880 //
881 ast::type::I32Type i32;
882 ast::type::F32Type f32;
883
884 ast::type::VectorType vec4(&f32, 4);
885
886 ast::StructMemberDecorationList decos;
887 ast::StructMemberList b_members;
888 b_members.push_back(
889 std::make_unique<ast::StructMember>("foo", &vec4, std::move(decos)));
890
891 auto strctB = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
892 std::move(b_members));
893 ast::type::StructType stB(std::move(strctB));
dan sinclair8eddb782020-04-23 22:26:52 +0000894 stB.set_name("B");
dan sinclair8ee1d222020-04-07 16:41:33 +0000895
896 ast::type::VectorType vecB(&stB, 3);
897
898 ast::StructMemberList a_members;
899 a_members.push_back(
900 std::make_unique<ast::StructMember>("mem", &vecB, std::move(decos)));
901
902 auto strctA = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
903 std::move(a_members));
904
905 ast::type::StructType stA(std::move(strctA));
dan sinclair8eddb782020-04-23 22:26:52 +0000906 stA.set_name("A");
dan sinclair8ee1d222020-04-07 16:41:33 +0000907
908 auto var =
909 std::make_unique<ast::Variable>("c", ast::StorageClass::kNone, &stA);
dan sinclaircd077b02020-04-20 14:19:04 +0000910 mod()->AddGlobalVariable(std::move(var));
dan sinclair8ee1d222020-04-07 16:41:33 +0000911
912 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000913 EXPECT_TRUE(td()->Determine());
dan sinclair8ee1d222020-04-07 16:41:33 +0000914
915 auto ident = std::make_unique<ast::IdentifierExpression>("c");
916 auto mem_ident = std::make_unique<ast::IdentifierExpression>("mem");
917 auto foo_ident = std::make_unique<ast::IdentifierExpression>("foo");
918 auto idx = std::make_unique<ast::ScalarConstructorExpression>(
919 std::make_unique<ast::IntLiteral>(&i32, 0));
920 auto swizzle = std::make_unique<ast::IdentifierExpression>("yx");
921
922 ast::MemberAccessorExpression mem(
923 std::make_unique<ast::MemberAccessorExpression>(
924 std::make_unique<ast::ArrayAccessorExpression>(
925 std::make_unique<ast::MemberAccessorExpression>(
926 std::move(ident), std::move(mem_ident)),
927 std::move(idx)),
928 std::move(foo_ident)),
929 std::move(swizzle));
930 EXPECT_TRUE(td()->DetermineResultType(&mem)) << td()->error();
dan sinclair8eddb782020-04-23 22:26:52 +0000931
dan sinclair8ee1d222020-04-07 16:41:33 +0000932 ASSERT_NE(mem.result_type(), nullptr);
dan sinclair8eddb782020-04-23 22:26:52 +0000933 ASSERT_TRUE(mem.result_type()->IsPointer());
934
935 auto* ptr = mem.result_type()->AsPointer();
936 ASSERT_TRUE(ptr->type()->IsVector());
937 EXPECT_TRUE(ptr->type()->AsVector()->type()->IsF32());
938 EXPECT_EQ(ptr->type()->AsVector()->size(), 2u);
dan sinclair8ee1d222020-04-07 16:41:33 +0000939}
940
dan sinclaircd077b02020-04-20 14:19:04 +0000941using Expr_Binary_BitwiseTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +0000942TEST_P(Expr_Binary_BitwiseTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +0000943 auto op = GetParam();
944
945 ast::type::I32Type i32;
946
947 auto var =
948 std::make_unique<ast::Variable>("val", ast::StorageClass::kNone, &i32);
dan sinclaircd077b02020-04-20 14:19:04 +0000949 mod()->AddGlobalVariable(std::move(var));
dan sinclair9b978022020-04-07 19:26:39 +0000950
951 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000952 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000953
dan sinclair1c9b4862020-04-07 19:27:41 +0000954 ast::BinaryExpression expr(
dan sinclair9b978022020-04-07 19:26:39 +0000955 op, std::make_unique<ast::IdentifierExpression>("val"),
956 std::make_unique<ast::IdentifierExpression>("val"));
957
dan sinclaircd077b02020-04-20 14:19:04 +0000958 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000959 ASSERT_NE(expr.result_type(), nullptr);
960 EXPECT_TRUE(expr.result_type()->IsI32());
961}
962
dan sinclair1c9b4862020-04-07 19:27:41 +0000963TEST_P(Expr_Binary_BitwiseTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +0000964 auto op = GetParam();
965
966 ast::type::I32Type i32;
967 ast::type::VectorType vec3(&i32, 3);
968
969 auto var =
970 std::make_unique<ast::Variable>("val", ast::StorageClass::kNone, &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +0000971 mod()->AddGlobalVariable(std::move(var));
dan sinclair9b978022020-04-07 19:26:39 +0000972
973 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +0000974 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000975
dan sinclair1c9b4862020-04-07 19:27:41 +0000976 ast::BinaryExpression expr(
dan sinclair9b978022020-04-07 19:26:39 +0000977 op, std::make_unique<ast::IdentifierExpression>("val"),
978 std::make_unique<ast::IdentifierExpression>("val"));
979
dan sinclaircd077b02020-04-20 14:19:04 +0000980 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +0000981 ASSERT_NE(expr.result_type(), nullptr);
982 ASSERT_TRUE(expr.result_type()->IsVector());
983 EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsI32());
Ryan Harrison0a196c12020-04-17 13:18:20 +0000984 EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +0000985}
986INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +0000987 Expr_Binary_BitwiseTest,
988 testing::Values(ast::BinaryOp::kAnd,
989 ast::BinaryOp::kOr,
990 ast::BinaryOp::kXor,
991 ast::BinaryOp::kShiftLeft,
992 ast::BinaryOp::kShiftRight,
993 ast::BinaryOp::kShiftRightArith,
994 ast::BinaryOp::kAdd,
995 ast::BinaryOp::kSubtract,
996 ast::BinaryOp::kDivide,
997 ast::BinaryOp::kModulo));
dan sinclair9b978022020-04-07 19:26:39 +0000998
dan sinclaircd077b02020-04-20 14:19:04 +0000999using Expr_Binary_LogicalTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +00001000TEST_P(Expr_Binary_LogicalTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001001 auto op = GetParam();
1002
1003 ast::type::BoolType bool_type;
1004
1005 auto var = std::make_unique<ast::Variable>("val", ast::StorageClass::kNone,
1006 &bool_type);
dan sinclaircd077b02020-04-20 14:19:04 +00001007 mod()->AddGlobalVariable(std::move(var));
dan sinclair9b978022020-04-07 19:26:39 +00001008
1009 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001010 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001011
dan sinclair1c9b4862020-04-07 19:27:41 +00001012 ast::BinaryExpression expr(
dan sinclair9b978022020-04-07 19:26:39 +00001013 op, std::make_unique<ast::IdentifierExpression>("val"),
1014 std::make_unique<ast::IdentifierExpression>("val"));
1015
dan sinclaircd077b02020-04-20 14:19:04 +00001016 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001017 ASSERT_NE(expr.result_type(), nullptr);
1018 EXPECT_TRUE(expr.result_type()->IsBool());
1019}
1020
dan sinclair1c9b4862020-04-07 19:27:41 +00001021TEST_P(Expr_Binary_LogicalTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001022 auto op = GetParam();
1023
1024 ast::type::BoolType bool_type;
1025 ast::type::VectorType vec3(&bool_type, 3);
1026
1027 auto var =
1028 std::make_unique<ast::Variable>("val", ast::StorageClass::kNone, &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +00001029 mod()->AddGlobalVariable(std::move(var));
dan sinclair9b978022020-04-07 19:26:39 +00001030
1031 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001032 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001033
dan sinclair1c9b4862020-04-07 19:27:41 +00001034 ast::BinaryExpression expr(
dan sinclair9b978022020-04-07 19:26:39 +00001035 op, std::make_unique<ast::IdentifierExpression>("val"),
1036 std::make_unique<ast::IdentifierExpression>("val"));
1037
dan sinclaircd077b02020-04-20 14:19:04 +00001038 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001039 ASSERT_NE(expr.result_type(), nullptr);
1040 ASSERT_TRUE(expr.result_type()->IsVector());
1041 EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsBool());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001042 EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001043}
1044INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +00001045 Expr_Binary_LogicalTest,
1046 testing::Values(ast::BinaryOp::kLogicalAnd,
1047 ast::BinaryOp::kLogicalOr));
dan sinclair9b978022020-04-07 19:26:39 +00001048
dan sinclaircd077b02020-04-20 14:19:04 +00001049using Expr_Binary_CompareTest = TypeDeterminerTestWithParam<ast::BinaryOp>;
dan sinclair1c9b4862020-04-07 19:27:41 +00001050TEST_P(Expr_Binary_CompareTest, Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001051 auto op = GetParam();
1052
1053 ast::type::I32Type i32;
1054
1055 auto var =
1056 std::make_unique<ast::Variable>("val", ast::StorageClass::kNone, &i32);
dan sinclaircd077b02020-04-20 14:19:04 +00001057 mod()->AddGlobalVariable(std::move(var));
dan sinclair9b978022020-04-07 19:26:39 +00001058
1059 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001060 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001061
dan sinclair1c9b4862020-04-07 19:27:41 +00001062 ast::BinaryExpression expr(
dan sinclair9b978022020-04-07 19:26:39 +00001063 op, std::make_unique<ast::IdentifierExpression>("val"),
1064 std::make_unique<ast::IdentifierExpression>("val"));
1065
dan sinclaircd077b02020-04-20 14:19:04 +00001066 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001067 ASSERT_NE(expr.result_type(), nullptr);
1068 EXPECT_TRUE(expr.result_type()->IsBool());
1069}
1070
dan sinclair1c9b4862020-04-07 19:27:41 +00001071TEST_P(Expr_Binary_CompareTest, Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001072 auto op = GetParam();
1073
1074 ast::type::I32Type i32;
1075 ast::type::VectorType vec3(&i32, 3);
1076
1077 auto var =
1078 std::make_unique<ast::Variable>("val", ast::StorageClass::kNone, &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +00001079 mod()->AddGlobalVariable(std::move(var));
dan sinclair9b978022020-04-07 19:26:39 +00001080
1081 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001082 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001083
dan sinclair1c9b4862020-04-07 19:27:41 +00001084 ast::BinaryExpression expr(
dan sinclair9b978022020-04-07 19:26:39 +00001085 op, std::make_unique<ast::IdentifierExpression>("val"),
1086 std::make_unique<ast::IdentifierExpression>("val"));
1087
dan sinclaircd077b02020-04-20 14:19:04 +00001088 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001089 ASSERT_NE(expr.result_type(), nullptr);
1090 ASSERT_TRUE(expr.result_type()->IsVector());
1091 EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsBool());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001092 EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001093}
1094INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
dan sinclair1c9b4862020-04-07 19:27:41 +00001095 Expr_Binary_CompareTest,
1096 testing::Values(ast::BinaryOp::kEqual,
1097 ast::BinaryOp::kNotEqual,
1098 ast::BinaryOp::kLessThan,
1099 ast::BinaryOp::kGreaterThan,
1100 ast::BinaryOp::kLessThanEqual,
1101 ast::BinaryOp::kGreaterThanEqual));
dan sinclair9b978022020-04-07 19:26:39 +00001102
dan sinclair1c9b4862020-04-07 19:27:41 +00001103TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001104 ast::type::I32Type i32;
1105
1106 auto var =
1107 std::make_unique<ast::Variable>("val", ast::StorageClass::kNone, &i32);
dan sinclaircd077b02020-04-20 14:19:04 +00001108 mod()->AddGlobalVariable(std::move(var));
dan sinclair9b978022020-04-07 19:26:39 +00001109
1110 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001111 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001112
dan sinclair1c9b4862020-04-07 19:27:41 +00001113 ast::BinaryExpression expr(
1114 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001115 std::make_unique<ast::IdentifierExpression>("val"),
1116 std::make_unique<ast::IdentifierExpression>("val"));
1117
dan sinclaircd077b02020-04-20 14:19:04 +00001118 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001119 ASSERT_NE(expr.result_type(), nullptr);
1120 EXPECT_TRUE(expr.result_type()->IsI32());
1121}
1122
dan sinclair1c9b4862020-04-07 19:27:41 +00001123TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001124 ast::type::F32Type f32;
1125 ast::type::VectorType vec3(&f32, 3);
1126
1127 auto scalar =
1128 std::make_unique<ast::Variable>("scalar", ast::StorageClass::kNone, &f32);
1129 auto vector = std::make_unique<ast::Variable>(
1130 "vector", ast::StorageClass::kNone, &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +00001131 mod()->AddGlobalVariable(std::move(scalar));
1132 mod()->AddGlobalVariable(std::move(vector));
dan sinclair9b978022020-04-07 19:26:39 +00001133
1134 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001135 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001136
dan sinclair1c9b4862020-04-07 19:27:41 +00001137 ast::BinaryExpression expr(
1138 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001139 std::make_unique<ast::IdentifierExpression>("vector"),
1140 std::make_unique<ast::IdentifierExpression>("scalar"));
1141
dan sinclaircd077b02020-04-20 14:19:04 +00001142 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001143 ASSERT_NE(expr.result_type(), nullptr);
1144 ASSERT_TRUE(expr.result_type()->IsVector());
1145 EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001146 EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001147}
1148
dan sinclair1c9b4862020-04-07 19:27:41 +00001149TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001150 ast::type::F32Type f32;
1151 ast::type::VectorType vec3(&f32, 3);
1152
1153 auto scalar =
1154 std::make_unique<ast::Variable>("scalar", ast::StorageClass::kNone, &f32);
1155 auto vector = std::make_unique<ast::Variable>(
1156 "vector", ast::StorageClass::kNone, &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +00001157 mod()->AddGlobalVariable(std::move(scalar));
1158 mod()->AddGlobalVariable(std::move(vector));
dan sinclair9b978022020-04-07 19:26:39 +00001159
1160 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001161 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001162
dan sinclair1c9b4862020-04-07 19:27:41 +00001163 ast::BinaryExpression expr(
1164 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001165 std::make_unique<ast::IdentifierExpression>("scalar"),
1166 std::make_unique<ast::IdentifierExpression>("vector"));
1167
dan sinclaircd077b02020-04-20 14:19:04 +00001168 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001169 ASSERT_NE(expr.result_type(), nullptr);
1170 ASSERT_TRUE(expr.result_type()->IsVector());
1171 EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001172 EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001173}
1174
dan sinclair1c9b4862020-04-07 19:27:41 +00001175TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001176 ast::type::F32Type f32;
1177 ast::type::VectorType vec3(&f32, 3);
1178
1179 auto vector = std::make_unique<ast::Variable>(
1180 "vector", ast::StorageClass::kNone, &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +00001181 mod()->AddGlobalVariable(std::move(vector));
dan sinclair9b978022020-04-07 19:26:39 +00001182
1183 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001184 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001185
dan sinclair1c9b4862020-04-07 19:27:41 +00001186 ast::BinaryExpression expr(
1187 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001188 std::make_unique<ast::IdentifierExpression>("vector"),
1189 std::make_unique<ast::IdentifierExpression>("vector"));
1190
dan sinclaircd077b02020-04-20 14:19:04 +00001191 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001192 ASSERT_NE(expr.result_type(), nullptr);
1193 ASSERT_TRUE(expr.result_type()->IsVector());
1194 EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001195 EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001196}
1197
dan sinclair1c9b4862020-04-07 19:27:41 +00001198TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Scalar) {
dan sinclair9b978022020-04-07 19:26:39 +00001199 ast::type::F32Type f32;
1200 ast::type::MatrixType mat3x2(&f32, 3, 2);
1201
1202 auto scalar =
1203 std::make_unique<ast::Variable>("scalar", ast::StorageClass::kNone, &f32);
1204 auto matrix = std::make_unique<ast::Variable>(
1205 "matrix", ast::StorageClass::kNone, &mat3x2);
dan sinclaircd077b02020-04-20 14:19:04 +00001206 mod()->AddGlobalVariable(std::move(scalar));
1207 mod()->AddGlobalVariable(std::move(matrix));
dan sinclair9b978022020-04-07 19:26:39 +00001208
1209 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001210 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001211
dan sinclair1c9b4862020-04-07 19:27:41 +00001212 ast::BinaryExpression expr(
1213 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001214 std::make_unique<ast::IdentifierExpression>("matrix"),
1215 std::make_unique<ast::IdentifierExpression>("scalar"));
1216
dan sinclaircd077b02020-04-20 14:19:04 +00001217 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001218 ASSERT_NE(expr.result_type(), nullptr);
1219 ASSERT_TRUE(expr.result_type()->IsMatrix());
1220
Ryan Harrison0a196c12020-04-17 13:18:20 +00001221 auto* mat = expr.result_type()->AsMatrix();
dan sinclair9b978022020-04-07 19:26:39 +00001222 EXPECT_TRUE(mat->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001223 EXPECT_EQ(mat->rows(), 3u);
1224 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001225}
1226
dan sinclair1c9b4862020-04-07 19:27:41 +00001227TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Scalar_Matrix) {
dan sinclair9b978022020-04-07 19:26:39 +00001228 ast::type::F32Type f32;
1229 ast::type::MatrixType mat3x2(&f32, 3, 2);
1230
1231 auto scalar =
1232 std::make_unique<ast::Variable>("scalar", ast::StorageClass::kNone, &f32);
1233 auto matrix = std::make_unique<ast::Variable>(
1234 "matrix", ast::StorageClass::kNone, &mat3x2);
dan sinclaircd077b02020-04-20 14:19:04 +00001235 mod()->AddGlobalVariable(std::move(scalar));
1236 mod()->AddGlobalVariable(std::move(matrix));
dan sinclair9b978022020-04-07 19:26:39 +00001237
1238 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001239 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001240
dan sinclair1c9b4862020-04-07 19:27:41 +00001241 ast::BinaryExpression expr(
1242 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001243 std::make_unique<ast::IdentifierExpression>("scalar"),
1244 std::make_unique<ast::IdentifierExpression>("matrix"));
1245
dan sinclaircd077b02020-04-20 14:19:04 +00001246 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001247 ASSERT_NE(expr.result_type(), nullptr);
1248 ASSERT_TRUE(expr.result_type()->IsMatrix());
1249
Ryan Harrison0a196c12020-04-17 13:18:20 +00001250 auto* mat = expr.result_type()->AsMatrix();
dan sinclair9b978022020-04-07 19:26:39 +00001251 EXPECT_TRUE(mat->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001252 EXPECT_EQ(mat->rows(), 3u);
1253 EXPECT_EQ(mat->columns(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001254}
1255
dan sinclair1c9b4862020-04-07 19:27:41 +00001256TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Vector) {
dan sinclair9b978022020-04-07 19:26:39 +00001257 ast::type::F32Type f32;
1258 ast::type::VectorType vec3(&f32, 2);
1259 ast::type::MatrixType mat3x2(&f32, 3, 2);
1260
1261 auto vector = std::make_unique<ast::Variable>(
1262 "vector", ast::StorageClass::kNone, &vec3);
1263 auto matrix = std::make_unique<ast::Variable>(
1264 "matrix", ast::StorageClass::kNone, &mat3x2);
dan sinclaircd077b02020-04-20 14:19:04 +00001265 mod()->AddGlobalVariable(std::move(vector));
1266 mod()->AddGlobalVariable(std::move(matrix));
dan sinclair9b978022020-04-07 19:26:39 +00001267
1268 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001269 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001270
dan sinclair1c9b4862020-04-07 19:27:41 +00001271 ast::BinaryExpression expr(
1272 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001273 std::make_unique<ast::IdentifierExpression>("matrix"),
1274 std::make_unique<ast::IdentifierExpression>("vector"));
1275
dan sinclaircd077b02020-04-20 14:19:04 +00001276 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001277 ASSERT_NE(expr.result_type(), nullptr);
1278 ASSERT_TRUE(expr.result_type()->IsVector());
1279 EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001280 EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
dan sinclair9b978022020-04-07 19:26:39 +00001281}
1282
dan sinclair1c9b4862020-04-07 19:27:41 +00001283TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Vector_Matrix) {
dan sinclair9b978022020-04-07 19:26:39 +00001284 ast::type::F32Type f32;
1285 ast::type::VectorType vec3(&f32, 3);
1286 ast::type::MatrixType mat3x2(&f32, 3, 2);
1287
1288 auto vector = std::make_unique<ast::Variable>(
1289 "vector", ast::StorageClass::kNone, &vec3);
1290 auto matrix = std::make_unique<ast::Variable>(
1291 "matrix", ast::StorageClass::kNone, &mat3x2);
dan sinclaircd077b02020-04-20 14:19:04 +00001292 mod()->AddGlobalVariable(std::move(vector));
1293 mod()->AddGlobalVariable(std::move(matrix));
dan sinclair9b978022020-04-07 19:26:39 +00001294
1295 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001296 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001297
dan sinclair1c9b4862020-04-07 19:27:41 +00001298 ast::BinaryExpression expr(
1299 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001300 std::make_unique<ast::IdentifierExpression>("vector"),
1301 std::make_unique<ast::IdentifierExpression>("matrix"));
1302
dan sinclaircd077b02020-04-20 14:19:04 +00001303 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001304 ASSERT_NE(expr.result_type(), nullptr);
1305 ASSERT_TRUE(expr.result_type()->IsVector());
1306 EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001307 EXPECT_EQ(expr.result_type()->AsVector()->size(), 2u);
dan sinclair9b978022020-04-07 19:26:39 +00001308}
1309
dan sinclair1c9b4862020-04-07 19:27:41 +00001310TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Matrix) {
dan sinclair9b978022020-04-07 19:26:39 +00001311 ast::type::F32Type f32;
1312 ast::type::MatrixType mat4x3(&f32, 4, 3);
1313 ast::type::MatrixType mat3x4(&f32, 3, 4);
1314
1315 auto matrix1 = std::make_unique<ast::Variable>(
1316 "mat4x3", ast::StorageClass::kNone, &mat4x3);
1317 auto matrix2 = std::make_unique<ast::Variable>(
1318 "mat3x4", ast::StorageClass::kNone, &mat3x4);
dan sinclaircd077b02020-04-20 14:19:04 +00001319 mod()->AddGlobalVariable(std::move(matrix1));
1320 mod()->AddGlobalVariable(std::move(matrix2));
dan sinclair9b978022020-04-07 19:26:39 +00001321
1322 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001323 ASSERT_TRUE(td()->Determine()) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001324
dan sinclair1c9b4862020-04-07 19:27:41 +00001325 ast::BinaryExpression expr(
1326 ast::BinaryOp::kMultiply,
dan sinclair9b978022020-04-07 19:26:39 +00001327 std::make_unique<ast::IdentifierExpression>("mat4x3"),
1328 std::make_unique<ast::IdentifierExpression>("mat3x4"));
1329
dan sinclaircd077b02020-04-20 14:19:04 +00001330 ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
dan sinclair9b978022020-04-07 19:26:39 +00001331 ASSERT_NE(expr.result_type(), nullptr);
1332 ASSERT_TRUE(expr.result_type()->IsMatrix());
1333
Ryan Harrison0a196c12020-04-17 13:18:20 +00001334 auto* mat = expr.result_type()->AsMatrix();
dan sinclair9b978022020-04-07 19:26:39 +00001335 EXPECT_TRUE(mat->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001336 EXPECT_EQ(mat->rows(), 4u);
1337 EXPECT_EQ(mat->columns(), 4u);
dan sinclair9b978022020-04-07 19:26:39 +00001338}
1339
dan sinclairb1730562020-04-07 19:26:49 +00001340using UnaryDerivativeExpressionTest =
dan sinclaircd077b02020-04-20 14:19:04 +00001341 TypeDeterminerTestWithParam<ast::UnaryDerivative>;
dan sinclairb1730562020-04-07 19:26:49 +00001342TEST_P(UnaryDerivativeExpressionTest, Expr_UnaryDerivative) {
1343 auto derivative = GetParam();
1344
1345 ast::type::F32Type f32;
1346
1347 ast::type::VectorType vec4(&f32, 4);
1348
1349 auto var =
1350 std::make_unique<ast::Variable>("ident", ast::StorageClass::kNone, &vec4);
dan sinclaircd077b02020-04-20 14:19:04 +00001351 mod()->AddGlobalVariable(std::move(var));
dan sinclairb1730562020-04-07 19:26:49 +00001352
1353 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001354 EXPECT_TRUE(td()->Determine());
dan sinclairb1730562020-04-07 19:26:49 +00001355
1356 ast::UnaryDerivativeExpression der(
1357 derivative, ast::DerivativeModifier::kNone,
1358 std::make_unique<ast::IdentifierExpression>("ident"));
dan sinclaircd077b02020-04-20 14:19:04 +00001359 EXPECT_TRUE(td()->DetermineResultType(&der));
dan sinclairb1730562020-04-07 19:26:49 +00001360 ASSERT_NE(der.result_type(), nullptr);
1361 ASSERT_TRUE(der.result_type()->IsVector());
1362 EXPECT_TRUE(der.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001363 EXPECT_EQ(der.result_type()->AsVector()->size(), 4u);
dan sinclairb1730562020-04-07 19:26:49 +00001364}
1365INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
1366 UnaryDerivativeExpressionTest,
1367 testing::Values(ast::UnaryDerivative::kDpdx,
1368 ast::UnaryDerivative::kDpdy,
1369 ast::UnaryDerivative::kFwidth));
1370
dan sinclaircd077b02020-04-20 14:19:04 +00001371using UnaryMethodExpressionBoolTest =
1372 TypeDeterminerTestWithParam<ast::UnaryMethod>;
dan sinclair8dcfd102020-04-07 19:27:00 +00001373TEST_P(UnaryMethodExpressionBoolTest, Expr_UnaryMethod_Any) {
1374 auto op = GetParam();
1375
1376 ast::type::BoolType bool_type;
1377 ast::type::VectorType vec3(&bool_type, 3);
1378
1379 auto var = std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone,
1380 &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +00001381 mod()->AddGlobalVariable(std::move(var));
dan sinclair8dcfd102020-04-07 19:27:00 +00001382
1383 ast::ExpressionList params;
1384 params.push_back(std::make_unique<ast::IdentifierExpression>("my_var"));
1385
1386 ast::UnaryMethodExpression exp(op, std::move(params));
1387
dan sinclair8dcfd102020-04-07 19:27:00 +00001388 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001389 EXPECT_TRUE(td()->Determine());
dan sinclair8dcfd102020-04-07 19:27:00 +00001390
dan sinclaircd077b02020-04-20 14:19:04 +00001391 EXPECT_TRUE(td()->DetermineResultType(&exp));
dan sinclair8dcfd102020-04-07 19:27:00 +00001392 ASSERT_NE(exp.result_type(), nullptr);
1393 EXPECT_TRUE(exp.result_type()->IsBool());
1394}
1395INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
1396 UnaryMethodExpressionBoolTest,
1397 testing::Values(ast::UnaryMethod::kAny,
1398 ast::UnaryMethod::kAll));
1399
dan sinclaircd077b02020-04-20 14:19:04 +00001400using UnaryMethodExpressionVecTest =
1401 TypeDeterminerTestWithParam<ast::UnaryMethod>;
dan sinclair8dcfd102020-04-07 19:27:00 +00001402TEST_P(UnaryMethodExpressionVecTest, Expr_UnaryMethod_Bool) {
1403 auto op = GetParam();
1404
1405 ast::type::F32Type f32;
1406 ast::type::VectorType vec3(&f32, 3);
1407
1408 auto var = std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone,
1409 &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +00001410 mod()->AddGlobalVariable(std::move(var));
dan sinclair8dcfd102020-04-07 19:27:00 +00001411
1412 ast::ExpressionList params;
1413 params.push_back(std::make_unique<ast::IdentifierExpression>("my_var"));
1414
1415 ast::UnaryMethodExpression exp(op, std::move(params));
1416
dan sinclair8dcfd102020-04-07 19:27:00 +00001417 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001418 EXPECT_TRUE(td()->Determine());
dan sinclair8dcfd102020-04-07 19:27:00 +00001419
dan sinclaircd077b02020-04-20 14:19:04 +00001420 EXPECT_TRUE(td()->DetermineResultType(&exp));
dan sinclair8dcfd102020-04-07 19:27:00 +00001421 ASSERT_NE(exp.result_type(), nullptr);
1422 ASSERT_TRUE(exp.result_type()->IsVector());
1423 EXPECT_TRUE(exp.result_type()->AsVector()->type()->IsBool());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001424 EXPECT_EQ(exp.result_type()->AsVector()->size(), 3u);
dan sinclair8dcfd102020-04-07 19:27:00 +00001425}
1426TEST_P(UnaryMethodExpressionVecTest, Expr_UnaryMethod_Vec) {
1427 auto op = GetParam();
1428
1429 ast::type::F32Type f32;
1430
1431 auto var =
1432 std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
dan sinclaircd077b02020-04-20 14:19:04 +00001433 mod()->AddGlobalVariable(std::move(var));
dan sinclair8dcfd102020-04-07 19:27:00 +00001434
1435 ast::ExpressionList params;
1436 params.push_back(std::make_unique<ast::IdentifierExpression>("my_var"));
1437
1438 ast::UnaryMethodExpression exp(op, std::move(params));
1439
dan sinclair8dcfd102020-04-07 19:27:00 +00001440 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001441 EXPECT_TRUE(td()->Determine());
dan sinclair8dcfd102020-04-07 19:27:00 +00001442
dan sinclaircd077b02020-04-20 14:19:04 +00001443 EXPECT_TRUE(td()->DetermineResultType(&exp));
dan sinclair8dcfd102020-04-07 19:27:00 +00001444 ASSERT_NE(exp.result_type(), nullptr);
1445 EXPECT_TRUE(exp.result_type()->IsBool());
1446}
1447INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
1448 UnaryMethodExpressionVecTest,
1449 testing::Values(ast::UnaryMethod::kIsInf,
1450 ast::UnaryMethod::kIsNan,
1451 ast::UnaryMethod::kIsFinite,
1452 ast::UnaryMethod::kIsNormal));
1453
1454TEST_F(TypeDeterminerTest, Expr_UnaryMethod_Dot) {
1455 ast::type::F32Type f32;
1456 ast::type::VectorType vec3(&f32, 3);
1457
1458 auto var = std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone,
1459 &vec3);
dan sinclaircd077b02020-04-20 14:19:04 +00001460 mod()->AddGlobalVariable(std::move(var));
dan sinclair8dcfd102020-04-07 19:27:00 +00001461
1462 ast::ExpressionList params;
1463 params.push_back(std::make_unique<ast::IdentifierExpression>("my_var"));
1464 params.push_back(std::make_unique<ast::IdentifierExpression>("my_var"));
1465
1466 ast::UnaryMethodExpression exp(ast::UnaryMethod::kDot, std::move(params));
1467
dan sinclair8dcfd102020-04-07 19:27:00 +00001468 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001469 EXPECT_TRUE(td()->Determine());
dan sinclair8dcfd102020-04-07 19:27:00 +00001470
dan sinclaircd077b02020-04-20 14:19:04 +00001471 EXPECT_TRUE(td()->DetermineResultType(&exp));
dan sinclair8dcfd102020-04-07 19:27:00 +00001472 ASSERT_NE(exp.result_type(), nullptr);
1473 EXPECT_TRUE(exp.result_type()->IsF32());
1474}
1475
1476TEST_F(TypeDeterminerTest, Expr_UnaryMethod_OuterProduct) {
1477 ast::type::F32Type f32;
1478 ast::type::VectorType vec3(&f32, 3);
1479 ast::type::VectorType vec2(&f32, 2);
1480
1481 auto var1 =
1482 std::make_unique<ast::Variable>("v3", ast::StorageClass::kNone, &vec3);
1483 auto var2 =
1484 std::make_unique<ast::Variable>("v2", ast::StorageClass::kNone, &vec2);
dan sinclaircd077b02020-04-20 14:19:04 +00001485 mod()->AddGlobalVariable(std::move(var1));
1486 mod()->AddGlobalVariable(std::move(var2));
dan sinclair8dcfd102020-04-07 19:27:00 +00001487
1488 ast::ExpressionList params;
1489 params.push_back(std::make_unique<ast::IdentifierExpression>("v3"));
1490 params.push_back(std::make_unique<ast::IdentifierExpression>("v2"));
1491
1492 ast::UnaryMethodExpression exp(ast::UnaryMethod::kOuterProduct,
1493 std::move(params));
1494
dan sinclair8dcfd102020-04-07 19:27:00 +00001495 // Register the variable
dan sinclairb950e802020-04-20 14:20:01 +00001496 EXPECT_TRUE(td()->Determine());
dan sinclair8dcfd102020-04-07 19:27:00 +00001497
dan sinclaircd077b02020-04-20 14:19:04 +00001498 EXPECT_TRUE(td()->DetermineResultType(&exp));
dan sinclair8dcfd102020-04-07 19:27:00 +00001499 ASSERT_NE(exp.result_type(), nullptr);
1500 ASSERT_TRUE(exp.result_type()->IsMatrix());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001501 auto* mat = exp.result_type()->AsMatrix();
dan sinclair8dcfd102020-04-07 19:27:00 +00001502 EXPECT_TRUE(mat->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001503 EXPECT_EQ(mat->rows(), 3u);
1504 EXPECT_EQ(mat->columns(), 2u);
dan sinclair8dcfd102020-04-07 19:27:00 +00001505}
1506
dan sinclaircd077b02020-04-20 14:19:04 +00001507using UnaryOpExpressionTest = TypeDeterminerTestWithParam<ast::UnaryOp>;
dan sinclair0e257622020-04-07 19:27:11 +00001508TEST_P(UnaryOpExpressionTest, Expr_UnaryOp) {
1509 auto op = GetParam();
1510
1511 ast::type::F32Type f32;
1512
1513 ast::type::VectorType vec4(&f32, 4);
1514
1515 auto var =
1516 std::make_unique<ast::Variable>("ident", ast::StorageClass::kNone, &vec4);
dan sinclaircd077b02020-04-20 14:19:04 +00001517 mod()->AddGlobalVariable(std::move(var));
dan sinclair0e257622020-04-07 19:27:11 +00001518
1519 // Register the global
dan sinclairb950e802020-04-20 14:20:01 +00001520 EXPECT_TRUE(td()->Determine());
dan sinclair0e257622020-04-07 19:27:11 +00001521
1522 ast::UnaryOpExpression der(
1523 op, std::make_unique<ast::IdentifierExpression>("ident"));
dan sinclaircd077b02020-04-20 14:19:04 +00001524 EXPECT_TRUE(td()->DetermineResultType(&der));
dan sinclair0e257622020-04-07 19:27:11 +00001525 ASSERT_NE(der.result_type(), nullptr);
1526 ASSERT_TRUE(der.result_type()->IsVector());
1527 EXPECT_TRUE(der.result_type()->AsVector()->type()->IsF32());
Ryan Harrison0a196c12020-04-17 13:18:20 +00001528 EXPECT_EQ(der.result_type()->AsVector()->size(), 4u);
dan sinclair0e257622020-04-07 19:27:11 +00001529}
1530INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
1531 UnaryOpExpressionTest,
1532 testing::Values(ast::UnaryOp::kNegation,
1533 ast::UnaryOp::kNot));
1534
dan sinclairee8ae042020-04-08 19:58:20 +00001535TEST_F(TypeDeterminerTest, StorageClass_SetsIfMissing) {
1536 ast::type::I32Type i32;
1537
1538 auto var =
1539 std::make_unique<ast::Variable>("var", ast::StorageClass::kNone, &i32);
Ryan Harrison0a196c12020-04-17 13:18:20 +00001540 auto* var_ptr = var.get();
dan sinclairee8ae042020-04-08 19:58:20 +00001541 auto stmt = std::make_unique<ast::VariableDeclStatement>(std::move(var));
1542
1543 auto func =
1544 std::make_unique<ast::Function>("func", ast::VariableList{}, &i32);
1545 ast::StatementList stmts;
1546 stmts.push_back(std::move(stmt));
1547 func->set_body(std::move(stmts));
1548
dan sinclaircd077b02020-04-20 14:19:04 +00001549 mod()->AddFunction(std::move(func));
dan sinclairee8ae042020-04-08 19:58:20 +00001550
dan sinclairb950e802020-04-20 14:20:01 +00001551 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclairee8ae042020-04-08 19:58:20 +00001552 EXPECT_EQ(var_ptr->storage_class(), ast::StorageClass::kFunction);
1553}
1554
1555TEST_F(TypeDeterminerTest, StorageClass_DoesNotSetOnConst) {
1556 ast::type::I32Type i32;
1557
1558 auto var =
1559 std::make_unique<ast::Variable>("var", ast::StorageClass::kNone, &i32);
1560 var->set_is_const(true);
Ryan Harrison0a196c12020-04-17 13:18:20 +00001561 auto* var_ptr = var.get();
dan sinclairee8ae042020-04-08 19:58:20 +00001562 auto stmt = std::make_unique<ast::VariableDeclStatement>(std::move(var));
1563
1564 auto func =
1565 std::make_unique<ast::Function>("func", ast::VariableList{}, &i32);
1566 ast::StatementList stmts;
1567 stmts.push_back(std::move(stmt));
1568 func->set_body(std::move(stmts));
1569
dan sinclaircd077b02020-04-20 14:19:04 +00001570 mod()->AddFunction(std::move(func));
dan sinclairee8ae042020-04-08 19:58:20 +00001571
dan sinclairb950e802020-04-20 14:20:01 +00001572 EXPECT_TRUE(td()->Determine()) << td()->error();
dan sinclairee8ae042020-04-08 19:58:20 +00001573 EXPECT_EQ(var_ptr->storage_class(), ast::StorageClass::kNone);
1574}
1575
1576TEST_F(TypeDeterminerTest, StorageClass_NonFunctionClassError) {
1577 ast::type::I32Type i32;
1578
1579 auto var = std::make_unique<ast::Variable>(
1580 "var", ast::StorageClass::kWorkgroup, &i32);
1581 auto stmt = std::make_unique<ast::VariableDeclStatement>(std::move(var));
1582
1583 auto func =
1584 std::make_unique<ast::Function>("func", ast::VariableList{}, &i32);
1585 ast::StatementList stmts;
1586 stmts.push_back(std::move(stmt));
1587 func->set_body(std::move(stmts));
1588
dan sinclaircd077b02020-04-20 14:19:04 +00001589 mod()->AddFunction(std::move(func));
dan sinclairee8ae042020-04-08 19:58:20 +00001590
dan sinclairb950e802020-04-20 14:20:01 +00001591 EXPECT_FALSE(td()->Determine());
dan sinclairee8ae042020-04-08 19:58:20 +00001592 EXPECT_EQ(td()->error(),
1593 "function variable has a non-function storage class");
1594}
1595
dan sinclairca1723e2020-04-20 15:47:55 +00001596struct GLSLData {
1597 const char* name;
1598 uint32_t value;
1599};
1600inline std::ostream& operator<<(std::ostream& out, GLSLData data) {
1601 out << data.name;
1602 return out;
1603}
dan sinclair37d62c92020-04-21 12:55:06 +00001604using ImportData_SingleParamTest = TypeDeterminerTestWithParam<GLSLData>;
dan sinclairca1723e2020-04-20 15:47:55 +00001605
dan sinclair37d62c92020-04-21 12:55:06 +00001606TEST_P(ImportData_SingleParamTest, Scalar) {
dan sinclairca1723e2020-04-20 15:47:55 +00001607 auto param = GetParam();
1608
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001609 ast::type::F32Type f32;
1610
1611 ast::ExpressionList params;
1612 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
dan sinclair37d62c92020-04-21 12:55:06 +00001613 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001614
1615 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1616
1617 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00001618 auto* type =
1619 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001620 ASSERT_NE(type, nullptr);
1621 EXPECT_TRUE(type->is_float_scalar());
dan sinclairca1723e2020-04-20 15:47:55 +00001622 EXPECT_EQ(id, param.value);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001623}
1624
dan sinclair37d62c92020-04-21 12:55:06 +00001625TEST_P(ImportData_SingleParamTest, Vector) {
dan sinclairca1723e2020-04-20 15:47:55 +00001626 auto param = GetParam();
1627
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001628 ast::type::F32Type f32;
1629 ast::type::VectorType vec(&f32, 3);
1630
1631 ast::ExpressionList vals;
1632 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1633 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1634 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1635 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1636 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1637 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
1638
1639 ast::ExpressionList params;
1640 params.push_back(
1641 std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals)));
1642
1643 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1644
1645 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00001646 auto* type =
1647 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001648 ASSERT_NE(type, nullptr);
1649 EXPECT_TRUE(type->is_float_vector());
1650 EXPECT_EQ(type->AsVector()->size(), 3);
dan sinclairca1723e2020-04-20 15:47:55 +00001651 EXPECT_EQ(id, param.value);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001652}
1653
dan sinclair37d62c92020-04-21 12:55:06 +00001654TEST_P(ImportData_SingleParamTest, Error_Integer) {
dan sinclairca1723e2020-04-20 15:47:55 +00001655 auto param = GetParam();
1656
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001657 ast::type::I32Type i32;
1658
1659 ast::ExpressionList params;
1660 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1661 std::make_unique<ast::IntLiteral>(&i32, 1)));
1662
1663 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1664
1665 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00001666 auto* type =
1667 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001668 ASSERT_EQ(type, nullptr);
dan sinclairca1723e2020-04-20 15:47:55 +00001669 EXPECT_EQ(td()->error(), std::string("incorrect type for ") + param.name +
1670 ". Requires a float scalar or a float vector");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001671}
1672
dan sinclair37d62c92020-04-21 12:55:06 +00001673TEST_P(ImportData_SingleParamTest, Error_NoParams) {
dan sinclairca1723e2020-04-20 15:47:55 +00001674 auto param = GetParam();
1675
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001676 ast::ExpressionList params;
1677 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00001678 auto* type =
1679 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001680 ASSERT_EQ(type, nullptr);
dan sinclairca1723e2020-04-20 15:47:55 +00001681 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
1682 param.name + ". Expected 1 got 0");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001683}
1684
dan sinclair37d62c92020-04-21 12:55:06 +00001685TEST_P(ImportData_SingleParamTest, Error_MultipleParams) {
dan sinclairca1723e2020-04-20 15:47:55 +00001686 auto param = GetParam();
1687
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001688 ast::type::F32Type f32;
1689 ast::ExpressionList params;
1690 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1691 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1692 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1693 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1694 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1695 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1696
1697 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1698
1699 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00001700 auto* type =
1701 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001702 ASSERT_EQ(type, nullptr);
dan sinclairca1723e2020-04-20 15:47:55 +00001703 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
1704 param.name + ". Expected 1 got 3");
dan sinclairfd5d4ca2020-04-20 15:46:18 +00001705}
1706
dan sinclaira49328f2020-04-20 15:49:50 +00001707INSTANTIATE_TEST_SUITE_P(
1708 TypeDeterminerTest,
dan sinclair37d62c92020-04-21 12:55:06 +00001709 ImportData_SingleParamTest,
dan sinclaira49328f2020-04-20 15:49:50 +00001710 testing::Values(GLSLData{"round", GLSLstd450Round},
1711 GLSLData{"roundeven", GLSLstd450RoundEven},
1712 GLSLData{"trunc", GLSLstd450Trunc},
1713 GLSLData{"fabs", GLSLstd450FAbs},
1714 GLSLData{"fsign", GLSLstd450FSign},
1715 GLSLData{"floor", GLSLstd450Floor},
1716 GLSLData{"ceil", GLSLstd450Ceil},
1717 GLSLData{"fract", GLSLstd450Fract},
1718 GLSLData{"radians", GLSLstd450Radians},
1719 GLSLData{"degrees", GLSLstd450Degrees},
1720 GLSLData{"sin", GLSLstd450Sin},
1721 GLSLData{"cos", GLSLstd450Cos},
1722 GLSLData{"tan", GLSLstd450Tan},
1723 GLSLData{"asin", GLSLstd450Asin},
1724 GLSLData{"acos", GLSLstd450Acos},
1725 GLSLData{"atan", GLSLstd450Atan},
1726 GLSLData{"sinh", GLSLstd450Sinh},
1727 GLSLData{"cosh", GLSLstd450Cosh},
1728 GLSLData{"tanh", GLSLstd450Tanh},
1729 GLSLData{"asinh", GLSLstd450Asinh},
1730 GLSLData{"acosh", GLSLstd450Acosh},
1731 GLSLData{"atanh", GLSLstd450Atanh},
1732 GLSLData{"exp", GLSLstd450Exp},
1733 GLSLData{"log", GLSLstd450Log},
1734 GLSLData{"exp2", GLSLstd450Exp2},
1735 GLSLData{"log2", GLSLstd450Log2},
1736 GLSLData{"sqrt", GLSLstd450Sqrt},
dan sinclair3df20442020-04-20 15:51:18 +00001737 GLSLData{"inversesqrt", GLSLstd450InverseSqrt},
1738 GLSLData{"normalize", GLSLstd450Normalize}));
dan sinclairca1723e2020-04-20 15:47:55 +00001739
dan sinclair652a4b92020-04-20 21:09:14 +00001740TEST_F(TypeDeterminerTest, ImportData_Length_Scalar) {
1741 ast::type::F32Type f32;
1742
1743 ast::ExpressionList params;
1744 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
dan sinclair37d62c92020-04-21 12:55:06 +00001745 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
dan sinclair652a4b92020-04-20 21:09:14 +00001746
1747 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1748
1749 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00001750 auto* type =
1751 td()->GetImportData({0, 0}, "GLSL.std.450", "length", params, &id);
dan sinclair652a4b92020-04-20 21:09:14 +00001752 ASSERT_NE(type, nullptr);
1753 EXPECT_TRUE(type->is_float_scalar());
1754 EXPECT_EQ(id, GLSLstd450Length);
1755}
1756
1757TEST_F(TypeDeterminerTest, ImportData_Length_FloatVector) {
1758 ast::type::F32Type f32;
1759 ast::type::VectorType vec(&f32, 3);
1760
1761 ast::ExpressionList vals;
1762 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1763 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1764 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1765 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1766 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1767 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
1768
1769 ast::ExpressionList params;
1770 params.push_back(
1771 std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals)));
1772
1773 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1774
1775 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00001776 auto* type =
1777 td()->GetImportData({0, 0}, "GLSL.std.450", "length", params, &id);
dan sinclair652a4b92020-04-20 21:09:14 +00001778 ASSERT_NE(type, nullptr);
1779 EXPECT_TRUE(type->is_float_scalar());
1780 EXPECT_EQ(id, GLSLstd450Length);
1781}
1782
1783TEST_F(TypeDeterminerTest, ImportData_Length_Error_Integer) {
1784 ast::type::I32Type i32;
1785
1786 ast::ExpressionList params;
1787 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1788 std::make_unique<ast::IntLiteral>(&i32, 1)));
1789
1790 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1791
1792 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00001793 auto* type =
1794 td()->GetImportData({0, 0}, "GLSL.std.450", "length", params, &id);
dan sinclair652a4b92020-04-20 21:09:14 +00001795 ASSERT_EQ(type, nullptr);
1796 EXPECT_EQ(
1797 td()->error(),
1798 "incorrect type for length. Requires a float scalar or a float vector");
1799}
1800
1801TEST_F(TypeDeterminerTest, ImportData_Length_Error_NoParams) {
1802 ast::ExpressionList params;
1803 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00001804 auto* type =
1805 td()->GetImportData({0, 0}, "GLSL.std.450", "length", params, &id);
dan sinclair652a4b92020-04-20 21:09:14 +00001806 ASSERT_EQ(type, nullptr);
1807 EXPECT_EQ(td()->error(),
1808 "incorrect number of parameters for length. Expected 1 got 0");
1809}
1810
1811TEST_F(TypeDeterminerTest, ImportData_Length_Error_MultipleParams) {
1812 ast::type::F32Type f32;
1813 ast::ExpressionList params;
1814 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1815 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1816 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1817 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1818 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1819 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1820
1821 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1822
1823 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00001824 auto* type =
1825 td()->GetImportData({0, 0}, "GLSL.std.450", "length", params, &id);
dan sinclair652a4b92020-04-20 21:09:14 +00001826 ASSERT_EQ(type, nullptr);
1827 EXPECT_EQ(td()->error(),
1828 "incorrect number of parameters for length. Expected 1 got 3");
1829}
1830
dan sinclair37d62c92020-04-21 12:55:06 +00001831using ImportData_TwoParamTest = TypeDeterminerTestWithParam<GLSLData>;
1832
1833TEST_P(ImportData_TwoParamTest, Scalar) {
1834 auto param = GetParam();
1835
1836 ast::type::F32Type f32;
1837
1838 ast::ExpressionList params;
1839 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1840 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1841 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1842 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1843
1844 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1845
1846 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00001847 auto* type =
1848 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
dan sinclair37d62c92020-04-21 12:55:06 +00001849 ASSERT_NE(type, nullptr);
1850 EXPECT_TRUE(type->is_float_scalar());
1851 EXPECT_EQ(id, param.value);
1852}
1853
1854TEST_P(ImportData_TwoParamTest, Vector) {
1855 auto param = GetParam();
1856
1857 ast::type::F32Type f32;
1858 ast::type::VectorType vec(&f32, 3);
1859
1860 ast::ExpressionList vals_1;
1861 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1862 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1863 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1864 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1865 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1866 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
1867
1868 ast::ExpressionList vals_2;
1869 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1870 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1871 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1872 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1873 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1874 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
1875
1876 ast::ExpressionList params;
1877 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
1878 &vec, std::move(vals_1)));
1879 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
1880 &vec, std::move(vals_2)));
1881
1882 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1883
1884 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00001885 auto* type =
1886 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
dan sinclair37d62c92020-04-21 12:55:06 +00001887 ASSERT_NE(type, nullptr);
1888 EXPECT_TRUE(type->is_float_vector());
1889 EXPECT_EQ(type->AsVector()->size(), 3);
1890 EXPECT_EQ(id, param.value);
1891}
1892
1893TEST_P(ImportData_TwoParamTest, Error_Integer) {
1894 auto param = GetParam();
1895
1896 ast::type::I32Type i32;
1897
1898 ast::ExpressionList params;
1899 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1900 std::make_unique<ast::IntLiteral>(&i32, 1)));
1901 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1902 std::make_unique<ast::IntLiteral>(&i32, 2)));
1903
1904 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1905
1906 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00001907 auto* type =
1908 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
dan sinclair37d62c92020-04-21 12:55:06 +00001909 ASSERT_EQ(type, nullptr);
1910 EXPECT_EQ(td()->error(),
1911 std::string("incorrect type for ") + param.name +
1912 ". Requires float scalar or a float vector values");
1913}
1914
1915TEST_P(ImportData_TwoParamTest, Error_NoParams) {
1916 auto param = GetParam();
1917
1918 ast::ExpressionList params;
1919 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00001920 auto* type =
1921 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
dan sinclair37d62c92020-04-21 12:55:06 +00001922 ASSERT_EQ(type, nullptr);
1923 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
1924 param.name + ". Expected 2 got 0");
1925}
1926
1927TEST_P(ImportData_TwoParamTest, Error_OneParam) {
1928 auto param = GetParam();
1929
1930 ast::type::F32Type f32;
1931 ast::ExpressionList params;
1932 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1933 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
1934
1935 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1936
1937 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00001938 auto* type =
1939 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
dan sinclair37d62c92020-04-21 12:55:06 +00001940 ASSERT_EQ(type, nullptr);
1941 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
1942 param.name + ". Expected 2 got 1");
1943}
1944
1945TEST_P(ImportData_TwoParamTest, Error_MismatchedParamCount) {
1946 auto param = GetParam();
1947
1948 ast::type::F32Type f32;
1949 ast::type::VectorType vec2(&f32, 2);
1950 ast::type::VectorType vec3(&f32, 3);
1951
1952 ast::ExpressionList vals_1;
1953 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1954 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1955 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1956 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1957
1958 ast::ExpressionList vals_2;
1959 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1960 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1961 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1962 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1963 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1964 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
1965
1966 ast::ExpressionList params;
1967 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
1968 &vec2, std::move(vals_1)));
1969 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
1970 &vec3, std::move(vals_2)));
1971
1972 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
1973
1974 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00001975 auto* type =
1976 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
dan sinclair37d62c92020-04-21 12:55:06 +00001977 ASSERT_EQ(type, nullptr);
1978 EXPECT_EQ(td()->error(),
1979 std::string("mismatched parameter types for ") + param.name);
1980}
1981
1982TEST_P(ImportData_TwoParamTest, Error_MismatchedParamType) {
1983 auto param = GetParam();
1984
1985 ast::type::F32Type f32;
1986 ast::type::VectorType vec(&f32, 3);
1987
1988 ast::ExpressionList vals;
1989 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1990 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1991 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1992 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1993 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1994 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
1995
1996 ast::ExpressionList params;
1997 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
1998 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
1999 params.push_back(
2000 std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals)));
2001
2002 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2003
2004 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00002005 auto* type =
2006 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
dan sinclair37d62c92020-04-21 12:55:06 +00002007 ASSERT_EQ(type, nullptr);
2008 EXPECT_EQ(td()->error(),
2009 std::string("mismatched parameter types for ") + param.name);
2010}
2011
2012TEST_P(ImportData_TwoParamTest, Error_TooManyParams) {
2013 auto param = GetParam();
2014
2015 ast::type::F32Type f32;
2016 ast::ExpressionList params;
2017 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2018 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2019 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2020 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2021 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2022 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2023
2024 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2025
2026 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00002027 auto* type =
2028 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
dan sinclair37d62c92020-04-21 12:55:06 +00002029 ASSERT_EQ(type, nullptr);
2030 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2031 param.name + ". Expected 2 got 3");
2032}
2033
2034INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
2035 ImportData_TwoParamTest,
dan sinclair2ee4a7e2020-04-21 12:58:35 +00002036 testing::Values(GLSLData{"atan2", GLSLstd450Atan2},
2037 GLSLData{"pow", GLSLstd450Pow},
2038 GLSLData{"fmin", GLSLstd450FMin},
2039 GLSLData{"fmax", GLSLstd450FMax},
2040 GLSLData{"step", GLSLstd450Step},
2041 GLSLData{"reflect", GLSLstd450Reflect},
2042 GLSLData{"nmin", GLSLstd450NMin},
2043 GLSLData{"nmax", GLSLstd450NMax}));
dan sinclair37d62c92020-04-21 12:55:06 +00002044
dan sinclair54444382020-04-21 13:04:15 +00002045TEST_F(TypeDeterminerTest, ImportData_Distance_Scalar) {
2046 ast::type::F32Type f32;
2047
2048 ast::ExpressionList params;
2049 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2050 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2051 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2052 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2053
2054 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2055
2056 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00002057 auto* type =
2058 td()->GetImportData({0, 0}, "GLSL.std.450", "distance", params, &id);
dan sinclair54444382020-04-21 13:04:15 +00002059 ASSERT_NE(type, nullptr);
2060 EXPECT_TRUE(type->is_float_scalar());
2061 EXPECT_EQ(id, GLSLstd450Distance);
2062}
2063
2064TEST_F(TypeDeterminerTest, ImportData_Distance_Vector) {
2065 ast::type::F32Type f32;
2066 ast::type::VectorType vec(&f32, 3);
2067
2068 ast::ExpressionList vals_1;
2069 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2070 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2071 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2072 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2073 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2074 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
2075
2076 ast::ExpressionList vals_2;
2077 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2078 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2079 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2080 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2081 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2082 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
2083
2084 ast::ExpressionList params;
2085 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
2086 &vec, std::move(vals_1)));
2087 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
2088 &vec, std::move(vals_2)));
2089
2090 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2091
2092 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00002093 auto* type =
2094 td()->GetImportData({0, 0}, "GLSL.std.450", "distance", params, &id);
dan sinclair54444382020-04-21 13:04:15 +00002095 ASSERT_NE(type, nullptr);
2096 EXPECT_TRUE(type->IsF32());
2097 EXPECT_EQ(id, GLSLstd450Distance);
2098}
2099
2100TEST_F(TypeDeterminerTest, ImportData_Distance_Error_Integer) {
2101 ast::type::I32Type i32;
2102
2103 ast::ExpressionList params;
2104 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2105 std::make_unique<ast::IntLiteral>(&i32, 1)));
2106 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2107 std::make_unique<ast::IntLiteral>(&i32, 2)));
2108
2109 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2110
2111 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00002112 auto* type =
2113 td()->GetImportData({0, 0}, "GLSL.std.450", "distance", params, &id);
dan sinclair54444382020-04-21 13:04:15 +00002114 ASSERT_EQ(type, nullptr);
2115 EXPECT_EQ(td()->error(),
2116 "incorrect type for distance. Requires float scalar or a float "
2117 "vector values");
2118}
2119
2120TEST_F(TypeDeterminerTest, ImportData_Distance_Error_NoParams) {
2121 ast::ExpressionList params;
2122 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00002123 auto* type =
2124 td()->GetImportData({0, 0}, "GLSL.std.450", "distance", params, &id);
dan sinclair54444382020-04-21 13:04:15 +00002125 ASSERT_EQ(type, nullptr);
2126 EXPECT_EQ(td()->error(),
2127 "incorrect number of parameters for distance. Expected 2 got 0");
2128}
2129
2130TEST_F(TypeDeterminerTest, ImportData_Distance_Error_OneParam) {
2131 ast::type::F32Type f32;
2132 ast::ExpressionList params;
2133 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2134 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2135
2136 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2137
2138 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00002139 auto* type =
2140 td()->GetImportData({0, 0}, "GLSL.std.450", "distance", params, &id);
dan sinclair54444382020-04-21 13:04:15 +00002141 ASSERT_EQ(type, nullptr);
2142 EXPECT_EQ(td()->error(),
2143 "incorrect number of parameters for distance. Expected 2 got 1");
2144}
2145
2146TEST_F(TypeDeterminerTest, ImportData_Distance_Error_MismatchedParamCount) {
2147 ast::type::F32Type f32;
2148 ast::type::VectorType vec2(&f32, 2);
2149 ast::type::VectorType vec3(&f32, 3);
2150
2151 ast::ExpressionList vals_1;
2152 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2153 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2154 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2155 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2156
2157 ast::ExpressionList vals_2;
2158 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2159 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2160 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2161 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2162 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2163 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
2164
2165 ast::ExpressionList params;
2166 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
2167 &vec2, std::move(vals_1)));
2168 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
2169 &vec3, std::move(vals_2)));
2170
2171 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2172
2173 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00002174 auto* type =
2175 td()->GetImportData({0, 0}, "GLSL.std.450", "distance", params, &id);
dan sinclair54444382020-04-21 13:04:15 +00002176 ASSERT_EQ(type, nullptr);
2177 EXPECT_EQ(td()->error(), "mismatched parameter types for distance");
2178}
2179
2180TEST_F(TypeDeterminerTest, ImportData_Distance_Error_MismatchedParamType) {
2181 ast::type::F32Type f32;
2182 ast::type::VectorType vec(&f32, 3);
2183
2184 ast::ExpressionList vals;
2185 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2186 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2187 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2188 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2189 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2190 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
2191
2192 ast::ExpressionList params;
2193 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2194 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2195 params.push_back(
2196 std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals)));
2197
2198 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2199
2200 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00002201 auto* type =
2202 td()->GetImportData({0, 0}, "GLSL.std.450", "distance", params, &id);
dan sinclair54444382020-04-21 13:04:15 +00002203 ASSERT_EQ(type, nullptr);
2204 EXPECT_EQ(td()->error(), "mismatched parameter types for distance");
2205}
2206
2207TEST_F(TypeDeterminerTest, ImportData_Distance_Error_TooManyParams) {
2208 ast::type::F32Type f32;
2209 ast::ExpressionList params;
2210 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2211 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2212 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2213 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2214 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2215 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2216
2217 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2218
2219 uint32_t id = 0;
dan sinclair70259182020-04-21 13:05:42 +00002220 auto* type =
2221 td()->GetImportData({0, 0}, "GLSL.std.450", "distance", params, &id);
dan sinclair54444382020-04-21 13:04:15 +00002222 ASSERT_EQ(type, nullptr);
2223 EXPECT_EQ(td()->error(),
2224 "incorrect number of parameters for distance. Expected 2 got 3");
2225}
2226
dan sinclair2287d012020-04-22 00:23:57 +00002227using ImportData_ThreeParamTest = TypeDeterminerTestWithParam<GLSLData>;
2228
2229TEST_P(ImportData_ThreeParamTest, Scalar) {
2230 auto param = GetParam();
2231
2232 ast::type::F32Type f32;
2233
2234 ast::ExpressionList params;
2235 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2236 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2237 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2238 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2239 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2240 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2241
2242 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2243
2244 uint32_t id = 0;
2245 auto* type =
2246 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
2247 ASSERT_NE(type, nullptr);
2248 EXPECT_TRUE(type->is_float_scalar());
2249 EXPECT_EQ(id, param.value);
2250}
2251
2252TEST_P(ImportData_ThreeParamTest, Vector) {
2253 auto param = GetParam();
2254
2255 ast::type::F32Type f32;
2256 ast::type::VectorType vec(&f32, 3);
2257
2258 ast::ExpressionList vals_1;
2259 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2260 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2261 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2262 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2263 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2264 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
2265
2266 ast::ExpressionList vals_2;
2267 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2268 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2269 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2270 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2271 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2272 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
2273
2274 ast::ExpressionList vals_3;
2275 vals_3.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2276 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2277 vals_3.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2278 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2279 vals_3.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2280 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
2281
2282 ast::ExpressionList params;
2283 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
2284 &vec, std::move(vals_1)));
2285 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
2286 &vec, std::move(vals_2)));
2287 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
2288 &vec, std::move(vals_3)));
2289
2290 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2291
2292 uint32_t id = 0;
2293 auto* type =
2294 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
2295 ASSERT_NE(type, nullptr);
2296 EXPECT_TRUE(type->is_float_vector());
2297 EXPECT_EQ(type->AsVector()->size(), 3);
2298 EXPECT_EQ(id, param.value);
2299}
2300
2301TEST_P(ImportData_ThreeParamTest, Error_Integer) {
2302 auto param = GetParam();
2303
2304 ast::type::I32Type i32;
2305
2306 ast::ExpressionList params;
2307 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2308 std::make_unique<ast::IntLiteral>(&i32, 1)));
2309 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2310 std::make_unique<ast::IntLiteral>(&i32, 2)));
2311 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2312 std::make_unique<ast::IntLiteral>(&i32, 3)));
2313
2314 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2315
2316 uint32_t id = 0;
2317 auto* type =
2318 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
2319 ASSERT_EQ(type, nullptr);
2320 EXPECT_EQ(td()->error(),
2321 std::string("incorrect type for ") + param.name +
2322 ". Requires float scalar or a float vector values");
2323}
2324
2325TEST_P(ImportData_ThreeParamTest, Error_NoParams) {
2326 auto param = GetParam();
2327
2328 ast::ExpressionList params;
2329 uint32_t id = 0;
2330 auto* type =
2331 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
2332 ASSERT_EQ(type, nullptr);
2333 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2334 param.name + ". Expected 3 got 0");
2335}
2336
2337TEST_P(ImportData_ThreeParamTest, Error_OneParam) {
2338 auto param = GetParam();
2339
2340 ast::type::F32Type f32;
2341 ast::ExpressionList params;
2342 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2343 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2344
2345 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2346
2347 uint32_t id = 0;
2348 auto* type =
2349 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
2350 ASSERT_EQ(type, nullptr);
2351 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2352 param.name + ". Expected 3 got 1");
2353}
2354
2355TEST_P(ImportData_ThreeParamTest, Error_TwoParams) {
2356 auto param = GetParam();
2357
2358 ast::type::F32Type f32;
2359 ast::ExpressionList params;
2360 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2361 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2362 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2363 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2364
2365 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2366
2367 uint32_t id = 0;
2368 auto* type =
2369 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
2370 ASSERT_EQ(type, nullptr);
2371 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2372 param.name + ". Expected 3 got 2");
2373}
2374
2375TEST_P(ImportData_ThreeParamTest, Error_MismatchedParamCount) {
2376 auto param = GetParam();
2377
2378 ast::type::F32Type f32;
2379 ast::type::VectorType vec2(&f32, 2);
2380 ast::type::VectorType vec3(&f32, 3);
2381
2382 ast::ExpressionList vals_1;
2383 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2384 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2385 vals_1.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2386 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2387
2388 ast::ExpressionList vals_2;
2389 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2390 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2391 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2392 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2393 vals_2.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2394 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
2395
2396 ast::ExpressionList vals_3;
2397 vals_3.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2398 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2399 vals_3.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2400 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2401 vals_3.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2402 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
2403
2404 ast::ExpressionList params;
2405 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
2406 &vec2, std::move(vals_1)));
2407 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
2408 &vec3, std::move(vals_2)));
2409 params.push_back(std::make_unique<ast::TypeConstructorExpression>(
2410 &vec3, std::move(vals_3)));
2411
2412 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2413
2414 uint32_t id = 0;
2415 auto* type =
2416 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
2417 ASSERT_EQ(type, nullptr);
2418 EXPECT_EQ(td()->error(),
2419 std::string("mismatched parameter types for ") + param.name);
2420}
2421
2422TEST_P(ImportData_ThreeParamTest, Error_MismatchedParamType) {
2423 auto param = GetParam();
2424
2425 ast::type::F32Type f32;
2426 ast::type::VectorType vec(&f32, 3);
2427
2428 ast::ExpressionList vals;
2429 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2430 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2431 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2432 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2433 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2434 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
2435
2436 ast::ExpressionList params;
2437 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2438 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2439 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2440 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
2441 params.push_back(
2442 std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals)));
2443
2444 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2445
2446 uint32_t id = 0;
2447 auto* type =
2448 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
2449 ASSERT_EQ(type, nullptr);
2450 EXPECT_EQ(td()->error(),
2451 std::string("mismatched parameter types for ") + param.name);
2452}
2453
2454TEST_P(ImportData_ThreeParamTest, Error_TooManyParams) {
2455 auto param = GetParam();
2456
2457 ast::type::F32Type f32;
2458 ast::ExpressionList params;
2459 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2460 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2461 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2462 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2463 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2464 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2465 params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
2466 std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
2467
2468 ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
2469
2470 uint32_t id = 0;
2471 auto* type =
2472 td()->GetImportData({0, 0}, "GLSL.std.450", param.name, params, &id);
2473 ASSERT_EQ(type, nullptr);
2474 EXPECT_EQ(td()->error(), std::string("incorrect number of parameters for ") +
2475 param.name + ". Expected 3 got 4");
2476}
2477
2478INSTANTIATE_TEST_SUITE_P(
2479 TypeDeterminerTest,
2480 ImportData_ThreeParamTest,
2481 testing::Values(GLSLData{"fclamp", GLSLstd450FClamp},
2482 GLSLData{"fmix", GLSLstd450FMix},
2483 GLSLData{"smoothstep", GLSLstd450SmoothStep},
2484 GLSLData{"fma", GLSLstd450Fma},
2485 GLSLData{"faceforward", GLSLstd450FaceForward},
2486 GLSLData{"nclamp", GLSLstd450NClamp}));
dan sinclairb7edc4c2020-04-07 12:46:30 +00002487} // namespace
2488} // namespace tint