Simplify usage of the TypeDeterminer in tests

Make private all TypeDeterminer::DetermineXXX() methods, forcing all tests to use the root-level TypeDeterminer::Determine() method.
Remove TypeDeterminer::RegisterVariableForTesting().

The main use for calling the TypeDeterminer::DetermineXXX() methods was to perform type determination on a partial AST.
This was messy and often resulting in multiple calls into TypeDeterminer. Most tests already perform a full TypeDeterminer::Determine() call when the program is built, so many of these were redundant.
The exposure of these internal methods for testing also makes refactoring the TypeDeterminer extremely difficult.

Add a number of ProgramBuilder helper methods for attaching the partial AST in these tests to the root of the AST, greatly simplifying the use of the TypeDeterminer:
* ProgramBuilder::Global() and ProgramBuilder::GlobalConst() are helpers that register the variable returned by ProgramBuilder::Var() and ProgramBuilder::Const(), respectively.
* ProgramBuilder::WrapInFunction() is a variadic function that accepts variables, expressions and statements, attaching these to the root of the AST via a dummy function.

Most test classes now no longer use their own TypeDeterminer, and instead properly depend on the automatic type determination performed at Program build time.

Bug: tint:390
Change-Id: Ie901890420c5de170cdf2a7aaef9b96fc3bebd60
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/40062
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
Ben Clayton
2021-02-03 17:19:59 +00:00
committed by Commit Bot service account
parent 87c78ddabc
commit 401b96b9bb
59 changed files with 1946 additions and 2388 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -56,7 +56,7 @@ TEST_F(ValidateControlBlockTest, SwitchSelectorExpressionNoneIntegerType_Fail) {
body),
});
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
WrapInFunction(block);
ValidatorImpl& v = Build();
@@ -87,7 +87,7 @@ TEST_F(ValidateControlBlockTest, SwitchWithoutDefault_Fail) {
body),
});
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
WrapInFunction(block);
ValidatorImpl& v = Build();
@@ -129,7 +129,7 @@ TEST_F(ValidateControlBlockTest, SwitchWithTwoDefault_Fail) {
switch_body),
});
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
WrapInFunction(block);
ValidatorImpl& v = Build();
@@ -164,7 +164,7 @@ TEST_F(ValidateControlBlockTest,
create<ast::VariableDeclStatement>(var),
create<ast::SwitchStatement>(Expr("a"), switch_body),
});
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
WrapInFunction(block);
ValidatorImpl& v = Build();
@@ -199,7 +199,7 @@ TEST_F(ValidateControlBlockTest,
create<ast::VariableDeclStatement>(var),
create<ast::SwitchStatement>(Expr("a"), switch_body),
});
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
WrapInFunction(block);
ValidatorImpl& v = Build();
@@ -240,7 +240,7 @@ TEST_F(ValidateControlBlockTest, NonUniqueCaseSelectorValueUint_Fail) {
create<ast::VariableDeclStatement>(var),
create<ast::SwitchStatement>(Expr("a"), switch_body),
});
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
WrapInFunction(block);
ValidatorImpl& v = Build();
@@ -283,7 +283,7 @@ TEST_F(ValidateControlBlockTest, NonUniqueCaseSelectorValueSint_Fail) {
create<ast::VariableDeclStatement>(var),
create<ast::SwitchStatement>(Expr("a"), switch_body),
});
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
WrapInFunction(block);
ValidatorImpl& v = Build();
@@ -314,7 +314,7 @@ TEST_F(ValidateControlBlockTest, LastClauseLastStatementIsFallthrough_Fail) {
create<ast::VariableDeclStatement>(var),
create<ast::SwitchStatement>(Expr("a"), body),
});
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
WrapInFunction(block);
ValidatorImpl& v = Build();
@@ -347,7 +347,7 @@ TEST_F(ValidateControlBlockTest, SwitchCase_Pass) {
create<ast::VariableDeclStatement>(var),
create<ast::SwitchStatement>(Expr("a"), body),
});
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
WrapInFunction(block);
ValidatorImpl& v = Build();
@@ -377,7 +377,7 @@ TEST_F(ValidateControlBlockTest, SwitchCaseAlias_Pass) {
});
AST().AddConstructedType(my_int);
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
WrapInFunction(block);
ValidatorImpl& v = Build();

