mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-10 22:17:51 +00:00
Diagnostics: Add error code to the Diagnostic
Allows this to be formatted similarly to the severity. Change-Id: I74cd863d8f1d94089ce753ab76a2c70784eb5553 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/33938 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
committed by
Commit Bot service account
parent
61ec48b99e
commit
f32a3c1f35
@@ -61,7 +61,7 @@ TEST_F(ValidateControlBlockTest, SwitchSelectorExpressionNoneIntegerType_Fail) {
|
||||
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
|
||||
EXPECT_FALSE(v()->ValidateStatements(block));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0025: switch statement selector expression must be "
|
||||
"12:34 v-0025: switch statement selector expression must be "
|
||||
"of a scalar integer type");
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ TEST_F(ValidateControlBlockTest, SwitchWithoutDefault_Fail) {
|
||||
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
|
||||
EXPECT_FALSE(v()->ValidateStatements(block));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0008: switch statement must have exactly one default "
|
||||
"12:34 v-0008: switch statement must have exactly one default "
|
||||
"clause");
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ TEST_F(ValidateControlBlockTest, SwitchWithTwoDefault_Fail) {
|
||||
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
|
||||
EXPECT_FALSE(v()->ValidateStatements(block));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0008: switch statement must have exactly one default "
|
||||
"12:34 v-0008: switch statement must have exactly one default "
|
||||
"clause");
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ TEST_F(ValidateControlBlockTest,
|
||||
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
|
||||
EXPECT_FALSE(v()->ValidateStatements(block));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0026: the case selector values must have the same "
|
||||
"12:34 v-0026: the case selector values must have the same "
|
||||
"type as the selector expression.");
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ TEST_F(ValidateControlBlockTest,
|
||||
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
|
||||
EXPECT_FALSE(v()->ValidateStatements(block));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0026: the case selector values must have the same "
|
||||
"12:34 v-0026: the case selector values must have the same "
|
||||
"type as the selector expression.");
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ TEST_F(ValidateControlBlockTest, NonUniqueCaseSelectorValueUint_Fail) {
|
||||
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
|
||||
EXPECT_FALSE(v()->ValidateStatements(block));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0027: a literal value must not appear more than once "
|
||||
"12:34 v-0027: a literal value must not appear more than once "
|
||||
"in the case selectors for a switch statement: '2'");
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ TEST_F(ValidateControlBlockTest, NonUniqueCaseSelectorValueSint_Fail) {
|
||||
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
|
||||
EXPECT_FALSE(v()->ValidateStatements(block));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0027: a literal value must not appear more than once in "
|
||||
"12:34 v-0027: a literal value must not appear more than once in "
|
||||
"the case selectors for a switch statement: '10'");
|
||||
}
|
||||
|
||||
@@ -317,7 +317,7 @@ TEST_F(ValidateControlBlockTest, LastClauseLastStatementIsFallthrough_Fail) {
|
||||
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
|
||||
EXPECT_FALSE(v()->ValidateStatements(block));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0028: a fallthrough statement must not appear as the "
|
||||
"12:34 v-0028: a fallthrough statement must not appear as the "
|
||||
"last statement in last clause of a switch");
|
||||
}
|
||||
|
||||
|
||||
@@ -92,9 +92,8 @@ TEST_F(ValidateFunctionTest, FunctionEndWithoutReturnStatement_Fail) {
|
||||
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
EXPECT_FALSE(v()->Validate(mod()));
|
||||
EXPECT_EQ(
|
||||
v()->error(),
|
||||
"12:34: v-0002: non-void function must end with a return statement");
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34 v-0002: non-void function must end with a return statement");
|
||||
}
|
||||
|
||||
TEST_F(ValidateFunctionTest, FunctionEndWithoutReturnStatementEmptyBody_Fail) {
|
||||
@@ -109,9 +108,8 @@ TEST_F(ValidateFunctionTest, FunctionEndWithoutReturnStatementEmptyBody_Fail) {
|
||||
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
EXPECT_FALSE(v()->Validate(mod()));
|
||||
EXPECT_EQ(
|
||||
v()->error(),
|
||||
"12:34: v-0002: non-void function must end with a return statement");
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34 v-0002: non-void function must end with a return statement");
|
||||
}
|
||||
|
||||
TEST_F(ValidateFunctionTest, FunctionTypeMustMatchReturnStatementType_Pass) {
|
||||
@@ -149,7 +147,7 @@ TEST_F(ValidateFunctionTest, FunctionTypeMustMatchReturnStatementType_fail) {
|
||||
EXPECT_FALSE(v()->Validate(mod()));
|
||||
// TODO(sarahM0): replace 000y with a rule number
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-000y: return statement type must match its function "
|
||||
"12:34 v-000y: return statement type must match its function "
|
||||
"return type, returned '__i32', expected '__void'");
|
||||
}
|
||||
|
||||
@@ -171,7 +169,7 @@ TEST_F(ValidateFunctionTest, FunctionTypeMustMatchReturnStatementTypeF32_fail) {
|
||||
EXPECT_FALSE(v()->Validate(mod()));
|
||||
// TODO(sarahM0): replace 000y with a rule number
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-000y: return statement type must match its function "
|
||||
"12:34 v-000y: return statement type must match its function "
|
||||
"return type, returned '__i32', expected '__f32'");
|
||||
}
|
||||
|
||||
@@ -203,8 +201,7 @@ TEST_F(ValidateFunctionTest, FunctionNamesMustBeUnique_fail) {
|
||||
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
EXPECT_FALSE(v()->Validate(mod()));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0016: function names must be unique 'func'");
|
||||
EXPECT_EQ(v()->error(), "12:34 v-0016: function names must be unique 'func'");
|
||||
}
|
||||
|
||||
TEST_F(ValidateFunctionTest, RecursionIsNotAllowed_Fail) {
|
||||
@@ -224,7 +221,7 @@ TEST_F(ValidateFunctionTest, RecursionIsNotAllowed_Fail) {
|
||||
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
EXPECT_FALSE(v()->Validate(mod())) << v()->error();
|
||||
EXPECT_EQ(v()->error(), "12:34: v-0004: recursion is not allowed: 'func'");
|
||||
EXPECT_EQ(v()->error(), "12:34 v-0004: recursion is not allowed: 'func'");
|
||||
}
|
||||
|
||||
TEST_F(ValidateFunctionTest, RecursionIsNotAllowedExpr_Fail) {
|
||||
@@ -248,7 +245,7 @@ TEST_F(ValidateFunctionTest, RecursionIsNotAllowedExpr_Fail) {
|
||||
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
EXPECT_FALSE(v()->Validate(mod())) << v()->error();
|
||||
EXPECT_EQ(v()->error(), "12:34: v-0004: recursion is not allowed: 'func'");
|
||||
EXPECT_EQ(v()->error(), "12:34 v-0004: recursion is not allowed: 'func'");
|
||||
}
|
||||
|
||||
TEST_F(ValidateFunctionTest, Function_WithPipelineStage_NotVoid_Fail) {
|
||||
@@ -270,7 +267,7 @@ TEST_F(ValidateFunctionTest, Function_WithPipelineStage_NotVoid_Fail) {
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
EXPECT_FALSE(v()->Validate(mod()));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0024: Entry point function must return void: 'vtx_main'");
|
||||
"12:34 v-0024: Entry point function must return void: 'vtx_main'");
|
||||
}
|
||||
|
||||
TEST_F(ValidateFunctionTest, Function_WithPipelineStage_WithParams_Fail) {
|
||||
@@ -291,7 +288,7 @@ TEST_F(ValidateFunctionTest, Function_WithPipelineStage_WithParams_Fail) {
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
EXPECT_FALSE(v()->Validate(mod()));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0023: Entry point function must accept no parameters: "
|
||||
"12:34 v-0023: Entry point function must accept no parameters: "
|
||||
"'vtx_func'");
|
||||
}
|
||||
|
||||
@@ -314,7 +311,7 @@ TEST_F(ValidateFunctionTest, PipelineStage_MustBeUnique_Fail) {
|
||||
EXPECT_FALSE(v()->Validate(mod()));
|
||||
EXPECT_EQ(
|
||||
v()->error(),
|
||||
"12:34: v-0020: only one stage decoration permitted per entry point");
|
||||
"12:34 v-0020: only one stage decoration permitted per entry point");
|
||||
}
|
||||
|
||||
TEST_F(ValidateFunctionTest, OnePipelineStageFunctionMustBePresent_Pass) {
|
||||
|
||||
@@ -39,6 +39,17 @@ ValidatorImpl::ValidatorImpl() = default;
|
||||
|
||||
ValidatorImpl::~ValidatorImpl() = default;
|
||||
|
||||
void ValidatorImpl::add_error(const Source& src,
|
||||
const char* code,
|
||||
const std::string& msg) {
|
||||
diag::Diagnostic diag;
|
||||
diag.severity = diag::Severity::Error;
|
||||
diag.source = src;
|
||||
diag.message = msg;
|
||||
diag.code = code;
|
||||
diags_.add(std::move(diag));
|
||||
}
|
||||
|
||||
void ValidatorImpl::add_error(const Source& src, const std::string& msg) {
|
||||
diag::Diagnostic diag;
|
||||
diag.severity = diag::Severity::Error;
|
||||
@@ -79,15 +90,15 @@ bool ValidatorImpl::ValidateConstructedTypes(
|
||||
auto* r = member->type()->UnwrapAll()->AsArray();
|
||||
if (r->IsRuntimeArray()) {
|
||||
if (member != st->impl()->members().back()) {
|
||||
add_error(member->source(),
|
||||
"v-0015: runtime arrays may only appear as the last "
|
||||
add_error(member->source(), "v-0015",
|
||||
"runtime arrays may only appear as the last "
|
||||
"member of a struct: '" +
|
||||
member->name() + "'");
|
||||
return false;
|
||||
}
|
||||
if (!st->IsBlockDecorated()) {
|
||||
add_error(member->source(),
|
||||
"v-0031: a struct containing a runtime-sized array "
|
||||
add_error(member->source(), "v-0031",
|
||||
"a struct containing a runtime-sized array "
|
||||
"must be in the 'storage' storage class: '" +
|
||||
st->name() + "'");
|
||||
return false;
|
||||
@@ -104,19 +115,19 @@ bool ValidatorImpl::ValidateGlobalVariables(
|
||||
const ast::VariableList& global_vars) {
|
||||
for (auto* var : global_vars) {
|
||||
if (variable_stack_.has(var->name())) {
|
||||
add_error(var->source(),
|
||||
"v-0011: redeclared global identifier '" + var->name() + "'");
|
||||
add_error(var->source(), "v-0011",
|
||||
"redeclared global identifier '" + var->name() + "'");
|
||||
return false;
|
||||
}
|
||||
if (!var->is_const() && var->storage_class() == ast::StorageClass::kNone) {
|
||||
add_error(var->source(),
|
||||
"v-0022: global variables must have a storage class");
|
||||
add_error(var->source(), "v-0022",
|
||||
"global variables must have a storage class");
|
||||
return false;
|
||||
}
|
||||
if (var->is_const() &&
|
||||
!(var->storage_class() == ast::StorageClass::kNone)) {
|
||||
add_error(var->source(),
|
||||
"v-global01: global constants shouldn't have a storage class");
|
||||
add_error(var->source(), "v-global01",
|
||||
"global constants shouldn't have a storage class");
|
||||
return false;
|
||||
}
|
||||
variable_stack_.set_global(var->name(), var);
|
||||
@@ -127,8 +138,8 @@ bool ValidatorImpl::ValidateGlobalVariables(
|
||||
bool ValidatorImpl::ValidateFunctions(const ast::FunctionList& funcs) {
|
||||
for (auto* func : funcs) {
|
||||
if (function_stack_.has(func->name())) {
|
||||
add_error(func->source(),
|
||||
"v-0016: function names must be unique '" + func->name() + "'");
|
||||
add_error(func->source(), "v-0016",
|
||||
"function names must be unique '" + func->name() + "'");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -149,16 +160,16 @@ bool ValidatorImpl::ValidateEntryPoint(const ast::FunctionList& funcs) {
|
||||
if (func->IsEntryPoint()) {
|
||||
shader_is_present = true;
|
||||
if (!func->params().empty()) {
|
||||
add_error(func->source(),
|
||||
"v-0023: Entry point function must accept no parameters: '" +
|
||||
add_error(func->source(), "v-0023",
|
||||
"Entry point function must accept no parameters: '" +
|
||||
func->name() + "'");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!func->return_type()->IsVoid()) {
|
||||
add_error(func->source(),
|
||||
"v-0024: Entry point function must return void: '" +
|
||||
func->name() + "'");
|
||||
add_error(
|
||||
func->source(), "v-0024",
|
||||
"Entry point function must return void: '" + func->name() + "'");
|
||||
return false;
|
||||
}
|
||||
auto stage_deco_count = 0;
|
||||
@@ -168,16 +179,15 @@ bool ValidatorImpl::ValidateEntryPoint(const ast::FunctionList& funcs) {
|
||||
}
|
||||
}
|
||||
if (stage_deco_count > 1) {
|
||||
add_error(
|
||||
func->source(),
|
||||
"v-0020: only one stage decoration permitted per entry point");
|
||||
add_error(func->source(), "v-0020",
|
||||
"only one stage decoration permitted per entry point");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!shader_is_present) {
|
||||
add_error(Source{},
|
||||
"v-0003: At least one of vertex, fragment or compute shader must "
|
||||
add_error(Source{}, "v-0003",
|
||||
"At least one of vertex, fragment or compute shader must "
|
||||
"be present");
|
||||
return false;
|
||||
}
|
||||
@@ -198,8 +208,8 @@ bool ValidatorImpl::ValidateFunction(const ast::Function* func) {
|
||||
if (!current_function_->return_type()->IsVoid()) {
|
||||
if (!func->get_last_statement() ||
|
||||
!func->get_last_statement()->IsReturn()) {
|
||||
add_error(func->source(),
|
||||
"v-0002: non-void function must end with a return statement");
|
||||
add_error(func->source(), "v-0002",
|
||||
"non-void function must end with a return statement");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -216,8 +226,8 @@ bool ValidatorImpl::ValidateReturnStatement(const ast::ReturnStatement* ret) {
|
||||
ret->has_value() ? ret->value()->result_type()->UnwrapAll() : &void_type;
|
||||
|
||||
if (func_type->type_name() != ret_type->type_name()) {
|
||||
add_error(ret->source(),
|
||||
"v-000y: return statement type must match its function return "
|
||||
add_error(ret->source(), "v-000y",
|
||||
"return statement type must match its function return "
|
||||
"type, returned '" +
|
||||
ret_type->type_name() + "', expected '" +
|
||||
func_type->type_name() + "'");
|
||||
@@ -244,19 +254,19 @@ bool ValidatorImpl::ValidateDeclStatement(
|
||||
auto name = decl->variable()->name();
|
||||
bool is_global = false;
|
||||
if (variable_stack_.get(name, nullptr, &is_global)) {
|
||||
std::string error_number = "v-0014: ";
|
||||
const char* error_code = "v-0014";
|
||||
if (is_global) {
|
||||
error_number = "v-0013: ";
|
||||
error_code = "v-0013";
|
||||
}
|
||||
add_error(decl->source(),
|
||||
error_number + "redeclared identifier '" + name + "'");
|
||||
add_error(decl->source(), error_code,
|
||||
"redeclared identifier '" + name + "'");
|
||||
return false;
|
||||
}
|
||||
variable_stack_.set(name, decl->variable());
|
||||
if (decl->variable()->type()->UnwrapAll()->IsArray()) {
|
||||
if (decl->variable()->type()->UnwrapAll()->AsArray()->IsRuntimeArray()) {
|
||||
add_error(decl->source(),
|
||||
"v-0015: runtime arrays may only appear as the last "
|
||||
add_error(decl->source(), "v-0015",
|
||||
"runtime arrays may only appear as the last "
|
||||
"member of a struct: '" +
|
||||
decl->variable()->name() + "'");
|
||||
return false;
|
||||
@@ -303,8 +313,8 @@ bool ValidatorImpl::ValidateSwitch(const ast::SwitchStatement* s) {
|
||||
|
||||
auto* cond_type = s->condition()->result_type()->UnwrapAll();
|
||||
if (!(cond_type->IsI32() || cond_type->IsU32())) {
|
||||
add_error(s->condition()->source(),
|
||||
"v-0025: switch statement selector expression must be of a "
|
||||
add_error(s->condition()->source(), "v-0025",
|
||||
"switch statement selector expression must be of a "
|
||||
"scalar integer type");
|
||||
return false;
|
||||
}
|
||||
@@ -322,8 +332,8 @@ bool ValidatorImpl::ValidateSwitch(const ast::SwitchStatement* s) {
|
||||
|
||||
for (auto* selector : case_stmt->selectors()) {
|
||||
if (cond_type != selector->type()) {
|
||||
add_error(case_stmt->source(),
|
||||
"v-0026: the case selector values must have the same "
|
||||
add_error(case_stmt->source(), "v-0026",
|
||||
"the case selector values must have the same "
|
||||
"type as the selector expression.");
|
||||
return false;
|
||||
}
|
||||
@@ -334,8 +344,8 @@ bool ValidatorImpl::ValidateSwitch(const ast::SwitchStatement* s) {
|
||||
if (selector_set.count(v)) {
|
||||
auto v_str = selector->type()->IsU32() ? selector->AsUint()->to_str()
|
||||
: selector->AsSint()->to_str();
|
||||
add_error(case_stmt->source(),
|
||||
"v-0027: a literal value must not appear more than once in "
|
||||
add_error(case_stmt->source(), "v-0027",
|
||||
"a literal value must not appear more than once in "
|
||||
"the case selectors for a switch statement: '" +
|
||||
v_str + "'");
|
||||
return false;
|
||||
@@ -345,16 +355,16 @@ bool ValidatorImpl::ValidateSwitch(const ast::SwitchStatement* s) {
|
||||
}
|
||||
|
||||
if (default_counter != 1) {
|
||||
add_error(s->source(),
|
||||
"v-0008: switch statement must have exactly one default clause");
|
||||
add_error(s->source(), "v-0008",
|
||||
"switch statement must have exactly one default clause");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* last_clause = s->body().back();
|
||||
auto* last_stmt_of_last_clause = last_clause->AsCase()->body()->last();
|
||||
if (last_stmt_of_last_clause && last_stmt_of_last_clause->IsFallthrough()) {
|
||||
add_error(last_stmt_of_last_clause->source(),
|
||||
"v-0028: a fallthrough statement must not appear as "
|
||||
add_error(last_stmt_of_last_clause->source(), "v-0028",
|
||||
"a fallthrough statement must not appear as "
|
||||
"the last statement in last clause of a switch");
|
||||
return false;
|
||||
}
|
||||
@@ -382,14 +392,13 @@ bool ValidatorImpl::ValidateCallExpr(const ast::CallExpression* expr) {
|
||||
// TODO(sarahM0): validate intrinsics - tied with type-determiner
|
||||
} else {
|
||||
if (!function_stack_.has(func_name)) {
|
||||
add_error(expr->source(),
|
||||
"v-0005: function must be declared before use: '" +
|
||||
func_name + "'");
|
||||
add_error(expr->source(), "v-0005",
|
||||
"function must be declared before use: '" + func_name + "'");
|
||||
return false;
|
||||
}
|
||||
if (func_name == current_function_->name()) {
|
||||
add_error(expr->source(),
|
||||
"v-0004: recursion is not allowed: '" + func_name + "'");
|
||||
add_error(expr->source(), "v-0004",
|
||||
"recursion is not allowed: '" + func_name + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -428,8 +437,8 @@ bool ValidatorImpl::ValidateConstant(const ast::AssignmentStatement* assign) {
|
||||
auto* ident = assign->lhs()->AsIdentifier();
|
||||
if (variable_stack_.get(ident->name(), &var)) {
|
||||
if (var->is_const()) {
|
||||
add_error(assign->source(), "v-0021: cannot re-assign a constant: '" +
|
||||
ident->name() + "'");
|
||||
add_error(assign->source(), "v-0021",
|
||||
"cannot re-assign a constant: '" + ident->name() + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -447,9 +456,9 @@ bool ValidatorImpl::ValidateResultTypes(const ast::AssignmentStatement* a) {
|
||||
auto* rhs_result_type = a->rhs()->result_type()->UnwrapAll();
|
||||
if (lhs_result_type != rhs_result_type) {
|
||||
// TODO(sarahM0): figur out what should be the error number.
|
||||
add_error(a->source(), "v-000x: invalid assignment of '" +
|
||||
lhs_result_type->type_name() + "' to '" +
|
||||
rhs_result_type->type_name() + "'");
|
||||
add_error(a->source(), "v-000x",
|
||||
"invalid assignment of '" + lhs_result_type->type_name() +
|
||||
"' to '" + rhs_result_type->type_name() + "'");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -472,8 +481,8 @@ bool ValidatorImpl::ValidateExpression(const ast::Expression* expr) {
|
||||
bool ValidatorImpl::ValidateIdentifier(const ast::IdentifierExpression* ident) {
|
||||
ast::Variable* var;
|
||||
if (!variable_stack_.get(ident->name(), &var)) {
|
||||
add_error(ident->source(),
|
||||
"v-0006: '" + ident->name() + "' is not declared");
|
||||
add_error(ident->source(), "v-0006",
|
||||
"'" + ident->name() + "' is not declared");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -58,6 +58,12 @@ class ValidatorImpl {
|
||||
/// @returns true if an error was encountered
|
||||
bool has_error() const { return diags_.contains_errors(); }
|
||||
|
||||
/// Appends an error at @p src with the code @p code and message @p msg
|
||||
/// @param src the source causing the error
|
||||
/// @param code the validation error code
|
||||
/// @param msg the error message
|
||||
void add_error(const Source& src, const char* code, const std::string& msg);
|
||||
|
||||
/// Appends an error at @p src with the message @p msg
|
||||
/// @param src the source causing the error
|
||||
/// @param msg the error message
|
||||
|
||||
@@ -72,7 +72,7 @@ TEST_F(ValidatorTest, DISABLED_AssignToScalar_Fail) {
|
||||
// TODO(sarahM0): Invalidate assignment to scalar.
|
||||
ASSERT_TRUE(v()->has_error());
|
||||
// TODO(sarahM0): figure out what should be the error number.
|
||||
EXPECT_EQ(v()->error(), "12:34: v-000x: invalid assignment");
|
||||
EXPECT_EQ(v()->error(), "12:34 v-000x: invalid assignment");
|
||||
}
|
||||
|
||||
TEST_F(ValidatorTest, UsingUndefinedVariable_Fail) {
|
||||
@@ -156,7 +156,7 @@ TEST_F(ValidatorTest, AssignIncompatibleTypes_Fail) {
|
||||
ASSERT_TRUE(v()->has_error());
|
||||
// TODO(sarahM0): figure out what should be the error number.
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-000x: invalid assignment of '__i32' to '__f32'");
|
||||
"12:34 v-000x: invalid assignment of '__i32' to '__f32'");
|
||||
}
|
||||
|
||||
TEST_F(ValidatorTest, AssignCompatibleTypesInBlockStatement_Pass) {
|
||||
@@ -213,7 +213,7 @@ TEST_F(ValidatorTest, AssignIncompatibleTypesInBlockStatement_Fail) {
|
||||
ASSERT_TRUE(v()->has_error());
|
||||
// TODO(sarahM0): figure out what should be the error number.
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-000x: invalid assignment of '__i32' to '__f32'");
|
||||
"12:34 v-000x: invalid assignment of '__i32' to '__f32'");
|
||||
}
|
||||
|
||||
TEST_F(ValidatorTest, GlobalVariableWithStorageClass_Pass) {
|
||||
@@ -237,7 +237,7 @@ TEST_F(ValidatorTest, GlobalVariableNoStorageClass_Fail) {
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
EXPECT_FALSE(v()->Validate(mod()));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0022: global variables must have a storage class");
|
||||
"12:34 v-0022: global variables must have a storage class");
|
||||
}
|
||||
TEST_F(ValidatorTest, GlobalConstantWithStorageClass_Fail) {
|
||||
// const<in> gloabl_var: f32;
|
||||
@@ -252,7 +252,7 @@ TEST_F(ValidatorTest, GlobalConstantWithStorageClass_Fail) {
|
||||
EXPECT_FALSE(v()->Validate(mod()));
|
||||
EXPECT_EQ(
|
||||
v()->error(),
|
||||
"12:34: v-global01: global constants shouldn't have a storage class");
|
||||
"12:34 v-global01: global constants shouldn't have a storage class");
|
||||
}
|
||||
|
||||
TEST_F(ValidatorTest, GlobalConstNoStorageClass_Pass) {
|
||||
@@ -294,7 +294,7 @@ TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Fail) {
|
||||
mod()->AddFunction(func);
|
||||
|
||||
EXPECT_FALSE(v()->Validate(mod()));
|
||||
EXPECT_EQ(v()->error(), "12:34: v-0006: 'not_global_var' is not declared");
|
||||
EXPECT_EQ(v()->error(), "12:34 v-0006: 'not_global_var' is not declared");
|
||||
}
|
||||
|
||||
TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Pass) {
|
||||
@@ -361,7 +361,7 @@ TEST_F(ValidatorTest, UsingUndefinedVariableInnerScope_Fail) {
|
||||
ASSERT_NE(lhs->result_type(), nullptr);
|
||||
ASSERT_NE(rhs->result_type(), nullptr);
|
||||
EXPECT_FALSE(v()->ValidateStatements(outer_body));
|
||||
EXPECT_EQ(v()->error(), "12:34: v-0006: 'a' is not declared");
|
||||
EXPECT_EQ(v()->error(), "12:34 v-0006: 'a' is not declared");
|
||||
}
|
||||
|
||||
TEST_F(ValidatorTest, UsingUndefinedVariableOuterScope_Pass) {
|
||||
@@ -437,7 +437,7 @@ TEST_F(ValidatorTest, GlobalVariableNotUnique_Fail) {
|
||||
|
||||
EXPECT_FALSE(v()->ValidateGlobalVariables(mod()->global_variables()));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0011: redeclared global identifier 'global_var'");
|
||||
"12:34 v-0011: redeclared global identifier 'global_var'");
|
||||
}
|
||||
|
||||
TEST_F(ValidatorTest, AssignToConstant_Fail) {
|
||||
@@ -465,7 +465,7 @@ TEST_F(ValidatorTest, AssignToConstant_Fail) {
|
||||
ASSERT_NE(rhs->result_type(), nullptr);
|
||||
|
||||
EXPECT_FALSE(v()->ValidateStatements(body));
|
||||
EXPECT_EQ(v()->error(), "12:34: v-0021: cannot re-assign a constant: 'a'");
|
||||
EXPECT_EQ(v()->error(), "12:34 v-0021: cannot re-assign a constant: 'a'");
|
||||
}
|
||||
|
||||
TEST_F(ValidatorTest, GlobalVariableFunctionVariableNotUnique_Fail) {
|
||||
@@ -497,7 +497,7 @@ TEST_F(ValidatorTest, GlobalVariableFunctionVariableNotUnique_Fail) {
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
EXPECT_TRUE(td()->DetermineFunction(func)) << td()->error();
|
||||
EXPECT_FALSE(v()->Validate(mod())) << v()->error();
|
||||
EXPECT_EQ(v()->error(), "12:34: v-0013: redeclared identifier 'a'");
|
||||
EXPECT_EQ(v()->error(), "12:34 v-0013: redeclared identifier 'a'");
|
||||
}
|
||||
|
||||
TEST_F(ValidatorTest, RedeclaredIndentifier_Fail) {
|
||||
@@ -529,7 +529,7 @@ TEST_F(ValidatorTest, RedeclaredIndentifier_Fail) {
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
EXPECT_TRUE(td()->DetermineFunction(func)) << td()->error();
|
||||
EXPECT_FALSE(v()->Validate(mod()));
|
||||
EXPECT_EQ(v()->error(), "12:34: v-0014: redeclared identifier 'a'");
|
||||
EXPECT_EQ(v()->error(), "12:34 v-0014: redeclared identifier 'a'");
|
||||
}
|
||||
|
||||
TEST_F(ValidatorTest, RedeclaredIdentifierInnerScope_Pass) {
|
||||
@@ -592,7 +592,7 @@ TEST_F(ValidatorTest, DISABLED_RedeclaredIdentifierInnerScope_False) {
|
||||
|
||||
EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error();
|
||||
EXPECT_FALSE(v()->ValidateStatements(outer_body));
|
||||
EXPECT_EQ(v()->error(), "12:34: v-0014: redeclared identifier 'a'");
|
||||
EXPECT_EQ(v()->error(), "12:34 v-0014: redeclared identifier 'a'");
|
||||
}
|
||||
|
||||
TEST_F(ValidatorTest, RedeclaredIdentifierDifferentFunctions_Pass) {
|
||||
|
||||
@@ -88,7 +88,7 @@ TEST_F(ValidatorTypeTest, RuntimeArrayIsLastNoBlock_Fail) {
|
||||
mod()->AddConstructedType(&struct_type);
|
||||
EXPECT_FALSE(v()->ValidateConstructedTypes(mod()->constructed_types()));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0031: a struct containing a runtime-sized array must be "
|
||||
"12:34 v-0031: a struct containing a runtime-sized array must be "
|
||||
"in the 'storage' storage class: 'Foo'");
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ TEST_F(ValidatorTypeTest, RuntimeArrayIsNotLast_Fail) {
|
||||
mod()->AddConstructedType(&struct_type);
|
||||
EXPECT_FALSE(v()->ValidateConstructedTypes(mod()->constructed_types()));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0015: runtime arrays may only appear as the last member "
|
||||
"12:34 v-0015: runtime arrays may only appear as the last member "
|
||||
"of a struct: 'rt'");
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ TEST_F(ValidatorTypeTest, AliasRuntimeArrayIsNotLast_Fail) {
|
||||
mod()->AddConstructedType(&struct_type);
|
||||
EXPECT_FALSE(v()->ValidateConstructedTypes(mod()->constructed_types()));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0015: runtime arrays may only appear as the last member "
|
||||
"12:34 v-0015: runtime arrays may only appear as the last member "
|
||||
"of a struct: 'b'");
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ TEST_F(ValidatorTypeTest, RuntimeArrayInFunction_Fail) {
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
EXPECT_FALSE(v()->Validate(mod()));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0015: runtime arrays may only appear as the last member "
|
||||
"12:34 v-0015: runtime arrays may only appear as the last member "
|
||||
"of a struct: 'a'");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user