Add array accessor type determination.

This Cl adds type determination for an array accessor for arrays,
vectors and matrices.

Bug: tint:5
Change-Id: Ifce539338fd1f9b539c13970f115a4dbc207ff5a
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/18842
Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
dan sinclair 2020-04-07 12:57:42 +00:00 committed by dan sinclair
parent cab0e73b31
commit 973bd6a7b4
3 changed files with 134 additions and 0 deletions

View File

@ -14,6 +14,9 @@
#include "src/type_determiner.h"
#include <memory>
#include "src/ast/array_accessor_expression.h"
#include "src/ast/assignment_statement.h"
#include "src/ast/break_statement.h"
#include "src/ast/case_statement.h"
@ -26,6 +29,9 @@
#include "src/ast/return_statement.h"
#include "src/ast/scalar_constructor_expression.h"
#include "src/ast/switch_statement.h"
#include "src/ast/type/array_type.h"
#include "src/ast/type/matrix_type.h"
#include "src/ast/type/vector_type.h"
#include "src/ast/type_constructor_expression.h"
#include "src/ast/unless_statement.h"
#include "src/ast/variable_decl_statement.h"
@ -174,6 +180,9 @@ bool TypeDeterminer::DetermineResultType(ast::Expression* expr) {
return true;
}
if (expr->IsArrayAccessor()) {
return DetermineArrayAccessor(expr->AsArrayAccessor());
}
if (expr->IsConstructor()) {
return DetermineConstructor(expr->AsConstructor());
}
@ -185,6 +194,27 @@ bool TypeDeterminer::DetermineResultType(ast::Expression* expr) {
return false;
}
bool TypeDeterminer::DetermineArrayAccessor(
ast::ArrayAccessorExpression* expr) {
if (!DetermineResultType(expr->array())) {
return false;
}
auto parent_type = expr->array()->result_type();
if (parent_type->IsArray()) {
expr->set_result_type(parent_type->AsArray()->type());
} else if (parent_type->IsVector()) {
expr->set_result_type(parent_type->AsVector()->type());
} else if (parent_type->IsMatrix()) {
auto m = parent_type->AsMatrix();
expr->set_result_type(ctx_.type_mgr().Get(
std::make_unique<ast::type::VectorType>(m->type(), m->rows())));
} else {
error_ = "invalid parent type in array accessor";
return false;
}
return true;
}
bool TypeDeterminer::DetermineConstructor(ast::ConstructorExpression* expr) {
if (expr->IsTypeConstructor()) {
expr->set_result_type(expr->AsTypeConstructor()->type());

View File

@ -25,6 +25,7 @@
namespace tint {
namespace ast {
class ArrayAccessorExpression;
class ConstructorExpression;
class IdentifierExpression;
class Function;
@ -69,6 +70,7 @@ class TypeDeterminer {
bool DetermineResultType(ast::Expression* expr);
private:
bool DetermineArrayAccessor(ast::ArrayAccessorExpression* expr);
bool DetermineConstructor(ast::ConstructorExpression* expr);
bool DetermineIdentifier(ast::IdentifierExpression* expr);
Context& ctx_;

View File

@ -18,6 +18,7 @@
#include <utility>
#include "gtest/gtest.h"
#include "src/ast/array_accessor_expression.h"
#include "src/ast/assignment_statement.h"
#include "src/ast/break_statement.h"
#include "src/ast/case_statement.h"
@ -32,8 +33,10 @@
#include "src/ast/return_statement.h"
#include "src/ast/scalar_constructor_expression.h"
#include "src/ast/switch_statement.h"
#include "src/ast/type/array_type.h"
#include "src/ast/type/f32_type.h"
#include "src/ast/type/i32_type.h"
#include "src/ast/type/matrix_type.h"
#include "src/ast/type/vector_type.h"
#include "src/ast/type_constructor_expression.h"
#include "src/ast/unless_statement.h"
@ -376,6 +379,105 @@ TEST_F(TypeDeterminerTest, Stmt_VariableDecl) {
EXPECT_TRUE(init_ptr->result_type()->IsI32());
}
TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array) {
ast::type::I32Type i32;
ast::type::F32Type f32;
ast::type::ArrayType ary(&f32, 3);
auto idx = std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::IntLiteral>(&i32, 2));
ast::Module m;
auto var =
std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &ary);
m.AddGlobalVariable(std::move(var));
// Register the global
EXPECT_TRUE(td()->Determine(&m));
ast::ArrayAccessorExpression acc(
std::make_unique<ast::IdentifierExpression>("my_var"), std::move(idx));
EXPECT_TRUE(td()->DetermineResultType(&acc));
ASSERT_NE(acc.result_type(), nullptr);
EXPECT_TRUE(acc.result_type()->IsF32());
}
TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix) {
ast::type::I32Type i32;
ast::type::F32Type f32;
ast::type::MatrixType mat(&f32, 3, 2);
auto idx = std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::IntLiteral>(&i32, 2));
ast::Module m;
auto var =
std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &mat);
m.AddGlobalVariable(std::move(var));
// Register the global
EXPECT_TRUE(td()->Determine(&m));
ast::ArrayAccessorExpression acc(
std::make_unique<ast::IdentifierExpression>("my_var"), std::move(idx));
EXPECT_TRUE(td()->DetermineResultType(&acc));
ASSERT_NE(acc.result_type(), nullptr);
ASSERT_TRUE(acc.result_type()->IsVector());
EXPECT_EQ(acc.result_type()->AsVector()->size(), 3);
}
TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix_BothDimensions) {
ast::type::I32Type i32;
ast::type::F32Type f32;
ast::type::MatrixType mat(&f32, 3, 2);
auto idx1 = std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::IntLiteral>(&i32, 2));
auto idx2 = std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::IntLiteral>(&i32, 1));
ast::Module m;
auto var =
std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &mat);
m.AddGlobalVariable(std::move(var));
// Register the global
EXPECT_TRUE(td()->Determine(&m));
ast::ArrayAccessorExpression acc(
std::make_unique<ast::ArrayAccessorExpression>(
std::make_unique<ast::IdentifierExpression>("my_var"),
std::move(idx1)),
std::move(idx2));
EXPECT_TRUE(td()->DetermineResultType(&acc));
ASSERT_NE(acc.result_type(), nullptr);
EXPECT_TRUE(acc.result_type()->IsF32());
}
TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Vector) {
ast::type::I32Type i32;
ast::type::F32Type f32;
ast::type::VectorType vec(&f32, 3);
auto idx = std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::IntLiteral>(&i32, 2));
ast::Module m;
auto var =
std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &vec);
m.AddGlobalVariable(std::move(var));
// Register the global
EXPECT_TRUE(td()->Determine(&m));
ast::ArrayAccessorExpression acc(
std::make_unique<ast::IdentifierExpression>("my_var"), std::move(idx));
EXPECT_TRUE(td()->DetermineResultType(&acc));
ASSERT_NE(acc.result_type(), nullptr);
EXPECT_TRUE(acc.result_type()->IsF32());
}
TEST_F(TypeDeterminerTest, Expr_Constructor_Scalar) {
ast::type::F32Type f32;
ast::ScalarConstructorExpression s(