View File

@@ -50,8 +50,6 @@ TEST_F(ValidateFunctionTest, VoidFunctionEndWithoutReturnStatement_Pass) {
create<ast::StageDecoration>(ast::PipelineStage::kVertex),
});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_TRUE(v.Validate());
@@ -68,8 +66,6 @@ TEST_F(ValidateFunctionTest,
create<ast::StageDecoration>(ast::PipelineStage::kVertex),
});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_TRUE(v.Validate());
@@ -87,8 +83,6 @@ TEST_F(ValidateFunctionTest, FunctionEndWithoutReturnStatement_Fail) {
},
ast::FunctionDecorationList{});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_FALSE(v.Validate());
@@ -102,8 +96,6 @@ TEST_F(ValidateFunctionTest, FunctionEndWithoutReturnStatementEmptyBody_Fail) {
Func(Source{Source::Location{12, 34}}, "func", ast::VariableList{}, ty.i32(),
ast::StatementList{}, ast::FunctionDecorationList{});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_FALSE(v.Validate());
@@ -123,8 +115,6 @@ TEST_F(ValidateFunctionTest, FunctionTypeMustMatchReturnStatementType_Pass) {
create<ast::StageDecoration>(ast::PipelineStage::kVertex),
});
EXPECT_TRUE(td()->DetermineFunctions(AST().Functions())) << td()->error();
ValidatorImpl& v = Build();
const Program* program = v.program();
@@ -140,8 +130,6 @@ TEST_F(ValidateFunctionTest, FunctionTypeMustMatchReturnStatementType_fail) {
},
ast::FunctionDecorationList{});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_FALSE(v.Validate());
@@ -160,8 +148,6 @@ TEST_F(ValidateFunctionTest, FunctionTypeMustMatchReturnStatementTypeF32_fail) {
},
ast::FunctionDecorationList{});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_FALSE(v.Validate());
@@ -186,8 +172,6 @@ TEST_F(ValidateFunctionTest, FunctionNamesMustBeUnique_fail) {
},
ast::FunctionDecorationList{});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_FALSE(v.Validate());
@@ -207,8 +191,6 @@ TEST_F(ValidateFunctionTest, RecursionIsNotAllowed_Fail) {
},
ast::FunctionDecorationList{});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_FALSE(v.Validate()) << v.error();
@@ -230,8 +212,6 @@ TEST_F(ValidateFunctionTest, RecursionIsNotAllowedExpr_Fail) {
},
ast::FunctionDecorationList{});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_FALSE(v.Validate()) << v.error();
@@ -251,8 +231,6 @@ TEST_F(ValidateFunctionTest, Function_WithPipelineStage_NotVoid_Fail) {
create<ast::StageDecoration>(ast::PipelineStage::kVertex),
});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_FALSE(v.Validate());
@@ -275,8 +253,6 @@ TEST_F(ValidateFunctionTest, Function_WithPipelineStage_WithParams_Fail) {
create<ast::StageDecoration>(ast::PipelineStage::kVertex),
});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_FALSE(v.Validate());
@@ -299,8 +275,6 @@ TEST_F(ValidateFunctionTest, PipelineStage_MustBeUnique_Fail) {
create<ast::StageDecoration>(ast::PipelineStage::kFragment),
});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_FALSE(v.Validate());
@@ -321,8 +295,6 @@ TEST_F(ValidateFunctionTest, OnePipelineStageFunctionMustBePresent_Pass) {
create<ast::StageDecoration>(ast::PipelineStage::kVertex),
});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_TRUE(v.Validate()) << v.error();
@@ -336,8 +308,6 @@ TEST_F(ValidateFunctionTest, OnePipelineStageFunctionMustBePresent_Fail) {
},
ast::FunctionDecorationList{});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_FALSE(v.Validate());

View File

