blob: 75fb75ac340499b91643e2df1fda9842f9e611c6 [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>
19
20#include "gtest/gtest.h"
dan sinclair6c498fc2020-04-07 12:47:23 +000021#include "src/ast/assignment_statement.h"
dan sinclairb7ea6e22020-04-07 12:54:10 +000022#include "src/ast/break_statement.h"
dan sinclair6010b292020-04-07 12:54:20 +000023#include "src/ast/case_statement.h"
dan sinclairaec965e2020-04-07 12:54:29 +000024#include "src/ast/continue_statement.h"
dan sinclair0cf685f2020-04-07 12:54:37 +000025#include "src/ast/else_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000026#include "src/ast/float_literal.h"
dan sinclair91c44a52020-04-07 12:55:25 +000027#include "src/ast/if_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000028#include "src/ast/int_literal.h"
dan sinclairbc71eda2020-04-07 12:55:51 +000029#include "src/ast/loop_statement.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000030#include "src/ast/scalar_constructor_expression.h"
31#include "src/ast/type/f32_type.h"
dan sinclair6c498fc2020-04-07 12:47:23 +000032#include "src/ast/type/i32_type.h"
dan sinclairb7edc4c2020-04-07 12:46:30 +000033#include "src/ast/type/vector_type.h"
34#include "src/ast/type_constructor_expression.h"
35
36namespace tint {
37namespace {
38
39class TypeDeterminerTest : public testing::Test {
40 public:
41 void SetUp() { td_ = std::make_unique<TypeDeterminer>(&ctx_); }
42
43 TypeDeterminer* td() const { return td_.get(); }
44
45 private:
46 Context ctx_;
47 std::unique_ptr<TypeDeterminer> td_;
48};
49
dan sinclair6c498fc2020-04-07 12:47:23 +000050TEST_F(TypeDeterminerTest, Stmt_Assign) {
51 ast::type::F32Type f32;
52 ast::type::I32Type i32;
53
54 auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
55 std::make_unique<ast::IntLiteral>(&i32, 2));
56 auto lhs_ptr = lhs.get();
57
58 auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
59 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
60 auto rhs_ptr = rhs.get();
61
62 ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
63
64 EXPECT_TRUE(td()->DetermineResultType(&assign));
65 ASSERT_NE(lhs_ptr->result_type(), nullptr);
66 ASSERT_NE(rhs_ptr->result_type(), nullptr);
67
68 EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
69 EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
70}
71
dan sinclairb7ea6e22020-04-07 12:54:10 +000072TEST_F(TypeDeterminerTest, Stmt_Break) {
73 ast::type::I32Type i32;
74
75 auto cond = std::make_unique<ast::ScalarConstructorExpression>(
76 std::make_unique<ast::IntLiteral>(&i32, 2));
77 auto cond_ptr = cond.get();
78
79 ast::BreakStatement brk(ast::StatementCondition::kIf, std::move(cond));
80
81 EXPECT_TRUE(td()->DetermineResultType(&brk));
82 ASSERT_NE(cond_ptr->result_type(), nullptr);
83 EXPECT_TRUE(cond_ptr->result_type()->IsI32());
84}
85
dan sinclair6010b292020-04-07 12:54:20 +000086TEST_F(TypeDeterminerTest, Stmt_Case) {
87 ast::type::I32Type i32;
88 ast::type::F32Type f32;
89
90 auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
91 std::make_unique<ast::IntLiteral>(&i32, 2));
92 auto lhs_ptr = lhs.get();
93
94 auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
95 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
96 auto rhs_ptr = rhs.get();
97
98 ast::StatementList body;
99 body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
100 std::move(rhs)));
101
102 ast::CaseStatement cse(std::make_unique<ast::IntLiteral>(&i32, 3),
103 std::move(body));
104
105 EXPECT_TRUE(td()->DetermineResultType(&cse));
106 ASSERT_NE(lhs_ptr->result_type(), nullptr);
107 ASSERT_NE(rhs_ptr->result_type(), nullptr);
108 EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
109 EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
110}
111
dan sinclairaec965e2020-04-07 12:54:29 +0000112TEST_F(TypeDeterminerTest, Stmt_Continue) {
113 ast::type::I32Type i32;
114
115 auto cond = std::make_unique<ast::ScalarConstructorExpression>(
116 std::make_unique<ast::IntLiteral>(&i32, 2));
117 auto cond_ptr = cond.get();
118
119 ast::ContinueStatement stmt(ast::StatementCondition::kIf, std::move(cond));
120
121 EXPECT_TRUE(td()->DetermineResultType(&stmt));
122 ASSERT_NE(cond_ptr->result_type(), nullptr);
123 EXPECT_TRUE(cond_ptr->result_type()->IsI32());
124}
125
dan sinclair0cf685f2020-04-07 12:54:37 +0000126TEST_F(TypeDeterminerTest, Stmt_Else) {
127 ast::type::I32Type i32;
128 ast::type::F32Type f32;
129
130 auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
131 std::make_unique<ast::IntLiteral>(&i32, 2));
132 auto lhs_ptr = lhs.get();
133
134 auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
135 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
136 auto rhs_ptr = rhs.get();
137
138 ast::StatementList body;
139 body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
140 std::move(rhs)));
141
142 ast::ElseStatement stmt(std::make_unique<ast::ScalarConstructorExpression>(
143 std::make_unique<ast::IntLiteral>(&i32, 3)),
144 std::move(body));
145
146 EXPECT_TRUE(td()->DetermineResultType(&stmt));
147 ASSERT_NE(stmt.condition()->result_type(), nullptr);
148 ASSERT_NE(lhs_ptr->result_type(), nullptr);
149 ASSERT_NE(rhs_ptr->result_type(), nullptr);
150 EXPECT_TRUE(stmt.condition()->result_type()->IsI32());
151 EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
152 EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
153}
154
dan sinclair91c44a52020-04-07 12:55:25 +0000155TEST_F(TypeDeterminerTest, Stmt_If) {
156 ast::type::I32Type i32;
157 ast::type::F32Type f32;
158
159 auto else_lhs = std::make_unique<ast::ScalarConstructorExpression>(
160 std::make_unique<ast::IntLiteral>(&i32, 2));
161 auto else_lhs_ptr = else_lhs.get();
162
163 auto else_rhs = std::make_unique<ast::ScalarConstructorExpression>(
164 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
165 auto else_rhs_ptr = else_rhs.get();
166
167 ast::StatementList else_body;
168 else_body.push_back(std::make_unique<ast::AssignmentStatement>(
169 std::move(else_lhs), std::move(else_rhs)));
170
171 auto else_stmt = std::make_unique<ast::ElseStatement>(
172 std::make_unique<ast::ScalarConstructorExpression>(
173 std::make_unique<ast::IntLiteral>(&i32, 3)),
174 std::move(else_body));
175
176 ast::ElseStatementList else_stmts;
177 else_stmts.push_back(std::move(else_stmt));
178
179 auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
180 std::make_unique<ast::IntLiteral>(&i32, 2));
181 auto lhs_ptr = lhs.get();
182
183 auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
184 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
185 auto rhs_ptr = rhs.get();
186
187 ast::StatementList body;
188 body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
189 std::move(rhs)));
190
191 ast::IfStatement stmt(std::make_unique<ast::ScalarConstructorExpression>(
192 std::make_unique<ast::IntLiteral>(&i32, 3)),
193 std::move(body));
194 stmt.set_else_statements(std::move(else_stmts));
195
196 EXPECT_TRUE(td()->DetermineResultType(&stmt));
197 ASSERT_NE(stmt.condition()->result_type(), nullptr);
198 ASSERT_NE(else_lhs_ptr->result_type(), nullptr);
199 ASSERT_NE(else_rhs_ptr->result_type(), nullptr);
200 ASSERT_NE(lhs_ptr->result_type(), nullptr);
201 ASSERT_NE(rhs_ptr->result_type(), nullptr);
202 EXPECT_TRUE(stmt.condition()->result_type()->IsI32());
203 EXPECT_TRUE(else_lhs_ptr->result_type()->IsI32());
204 EXPECT_TRUE(else_rhs_ptr->result_type()->IsF32());
205 EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
206 EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
207}
208
dan sinclairbc71eda2020-04-07 12:55:51 +0000209TEST_F(TypeDeterminerTest, Stmt_Loop) {
210 ast::type::I32Type i32;
211 ast::type::F32Type f32;
212
213 auto body_lhs = std::make_unique<ast::ScalarConstructorExpression>(
214 std::make_unique<ast::IntLiteral>(&i32, 2));
215 auto body_lhs_ptr = body_lhs.get();
216
217 auto body_rhs = std::make_unique<ast::ScalarConstructorExpression>(
218 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
219 auto body_rhs_ptr = body_rhs.get();
220
221 ast::StatementList body;
222 body.push_back(std::make_unique<ast::AssignmentStatement>(
223 std::move(body_lhs), std::move(body_rhs)));
224
225 auto continuing_lhs = std::make_unique<ast::ScalarConstructorExpression>(
226 std::make_unique<ast::IntLiteral>(&i32, 2));
227 auto continuing_lhs_ptr = continuing_lhs.get();
228
229 auto continuing_rhs = std::make_unique<ast::ScalarConstructorExpression>(
230 std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
231 auto continuing_rhs_ptr = continuing_rhs.get();
232
233 ast::StatementList continuing;
234 continuing.push_back(std::make_unique<ast::AssignmentStatement>(
235 std::move(continuing_lhs), std::move(continuing_rhs)));
236
237 ast::LoopStatement stmt(std::move(body), std::move(continuing));
238
239 EXPECT_TRUE(td()->DetermineResultType(&stmt));
240 ASSERT_NE(body_lhs_ptr->result_type(), nullptr);
241 ASSERT_NE(body_rhs_ptr->result_type(), nullptr);
242 ASSERT_NE(continuing_lhs_ptr->result_type(), nullptr);
243 ASSERT_NE(continuing_rhs_ptr->result_type(), nullptr);
244 EXPECT_TRUE(body_lhs_ptr->result_type()->IsI32());
245 EXPECT_TRUE(body_rhs_ptr->result_type()->IsF32());
246 EXPECT_TRUE(continuing_lhs_ptr->result_type()->IsI32());
247 EXPECT_TRUE(continuing_rhs_ptr->result_type()->IsF32());
248}
249
dan sinclairb7edc4c2020-04-07 12:46:30 +0000250TEST_F(TypeDeterminerTest, Expr_Constructor_Scalar) {
251 ast::type::F32Type f32;
252 ast::ScalarConstructorExpression s(
253 std::make_unique<ast::FloatLiteral>(&f32, 1.0f));
254
255 EXPECT_TRUE(td()->DetermineResultType(&s));
256 ASSERT_NE(s.result_type(), nullptr);
257 EXPECT_TRUE(s.result_type()->IsF32());
258}
259
260TEST_F(TypeDeterminerTest, Expr_Constructor_Type) {
261 ast::type::F32Type f32;
262 ast::type::VectorType vec(&f32, 3);
263
264 ast::ExpressionList vals;
265 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
266 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
267 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
268 std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
269 vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
270 std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
271
272 ast::TypeConstructorExpression tc(&vec, std::move(vals));
273
274 EXPECT_TRUE(td()->DetermineResultType(&tc));
275 ASSERT_NE(tc.result_type(), nullptr);
276 ASSERT_TRUE(tc.result_type()->IsVector());
277 EXPECT_TRUE(tc.result_type()->AsVector()->type()->IsF32());
278 EXPECT_EQ(tc.result_type()->AsVector()->size(), 3);
279}
280
281} // namespace
282} // namespace tint