Add type determination for IdentifierExpression.
This CL adds the type determination for identifier expressions. Namespaced identifiers are not determined yet. Bug: tint:5 Change-Id: Id8f39ad122cef0349393de4d429a6d971b2a7ce8 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/18841 Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
ca893e3200
commit
cab0e73b31
|
@ -19,6 +19,7 @@
|
||||||
#include "src/ast/case_statement.h"
|
#include "src/ast/case_statement.h"
|
||||||
#include "src/ast/continue_statement.h"
|
#include "src/ast/continue_statement.h"
|
||||||
#include "src/ast/else_statement.h"
|
#include "src/ast/else_statement.h"
|
||||||
|
#include "src/ast/identifier_expression.h"
|
||||||
#include "src/ast/if_statement.h"
|
#include "src/ast/if_statement.h"
|
||||||
#include "src/ast/loop_statement.h"
|
#include "src/ast/loop_statement.h"
|
||||||
#include "src/ast/regardless_statement.h"
|
#include "src/ast/regardless_statement.h"
|
||||||
|
@ -176,6 +177,9 @@ bool TypeDeterminer::DetermineResultType(ast::Expression* expr) {
|
||||||
if (expr->IsConstructor()) {
|
if (expr->IsConstructor()) {
|
||||||
return DetermineConstructor(expr->AsConstructor());
|
return DetermineConstructor(expr->AsConstructor());
|
||||||
}
|
}
|
||||||
|
if (expr->IsIdentifier()) {
|
||||||
|
return DetermineIdentifier(expr->AsIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
error_ = "unknown expression for type determination";
|
error_ = "unknown expression for type determination";
|
||||||
return false;
|
return false;
|
||||||
|
@ -190,4 +194,28 @@ bool TypeDeterminer::DetermineConstructor(ast::ConstructorExpression* expr) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TypeDeterminer::DetermineIdentifier(ast::IdentifierExpression* expr) {
|
||||||
|
if (expr->name().size() > 1) {
|
||||||
|
// TODO(dsinclair): Handle imports
|
||||||
|
error_ = "imports not handled in type determination";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto name = expr->name()[0];
|
||||||
|
ast::Variable* var;
|
||||||
|
if (variable_stack_.get(name, &var)) {
|
||||||
|
expr->set_result_type(var->type());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto iter = name_to_function_.find(name);
|
||||||
|
if (iter != name_to_function_.end()) {
|
||||||
|
expr->set_result_type(iter->second->return_type());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_ = "unknown identifier for type determination";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
class ConstructorExpression;
|
class ConstructorExpression;
|
||||||
|
class IdentifierExpression;
|
||||||
class Function;
|
class Function;
|
||||||
class Variable;
|
class Variable;
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ class TypeDeterminer {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool DetermineConstructor(ast::ConstructorExpression* expr);
|
bool DetermineConstructor(ast::ConstructorExpression* expr);
|
||||||
|
bool DetermineIdentifier(ast::IdentifierExpression* expr);
|
||||||
Context& ctx_;
|
Context& ctx_;
|
||||||
std::string error_;
|
std::string error_;
|
||||||
ScopeStack<ast::Variable*> variable_stack_;
|
ScopeStack<ast::Variable*> variable_stack_;
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "src/ast/continue_statement.h"
|
#include "src/ast/continue_statement.h"
|
||||||
#include "src/ast/else_statement.h"
|
#include "src/ast/else_statement.h"
|
||||||
#include "src/ast/float_literal.h"
|
#include "src/ast/float_literal.h"
|
||||||
|
#include "src/ast/identifier_expression.h"
|
||||||
#include "src/ast/if_statement.h"
|
#include "src/ast/if_statement.h"
|
||||||
#include "src/ast/int_literal.h"
|
#include "src/ast/int_literal.h"
|
||||||
#include "src/ast/loop_statement.h"
|
#include "src/ast/loop_statement.h"
|
||||||
|
@ -406,5 +407,64 @@ TEST_F(TypeDeterminerTest, Expr_Constructor_Type) {
|
||||||
EXPECT_EQ(tc.result_type()->AsVector()->size(), 3);
|
EXPECT_EQ(tc.result_type()->AsVector()->size(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalVariable) {
|
||||||
|
ast::type::F32Type f32;
|
||||||
|
|
||||||
|
ast::Module m;
|
||||||
|
auto var =
|
||||||
|
std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone, &f32);
|
||||||
|
m.AddGlobalVariable(std::move(var));
|
||||||
|
|
||||||
|
// Register the global
|
||||||
|
EXPECT_TRUE(td()->Determine(&m));
|
||||||
|
|
||||||
|
ast::IdentifierExpression ident("my_var");
|
||||||
|
EXPECT_TRUE(td()->DetermineResultType(&ident));
|
||||||
|
ASSERT_NE(ident.result_type(), nullptr);
|
||||||
|
EXPECT_TRUE(ident.result_type()->IsF32());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable) {
|
||||||
|
ast::type::F32Type f32;
|
||||||
|
|
||||||
|
auto my_var = std::make_unique<ast::IdentifierExpression>("my_var");
|
||||||
|
auto my_var_ptr = my_var.get();
|
||||||
|
|
||||||
|
ast::StatementList body;
|
||||||
|
body.push_back(std::make_unique<ast::VariableDeclStatement>(
|
||||||
|
std::make_unique<ast::Variable>("my_var", ast::StorageClass::kNone,
|
||||||
|
&f32)));
|
||||||
|
|
||||||
|
body.push_back(std::make_unique<ast::AssignmentStatement>(
|
||||||
|
std::move(my_var),
|
||||||
|
std::make_unique<ast::IdentifierExpression>("my_var")));
|
||||||
|
|
||||||
|
ast::Function f("my_func", {}, &f32);
|
||||||
|
f.set_body(std::move(body));
|
||||||
|
|
||||||
|
EXPECT_TRUE(td()->DetermineFunction(&f));
|
||||||
|
|
||||||
|
ASSERT_NE(my_var_ptr->result_type(), nullptr);
|
||||||
|
EXPECT_TRUE(my_var_ptr->result_type()->IsF32());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TypeDeterminerTest, Expr_Identifier_Function) {
|
||||||
|
ast::type::F32Type f32;
|
||||||
|
|
||||||
|
ast::VariableList params;
|
||||||
|
auto func =
|
||||||
|
std::make_unique<ast::Function>("my_func", std::move(params), &f32);
|
||||||
|
ast::Module m;
|
||||||
|
m.AddFunction(std::move(func));
|
||||||
|
|
||||||
|
// Register the function
|
||||||
|
EXPECT_TRUE(td()->Determine(&m));
|
||||||
|
|
||||||
|
ast::IdentifierExpression ident("my_func");
|
||||||
|
EXPECT_TRUE(td()->DetermineResultType(&ident));
|
||||||
|
ASSERT_NE(ident.result_type(), nullptr);
|
||||||
|
EXPECT_TRUE(ident.result_type()->IsF32());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
Loading…
Reference in New Issue