@@ -66,14 +66,14 @@ TEST_F(ValidatorTest, AssignToScalar_Fail) {
auto* var = Var("my_var", ast::StorageClass::kNone, ty.i32(), Expr(2),
ast::VariableDecorationList{});
RegisterVariable(var);
auto* lhs = Expr(1);
auto* rhs = Expr("my_var");
SetSource(Source{Source::Location{12, 34}});
auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
RegisterVariable(var);
EXPECT_TRUE(td()->DetermineResultType(assign));
WrapInFunction(assign);
ValidatorImpl& v = Build();
@@ -93,8 +93,9 @@ TEST_F(ValidatorTest, UsingUndefinedVariable_Fail) {
auto* lhs = Expr("b");
auto* rhs = Expr(2);
auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
WrapInFunction(assign);
EXPECT_FALSE(td()->DetermineResultType(assign));
EXPECT_FALSE(td()->Determine());
EXPECT_EQ(td()->error(),
"12:34: v-0006: identifier must be declared before use: b");
}
@@ -111,8 +112,9 @@ TEST_F(ValidatorTest, UsingUndefinedVariableInBlockStatement_Fail) {
auto* body = create<ast::BlockStatement>(ast::StatementList{
create<ast::AssignmentStatement>(lhs, rhs),
});
WrapInFunction(body);
EXPECT_FALSE(td()->DetermineStatements(body));
EXPECT_FALSE(td()->Determine());
EXPECT_EQ(td()->error(),
"12:34: v-0006: identifier must be declared before use: b");
}
@@ -122,19 +124,20 @@ TEST_F(ValidatorTest, AssignCompatibleTypes_Pass) {
// a = 2
auto* var = Var("a", ast::StorageClass::kNone, ty.i32(), Expr(2),
ast::VariableDecorationList{});
RegisterVariable(var);
auto* lhs = Expr("a");
auto* rhs = Expr(2);
auto* assign = create<ast::AssignmentStatement>(
Source{Source::Location{12, 34}}, lhs, rhs);
RegisterVariable(var);
EXPECT_TRUE(td()->DetermineResultType(assign)) << td()->error();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
WrapInFunction(assign);
ValidatorImpl& v = Build();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
EXPECT_TRUE(v.ValidateAssign(assign)) << v.error();
}
@@ -145,19 +148,20 @@ TEST_F(ValidatorTest, AssignCompatibleTypesThroughAlias_Pass) {
auto* myint = ty.alias("myint", ty.i32());
auto* var = Var("a", ast::StorageClass::kNone, myint, Expr(2),
ast::VariableDecorationList{});
RegisterVariable(var);
auto* lhs = Expr("a");
auto* rhs = Expr(2);
auto* assign = create<ast::AssignmentStatement>(
Source{Source::Location{12, 34}}, lhs, rhs);
RegisterVariable(var);
EXPECT_TRUE(td()->DetermineResultType(assign)) << td()->error();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
WrapInFunction(assign);
ValidatorImpl& v = Build();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
EXPECT_TRUE(v.ValidateAssign(assign)) << v.error();
}
@@ -169,20 +173,21 @@ TEST_F(ValidatorTest, AssignCompatibleTypesInferRHSLoad_Pass) {
ast::VariableDecorationList{});
auto* var_b = Var("b", ast::StorageClass::kNone, ty.i32(), Expr(3),
ast::VariableDecorationList{});
RegisterVariable(var_a);
RegisterVariable(var_b);
auto* lhs = Expr("a");
auto* rhs = Expr("b");
auto* assign = create<ast::AssignmentStatement>(
Source{Source::Location{12, 34}}, lhs, rhs);
RegisterVariable(var_a);
RegisterVariable(var_b);
EXPECT_TRUE(td()->DetermineResultType(assign)) << td()->error();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
WrapInFunction(assign);
ValidatorImpl& v = Build();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
EXPECT_TRUE(v.ValidateAssign(assign)) << v.error();
}
@@ -194,20 +199,21 @@ TEST_F(ValidatorTest, AssignThroughPointer_Pass) {
auto* var_a = Var("a", func, ty.i32(), Expr(2), {});
auto* var_b = Const("b", ast::StorageClass::kNone, ty.pointer<int>(func),
Expr("a"), {});
RegisterVariable(var_a);
RegisterVariable(var_b);
auto* lhs = Expr("b");
auto* rhs = Expr(2);
auto* assign = create<ast::AssignmentStatement>(
Source{Source::Location{12, 34}}, lhs, rhs);
RegisterVariable(var_a);
RegisterVariable(var_b);
EXPECT_TRUE(td()->DetermineResultType(assign)) << td()->error();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
WrapInFunction(assign);
ValidatorImpl& v = Build();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
EXPECT_TRUE(v.ValidateAssign(assign)) << v.error();
}
@@ -219,19 +225,20 @@ TEST_F(ValidatorTest, AssignIncompatibleTypes_Fail) {
auto* var = Var("a", ast::StorageClass::kNone, ty.i32(), Expr(2),
ast::VariableDecorationList{});
RegisterVariable(var);
auto* lhs = Expr("a");
auto* rhs = Expr(2.3f);
auto* assign = create<ast::AssignmentStatement>(
Source{Source::Location{12, 34}}, lhs, rhs);
RegisterVariable(var);
EXPECT_TRUE(td()->DetermineResultType(assign)) << td()->error();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
WrapInFunction(assign);
ValidatorImpl& v = Build();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
EXPECT_FALSE(v.ValidateAssign(assign));
ASSERT_TRUE(v.has_error());
// TODO(sarahM0): figure out what should be the error number.
@@ -248,20 +255,21 @@ TEST_F(ValidatorTest, AssignThroughPointerWrongeStoreType_Fail) {
auto* var_a = Var("a", priv, ty.f32(), Expr(2), {});
auto* var_b = Const("b", ast::StorageClass::kNone, ty.pointer<float>(priv),
Expr("a"), {});
RegisterVariable(var_a);
RegisterVariable(var_b);
auto* lhs = Expr("a");
auto* rhs = Expr(2);
auto* assign = create<ast::AssignmentStatement>(
Source{Source::Location{12, 34}}, lhs, rhs);
RegisterVariable(var_a);
RegisterVariable(var_b);
EXPECT_TRUE(td()->DetermineResultType(assign)) << td()->error();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
WrapInFunction(assign);
ValidatorImpl& v = Build();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
EXPECT_FALSE(v.ValidateAssign(assign));
EXPECT_EQ(v.error(),
"12:34 v-000x: invalid assignment: can't assign value of type "
@@ -284,13 +292,13 @@ TEST_F(ValidatorTest, AssignCompatibleTypesInBlockStatement_Pass) {
create<ast::AssignmentStatement>(Source{Source::Location{12, 34}}, lhs,
rhs),
});
EXPECT_TRUE(td()->DetermineStatements(body)) << td()->error();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
WrapInFunction(body);
ValidatorImpl& v = Build();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
EXPECT_TRUE(v.ValidateStatements(body)) << v.error();
}
@@ -311,13 +319,13 @@ TEST_F(ValidatorTest, AssignIncompatibleTypesInBlockStatement_Fail) {
create<ast::AssignmentStatement>(Source{Source::Location{12, 34}}, lhs,
rhs),
});
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
WrapInFunction(block);
ValidatorImpl& v = Build();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
EXPECT_FALSE(v.ValidateStatements(block));
ASSERT_TRUE(v.has_error());
// TODO(sarahM0): figure out what should be the error number.
@@ -350,12 +358,13 @@ TEST_F(ValidatorTest, AssignIncompatibleTypesInNestedBlockStatement_Fail) {
inner_block,
});
EXPECT_TRUE(td()->DetermineStatements(outer_block)) << td()->error();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
WrapInFunction(outer_block);
ValidatorImpl& v = Build();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
EXPECT_FALSE(v.ValidateStatements(outer_block));
ASSERT_TRUE(v.has_error());
// TODO(sarahM0): figure out what should be the error number.
@@ -366,9 +375,9 @@ TEST_F(ValidatorTest, AssignIncompatibleTypesInNestedBlockStatement_Fail) {
TEST_F(ValidatorTest, GlobalVariableWithStorageClass_Pass) {
// var<in> gloabl_var: f32;
AST().AddGlobalVariable(Var(Source{Source::Location{12, 34}}, "global_var",
ast::StorageClass::kInput, ty.f32(), nullptr,
ast::VariableDecorationList{}));
Global(Source{Source::Location{12, 34}}, "global_var",
ast::StorageClass::kInput, ty.f32(), nullptr,
ast::VariableDecorationList{});
ValidatorImpl& v = Build();
const Program* program = v.program();
@@ -379,10 +388,9 @@ TEST_F(ValidatorTest, GlobalVariableWithStorageClass_Pass) {
TEST_F(ValidatorTest, GlobalVariableNoStorageClass_Fail) {
// var gloabl_var: f32;
AST().AddGlobalVariable(Var(Source{Source::Location{12, 34}}, "global_var",
ast::StorageClass::kNone, ty.f32(), nullptr,
ast::VariableDecorationList{}));
EXPECT_TRUE(td()->Determine()) << td()->error();
Global(Source{Source::Location{12, 34}}, "global_var",
ast::StorageClass::kNone, ty.f32(), nullptr,
ast::VariableDecorationList{});
ValidatorImpl& v = Build();
@@ -393,10 +401,9 @@ TEST_F(ValidatorTest, GlobalVariableNoStorageClass_Fail) {
TEST_F(ValidatorTest, GlobalConstantWithStorageClass_Fail) {
// const<in> gloabl_var: f32;
AST().AddGlobalVariable(Const(Source{Source::Location{12, 34}}, "global_var",
ast::StorageClass::kInput, ty.f32(), nullptr,
ast::VariableDecorationList{}));
EXPECT_TRUE(td()->Determine()) << td()->error();
GlobalConst(Source{Source::Location{12, 34}}, "global_var",
ast::StorageClass::kInput, ty.f32(), nullptr,
ast::VariableDecorationList{});
ValidatorImpl& v = Build();
@@ -408,10 +415,9 @@ TEST_F(ValidatorTest, GlobalConstantWithStorageClass_Fail) {
TEST_F(ValidatorTest, GlobalConstNoStorageClass_Pass) {
// const gloabl_var: f32;
AST().AddGlobalVariable(Const(Source{Source::Location{12, 34}}, "global_var",
ast::StorageClass::kNone, ty.f32(), nullptr,
ast::VariableDecorationList{}));
EXPECT_TRUE(td()->Determine()) << td()->error();
GlobalConst(Source{Source::Location{12, 34}}, "global_var",
ast::StorageClass::kNone, ty.f32(), nullptr,
ast::VariableDecorationList{});
ValidatorImpl& v = Build();
@@ -423,9 +429,8 @@ TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Fail) {
// fn my_func() -> f32 {
// not_global_var = 3.14f;
// }
AST().AddGlobalVariable(Var("global_var", ast::StorageClass::kPrivate,
ty.f32(), Expr(2.1f),
ast::VariableDecorationList{}));
Global("global_var", ast::StorageClass::kPrivate, ty.f32(), Expr(2.1f),
ast::VariableDecorationList{});
SetSource(Source{Source::Location{12, 34}});
auto* lhs = Expr("not_global_var");
@@ -451,9 +456,8 @@ TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Pass) {
// return;
// }
AST().AddGlobalVariable(Var("global_var", ast::StorageClass::kPrivate,
ty.f32(), Expr(2.1f),
ast::VariableDecorationList{}));
Global("global_var", ast::StorageClass::kPrivate, ty.f32(), Expr(2.1f),
ast::VariableDecorationList{});
Func("my_func", ast::VariableList{}, ty.void_(),
ast::StatementList{
@@ -465,8 +469,6 @@ TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Pass) {
create<ast::StageDecoration>(ast::PipelineStage::kVertex),
});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_TRUE(v.Validate()) << v.error();
@@ -495,12 +497,13 @@ TEST_F(ValidatorTest, UsingUndefinedVariableInnerScope_Fail) {
rhs),
});
EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
WrapInFunction(outer_body);
ValidatorImpl& v = Build();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
EXPECT_FALSE(v.ValidateStatements(outer_body));
EXPECT_EQ(v.error(), "12:34 v-0006: 'a' is not declared");
}
@@ -528,12 +531,13 @@ TEST_F(ValidatorTest, UsingUndefinedVariableOuterScope_Pass) {
create<ast::IfStatement>(cond, body, ast::ElseStatementList{}),
});
EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
WrapInFunction(outer_body);
ValidatorImpl& v = Build();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
EXPECT_TRUE(v.ValidateStatements(outer_body)) << v.error();
}
@@ -561,12 +565,13 @@ TEST_F(ValidatorTest, UsingUndefinedVariableDifferentScope_Fail) {
second_body,
});
EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
WrapInFunction(outer_body);
ValidatorImpl& v = Build();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
EXPECT_FALSE(v.ValidateStatements(outer_body));
EXPECT_EQ(v.error(), "12:34 v-0006: 'a' is not declared");
}
@@ -574,14 +579,12 @@ TEST_F(ValidatorTest, UsingUndefinedVariableDifferentScope_Fail) {
TEST_F(ValidatorTest, GlobalVariableUnique_Pass) {
// var global_var0 : f32 = 0.1;
// var global_var1 : i32 = 0;
auto* var0 = Var("global_var0", ast::StorageClass::kPrivate, ty.f32(),
Expr(0.1f), ast::VariableDecorationList{});
AST().AddGlobalVariable(var0);
Global("global_var0", ast::StorageClass::kPrivate, ty.f32(), Expr(0.1f),
ast::VariableDecorationList{});
auto* var1 = Var(Source{Source::Location{12, 34}}, "global_var1",
ast::StorageClass::kPrivate, ty.f32(), Expr(0),
ast::VariableDecorationList{});
AST().AddGlobalVariable(var1);
Global(Source{Source::Location{12, 34}}, "global_var1",
ast::StorageClass::kPrivate, ty.f32(), Expr(0),
ast::VariableDecorationList{});
ValidatorImpl& v = Build();
const Program* program = v.program();
@@ -593,14 +596,12 @@ TEST_F(ValidatorTest, GlobalVariableUnique_Pass) {
TEST_F(ValidatorTest, GlobalVariableNotUnique_Fail) {
// var global_var : f32 = 0.1;
// var global_var : i32 = 0;
auto* var0 = Var("global_var", ast::StorageClass::kPrivate, ty.f32(),
Expr(0.1f), ast::VariableDecorationList{});
AST().AddGlobalVariable(var0);
Global("global_var", ast::StorageClass::kPrivate, ty.f32(), Expr(0.1f),
ast::VariableDecorationList{});
auto* var1 = Var(Source{Source::Location{12, 34}}, "global_var",
ast::StorageClass::kPrivate, ty.i32(), Expr(0),
ast::VariableDecorationList{});
AST().AddGlobalVariable(var1);
Global(Source{Source::Location{12, 34}}, "global_var",
ast::StorageClass::kPrivate, ty.i32(), Expr(0),
ast::VariableDecorationList{});
ValidatorImpl& v = Build();
const Program* program = v.program();
@@ -627,12 +628,13 @@ TEST_F(ValidatorTest, AssignToConstant_Fail) {
rhs),
});
EXPECT_TRUE(td()->DetermineStatements(body)) << td()->error();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
WrapInFunction(body);
ValidatorImpl& v = Build();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
EXPECT_FALSE(v.ValidateStatements(body));
EXPECT_EQ(v.error(), "12:34 v-0021: cannot re-assign a constant: 'a'");
}
@@ -644,9 +646,8 @@ TEST_F(ValidatorTest, GlobalVariableFunctionVariableNotUnique_Fail) {
// return 0;
// }
auto* global_var = Var("a", ast::StorageClass::kPrivate, ty.f32(), Expr(2.1f),
ast::VariableDecorationList{});
AST().AddGlobalVariable(global_var);
Global("a", ast::StorageClass::kPrivate, ty.f32(), Expr(2.1f),
ast::VariableDecorationList{});
auto* var = Var("a", ast::StorageClass::kNone, ty.f32(), Expr(2.0f),
ast::VariableDecorationList{});
@@ -658,8 +659,6 @@ TEST_F(ValidatorTest, GlobalVariableFunctionVariableNotUnique_Fail) {
},
ast::FunctionDecorationList{});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_FALSE(v.Validate()) << v.error();
@@ -685,8 +684,6 @@ TEST_F(ValidatorTest, RedeclaredIndentifier_Fail) {
},
ast::FunctionDecorationList{});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_FALSE(v.Validate());
@@ -715,7 +712,7 @@ TEST_F(ValidatorTest, RedeclaredIdentifierInnerScope_Pass) {
var_a_float),
});
EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error();
WrapInFunction(outer_body);
ValidatorImpl& v = Build();
@@ -745,7 +742,7 @@ TEST_F(ValidatorTest, DISABLED_RedeclaredIdentifierInnerScope_False) {
create<ast::IfStatement>(cond, body, ast::ElseStatementList{}),
});
EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error();
WrapInFunction(outer_body);
ValidatorImpl& v = Build();
@@ -770,7 +767,7 @@ TEST_F(ValidatorTest, RedeclaredIdentifierInnerScopeBlock_Pass) {
create<ast::VariableDeclStatement>(var_outer),
});
EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error();
WrapInFunction(outer_body);
ValidatorImpl& v = Build();
@@ -794,7 +791,7 @@ TEST_F(ValidatorTest, RedeclaredIdentifierInnerScopeBlock_Fail) {
inner,
});
EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error();
WrapInFunction(outer_body);
ValidatorImpl& v = Build();
@@ -829,8 +826,6 @@ TEST_F(ValidatorTest, RedeclaredIdentifierDifferentFunctions_Pass) {
create<ast::StageDecoration>(ast::PipelineStage::kVertex),
});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_TRUE(v.Validate()) << v.error();
@@ -843,8 +838,6 @@ TEST_F(ValidatorTest, VariableDeclNoConstructor_Pass) {
// }
auto* var = Var("a", ast::StorageClass::kNone, ty.i32(), nullptr,
ast::VariableDecorationList{});
td()->RegisterVariableForTesting(var);
auto* lhs = Expr("a");
auto* rhs = Expr(2);
@@ -854,12 +847,13 @@ TEST_F(ValidatorTest, VariableDeclNoConstructor_Pass) {
rhs),
});
EXPECT_TRUE(td()->DetermineStatements(body)) << td()->error();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
WrapInFunction(body);
ValidatorImpl& v = Build();
ASSERT_NE(TypeOf(lhs), nullptr);
ASSERT_NE(TypeOf(rhs), nullptr);
EXPECT_TRUE(v.ValidateStatements(body)) << v.error();
}

