Better type determiner errors.
This CL adds the source info into the type determiner errors so they will include line and column number if available. If the line number is 0 then it's considered the source info is missing and it is not emitted. Add line and colummn to type determiner errors Change-Id: I18764a71db80082fd31c8509c5e9b193800f1d95 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/19105 Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
d5dea224e0
commit
7456f4258a
|
@ -49,13 +49,19 @@
|
|||
|
||||
namespace tint {
|
||||
|
||||
TypeDeterminer::TypeDeterminer(Context* ctx) : ctx_(*ctx) {
|
||||
// TODO(dsinclair): Temporary usage to avoid compiler warning
|
||||
static_cast<void>(ctx_.type_mgr());
|
||||
}
|
||||
TypeDeterminer::TypeDeterminer(Context* ctx) : ctx_(*ctx) {}
|
||||
|
||||
TypeDeterminer::~TypeDeterminer() = default;
|
||||
|
||||
void TypeDeterminer::set_error(const Source& src, const std::string& msg) {
|
||||
error_ = "";
|
||||
if (src.line > 0) {
|
||||
error_ +=
|
||||
std::to_string(src.line) + ":" + std::to_string(src.column) + ": ";
|
||||
}
|
||||
error_ += msg;
|
||||
}
|
||||
|
||||
bool TypeDeterminer::Determine(ast::Module* mod) {
|
||||
for (const auto& var : mod->global_variables()) {
|
||||
variable_stack_.set_global(var->name(), var.get());
|
||||
|
@ -209,7 +215,7 @@ bool TypeDeterminer::DetermineResultType(ast::Statement* stmt) {
|
|||
return DetermineResultType(v->variable()->constructor());
|
||||
}
|
||||
|
||||
error_ = "unknown statement type for type determination";
|
||||
set_error(stmt->source(), "unknown statement type for type determination");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -253,7 +259,7 @@ bool TypeDeterminer::DetermineResultType(ast::Expression* expr) {
|
|||
return DetermineUnaryOp(expr->AsUnaryOp());
|
||||
}
|
||||
|
||||
error_ = "unknown expression for type determination";
|
||||
set_error(expr->source(), "unknown expression for type determination");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -272,7 +278,7 @@ bool TypeDeterminer::DetermineArrayAccessor(
|
|||
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";
|
||||
set_error(expr->source(), "invalid parent type in array accessor");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -308,7 +314,7 @@ bool TypeDeterminer::DetermineConstructor(ast::ConstructorExpression* expr) {
|
|||
bool TypeDeterminer::DetermineIdentifier(ast::IdentifierExpression* expr) {
|
||||
if (expr->name().size() > 1) {
|
||||
// TODO(dsinclair): Handle imports
|
||||
error_ = "imports not handled in type determination";
|
||||
set_error(expr->source(), "imports not handled in type determination");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -348,7 +354,7 @@ bool TypeDeterminer::DetermineMemberAccessor(
|
|||
return true;
|
||||
}
|
||||
|
||||
error_ = "struct member not found";
|
||||
set_error(expr->source(), "struct member not found");
|
||||
return false;
|
||||
}
|
||||
if (data_type->IsVector()) {
|
||||
|
@ -363,7 +369,7 @@ bool TypeDeterminer::DetermineMemberAccessor(
|
|||
return true;
|
||||
}
|
||||
|
||||
error_ = "invalid type in member accessor";
|
||||
set_error(expr->source(), "invalid type in member accessor");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -470,7 +476,7 @@ bool TypeDeterminer::DetermineUnaryMethod(ast::UnaryMethodExpression* expr) {
|
|||
case ast::UnaryMethod::kIsFinite:
|
||||
case ast::UnaryMethod::kIsNormal: {
|
||||
if (expr->params().empty()) {
|
||||
error_ = "incorrect number of parameters";
|
||||
set_error(expr->source(), "incorrect number of parameters");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -493,13 +499,14 @@ bool TypeDeterminer::DetermineUnaryMethod(ast::UnaryMethodExpression* expr) {
|
|||
}
|
||||
case ast::UnaryMethod::kOuterProduct: {
|
||||
if (expr->params().size() != 2) {
|
||||
error_ = "incorrect number of parameters for outer product";
|
||||
set_error(expr->source(),
|
||||
"incorrect number of parameters for outer product");
|
||||
return false;
|
||||
}
|
||||
auto param0_type = expr->params()[0]->result_type();
|
||||
auto param1_type = expr->params()[1]->result_type();
|
||||
if (!param0_type->IsVector() || !param1_type->IsVector()) {
|
||||
error_ = "invalid parameter type for outer product";
|
||||
set_error(expr->source(), "invalid parameter type for outer product");
|
||||
return false;
|
||||
}
|
||||
expr->set_result_type(
|
||||
|
|
|
@ -83,6 +83,8 @@ class TypeDeterminer {
|
|||
bool DetermineVariableStorageClass(ast::Statement* stmt);
|
||||
|
||||
private:
|
||||
void set_error(const Source& src, const std::string& msg);
|
||||
|
||||
bool DetermineArrayAccessor(ast::ArrayAccessorExpression* expr);
|
||||
bool DetermineAs(ast::AsExpression* expr);
|
||||
bool DetermineBinary(ast::BinaryExpression* expr);
|
||||
|
|
|
@ -58,6 +58,18 @@
|
|||
namespace tint {
|
||||
namespace {
|
||||
|
||||
class FakeStmt : public ast::Statement {
|
||||
public:
|
||||
bool IsValid() const override { return true; }
|
||||
void to_str(std::ostream&, size_t) const override {}
|
||||
};
|
||||
|
||||
class FakeExpr : public ast::Expression {
|
||||
public:
|
||||
bool IsValid() const override { return true; }
|
||||
void to_str(std::ostream&, size_t) const override {}
|
||||
};
|
||||
|
||||
class TypeDeterminerTest : public testing::Test {
|
||||
public:
|
||||
void SetUp() { td_ = std::make_unique<TypeDeterminer>(&ctx_); }
|
||||
|
@ -69,6 +81,23 @@ class TypeDeterminerTest : public testing::Test {
|
|||
std::unique_ptr<TypeDeterminer> td_;
|
||||
};
|
||||
|
||||
TEST_F(TypeDeterminerTest, Error_WithEmptySource) {
|
||||
FakeStmt s;
|
||||
s.set_source(Source{0, 0});
|
||||
|
||||
EXPECT_FALSE(td()->DetermineResultType(&s));
|
||||
EXPECT_EQ(td()->error(), "unknown statement type for type determination");
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Stmt_Error_Unknown) {
|
||||
FakeStmt s;
|
||||
s.set_source(Source{2, 30});
|
||||
|
||||
EXPECT_FALSE(td()->DetermineResultType(&s));
|
||||
EXPECT_EQ(td()->error(),
|
||||
"2:30: unknown statement type for type determination");
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Stmt_Assign) {
|
||||
ast::type::F32Type f32;
|
||||
ast::type::I32Type i32;
|
||||
|
@ -410,6 +439,14 @@ TEST_F(TypeDeterminerTest, Stmt_VariableDecl) {
|
|||
EXPECT_TRUE(init_ptr->result_type()->IsI32());
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Expr_Error_Unknown) {
|
||||
FakeExpr e;
|
||||
e.set_source(Source{2, 30});
|
||||
|
||||
EXPECT_FALSE(td()->DetermineResultType(&e));
|
||||
EXPECT_EQ(td()->error(), "2:30: unknown expression for type determination");
|
||||
}
|
||||
|
||||
TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array) {
|
||||
ast::type::I32Type i32;
|
||||
ast::type::F32Type f32;
|
||||
|
|
Loading…
Reference in New Issue