From b7edc4c765da66c20ad142190efdaf12c8453cb0 Mon Sep 17 00:00:00 2001 From: dan sinclair Date: Tue, 7 Apr 2020 12:46:30 +0000 Subject: [PATCH] Add type determination for constructors. This CL adds type determination for the ScalarConstructorExpression and TypeConstructorExpression. Bug: tint:5 Change-Id: I46299140785eb420c3801de470d6423c25e9c700 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/18827 Reviewed-by: David Neto --- src/CMakeLists.txt | 1 + src/type_determiner.cc | 16 ++++++++ src/type_determiner.h | 3 ++ src/type_determiner_test.cc | 74 +++++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+) create mode 100644 src/type_determiner_test.cc diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 60cfea05a4..f6fcaa5a3c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -308,6 +308,7 @@ set(TINT_TEST_SRCS ast/variable_decl_statement_test.cc ast/variable_test.cc scope_stack_test.cc + type_determiner_test.cc type_manager_test.cc validator_impl_import_test.cc ) diff --git a/src/type_determiner.cc b/src/type_determiner.cc index 4e8a0465f5..c911281991 100644 --- a/src/type_determiner.cc +++ b/src/type_determiner.cc @@ -14,6 +14,9 @@ #include "src/type_determiner.h" +#include "src/ast/scalar_constructor_expression.h" +#include "src/ast/type_constructor_expression.h" + namespace tint { TypeDeterminer::TypeDeterminer(Context* ctx) : ctx_(*ctx) { @@ -77,8 +80,21 @@ bool TypeDeterminer::DetermineResultType(ast::Expression* expr) { return true; } + if (expr->IsConstructor()) { + return DetermineConstructor(expr->AsConstructor()); + } + error_ = "unknown expression for type determination"; return false; } +bool TypeDeterminer::DetermineConstructor(ast::ConstructorExpression* expr) { + if (expr->IsTypeConstructor()) { + expr->set_result_type(expr->AsTypeConstructor()->type()); + } else { + expr->set_result_type(expr->AsScalarConstructor()->literal()->type()); + } + return true; +} + } // namespace tint diff --git a/src/type_determiner.h b/src/type_determiner.h index 2bfba85798..f8d8388ac4 100644 --- a/src/type_determiner.h +++ b/src/type_determiner.h @@ -25,6 +25,7 @@ namespace tint { namespace ast { +class ConstructorExpression; class Function; class Variable; @@ -67,6 +68,8 @@ class TypeDeterminer { bool DetermineResultType(ast::Expression* expr); private: + bool DetermineConstructor(ast::ConstructorExpression* expr); + Context& ctx_; std::string error_; ScopeStack variable_stack_; diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc new file mode 100644 index 0000000000..49a9c89d1d --- /dev/null +++ b/src/type_determiner_test.cc @@ -0,0 +1,74 @@ +// Copyright 2020 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/type_determiner.h" + +#include +#include + +#include "gtest/gtest.h" +#include "src/ast/float_literal.h" +#include "src/ast/int_literal.h" +#include "src/ast/scalar_constructor_expression.h" +#include "src/ast/type/f32_type.h" +#include "src/ast/type/vector_type.h" +#include "src/ast/type_constructor_expression.h" + +namespace tint { +namespace { + +class TypeDeterminerTest : public testing::Test { + public: + void SetUp() { td_ = std::make_unique(&ctx_); } + + TypeDeterminer* td() const { return td_.get(); } + + private: + Context ctx_; + std::unique_ptr td_; +}; + +TEST_F(TypeDeterminerTest, Expr_Constructor_Scalar) { + ast::type::F32Type f32; + ast::ScalarConstructorExpression s( + std::make_unique(&f32, 1.0f)); + + EXPECT_TRUE(td()->DetermineResultType(&s)); + ASSERT_NE(s.result_type(), nullptr); + EXPECT_TRUE(s.result_type()->IsF32()); +} + +TEST_F(TypeDeterminerTest, Expr_Constructor_Type) { + ast::type::F32Type f32; + ast::type::VectorType vec(&f32, 3); + + ast::ExpressionList vals; + vals.push_back(std::make_unique( + std::make_unique(&f32, 1.0f))); + vals.push_back(std::make_unique( + std::make_unique(&f32, 1.0f))); + vals.push_back(std::make_unique( + std::make_unique(&f32, 3.0f))); + + ast::TypeConstructorExpression tc(&vec, std::move(vals)); + + EXPECT_TRUE(td()->DetermineResultType(&tc)); + ASSERT_NE(tc.result_type(), nullptr); + ASSERT_TRUE(tc.result_type()->IsVector()); + EXPECT_TRUE(tc.result_type()->AsVector()->type()->IsF32()); + EXPECT_EQ(tc.result_type()->AsVector()->size(), 3); +} + +} // namespace +} // namespace tint