View File

@@ -58,8 +58,18 @@ class ValidatorTestHelper : public ProgramBuilder {
/// Inserts a variable into the current scope.
/// @param var the variable to register.
void RegisterVariable(ast::Variable* var) {
AST().AddGlobalVariable(var);
vars_for_testing_.emplace_back(var);
td_->RegisterVariableForTesting(var);
}
/// Helper for returning the resolved semantic type of the expression `expr`
/// from the built program.
/// @param expr the AST expression
/// @return the resolved semantic type for the expression, or nullptr if the
/// expression has no resolved type.
type::Type* TypeOf(ast::Expression* expr) const {
auto* sem = program_->Sem().Get(expr);
return sem ? sem->Type() : nullptr;
}
private:

View File

@@ -178,8 +178,6 @@ TEST_F(ValidatorTypeTest, RuntimeArrayInFunction_Fail) {
create<ast::StageDecoration>(ast::PipelineStage::kVertex),
});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_FALSE(v.Validate());
@@ -210,8 +208,6 @@ TEST_F(ValidatorTypeTest, RuntimeArrayAsParameter_Fail) {
create<ast::StageDecoration>(ast::PipelineStage::kVertex),
});
EXPECT_TRUE(td()->Determine()) << td()->error();
ValidatorImpl& v = Build();
EXPECT_FALSE(v.Validate());