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>
diff --git a/src/type_determiner.cc b/src/type_determiner.cc
index aa1c58e..4ccdbb4 100644
--- a/src/type_determiner.cc
+++ b/src/type_determiner.cc
@@ -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 @@
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 @@
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 @@
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::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 @@
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 @@
return true;
}
- error_ = "invalid type in member accessor";
+ set_error(expr->source(), "invalid type in member accessor");
return false;
}
@@ -470,7 +476,7 @@
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 @@
}
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(
diff --git a/src/type_determiner.h b/src/type_determiner.h
index 1870b4c..8f50a9e 100644
--- a/src/type_determiner.h
+++ b/src/type_determiner.h
@@ -83,6 +83,8 @@
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);
diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc
index 1fe0895..98997fc 100644
--- a/src/type_determiner_test.cc
+++ b/src/type_determiner_test.cc
@@ -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 @@
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 @@
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;