Add type determination for member accessor.
This Cl adds the member accessor type determination for both structures
and vector swizzles.
Bug: tint:5
Change-Id: I1172db29d8cbed2d9e0ae228ebc3a818d4930b7f
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/18846
Reviewed-by: David Neto <dneto@google.com>
diff --git a/src/type_determiner.cc b/src/type_determiner.cc
index f1da09c..9a81e19 100644
--- a/src/type_determiner.cc
+++ b/src/type_determiner.cc
@@ -28,12 +28,14 @@
#include "src/ast/identifier_expression.h"
#include "src/ast/if_statement.h"
#include "src/ast/loop_statement.h"
+#include "src/ast/member_accessor_expression.h"
#include "src/ast/regardless_statement.h"
#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/struct_type.h"
#include "src/ast/type/vector_type.h"
#include "src/ast/type_constructor_expression.h"
#include "src/ast/unless_statement.h"
@@ -41,7 +43,10 @@
namespace tint {
-TypeDeterminer::TypeDeterminer(Context* ctx) : ctx_(*ctx) {}
+TypeDeterminer::TypeDeterminer(Context* ctx) : ctx_(*ctx) {
+ // TODO(dsinclair): Temporary usage to avoid compiler warning
+ static_cast<void>(ctx_.type_mgr());
+}
TypeDeterminer::~TypeDeterminer() = default;
@@ -174,15 +179,6 @@
return false;
}
-bool TypeDeterminer::DetermineResultType(const ast::ExpressionList& exprs) {
- for (const auto& expr : exprs) {
- if (!DetermineResultType(expr.get())) {
- return false;
- }
- }
- return true;
-}
-
bool TypeDeterminer::DetermineResultType(ast::Expression* expr) {
// This is blindly called above, so in some cases the expression won't exist.
if (!expr) {
@@ -207,6 +203,9 @@
if (expr->IsIdentifier()) {
return DetermineIdentifier(expr->AsIdentifier());
}
+ if (expr->IsMemberAccessor()) {
+ return DetermineMemberAccessor(expr->AsMemberAccessor());
+ }
error_ = "unknown expression for type determination";
return false;
@@ -242,9 +241,6 @@
if (!DetermineResultType(expr->func())) {
return false;
}
- if (!DetermineResultType(expr->params())) {
- return false;
- }
expr->set_result_type(expr->func()->result_type());
return true;
}
@@ -283,7 +279,45 @@
return true;
}
- error_ = "unknown identifier for type determination";
+ return true;
+}
+
+bool TypeDeterminer::DetermineMemberAccessor(
+ ast::MemberAccessorExpression* expr) {
+ if (!DetermineResultType(expr->structure())) {
+ return false;
+ }
+
+ auto data_type = expr->structure()->result_type();
+ if (data_type->IsStruct()) {
+ auto strct = data_type->AsStruct()->impl();
+ auto name = expr->member()->name()[0];
+
+ for (const auto& member : strct->members()) {
+ if (member->name() != name) {
+ continue;
+ }
+
+ expr->set_result_type(member->type());
+ return true;
+ }
+
+ error_ = "struct member not found";
+ return false;
+ }
+ if (data_type->IsVector()) {
+ auto vec = data_type->AsVector();
+
+ // The vector will have a number of components equal to the length of the
+ // swizzle. This assumes the validator will check that the swizzle
+ // is correct.
+ expr->set_result_type(
+ ctx_.type_mgr().Get(std::make_unique<ast::type::VectorType>(
+ vec->type(), expr->member()->name()[0].size())));
+ return true;
+ }
+
+ error_ = "invalid type in member accessor";
return false;
}