diff --git a/src/ast/builder.cc b/src/ast/builder.cc index f9b96a7563..612bc9e44e 100644 --- a/src/ast/builder.cc +++ b/src/ast/builder.cc @@ -75,6 +75,18 @@ Variable* Builder::Const(const std::string& name, return var; } +Variable* Builder::Const(const Source& source, + const std::string& name, + StorageClass storage, + type::Type* type, + Expression* constructor, + VariableDecorationList decorations) { + auto* var = create(source, name, storage, type, true, constructor, + decorations); + OnVariableBuilt(var); + return var; +} + BuilderWithModule::BuilderWithModule() : Builder(new Module()) {} BuilderWithModule::~BuilderWithModule() { diff --git a/src/ast/builder.h b/src/ast/builder.h index a4f4b64488..05afa92ce2 100644 --- a/src/ast/builder.h +++ b/src/ast/builder.h @@ -499,6 +499,20 @@ class Builder { Expression* constructor, VariableDecorationList decorations); + /// @param source the variable source + /// @param name the variable name + /// @param storage the variable storage class + /// @param type the variable type + /// @param constructor optional constructor expression + /// @param decorations optional variable decorations + /// @returns a constant `Variable` with the given name, storage and type + Variable* Const(const Source& source, + const std::string& name, + StorageClass storage, + type::Type* type, + Expression* constructor, + VariableDecorationList decorations); + /// @param func the function name /// @param args the function call arguments /// @returns a `CallExpression` to the function `func`, with the diff --git a/src/transform/vertex_pulling_test.cc b/src/transform/vertex_pulling_test.cc index 65e644bbb9..3a7c2f0c60 100644 --- a/src/transform/vertex_pulling_test.cc +++ b/src/transform/vertex_pulling_test.cc @@ -17,6 +17,7 @@ #include #include "gtest/gtest.h" +#include "src/ast/builder.h" #include "src/ast/function.h" #include "src/ast/pipeline_stage.h" #include "src/ast/stage_decoration.h" @@ -34,10 +35,9 @@ namespace tint { namespace transform { namespace { -class VertexPullingHelper { +class VertexPullingHelper : public ast::BuilderWithModule { public: VertexPullingHelper() { - mod_ = std::make_unique(); manager_ = std::make_unique(); auto transform = std::make_unique(); transform_ = transform.get(); @@ -47,19 +47,19 @@ class VertexPullingHelper { // Create basic module with an entry point and vertex function void InitBasicModule() { auto* func = create( - Source{}, mod()->RegisterSymbol("main"), "main", ast::VariableList{}, - mod_->create(), - create(Source{}, ast::StatementList{}), - ast::FunctionDecorationList{create( - Source{}, ast::PipelineStage::kVertex)}); - mod()->AddFunction(func); + mod->RegisterSymbol("main"), "main", ast::VariableList{}, + mod->create(), + create(ast::StatementList{}), + ast::FunctionDecorationList{ + create(ast::PipelineStage::kVertex)}); + mod->AddFunction(func); } // Set up the transformation, after building the module void InitTransform(VertexStateDescriptor vertex_state) { - EXPECT_TRUE(mod_->IsValid()); + EXPECT_TRUE(mod->IsValid()); - TypeDeterminer td(mod_.get()); + TypeDeterminer td(mod); EXPECT_TRUE(td.Determine()); transform_->SetVertexState(vertex_state); @@ -70,37 +70,18 @@ class VertexPullingHelper { void AddVertexInputVariable(uint32_t location, std::string name, ast::type::Type* type) { - auto* var = create( - Source{}, // source - name, // name - ast::StorageClass::kInput, // storage_class - type, // type - false, // is_const - nullptr, // constructor - ast::VariableDecorationList{ - // decorations - create(Source{}, location), - }); + auto* var = Var(name, ast::StorageClass::kInput, type, nullptr, + ast::VariableDecorationList{ + create(location), + }); - mod_->AddGlobalVariable(var); + mod->AddGlobalVariable(var); } - ast::Module* mod() { return mod_.get(); } - Manager* manager() { return manager_.get(); } VertexPulling* transform() { return transform_; } - /// Creates a new `ast::Node` owned by the Module. When the Module is - /// destructed, the `ast::Node` will also be destructed. - /// @param args the arguments to pass to the type constructor - /// @returns the node pointer - template - T* create(ARGS&&... args) { - return mod_->create(std::forward(args)...); - } - private: - std::unique_ptr mod_; std::unique_ptr manager_; VertexPulling* transform_; }; @@ -108,7 +89,7 @@ class VertexPullingHelper { class VertexPullingTest : public VertexPullingHelper, public testing::Test {}; TEST_F(VertexPullingTest, Error_NoVertexState) { - auto result = manager()->Run(mod()); + auto result = manager()->Run(mod); EXPECT_TRUE(result.diagnostics.contains_errors()); EXPECT_EQ(diag::Formatter().format(result.diagnostics), "error: SetVertexState not called"); @@ -116,7 +97,7 @@ TEST_F(VertexPullingTest, Error_NoVertexState) { TEST_F(VertexPullingTest, Error_NoEntryPoint) { transform()->SetVertexState({}); - auto result = manager()->Run(mod()); + auto result = manager()->Run(mod); EXPECT_TRUE(result.diagnostics.contains_errors()); EXPECT_EQ(diag::Formatter().format(result.diagnostics), "error: Vertex stage entry point not found"); @@ -127,7 +108,7 @@ TEST_F(VertexPullingTest, Error_InvalidEntryPoint) { InitTransform({}); transform()->SetEntryPoint("_"); - auto result = manager()->Run(mod()); + auto result = manager()->Run(mod); EXPECT_TRUE(result.diagnostics.contains_errors()); EXPECT_EQ(diag::Formatter().format(result.diagnostics), "error: Vertex stage entry point not found"); @@ -135,16 +116,16 @@ TEST_F(VertexPullingTest, Error_InvalidEntryPoint) { TEST_F(VertexPullingTest, Error_EntryPointWrongStage) { auto* func = create( - Source{}, mod()->RegisterSymbol("main"), "main", ast::VariableList{}, - mod()->create(), - create(Source{}, ast::StatementList{}), + mod->RegisterSymbol("main"), "main", ast::VariableList{}, + mod->create(), + create(ast::StatementList{}), ast::FunctionDecorationList{ - create(Source{}, ast::PipelineStage::kFragment), + create(ast::PipelineStage::kFragment), }); - mod()->AddFunction(func); + mod->AddFunction(func); InitTransform({}); - auto result = manager()->Run(mod()); + auto result = manager()->Run(mod); EXPECT_TRUE(result.diagnostics.contains_errors()); EXPECT_EQ(diag::Formatter().format(result.diagnostics), "error: Vertex stage entry point not found"); @@ -153,7 +134,7 @@ TEST_F(VertexPullingTest, Error_EntryPointWrongStage) { TEST_F(VertexPullingTest, BasicModule) { InitBasicModule(); InitTransform({}); - auto result = manager()->Run(mod()); + auto result = manager()->Run(mod); ASSERT_FALSE(result.diagnostics.contains_errors()) << diag::Formatter().format(result.diagnostics); } @@ -166,7 +147,7 @@ TEST_F(VertexPullingTest, OneAttribute) { InitTransform({{{4, InputStepMode::kVertex, {{VertexFormat::kF32, 0, 0}}}}}); - auto result = manager()->Run(mod()); + auto result = manager()->Run(mod); ASSERT_FALSE(result.diagnostics.contains_errors()) << diag::Formatter().format(result.diagnostics); @@ -253,7 +234,7 @@ TEST_F(VertexPullingTest, OneInstancedAttribute) { InitTransform( {{{4, InputStepMode::kInstance, {{VertexFormat::kF32, 0, 0}}}}}); - auto result = manager()->Run(mod()); + auto result = manager()->Run(mod); ASSERT_FALSE(result.diagnostics.contains_errors()) << diag::Formatter().format(result.diagnostics); @@ -340,7 +321,7 @@ TEST_F(VertexPullingTest, OneAttributeDifferentOutputSet) { InitTransform({{{4, InputStepMode::kVertex, {{VertexFormat::kF32, 0, 0}}}}}); transform()->SetPullingBufferBindingSet(5); - auto result = manager()->Run(mod()); + auto result = manager()->Run(mod); ASSERT_FALSE(result.diagnostics.contains_errors()) << diag::Formatter().format(result.diagnostics); @@ -428,35 +409,23 @@ TEST_F(VertexPullingTest, ExistingVertexIndexAndInstanceIndex) { ast::type::I32 i32; - mod()->AddGlobalVariable(create( - Source{}, // source - "custom_vertex_index", // name - ast::StorageClass::kInput, // storage_class - &i32, // type - false, // is_const - nullptr, // constructor - ast::VariableDecorationList{ - // decorations - create(Source{}, ast::Builtin::kVertexIdx), - })); + mod->AddGlobalVariable( + Var("custom_vertex_index", ast::StorageClass::kInput, &i32, nullptr, + ast::VariableDecorationList{ + create(ast::Builtin::kVertexIdx), + })); - mod()->AddGlobalVariable(create( - Source{}, // source - "custom_instance_index", // name - ast::StorageClass::kInput, // storage_class - &i32, // type - false, // is_const - nullptr, // constructor - ast::VariableDecorationList{ - // decorations - create(Source{}, ast::Builtin::kInstanceIdx), - })); + mod->AddGlobalVariable( + Var("custom_instance_index", ast::StorageClass::kInput, &i32, nullptr, + ast::VariableDecorationList{ + create(ast::Builtin::kInstanceIdx), + })); InitTransform( {{{4, InputStepMode::kVertex, {{VertexFormat::kF32, 0, 0}}}, {4, InputStepMode::kInstance, {{VertexFormat::kF32, 0, 1}}}}}); - auto result = manager()->Run(mod()); + auto result = manager()->Run(mod); ASSERT_FALSE(result.diagnostics.contains_errors()) << diag::Formatter().format(result.diagnostics); @@ -598,7 +567,7 @@ TEST_F(VertexPullingTest, TwoAttributesSameBuffer) { InputStepMode::kVertex, {{VertexFormat::kF32, 0, 0}, {VertexFormat::kVec4F32, 0, 1}}}}}); - auto result = manager()->Run(mod()); + auto result = manager()->Run(mod); ASSERT_FALSE(result.diagnostics.contains_errors()) << diag::Formatter().format(result.diagnostics); @@ -785,7 +754,7 @@ TEST_F(VertexPullingTest, FloatVectorAttributes) { {12, InputStepMode::kVertex, {{VertexFormat::kVec3F32, 0, 1}}}, {16, InputStepMode::kVertex, {{VertexFormat::kVec4F32, 0, 2}}}}}); - auto result = manager()->Run(mod()); + auto result = manager()->Run(mod); ASSERT_FALSE(result.diagnostics.contains_errors()) << diag::Formatter().format(result.diagnostics); diff --git a/src/validator/validator_control_block_test.cc b/src/validator/validator_control_block_test.cc index 0cbd07b2f9..8009eefc55 100644 --- a/src/validator/validator_control_block_test.cc +++ b/src/validator/validator_control_block_test.cc @@ -42,32 +42,20 @@ TEST_F(ValidateControlBlockTest, SwitchSelectorExpressionNoneIntegerType_Fail) { // switch (a) { // default: {} // } - ast::type::F32 f32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &f32, 3.14f)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.f32, Expr(3.14f), + ast::VariableDecorationList{}); auto* cond = create( - Source{Source::Location{12, 34}}, mod()->RegisterSymbol("a"), "a"); + Source{Source::Location{12, 34}}, mod->RegisterSymbol("a"), "a"); ast::CaseSelectorList default_csl; - auto* block_default = - create(Source{}, ast::StatementList{}); + auto* block_default = create(ast::StatementList{}); ast::CaseStatementList body; - body.push_back( - create(Source{}, default_csl, block_default)); + body.push_back(create(default_csl, block_default)); - auto* block = create( - Source{}, ast::StatementList{ - create(Source{}, var), - create(Source{}, cond, body), - }); + auto* block = create(ast::StatementList{ + create(var), + create(cond, body), + }); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_FALSE(v()->ValidateStatements(block)); @@ -81,33 +69,21 @@ TEST_F(ValidateControlBlockTest, SwitchWithoutDefault_Fail) { // switch (a) { // case 1: {} // } - ast::type::I32 i32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - false, // is_const - create( - Source{}, - create(Source{}, &i32, 2)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2), + ast::VariableDecorationList{}); - auto* cond = create( - Source{}, mod()->RegisterSymbol("a"), "a"); + auto* cond = Expr("a"); ast::CaseSelectorList csl; - csl.push_back(create(Source{}, &i32, 1)); + csl.push_back(Literal(1)); ast::CaseStatementList body; body.push_back(create( - Source{}, csl, - create(Source{}, ast::StatementList{}))); + csl, create(ast::StatementList{}))); - auto* block = create( - Source{}, ast::StatementList{ - create(Source{}, var), - create( - Source{Source::Location{12, 34}}, cond, body), - }); + auto* block = create(ast::StatementList{ + create(var), + create(Source{Source::Location{12, 34}}, cond, + body), + }); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_FALSE(v()->ValidateStatements(block)); @@ -123,47 +99,32 @@ TEST_F(ValidateControlBlockTest, SwitchWithTwoDefault_Fail) { // case 1: {} // default: {} // } - ast::type::I32 i32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - false, // is_const - create( - Source{}, - create(Source{}, &i32, 2)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2), + ast::VariableDecorationList{}); ast::CaseStatementList switch_body; - auto* cond = create( - Source{}, mod()->RegisterSymbol("a"), "a"); + auto* cond = Expr("a"); ast::CaseSelectorList default_csl_1; - auto* block_default_1 = - create(Source{}, ast::StatementList{}); + auto* block_default_1 = create(ast::StatementList{}); switch_body.push_back( - create(Source{}, default_csl_1, block_default_1)); + create(default_csl_1, block_default_1)); ast::CaseSelectorList csl_case_1; - csl_case_1.push_back(create(Source{}, &i32, 1)); - auto* block_case_1 = - create(Source{}, ast::StatementList{}); - switch_body.push_back( - create(Source{}, csl_case_1, block_case_1)); + csl_case_1.push_back(Literal(1)); + auto* block_case_1 = create(ast::StatementList{}); + switch_body.push_back(create(csl_case_1, block_case_1)); ast::CaseSelectorList default_csl_2; - auto* block_default_2 = - create(Source{}, ast::StatementList{}); + auto* block_default_2 = create(ast::StatementList{}); switch_body.push_back( - create(Source{}, default_csl_2, block_default_2)); + create(default_csl_2, block_default_2)); - auto* block = create( - Source{}, ast::StatementList{ - create(Source{}, var), - create( - Source{Source::Location{12, 34}}, cond, switch_body), - }); + auto* block = create(ast::StatementList{ + create(var), + create(Source{Source::Location{12, 34}}, cond, + switch_body), + }); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_FALSE(v()->ValidateStatements(block)); @@ -179,40 +140,26 @@ TEST_F(ValidateControlBlockTest, // case 1: {} // default: {} // } - ast::type::U32 u32; - ast::type::I32 i32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - false, // is_const - create( - Source{}, - create(Source{}, &i32, 2)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2), + ast::VariableDecorationList{}); ast::CaseStatementList switch_body; - auto* cond = create( - Source{}, mod()->RegisterSymbol("a"), "a"); + auto* cond = Expr("a"); ast::CaseSelectorList csl; - csl.push_back(create(Source{}, &u32, 1)); + csl.push_back(create(ty.u32, 1)); switch_body.push_back(create( Source{Source::Location{12, 34}}, csl, - create(Source{}, ast::StatementList{}))); + create(ast::StatementList{}))); ast::CaseSelectorList default_csl; - auto* block_default = - create(Source{}, ast::StatementList{}); - switch_body.push_back( - create(Source{}, default_csl, block_default)); + auto* block_default = create(ast::StatementList{}); + switch_body.push_back(create(default_csl, block_default)); - auto* block = create( - Source{}, ast::StatementList{ - create(Source{}, var), - create(Source{}, cond, switch_body), - }); + auto* block = create(ast::StatementList{ + create(var), + create(cond, switch_body), + }); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_FALSE(v()->ValidateStatements(block)); EXPECT_EQ(v()->error(), @@ -227,40 +174,28 @@ TEST_F(ValidateControlBlockTest, // case -1: {} // default: {} // } - ast::type::U32 u32; - ast::type::I32 i32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &u32, // type - false, // is_const - create( - Source{}, - create(Source{}, &u32, 2)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.u32, + create( + create(ty.u32, 2)), + ast::VariableDecorationList{}); ast::CaseStatementList switch_body; - auto* cond = create( - Source{}, mod()->RegisterSymbol("a"), "a"); + auto* cond = Expr("a"); ast::CaseSelectorList csl; - csl.push_back(create(Source{}, &i32, -1)); + csl.push_back(Literal(-1)); switch_body.push_back(create( Source{Source::Location{12, 34}}, csl, - create(Source{}, ast::StatementList{}))); + create(ast::StatementList{}))); ast::CaseSelectorList default_csl; - auto* block_default = - create(Source{}, ast::StatementList{}); - switch_body.push_back( - create(Source{}, default_csl, block_default)); + auto* block_default = create(ast::StatementList{}); + switch_body.push_back(create(default_csl, block_default)); - auto* block = create( - Source{}, ast::StatementList{ - create(Source{}, var), - create(Source{}, cond, switch_body), - }); + auto* block = create(ast::StatementList{ + create(var), + create(cond, switch_body), + }); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_FALSE(v()->ValidateStatements(block)); EXPECT_EQ(v()->error(), @@ -275,46 +210,34 @@ TEST_F(ValidateControlBlockTest, NonUniqueCaseSelectorValueUint_Fail) { // case 2, 2: {} // default: {} // } - ast::type::U32 u32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &u32, // type - false, // is_const - create( - Source{}, - create(Source{}, &u32, 3)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.u32, + create( + create(ty.u32, 3)), + ast::VariableDecorationList{}); ast::CaseStatementList switch_body; - auto* cond = create( - Source{}, mod()->RegisterSymbol("a"), "a"); + auto* cond = Expr("a"); ast::CaseSelectorList csl_1; - csl_1.push_back(create(Source{}, &u32, 0)); + csl_1.push_back(create(ty.u32, 0)); switch_body.push_back(create( - Source{}, csl_1, - create(Source{}, ast::StatementList{}))); + csl_1, create(ast::StatementList{}))); ast::CaseSelectorList csl_2; - csl_2.push_back(create(Source{}, &u32, 2)); - csl_2.push_back(create(Source{}, &u32, 2)); + csl_2.push_back(create(ty.u32, 2)); + csl_2.push_back(create(ty.u32, 2)); switch_body.push_back(create( Source{Source::Location{12, 34}}, csl_2, - create(Source{}, ast::StatementList{}))); + create(ast::StatementList{}))); ast::CaseSelectorList default_csl; - auto* block_default = - create(Source{}, ast::StatementList{}); - switch_body.push_back( - create(Source{}, default_csl, block_default)); + auto* block_default = create(ast::StatementList{}); + switch_body.push_back(create(default_csl, block_default)); - auto* block = create( - Source{}, ast::StatementList{ - create(Source{}, var), - create(Source{}, cond, switch_body), - }); + auto* block = create(ast::StatementList{ + create(var), + create(cond, switch_body), + }); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_FALSE(v()->ValidateStatements(block)); EXPECT_EQ(v()->error(), @@ -329,48 +252,34 @@ TEST_F(ValidateControlBlockTest, NonUniqueCaseSelectorValueSint_Fail) { // case 0,1,2,10: {} // default: {} // } - ast::type::I32 i32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - false, // is_const - create( - Source{}, - create(Source{}, &i32, 2)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2), + ast::VariableDecorationList{}); ast::CaseStatementList switch_body; - auto* cond = create( - Source{}, mod()->RegisterSymbol("a"), "a"); + auto* cond = Expr("a"); ast::CaseSelectorList csl_1; - csl_1.push_back(create(Source{}, &i32, 10)); + csl_1.push_back(Literal(10)); switch_body.push_back(create( - Source{}, csl_1, - create(Source{}, ast::StatementList{}))); + csl_1, create(ast::StatementList{}))); ast::CaseSelectorList csl_2; - csl_2.push_back(create(Source{}, &i32, 0)); - csl_2.push_back(create(Source{}, &i32, 1)); - csl_2.push_back(create(Source{}, &i32, 2)); - csl_2.push_back(create(Source{}, &i32, 10)); + csl_2.push_back(Literal(0)); + csl_2.push_back(Literal(1)); + csl_2.push_back(Literal(2)); + csl_2.push_back(Literal(10)); switch_body.push_back(create( Source{Source::Location{12, 34}}, csl_2, - create(Source{}, ast::StatementList{}))); + create(ast::StatementList{}))); ast::CaseSelectorList default_csl; - auto* block_default = - create(Source{}, ast::StatementList{}); - switch_body.push_back( - create(Source{}, default_csl, block_default)); + auto* block_default = create(ast::StatementList{}); + switch_body.push_back(create(default_csl, block_default)); - auto* block = create( - Source{}, ast::StatementList{ - create(Source{}, var), - create(Source{}, cond, switch_body), - }); + auto* block = create(ast::StatementList{ + create(var), + create(cond, switch_body), + }); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_FALSE(v()->ValidateStatements(block)); EXPECT_EQ(v()->error(), @@ -383,35 +292,23 @@ TEST_F(ValidateControlBlockTest, LastClauseLastStatementIsFallthrough_Fail) { // switch (a) { // default: { fallthrough; } // } - ast::type::I32 i32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - false, // is_const - create( - Source{}, - create(Source{}, &i32, 2)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2), + ast::VariableDecorationList{}); - auto* cond = create( - Source{}, mod()->RegisterSymbol("a"), "a"); + auto* cond = Expr("a"); ast::CaseSelectorList default_csl; auto* block_default = create( - Source{}, + ast::StatementList{ create(Source{Source::Location{12, 34}}), }); ast::CaseStatementList body; - body.push_back( - create(Source{}, default_csl, block_default)); + body.push_back(create(default_csl, block_default)); - auto* block = create( - Source{}, ast::StatementList{ - create(Source{}, var), - create(Source{}, cond, body), - }); + auto* block = create(ast::StatementList{ + create(var), + create(cond, body), + }); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_FALSE(v()->ValidateStatements(block)); EXPECT_EQ(v()->error(), @@ -425,37 +322,24 @@ TEST_F(ValidateControlBlockTest, SwitchCase_Pass) { // default: {} // case 5: {} // } - ast::type::I32 i32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - false, // is_const - create( - Source{}, - create(Source{}, &i32, 2)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2), + ast::VariableDecorationList{}); - auto* cond = create( - Source{}, mod()->RegisterSymbol("a"), "a"); + auto* cond = Expr("a"); ast::CaseSelectorList default_csl; - auto* block_default = - create(Source{}, ast::StatementList{}); + auto* block_default = create(ast::StatementList{}); ast::CaseStatementList body; body.push_back(create(Source{Source::Location{12, 34}}, default_csl, block_default)); ast::CaseSelectorList case_csl; - case_csl.push_back(create(Source{}, &i32, 5)); - auto* block_case = - create(Source{}, ast::StatementList{}); - body.push_back(create(Source{}, case_csl, block_case)); + case_csl.push_back(Literal(5)); + auto* block_case = create(ast::StatementList{}); + body.push_back(create(case_csl, block_case)); - auto* block = create( - Source{}, ast::StatementList{ - create(Source{}, var), - create(Source{}, cond, body), - }); + auto* block = create(ast::StatementList{ + create(var), + create(cond, body), + }); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_TRUE(v()->ValidateStatements(block)) << v()->error(); } @@ -467,35 +351,23 @@ TEST_F(ValidateControlBlockTest, SwitchCaseAlias_Pass) { // default: {} // } - ast::type::U32 u32; - ast::type::Alias my_int{mod()->RegisterSymbol("MyInt"), "MyInt", &u32}; + ast::type::Alias my_int{mod->RegisterSymbol("MyInt"), "MyInt", ty.u32}; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &my_int, // type - false, // is_const - create( - Source{}, - create(Source{}, &u32, 2)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, &my_int, Expr(2u), + ast::VariableDecorationList{}); - auto* cond = create( - Source{}, mod()->RegisterSymbol("a"), "a"); + auto* cond = Expr("a"); ast::CaseSelectorList default_csl; - auto* block_default = - create(Source{}, ast::StatementList{}); + auto* block_default = create(ast::StatementList{}); ast::CaseStatementList body; body.push_back(create(Source{Source::Location{12, 34}}, default_csl, block_default)); - auto* block = create( - Source{}, ast::StatementList{ - create(Source{}, var), - create(Source{}, cond, body), - }); - mod()->AddConstructedType(&my_int); + auto* block = create(ast::StatementList{ + create(var), + create(cond, body), + }); + mod->AddConstructedType(&my_int); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_TRUE(v()->ValidateStatements(block)) << v()->error(); diff --git a/src/validator/validator_function_test.cc b/src/validator/validator_function_test.cc index 94db436708..5d2b2466cf 100644 --- a/src/validator/validator_function_test.cc +++ b/src/validator/validator_function_test.cc @@ -38,100 +38,74 @@ class ValidateFunctionTest : public ValidatorTestHelper, TEST_F(ValidateFunctionTest, VoidFunctionEndWithoutReturnStatement_Pass) { // [[stage(vertex)]] // fn func -> void { var a:i32 = 2; } - ast::type::I32 i32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - false, // is_const - create( - Source{}, - create(Source{}, &i32, 2)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2), + ast::VariableDecorationList{}); ast::VariableList params; - ast::type::Void void_type; - auto* body = create( - Source{}, ast::StatementList{ - create(Source{}, var), - }); + auto* body = create(ast::StatementList{ + create(var), + }); auto* func = create( - Source{Source::Location{12, 34}}, mod()->RegisterSymbol("func"), "func", - params, &void_type, body, + Source{Source::Location{12, 34}}, mod->RegisterSymbol("func"), "func", + params, ty.void_, body, ast::FunctionDecorationList{ - create(Source{}, ast::PipelineStage::kVertex), + create(ast::PipelineStage::kVertex), }); - mod()->AddFunction(func); + mod->AddFunction(func); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_TRUE(v()->Validate(mod())); + EXPECT_TRUE(v()->Validate(mod)); } TEST_F(ValidateFunctionTest, VoidFunctionEndWithoutReturnStatementEmptyBody_Pass) { // [[stage(vertex)]] // fn func -> void {} - ast::type::Void void_type; ast::VariableList params; auto* func = create( - Source{Source::Location{12, 34}}, mod()->RegisterSymbol("func"), "func", - params, &void_type, - create(Source{}, ast::StatementList{}), + Source{Source::Location{12, 34}}, mod->RegisterSymbol("func"), "func", + params, ty.void_, create(ast::StatementList{}), ast::FunctionDecorationList{ - create(Source{}, ast::PipelineStage::kVertex), + create(ast::PipelineStage::kVertex), }); - mod()->AddFunction(func); + mod->AddFunction(func); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_TRUE(v()->Validate(mod())); + EXPECT_TRUE(v()->Validate(mod)); } TEST_F(ValidateFunctionTest, FunctionEndWithoutReturnStatement_Fail) { // fn func -> int { var a:i32 = 2; } - ast::type::I32 i32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - false, // is_const - create( - Source{}, - create(Source{}, &i32, 2)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2), + ast::VariableDecorationList{}); ast::VariableList params; - ast::type::Void void_type; - auto* body = create( - Source{}, ast::StatementList{ - create(Source{}, var), - }); + auto* body = create(ast::StatementList{ + create(var), + }); auto* func = create( - Source{Source::Location{12, 34}}, mod()->RegisterSymbol("func"), "func", - params, &i32, body, ast::FunctionDecorationList{}); - mod()->AddFunction(func); + Source{Source::Location{12, 34}}, mod->RegisterSymbol("func"), "func", + params, ty.i32, body, ast::FunctionDecorationList{}); + mod->AddFunction(func); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())); + EXPECT_FALSE(v()->Validate(mod)); EXPECT_EQ(v()->error(), "12:34 v-0002: non-void function must end with a return statement"); } TEST_F(ValidateFunctionTest, FunctionEndWithoutReturnStatementEmptyBody_Fail) { // fn func -> int {} - ast::type::Void void_type; - ast::type::I32 i32; ast::VariableList params; auto* func = create( - Source{Source::Location{12, 34}}, mod()->RegisterSymbol("func"), "func", - params, &i32, create(Source{}, ast::StatementList{}), + Source{Source::Location{12, 34}}, mod->RegisterSymbol("func"), "func", + params, ty.i32, create(ast::StatementList{}), ast::FunctionDecorationList{}); - mod()->AddFunction(func); + mod->AddFunction(func); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())); + EXPECT_FALSE(v()->Validate(mod)); EXPECT_EQ(v()->error(), "12:34 v-0002: non-void function must end with a return statement"); } @@ -139,45 +113,39 @@ TEST_F(ValidateFunctionTest, FunctionEndWithoutReturnStatementEmptyBody_Fail) { TEST_F(ValidateFunctionTest, FunctionTypeMustMatchReturnStatementType_Pass) { // [[stage(vertex)]] // fn func -> void { return; } - ast::type::Void void_type; ast::VariableList params; - auto* body = create( - Source{}, ast::StatementList{ - create(Source{}), - }); + auto* body = create(ast::StatementList{ + create(), + }); auto* func = create( - Source{}, mod()->RegisterSymbol("func"), "func", params, &void_type, body, + mod->RegisterSymbol("func"), "func", params, ty.void_, body, ast::FunctionDecorationList{ - create(Source{}, ast::PipelineStage::kVertex), + create(ast::PipelineStage::kVertex), }); - mod()->AddFunction(func); + mod->AddFunction(func); - EXPECT_TRUE(td()->DetermineFunctions(mod()->functions())) << td()->error(); - EXPECT_TRUE(v()->ValidateFunctions(mod()->functions())) << v()->error(); + EXPECT_TRUE(td()->DetermineFunctions(mod->functions())) << td()->error(); + EXPECT_TRUE(v()->ValidateFunctions(mod->functions())) << v()->error(); } TEST_F(ValidateFunctionTest, FunctionTypeMustMatchReturnStatementType_fail) { // fn func -> void { return 2; } - ast::type::Void void_type; - ast::type::I32 i32; ast::VariableList params; - auto* return_expr = create( - Source{}, create(Source{}, &i32, 2)); + auto* return_expr = Expr(2); - auto* body = create( - Source{}, ast::StatementList{ - create( - Source{Source::Location{12, 34}}, return_expr), - }); + auto* body = create(ast::StatementList{ + create(Source{Source::Location{12, 34}}, + return_expr), + }); - auto* func = create(Source{}, mod()->RegisterSymbol("func"), - "func", params, &void_type, body, - ast::FunctionDecorationList{}); - mod()->AddFunction(func); + auto* func = + create(mod->RegisterSymbol("func"), "func", params, + ty.void_, body, ast::FunctionDecorationList{}); + mod->AddFunction(func); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())); + 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 " @@ -186,25 +154,21 @@ TEST_F(ValidateFunctionTest, FunctionTypeMustMatchReturnStatementType_fail) { TEST_F(ValidateFunctionTest, FunctionTypeMustMatchReturnStatementTypeF32_fail) { // fn func -> f32 { return 2; } - ast::type::I32 i32; - ast::type::F32 f32; ast::VariableList params; - auto* return_expr = create( - Source{}, create(Source{}, &i32, 2)); + auto* return_expr = Expr(2); - auto* body = create( - Source{}, ast::StatementList{ - create( - Source{Source::Location{12, 34}}, return_expr), - }); + auto* body = create(ast::StatementList{ + create(Source{Source::Location{12, 34}}, + return_expr), + }); auto* func = - create(Source{}, mod()->RegisterSymbol("func"), "func", - params, &f32, body, ast::FunctionDecorationList{}); - mod()->AddFunction(func); + create(mod->RegisterSymbol("func"), "func", params, ty.f32, + body, ast::FunctionDecorationList{}); + mod->AddFunction(func); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())); + 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 " @@ -214,127 +178,100 @@ TEST_F(ValidateFunctionTest, FunctionTypeMustMatchReturnStatementTypeF32_fail) { TEST_F(ValidateFunctionTest, FunctionNamesMustBeUnique_fail) { // fn func -> i32 { return 2; } // fn func -> i32 { return 2; } - ast::type::Void void_type; - ast::type::I32 i32; ast::VariableList params; - auto* return_expr = create( - Source{}, create(Source{}, &i32, 2)); + auto* return_expr = Expr(2); - auto* body = create( - Source{}, ast::StatementList{ - create(Source{}, return_expr), - }); + auto* body = create(ast::StatementList{ + create(return_expr), + }); auto* func = - create(Source{}, mod()->RegisterSymbol("func"), "func", - params, &i32, body, ast::FunctionDecorationList{}); + create(mod->RegisterSymbol("func"), "func", params, ty.i32, + body, ast::FunctionDecorationList{}); ast::VariableList params_copy; - auto* return_expr_copy = create( - Source{}, create(Source{}, &i32, 2)); - auto* body_copy = create( - Source{}, ast::StatementList{ - create(Source{}, return_expr_copy), - }); + auto* return_expr_copy = Expr(2); + auto* body_copy = create(ast::StatementList{ + create(return_expr_copy), + }); auto* func_copy = create( - Source{Source::Location{12, 34}}, mod()->RegisterSymbol("func"), "func", - params_copy, &i32, body_copy, ast::FunctionDecorationList{}); + Source{Source::Location{12, 34}}, mod->RegisterSymbol("func"), "func", + params_copy, ty.i32, body_copy, ast::FunctionDecorationList{}); - mod()->AddFunction(func); - mod()->AddFunction(func_copy); + mod->AddFunction(func); + mod->AddFunction(func_copy); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())); + EXPECT_FALSE(v()->Validate(mod)); EXPECT_EQ(v()->error(), "12:34 v-0016: function names must be unique 'func'"); } TEST_F(ValidateFunctionTest, RecursionIsNotAllowed_Fail) { // fn func() -> void {func(); return; } - ast::type::F32 f32; - ast::type::Void void_type; ast::ExpressionList call_params; auto* call_expr = create( - Source{Source::Location{12, 34}}, - create(Source{}, mod()->RegisterSymbol("func"), - "func"), - call_params); + Source{Source::Location{12, 34}}, Expr("func"), call_params); ast::VariableList params0; - auto* body0 = create( - Source{}, ast::StatementList{ - create(Source{}, call_expr), - create(Source{}), - }); - auto* func0 = create(Source{}, mod()->RegisterSymbol("func"), - "func", params0, &f32, body0, - ast::FunctionDecorationList{}); - mod()->AddFunction(func0); + auto* body0 = create(ast::StatementList{ + create(call_expr), + create(), + }); + auto* func0 = + create(mod->RegisterSymbol("func"), "func", params0, + ty.f32, body0, ast::FunctionDecorationList{}); + mod->AddFunction(func0); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())) << v()->error(); + EXPECT_FALSE(v()->Validate(mod)) << v()->error(); EXPECT_EQ(v()->error(), "12:34 v-0004: recursion is not allowed: 'func'"); } TEST_F(ValidateFunctionTest, RecursionIsNotAllowedExpr_Fail) { // fn func() -> i32 {var a: i32 = func(); return 2; } - ast::type::I32 i32; ast::ExpressionList call_params; auto* call_expr = create( - Source{Source::Location{12, 34}}, - create(Source{}, mod()->RegisterSymbol("func"), - "func"), - call_params); - auto* var = - create(Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - false, // is_const - call_expr, // constructor - ast::VariableDecorationList{}); // decorations + Source{Source::Location{12, 34}}, Expr("func"), call_params); + auto* var = Var("a", ast::StorageClass::kNone, ty.i32, call_expr, + ast::VariableDecorationList{}); ast::VariableList params0; - auto* return_expr = create( - Source{}, create(Source{}, &i32, 2)); + auto* return_expr = Expr(2); - auto* body0 = create( - Source{}, ast::StatementList{ - create(Source{}, var), - create(Source{}, return_expr), - }); + auto* body0 = create(ast::StatementList{ + create(var), + create(return_expr), + }); - auto* func0 = create(Source{}, mod()->RegisterSymbol("func"), - "func", params0, &i32, body0, - ast::FunctionDecorationList{}); - mod()->AddFunction(func0); + auto* func0 = + create(mod->RegisterSymbol("func"), "func", params0, + ty.i32, body0, ast::FunctionDecorationList{}); + mod->AddFunction(func0); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())) << v()->error(); + EXPECT_FALSE(v()->Validate(mod)) << v()->error(); EXPECT_EQ(v()->error(), "12:34 v-0004: recursion is not allowed: 'func'"); } TEST_F(ValidateFunctionTest, Function_WithPipelineStage_NotVoid_Fail) { // [[stage(vertex)]] // fn vtx_main() -> i32 { return 0; } - ast::type::I32 i32; ast::VariableList params; - auto* return_expr = create( - Source{}, create(Source{}, &i32, 0)); + auto* return_expr = Expr(0); - auto* body = create( - Source{}, ast::StatementList{ - create(Source{}, return_expr), - }); + auto* body = create(ast::StatementList{ + create(return_expr), + }); auto* func = create( - Source{Source::Location{12, 34}}, mod()->RegisterSymbol("vtx_main"), - "vtx_main", params, &i32, body, + Source{Source::Location{12, 34}}, mod->RegisterSymbol("vtx_main"), + "vtx_main", params, ty.i32, body, ast::FunctionDecorationList{ - create(Source{}, ast::PipelineStage::kVertex), + create(ast::PipelineStage::kVertex), }); - mod()->AddFunction(func); + mod->AddFunction(func); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())); + EXPECT_FALSE(v()->Validate(mod)); EXPECT_EQ(v()->error(), "12:34 v-0024: Entry point function must return void: 'vtx_main'"); } @@ -342,31 +279,22 @@ TEST_F(ValidateFunctionTest, Function_WithPipelineStage_NotVoid_Fail) { TEST_F(ValidateFunctionTest, Function_WithPipelineStage_WithParams_Fail) { // [[stage(vertex)]] // fn vtx_func(a : i32) -> void { return; } - ast::type::I32 i32; - ast::type::Void void_type; ast::VariableList params; - params.push_back( - create(Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - false, // is_const - nullptr, // constructor - ast::VariableDecorationList{})); // decorations - auto* body = create( - Source{}, ast::StatementList{ - create(Source{}), - }); + params.push_back(Var("a", ast::StorageClass::kNone, ty.i32, nullptr, + ast::VariableDecorationList{})); + auto* body = create(ast::StatementList{ + create(), + }); auto* func = create( - Source{Source::Location{12, 34}}, mod()->RegisterSymbol("vtx_func"), - "vtx_func", params, &void_type, body, + Source{Source::Location{12, 34}}, mod->RegisterSymbol("vtx_func"), + "vtx_func", params, ty.void_, body, ast::FunctionDecorationList{ - create(Source{}, ast::PipelineStage::kVertex), + create(ast::PipelineStage::kVertex), }); - mod()->AddFunction(func); + mod->AddFunction(func); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())); + EXPECT_FALSE(v()->Validate(mod)); EXPECT_EQ(v()->error(), "12:34 v-0023: Entry point function must accept no parameters: " "'vtx_func'"); @@ -376,23 +304,21 @@ TEST_F(ValidateFunctionTest, PipelineStage_MustBeUnique_Fail) { // [[stage(fragment)]] // [[stage(vertex)]] // fn main() -> void { return; } - ast::type::Void void_type; ast::VariableList params; - auto* body = create( - Source{}, ast::StatementList{ - create(Source{}), - }); + auto* body = create(ast::StatementList{ + create(), + }); auto* func = create( - Source{Source::Location{12, 34}}, mod()->RegisterSymbol("main"), "main", - params, &void_type, body, + Source{Source::Location{12, 34}}, mod->RegisterSymbol("main"), "main", + params, ty.void_, body, ast::FunctionDecorationList{ - create(Source{}, ast::PipelineStage::kVertex), - create(Source{}, ast::PipelineStage::kFragment), + create(ast::PipelineStage::kVertex), + create(ast::PipelineStage::kFragment), }); - mod()->AddFunction(func); + mod->AddFunction(func); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())); + EXPECT_FALSE(v()->Validate(mod)); EXPECT_EQ( v()->error(), "12:34 v-0020: only one stage decoration permitted per entry point"); @@ -401,39 +327,34 @@ TEST_F(ValidateFunctionTest, PipelineStage_MustBeUnique_Fail) { TEST_F(ValidateFunctionTest, OnePipelineStageFunctionMustBePresent_Pass) { // [[stage(vertex)]] // fn vtx_func() -> void { return; } - ast::type::Void void_type; ast::VariableList params; - auto* body = create( - Source{}, ast::StatementList{ - create(Source{}), - }); + auto* body = create(ast::StatementList{ + create(), + }); auto* func = create( - Source{}, mod()->RegisterSymbol("vtx_func"), "vtx_func", params, - &void_type, body, + mod->RegisterSymbol("vtx_func"), "vtx_func", params, ty.void_, body, ast::FunctionDecorationList{ - create(Source{}, ast::PipelineStage::kVertex), + create(ast::PipelineStage::kVertex), }); - mod()->AddFunction(func); + mod->AddFunction(func); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_TRUE(v()->Validate(mod())) << v()->error(); + EXPECT_TRUE(v()->Validate(mod)) << v()->error(); } TEST_F(ValidateFunctionTest, OnePipelineStageFunctionMustBePresent_Fail) { // fn vtx_func() -> void { return; } - ast::type::Void void_type; ast::VariableList params; - auto* body = create( - Source{}, ast::StatementList{ - create(Source{}), - }); - auto* func = create( - Source{}, mod()->RegisterSymbol("vtx_func"), "vtx_func", params, - &void_type, body, ast::FunctionDecorationList{}); - mod()->AddFunction(func); + auto* body = create(ast::StatementList{ + create(), + }); + auto* func = + create(mod->RegisterSymbol("vtx_func"), "vtx_func", params, + ty.void_, body, ast::FunctionDecorationList{}); + mod->AddFunction(func); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())); + EXPECT_FALSE(v()->Validate(mod)); EXPECT_EQ(v()->error(), "v-0003: At least one of vertex, fragment or compute shader must " "be present"); diff --git a/src/validator/validator_test.cc b/src/validator/validator_test.cc index e6176074bb..7a19bb5bfd 100644 --- a/src/validator/validator_test.cc +++ b/src/validator/validator_test.cc @@ -62,13 +62,11 @@ class ValidatorTest : public ValidatorTestHelper, public testing::Test {}; TEST_F(ValidatorTest, DISABLED_AssignToScalar_Fail) { // 1 = my_var; - ast::type::I32 i32; - auto* lhs = create( - Source{}, create(Source{}, &i32, 1)); - auto* rhs = create( - Source{}, mod()->RegisterSymbol("my_var"), "my_var"); - ast::AssignmentStatement assign(Source{Source::Location{12, 34}}, lhs, rhs); + auto* lhs = Expr(1); + auto* rhs = Expr("my_var"); + SetSource(Source{Source::Location{12, 34}}); + create(lhs, rhs); // TODO(sarahM0): Invalidate assignment to scalar. ASSERT_TRUE(v()->has_error()); @@ -78,14 +76,11 @@ TEST_F(ValidatorTest, DISABLED_AssignToScalar_Fail) { TEST_F(ValidatorTest, UsingUndefinedVariable_Fail) { // b = 2; - ast::type::I32 i32; - auto* lhs = create( - Source{Source::Location{12, 34}}, mod()->RegisterSymbol("b"), "b"); - auto* rhs = create( - Source{}, create(Source{}, &i32, 2)); - auto* assign = create( - Source{Source::Location{12, 34}}, lhs, rhs); + SetSource(Source{Source::Location{12, 34}}); + auto* lhs = Expr("b"); + auto* rhs = Expr(2); + auto* assign = create(lhs, rhs); EXPECT_FALSE(td()->DetermineResultType(assign)); EXPECT_EQ(td()->error(), @@ -96,18 +91,14 @@ TEST_F(ValidatorTest, UsingUndefinedVariableInBlockStatement_Fail) { // { // b = 2; // } - ast::type::I32 i32; - auto* lhs = create( - Source{Source::Location{12, 34}}, mod()->RegisterSymbol("b"), "b"); - auto* rhs = create( - Source{}, create(Source{}, &i32, 2)); + SetSource(Source{Source::Location{12, 34}}); + auto* lhs = Expr("b"); + auto* rhs = Expr(2); - auto* body = create( - Source{}, ast::StatementList{ - create( - Source{Source::Location{12, 34}}, lhs, rhs), - }); + auto* body = create(ast::StatementList{ + create(lhs, rhs), + }); EXPECT_FALSE(td()->DetermineStatements(body)); EXPECT_EQ(td()->error(), @@ -117,29 +108,19 @@ TEST_F(ValidatorTest, UsingUndefinedVariableInBlockStatement_Fail) { TEST_F(ValidatorTest, AssignCompatibleTypes_Pass) { // var a :i32 = 2; // a = 2 - ast::type::I32 i32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - false, // is_const - create( - Source{}, - create(Source{}, &i32, 2)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2), + ast::VariableDecorationList{}); - auto* lhs = create( - Source{}, mod()->RegisterSymbol("a"), "a"); - auto* rhs = create( - Source{}, create(Source{}, &i32, 2)); + auto* lhs = Expr("a"); + auto* rhs = Expr(2); - ast::AssignmentStatement assign(Source{Source::Location{12, 34}}, lhs, rhs); + auto* assign = create( + Source{Source::Location{12, 34}}, lhs, rhs); td()->RegisterVariableForTesting(var); - EXPECT_TRUE(td()->DetermineResultType(&assign)) << td()->error(); + EXPECT_TRUE(td()->DetermineResultType(assign)) << td()->error(); ASSERT_NE(lhs->result_type(), nullptr); ASSERT_NE(rhs->result_type(), nullptr); - EXPECT_TRUE(v()->ValidateResultTypes(&assign)); + EXPECT_TRUE(v()->ValidateResultTypes(assign)); } TEST_F(ValidatorTest, AssignIncompatibleTypes_Fail) { @@ -147,32 +128,21 @@ TEST_F(ValidatorTest, AssignIncompatibleTypes_Fail) { // var a :i32 = 2; // a = 2.3; // } - ast::type::F32 f32; - ast::type::I32 i32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - false, // is_const - create( - Source{}, - create(Source{}, &i32, 2)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2), + ast::VariableDecorationList{}); - auto* lhs = create( - Source{}, mod()->RegisterSymbol("a"), "a"); - auto* rhs = create( - Source{}, create(Source{}, &f32, 2.3f)); + auto* lhs = Expr("a"); + auto* rhs = Expr(2.3f); - ast::AssignmentStatement assign(Source{Source::Location{12, 34}}, lhs, rhs); + auto* assign = create( + Source{Source::Location{12, 34}}, lhs, rhs); td()->RegisterVariableForTesting(var); - EXPECT_TRUE(td()->DetermineResultType(&assign)) << td()->error(); + EXPECT_TRUE(td()->DetermineResultType(assign)) << td()->error(); ASSERT_NE(lhs->result_type(), nullptr); ASSERT_NE(rhs->result_type(), nullptr); - EXPECT_FALSE(v()->ValidateResultTypes(&assign)); + EXPECT_FALSE(v()->ValidateResultTypes(assign)); ASSERT_TRUE(v()->has_error()); // TODO(sarahM0): figure out what should be the error number. EXPECT_EQ(v()->error(), @@ -184,29 +154,17 @@ TEST_F(ValidatorTest, AssignCompatibleTypesInBlockStatement_Pass) { // var a :i32 = 2; // a = 2 // } - ast::type::I32 i32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - false, // is_const - create( - Source{}, - create(Source{}, &i32, 2)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2), + ast::VariableDecorationList{}); - auto* lhs = create( - Source{}, mod()->RegisterSymbol("a"), "a"); - auto* rhs = create( - Source{}, create(Source{}, &i32, 2)); + auto* lhs = Expr("a"); + auto* rhs = Expr(2); - auto* body = create( - Source{}, ast::StatementList{ - create(Source{}, var), - create( - Source{Source::Location{12, 34}}, lhs, rhs), - }); + auto* body = create(ast::StatementList{ + create(var), + create(Source{Source::Location{12, 34}}, lhs, + rhs), + }); EXPECT_TRUE(td()->DetermineStatements(body)) << td()->error(); ASSERT_NE(lhs->result_type(), nullptr); @@ -220,36 +178,24 @@ TEST_F(ValidatorTest, AssignIncompatibleTypesInBlockStatement_Fail) { // var a :i32 = 2; // a = 2.3; // } - ast::type::F32 f32; - ast::type::I32 i32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - false, // is_const - create( - Source{}, - create(Source{}, &i32, 2)), // constructor - ast::VariableDecorationList{}); // decorations - auto* lhs = create( - Source{}, mod()->RegisterSymbol("a"), "a"); - auto* rhs = create( - Source{}, create(Source{}, &f32, 2.3f)); + auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2), + ast::VariableDecorationList{}); - ast::BlockStatement block( - Source{}, ast::StatementList{ - create(Source{}, var), - create( - Source{Source::Location{12, 34}}, lhs, rhs), - }); + auto* lhs = Expr("a"); + auto* rhs = Expr(2.3f); - EXPECT_TRUE(td()->DetermineStatements(&block)) << td()->error(); + auto* block = create(ast::StatementList{ + create(var), + create(Source{Source::Location{12, 34}}, lhs, + rhs), + }); + + EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); ASSERT_NE(lhs->result_type(), nullptr); ASSERT_NE(rhs->result_type(), nullptr); - EXPECT_FALSE(v()->ValidateStatements(&block)); + EXPECT_FALSE(v()->ValidateStatements(block)); ASSERT_TRUE(v()->has_error()); // TODO(sarahM0): figure out what should be the error number. EXPECT_EQ(v()->error(), @@ -258,49 +204,31 @@ TEST_F(ValidatorTest, AssignIncompatibleTypesInBlockStatement_Fail) { TEST_F(ValidatorTest, GlobalVariableWithStorageClass_Pass) { // var gloabl_var: f32; - ast::type::F32 f32; - mod()->AddGlobalVariable( - create(Source{Source::Location{12, 34}}, // source - "global_var", // name - ast::StorageClass::kInput, // storage_class - &f32, // type - false, // is_const - nullptr, // constructor - ast::VariableDecorationList{})); // decorations - EXPECT_TRUE(v()->ValidateGlobalVariables(mod()->global_variables())) + mod->AddGlobalVariable(Var(Source{Source::Location{12, 34}}, "global_var", + ast::StorageClass::kInput, ty.f32, nullptr, + ast::VariableDecorationList{})); + EXPECT_TRUE(v()->ValidateGlobalVariables(mod->global_variables())) << v()->error(); } TEST_F(ValidatorTest, GlobalVariableNoStorageClass_Fail) { // var gloabl_var: f32; - ast::type::F32 f32; - mod()->AddGlobalVariable( - create(Source{Source::Location{12, 34}}, // source - "global_var", // name - ast::StorageClass::kNone, // storage_class - &f32, // type - false, // is_const - nullptr, // constructor - ast::VariableDecorationList{})); // decorations + mod->AddGlobalVariable(Var(Source{Source::Location{12, 34}}, "global_var", + ast::StorageClass::kNone, ty.f32, nullptr, + ast::VariableDecorationList{})); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())); + EXPECT_FALSE(v()->Validate(mod)); EXPECT_EQ(v()->error(), "12:34 v-0022: global variables must have a storage class"); } TEST_F(ValidatorTest, GlobalConstantWithStorageClass_Fail) { // const gloabl_var: f32; - ast::type::F32 f32; - mod()->AddGlobalVariable( - create(Source{Source::Location{12, 34}}, // source - "global_var", // name - ast::StorageClass::kInput, // storage_class - &f32, // type - true, // is_const - nullptr, // constructor - ast::VariableDecorationList{})); // decorations + mod->AddGlobalVariable(Const(Source{Source::Location{12, 34}}, "global_var", + ast::StorageClass::kInput, ty.f32, nullptr, + ast::VariableDecorationList{})); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())); + EXPECT_FALSE(v()->Validate(mod)); EXPECT_EQ( v()->error(), "12:34 v-global01: global constants shouldn't have a storage class"); @@ -308,17 +236,11 @@ TEST_F(ValidatorTest, GlobalConstantWithStorageClass_Fail) { TEST_F(ValidatorTest, GlobalConstNoStorageClass_Pass) { // const gloabl_var: f32; - ast::type::F32 f32; - mod()->AddGlobalVariable( - create(Source{Source::Location{12, 34}}, // source - "global_var", // name - ast::StorageClass::kNone, // storage_class - &f32, // type - true, // is_const - nullptr, // constructor - ast::VariableDecorationList{})); // decorations + mod->AddGlobalVariable(Const(Source{Source::Location{12, 34}}, "global_var", + ast::StorageClass::kNone, ty.f32, nullptr, + ast::VariableDecorationList{})); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())) << v()->error(); + EXPECT_FALSE(v()->Validate(mod)) << v()->error(); } TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Fail) { @@ -326,37 +248,25 @@ TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Fail) { // fn my_func() -> f32 { // not_global_var = 3.14f; // } - ast::type::F32 f32; - mod()->AddGlobalVariable(create( - Source{}, // source - "global_var", // name - ast::StorageClass::kPrivate, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &f32, 2.1)), // constructor - ast::VariableDecorationList{})); // decorations + mod->AddGlobalVariable(Var("global_var", ast::StorageClass::kPrivate, ty.f32, + Expr(2.1f), ast::VariableDecorationList{})); - auto* lhs = create( - Source{Source::Location{12, 34}}, mod()->RegisterSymbol("not_global_var"), - "not_global_var"); - auto* rhs = create( - Source{}, create(Source{}, &f32, 3.14f)); + SetSource(Source{Source::Location{12, 34}}); + auto* lhs = Expr("not_global_var"); + auto* rhs = Expr(3.14f); ast::VariableList params; - auto* body = create( - Source{}, ast::StatementList{ - create( - Source{Source::Location{12, 34}}, lhs, rhs), - }); + auto* body = create(ast::StatementList{ + create(Source{Source::Location{12, 34}}, lhs, + rhs), + }); - auto* func = create(Source{}, mod()->RegisterSymbol("my_func"), - "my_func", params, &f32, body, - ast::FunctionDecorationList{}); - mod()->AddFunction(func); + auto* func = + create(mod->RegisterSymbol("my_func"), "my_func", params, + ty.f32, body, ast::FunctionDecorationList{}); + mod->AddFunction(func); - EXPECT_FALSE(v()->Validate(mod())); + EXPECT_FALSE(v()->Validate(mod)); EXPECT_EQ(v()->error(), "12:34 v-0006: 'not_global_var' is not declared"); } @@ -366,44 +276,31 @@ TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Pass) { // global_var = 3.14; // return; // } - ast::type::F32 f32; - ast::type::Void void_type; - mod()->AddGlobalVariable(create( - Source{}, // source - "global_var", // name - ast::StorageClass::kPrivate, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &f32, 2.1)), // constructor - ast::VariableDecorationList{})); // decorations + mod->AddGlobalVariable(Var("global_var", ast::StorageClass::kPrivate, ty.f32, + Expr(2.1f), ast::VariableDecorationList{})); auto* lhs = create( - Source{}, mod()->RegisterSymbol("global_var"), "global_var"); - auto* rhs = create( - Source{}, create(Source{}, &f32, 3.14f)); + mod->RegisterSymbol("global_var"), "global_var"); + auto* rhs = Expr(3.14f); ast::VariableList params; - auto* body = create( - Source{}, ast::StatementList{ - create( - Source{Source::Location{12, 34}}, lhs, rhs), - create(Source{}), - }); + auto* body = create(ast::StatementList{ + create(Source{Source::Location{12, 34}}, lhs, + rhs), + create(), + }); auto* func = create( - Source{}, mod()->RegisterSymbol("my_func"), "my_func", params, &void_type, - body, + mod->RegisterSymbol("my_func"), "my_func", params, ty.void_, body, ast::FunctionDecorationList{ - create(Source{}, ast::PipelineStage::kVertex), + create(ast::PipelineStage::kVertex), }); - mod()->AddFunction(func); + mod->AddFunction(func); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_TRUE(v()->Validate(mod())) << v()->error(); + EXPECT_TRUE(v()->Validate(mod)) << v()->error(); } TEST_F(ValidatorTest, UsingUndefinedVariableInnerScope_Fail) { @@ -411,38 +308,24 @@ TEST_F(ValidatorTest, UsingUndefinedVariableInnerScope_Fail) { // if (true) { var a : f32 = 2.0; } // a = 3.14; // } - ast::type::F32 f32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &f32, 2.0)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.f32, Expr(2.0f), + ast::VariableDecorationList{}); ast::type::Bool bool_type; - auto* cond = create( - Source{}, create(Source{}, &bool_type, true)); - auto* body = create( - Source{}, ast::StatementList{ - create(Source{}, var), - }); + auto* cond = Expr(true); + auto* body = create(ast::StatementList{ + create(var), + }); - auto* lhs = create( - Source{Source::Location{12, 34}}, mod()->RegisterSymbol("a"), "a"); - auto* rhs = create( - Source{}, create(Source{}, &f32, 3.14f)); + SetSource(Source{Source::Location{12, 34}}); + auto* lhs = Expr("a"); + auto* rhs = Expr(3.14f); - auto* outer_body = create( - Source{}, ast::StatementList{ - create(Source{}, cond, body, - ast::ElseStatementList{}), - create( - Source{Source::Location{12, 34}}, lhs, rhs), - }); + auto* outer_body = create(ast::StatementList{ + create(cond, body, ast::ElseStatementList{}), + create(Source{Source::Location{12, 34}}, lhs, + rhs), + }); EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error(); ASSERT_NE(lhs->result_type(), nullptr); @@ -456,38 +339,24 @@ TEST_F(ValidatorTest, UsingUndefinedVariableOuterScope_Pass) { // var a : f32 = 2.0; // if (true) { a = 3.14; } // } - ast::type::F32 f32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &f32, 2.0)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.f32, Expr(2.0f), + ast::VariableDecorationList{}); - auto* lhs = create( - Source{Source::Location{12, 34}}, mod()->RegisterSymbol("a"), "a"); - auto* rhs = create( - Source{}, create(Source{}, &f32, 3.14f)); + SetSource(Source{Source::Location{12, 34}}); + auto* lhs = Expr("a"); + auto* rhs = Expr(3.14f); ast::type::Bool bool_type; - auto* cond = create( - Source{}, create(Source{}, &bool_type, true)); - auto* body = create( - Source{}, ast::StatementList{ - create( - Source{Source::Location{12, 34}}, lhs, rhs), - }); + auto* cond = Expr(true); + auto* body = create(ast::StatementList{ + create(Source{Source::Location{12, 34}}, lhs, + rhs), + }); - auto* outer_body = create( - Source{}, ast::StatementList{ - create(Source{}, var), - create(Source{}, cond, body, - ast::ElseStatementList{}), - }); + auto* outer_body = create(ast::StatementList{ + create(var), + create(cond, body, ast::ElseStatementList{}), + }); EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error(); ASSERT_NE(lhs->result_type(), nullptr); @@ -498,66 +367,32 @@ TEST_F(ValidatorTest, UsingUndefinedVariableOuterScope_Pass) { TEST_F(ValidatorTest, GlobalVariableUnique_Pass) { // var global_var0 : f32 = 0.1; // var global_var1 : i32 = 0; - ast::type::F32 f32; - ast::type::I32 i32; - auto* var0 = create( - Source{}, // source - "global_var0", // name - ast::StorageClass::kPrivate, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &f32, 0.1)), // constructor - ast::VariableDecorationList{}); // decorations - mod()->AddGlobalVariable(var0); + auto* var0 = Var("global_var0", ast::StorageClass::kPrivate, ty.f32, + Expr(0.1f), ast::VariableDecorationList{}); + mod->AddGlobalVariable(var0); - auto* var1 = create( - Source{Source::Location{12, 34}}, // source - "global_var1", // name - ast::StorageClass::kPrivate, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &i32, 0)), // constructor - ast::VariableDecorationList{}); // decorations - mod()->AddGlobalVariable(var1); + auto* var1 = Var(Source{Source::Location{12, 34}}, "global_var1", + ast::StorageClass::kPrivate, ty.f32, Expr(0), + ast::VariableDecorationList{}); + mod->AddGlobalVariable(var1); - EXPECT_TRUE(v()->ValidateGlobalVariables(mod()->global_variables())) + EXPECT_TRUE(v()->ValidateGlobalVariables(mod->global_variables())) << v()->error(); } TEST_F(ValidatorTest, GlobalVariableNotUnique_Fail) { // var global_var : f32 = 0.1; // var global_var : i32 = 0; - ast::type::F32 f32; - ast::type::I32 i32; - auto* var0 = create( - Source{}, // source - "global_var", // name - ast::StorageClass::kPrivate, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &f32, 0.1)), // constructor - ast::VariableDecorationList{}); // decorations - mod()->AddGlobalVariable(var0); + auto* var0 = Var("global_var", ast::StorageClass::kPrivate, ty.f32, + Expr(0.1f), ast::VariableDecorationList{}); + mod->AddGlobalVariable(var0); - auto* var1 = create( - Source{Source::Location{12, 34}}, // source - "global_var", // name - ast::StorageClass::kPrivate, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &i32, 0)), // constructor - ast::VariableDecorationList{}); // decorations - mod()->AddGlobalVariable(var1); + auto* var1 = Var(Source{Source::Location{12, 34}}, "global_var", + ast::StorageClass::kPrivate, ty.i32, Expr(0), + ast::VariableDecorationList{}); + mod->AddGlobalVariable(var1); - EXPECT_FALSE(v()->ValidateGlobalVariables(mod()->global_variables())); + EXPECT_FALSE(v()->ValidateGlobalVariables(mod->global_variables())); EXPECT_EQ(v()->error(), "12:34 v-0011: redeclared global identifier 'global_var'"); } @@ -567,29 +402,17 @@ TEST_F(ValidatorTest, AssignToConstant_Fail) { // const a :i32 = 2; // a = 2 // } - ast::type::I32 i32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - true, // is_const - create( - Source{}, - create(Source{}, &i32, 2)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Const("a", ast::StorageClass::kNone, ty.i32, Expr(2), + ast::VariableDecorationList{}); - auto* lhs = create( - Source{}, mod()->RegisterSymbol("a"), "a"); - auto* rhs = create( - Source{}, create(Source{}, &i32, 2)); + auto* lhs = Expr("a"); + auto* rhs = Expr(2); - auto* body = create( - Source{}, ast::StatementList{ - create(Source{}, var), - create( - Source{Source::Location{12, 34}}, lhs, rhs), - }); + auto* body = create(ast::StatementList{ + create(var), + create(Source{Source::Location{12, 34}}, lhs, + rhs), + }); EXPECT_TRUE(td()->DetermineStatements(body)) << td()->error(); ASSERT_NE(lhs->result_type(), nullptr); @@ -606,46 +429,26 @@ TEST_F(ValidatorTest, GlobalVariableFunctionVariableNotUnique_Fail) { // return 0; // } - ast::type::Void void_type; - ast::type::F32 f32; - auto* global_var = create( - Source{}, // source - "a", // name - ast::StorageClass::kPrivate, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &f32, 2.1)), // constructor - ast::VariableDecorationList{}); // decorations - mod()->AddGlobalVariable(global_var); + auto* global_var = Var("a", ast::StorageClass::kPrivate, ty.f32, Expr(2.1f), + ast::VariableDecorationList{}); + mod->AddGlobalVariable(global_var); - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &f32, 2.0)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.f32, Expr(2.0f), + ast::VariableDecorationList{}); ast::VariableList params; - auto* body = create( - Source{}, ast::StatementList{ - create( - Source{Source::Location{12, 34}}, var), - }); + auto* body = create(ast::StatementList{ + create(Source{Source::Location{12, 34}}, var), + }); - auto* func = create(Source{}, mod()->RegisterSymbol("my_func"), - "my_func", params, &void_type, body, - ast::FunctionDecorationList{}); + auto* func = + create(mod->RegisterSymbol("my_func"), "my_func", params, + ty.void_, body, ast::FunctionDecorationList{}); - mod()->AddFunction(func); + mod->AddFunction(func); EXPECT_TRUE(td()->Determine()) << td()->error(); EXPECT_TRUE(td()->DetermineFunction(func)) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())) << v()->error(); + EXPECT_FALSE(v()->Validate(mod)) << v()->error(); EXPECT_EQ(v()->error(), "12:34 v-0013: redeclared identifier 'a'"); } @@ -654,48 +457,28 @@ TEST_F(ValidatorTest, RedeclaredIndentifier_Fail) { // var a :i32 = 2; // var a :f21 = 2.0; // } - ast::type::Void void_type; - ast::type::I32 i32; - ast::type::F32 f32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - false, // is_const - create( - Source{}, - create(Source{}, &i32, 2)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2), + ast::VariableDecorationList{}); - auto* var_a_float = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &f32, 0.1)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var_a_float = Var("a", ast::StorageClass::kNone, ty.f32, Expr(0.1f), + ast::VariableDecorationList{}); ast::VariableList params; - auto* body = create( - Source{}, ast::StatementList{ - create(Source{}, var), - create( - Source{Source::Location{12, 34}}, var_a_float), - }); + auto* body = create(ast::StatementList{ + create(var), + create(Source{Source::Location{12, 34}}, + var_a_float), + }); - auto* func = create(Source{}, mod()->RegisterSymbol("my_func"), - "my_func", params, &void_type, body, - ast::FunctionDecorationList{}); + auto* func = + create(mod->RegisterSymbol("my_func"), "my_func", params, + ty.void_, body, ast::FunctionDecorationList{}); - mod()->AddFunction(func); + mod->AddFunction(func); EXPECT_TRUE(td()->Determine()) << td()->error(); EXPECT_TRUE(td()->DetermineFunction(func)) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())); + EXPECT_FALSE(v()->Validate(mod)); EXPECT_EQ(v()->error(), "12:34 v-0014: redeclared identifier 'a'"); } @@ -704,44 +487,23 @@ TEST_F(ValidatorTest, RedeclaredIdentifierInnerScope_Pass) { // if (true) { var a : f32 = 2.0; } // var a : f32 = 3.14; // } - ast::type::F32 f32; - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &f32, 2.0)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.f32, Expr(2.0f), + ast::VariableDecorationList{}); ast::type::Bool bool_type; - auto* cond = create( - Source{}, create(Source{}, &bool_type, true)); - auto* body = create( - Source{}, ast::StatementList{ - create(Source{}, var), - }); + auto* cond = Expr(true); + auto* body = create(ast::StatementList{ + create(var), + }); - auto* var_a_float = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &f32, 3.14)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var_a_float = Var("a", ast::StorageClass::kNone, ty.f32, Expr(3.1f), + ast::VariableDecorationList{}); - auto* outer_body = create( - Source{}, ast::StatementList{ - create(Source{}, cond, body, - ast::ElseStatementList{}), - create( - Source{Source::Location{12, 34}}, var_a_float), - }); + auto* outer_body = create(ast::StatementList{ + create(cond, body, ast::ElseStatementList{}), + create(Source{Source::Location{12, 34}}, + var_a_float), + }); EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error(); EXPECT_TRUE(v()->ValidateStatements(outer_body)) << v()->error(); @@ -754,44 +516,22 @@ TEST_F(ValidatorTest, DISABLED_RedeclaredIdentifierInnerScope_False) { // var a : f32 = 3.14; // if (true) { var a : f32 = 2.0; } // } - ast::type::F32 f32; - auto* var_a_float = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &f32, 3.14)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var_a_float = Var("a", ast::StorageClass::kNone, ty.f32, Expr(3.1f), + ast::VariableDecorationList{}); - auto* var = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &f32, 2.0)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.f32, Expr(2.0f), + ast::VariableDecorationList{}); ast::type::Bool bool_type; - auto* cond = create( - Source{}, create(Source{}, &bool_type, true)); - auto* body = create( - Source{}, ast::StatementList{ - create( - Source{Source::Location{12, 34}}, var), - }); + auto* cond = Expr(true); + auto* body = create(ast::StatementList{ + create(Source{Source::Location{12, 34}}, var), + }); - auto* outer_body = create( - Source{}, ast::StatementList{ - create(Source{}, var_a_float), - create(Source{}, cond, body, - ast::ElseStatementList{}), - }); + auto* outer_body = create(ast::StatementList{ + create(var_a_float), + create(cond, body, ast::ElseStatementList{}), + }); EXPECT_TRUE(td()->DetermineStatements(outer_body)) << td()->error(); EXPECT_FALSE(v()->ValidateStatements(outer_body)); @@ -801,61 +541,40 @@ TEST_F(ValidatorTest, DISABLED_RedeclaredIdentifierInnerScope_False) { TEST_F(ValidatorTest, RedeclaredIdentifierDifferentFunctions_Pass) { // func0 { var a : f32 = 2.0; return; } // func1 { var a : f32 = 3.0; return; } - ast::type::F32 f32; - ast::type::Void void_type; - auto* var0 = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &f32, // type - false, // is_const - create( - Source{}, - create(Source{}, &f32, 2.0)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var0 = Var("a", ast::StorageClass::kNone, ty.f32, Expr(2.0f), + ast::VariableDecorationList{}); - auto* var1 = create( - Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &void_type, // type - false, // is_const - create( - Source{}, - create(Source{}, &f32, 1.0)), // constructor - ast::VariableDecorationList{}); // decorations + auto* var1 = Var("a", ast::StorageClass::kNone, ty.void_, Expr(1.0f), + ast::VariableDecorationList{}); ast::VariableList params0; - auto* body0 = create( - Source{}, ast::StatementList{ - create( - Source{Source::Location{12, 34}}, var0), - create(Source{}), - }); + auto* body0 = create(ast::StatementList{ + create(Source{Source::Location{12, 34}}, + var0), + create(), + }); - auto* func0 = create(Source{}, mod()->RegisterSymbol("func0"), - "func0", params0, &void_type, body0, - ast::FunctionDecorationList{}); + auto* func0 = + create(mod->RegisterSymbol("func0"), "func0", params0, + ty.void_, body0, ast::FunctionDecorationList{}); ast::VariableList params1; - auto* body1 = create( - Source{}, ast::StatementList{ - create( - Source{Source::Location{13, 34}}, var1), - create(Source{}), - }); + auto* body1 = create(ast::StatementList{ + create(Source{Source::Location{13, 34}}, + var1), + create(), + }); auto* func1 = create( - Source{}, mod()->RegisterSymbol("func1"), "func1", params1, &void_type, - body1, + mod->RegisterSymbol("func1"), "func1", params1, ty.void_, body1, ast::FunctionDecorationList{ - create(Source{}, ast::PipelineStage::kVertex), + create(ast::PipelineStage::kVertex), }); - mod()->AddFunction(func0); - mod()->AddFunction(func1); + mod->AddFunction(func0); + mod->AddFunction(func1); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_TRUE(v()->Validate(mod())) << v()->error(); + EXPECT_TRUE(v()->Validate(mod)) << v()->error(); } TEST_F(ValidatorTest, VariableDeclNoConstructor_Pass) { @@ -863,28 +582,18 @@ TEST_F(ValidatorTest, VariableDeclNoConstructor_Pass) { // var a :i32; // a = 2; // } - ast::type::I32 i32; - auto* var = - create(Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &i32, // type - false, // is_const - nullptr, // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.i32, nullptr, + ast::VariableDecorationList{}); td()->RegisterVariableForTesting(var); - auto* lhs = create( - Source{}, mod()->RegisterSymbol("a"), "a"); - auto* rhs = create( - Source{}, create(Source{}, &i32, 2)); + auto* lhs = Expr("a"); + auto* rhs = Expr(2); - auto* body = create( - Source{}, ast::StatementList{ - create(Source{}, var), - create( - Source{Source::Location{12, 34}}, lhs, rhs), - }); + auto* body = create(ast::StatementList{ + create(var), + create(Source{Source::Location{12, 34}}, lhs, + rhs), + }); EXPECT_TRUE(td()->DetermineStatements(body)) << td()->error(); ASSERT_NE(lhs->result_type(), nullptr); diff --git a/src/validator/validator_test_helper.cc b/src/validator/validator_test_helper.cc index eae9e961d0..656b6f69c8 100644 --- a/src/validator/validator_test_helper.cc +++ b/src/validator/validator_test_helper.cc @@ -19,7 +19,7 @@ namespace tint { ValidatorTestHelper::ValidatorTestHelper() { - td_ = std::make_unique(&mod_); + td_ = std::make_unique(mod); v_ = std::make_unique(); } diff --git a/src/validator/validator_test_helper.h b/src/validator/validator_test_helper.h index e5f3cfca14..bc15b32fb1 100644 --- a/src/validator/validator_test_helper.h +++ b/src/validator/validator_test_helper.h @@ -18,6 +18,7 @@ #include #include +#include "src/ast/builder.h" #include "src/ast/type/void_type.h" #include "src/type_determiner.h" #include "src/validator/validator_impl.h" @@ -25,11 +26,11 @@ namespace tint { /// A helper for testing validation -class ValidatorTestHelper { +class ValidatorTestHelper : public ast::BuilderWithModule { public: /// Constructor ValidatorTestHelper(); - ~ValidatorTestHelper(); + ~ValidatorTestHelper() override; /// A handle to validator /// @returns a pointer to the validator @@ -37,24 +38,10 @@ class ValidatorTestHelper { /// A handle to type_determiner /// @returns a pointer to the type_determiner object TypeDeterminer* td() const { return td_.get(); } - /// A handle to the created module - /// @return a pointer to the test module - ast::Module* mod() { return &mod_; } - - /// Creates a new `ast::Node` owned by the Module. When the Module is - /// destructed, the `ast::Node` will also be destructed. - /// @param args the arguments to pass to the type constructor - /// @returns the node pointer - template - T* create(ARGS&&... args) { - return mod_.create(std::forward(args)...); - } private: std::unique_ptr v_; - ast::Module mod_; std::unique_ptr td_; - ast::type::Void void_type_; }; } // namespace tint diff --git a/src/validator/validator_type_test.cc b/src/validator/validator_type_test.cc index 46aaa96f8d..aceeed0c35 100644 --- a/src/validator/validator_type_test.cc +++ b/src/validator/validator_type_test.cc @@ -42,25 +42,23 @@ TEST_F(ValidatorTypeTest, RuntimeArrayIsLast_Pass) { // rt: array; // }; - ast::type::F32 f32; - ast::type::Array arr(&f32, 0, ast::ArrayDecorationList{}); ast::StructMemberList members; { ast::StructMemberDecorationList deco; - members.push_back(create(Source{}, "vf", &f32, deco)); + members.push_back(create("vf", ty.f32, deco)); } { ast::StructMemberDecorationList deco; members.push_back(create( - Source{Source::Location{12, 34}}, "rt", &arr, deco)); + Source{Source::Location{12, 34}}, "rt", ty.array(), deco)); } ast::StructDecorationList decos; - decos.push_back(create(Source{})); - auto* st = create(Source{}, members, decos); - ast::type::Struct struct_type(mod()->RegisterSymbol("Foo"), "Foo", st); + decos.push_back(create()); + auto* st = create(members, decos); + ast::type::Struct struct_type(mod->RegisterSymbol("Foo"), "Foo", st); - mod()->AddConstructedType(&struct_type); - EXPECT_TRUE(v()->ValidateConstructedTypes(mod()->constructed_types())); + mod->AddConstructedType(&struct_type); + EXPECT_TRUE(v()->ValidateConstructedTypes(mod->constructed_types())); } TEST_F(ValidatorTypeTest, RuntimeArrayIsLastNoBlock_Fail) { @@ -69,24 +67,22 @@ TEST_F(ValidatorTypeTest, RuntimeArrayIsLastNoBlock_Fail) { // rt: array; // }; - ast::type::F32 f32; - ast::type::Array arr(&f32, 0, ast::ArrayDecorationList{}); ast::StructMemberList members; { ast::StructMemberDecorationList deco; - members.push_back(create(Source{}, "vf", &f32, deco)); + members.push_back(create("vf", ty.f32, deco)); } { ast::StructMemberDecorationList deco; members.push_back(create( - Source{Source::Location{12, 34}}, "rt", &arr, deco)); + Source{Source::Location{12, 34}}, "rt", ty.array(), deco)); } ast::StructDecorationList decos; - auto* st = create(Source{}, members, decos); - ast::type::Struct struct_type(mod()->RegisterSymbol("Foo"), "Foo", st); + auto* st = create(members, decos); + ast::type::Struct struct_type(mod->RegisterSymbol("Foo"), "Foo", st); - mod()->AddConstructedType(&struct_type); - EXPECT_FALSE(v()->ValidateConstructedTypes(mod()->constructed_types())); + 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 " "in the 'storage' storage class: 'Foo'"); @@ -99,25 +95,23 @@ TEST_F(ValidatorTypeTest, RuntimeArrayIsNotLast_Fail) { // vf: f32; // }; - ast::type::F32 f32; - ast::type::Array arr(&f32, 0, ast::ArrayDecorationList{}); ast::StructMemberList members; { ast::StructMemberDecorationList deco; members.push_back(create( - Source{Source::Location{12, 34}}, "rt", &arr, deco)); + Source{Source::Location{12, 34}}, "rt", ty.array(), deco)); } { ast::StructMemberDecorationList deco; - members.push_back(create(Source{}, "vf", &f32, deco)); + members.push_back(create("vf", ty.f32, deco)); } ast::StructDecorationList decos; - decos.push_back(create(Source{})); - auto* st = create(Source{}, members, decos); - ast::type::Struct struct_type(mod()->RegisterSymbol("Foo"), "Foo", st); + decos.push_back(create()); + auto* st = create(members, decos); + ast::type::Struct struct_type(mod->RegisterSymbol("Foo"), "Foo", st); - mod()->AddConstructedType(&struct_type); - EXPECT_FALSE(v()->ValidateConstructedTypes(mod()->constructed_types())); + 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 " "of a struct: 'rt'"); @@ -131,9 +125,8 @@ TEST_F(ValidatorTypeTest, AliasRuntimeArrayIsNotLast_Fail) { // a: u32; //} - ast::type::F32 u32; - ast::type::Array array(&u32, 0, ast::ArrayDecorationList{}); - ast::type::Alias alias{mod()->RegisterSymbol("RTArr"), "RTArr", &array}; + ast::type::Alias alias{mod->RegisterSymbol("RTArr"), "RTArr", + ty.array()}; ast::StructMemberList members; { @@ -143,15 +136,15 @@ TEST_F(ValidatorTypeTest, AliasRuntimeArrayIsNotLast_Fail) { } { ast::StructMemberDecorationList deco; - members.push_back(create(Source{}, "a", &u32, deco)); + members.push_back(create("a", ty.u32, deco)); } ast::StructDecorationList decos; - decos.push_back(create(Source{})); - auto* st = create(Source{}, members, decos); - ast::type::Struct struct_type(mod()->RegisterSymbol("s"), "s", st); - mod()->AddConstructedType(&struct_type); - EXPECT_FALSE(v()->ValidateConstructedTypes(mod()->constructed_types())); + decos.push_back(create()); + auto* st = create(members, decos); + ast::type::Struct struct_type(mod->RegisterSymbol("s"), "s", st); + 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 " "of a struct: 'b'"); @@ -165,14 +158,13 @@ TEST_F(ValidatorTypeTest, AliasRuntimeArrayIsLast_Pass) { // b: RTArr; //} - ast::type::F32 u32; - ast::type::Array array(&u32, 0, ast::ArrayDecorationList{}); - ast::type::Alias alias{mod()->RegisterSymbol("RTArr"), "RTArr", &array}; + ast::type::Alias alias{mod->RegisterSymbol("RTArr"), "RTArr", + ty.array()}; ast::StructMemberList members; { ast::StructMemberDecorationList deco; - members.push_back(create(Source{}, "a", &u32, deco)); + members.push_back(create("a", ty.u32, deco)); } { ast::StructMemberDecorationList deco; @@ -180,43 +172,31 @@ TEST_F(ValidatorTypeTest, AliasRuntimeArrayIsLast_Pass) { Source{Source::Location{12, 34}}, "b", &alias, deco)); } ast::StructDecorationList decos; - decos.push_back(create(Source{})); - auto* st = create(Source{}, members, decos); - ast::type::Struct struct_type(mod()->RegisterSymbol("s"), "s", st); - mod()->AddConstructedType(&struct_type); - EXPECT_TRUE(v()->ValidateConstructedTypes(mod()->constructed_types())); + decos.push_back(create()); + auto* st = create(members, decos); + ast::type::Struct struct_type(mod->RegisterSymbol("s"), "s", st); + mod->AddConstructedType(&struct_type); + EXPECT_TRUE(v()->ValidateConstructedTypes(mod->constructed_types())); } TEST_F(ValidatorTypeTest, RuntimeArrayInFunction_Fail) { /// [[stage(vertex)]] // fn func -> void { var a : array; } - ast::type::I32 i32; - ast::type::Array array(&i32, 0, ast::ArrayDecorationList{}); - auto* var = - create(Source{}, // source - "a", // name - ast::StorageClass::kNone, // storage_class - &array, // type - false, // is_const - nullptr, // constructor - ast::VariableDecorationList{}); // decorations + auto* var = Var("a", ast::StorageClass::kNone, ty.array()); ast::VariableList params; - ast::type::Void void_type; - auto* body = create( - Source{}, ast::StatementList{ - create( - Source{Source::Location{12, 34}}, var), - }); + auto* body = create(ast::StatementList{ + create(Source{Source::Location{12, 34}}, var), + }); auto* func = create( - Source{}, mod()->RegisterSymbol("func"), "func", params, &void_type, body, + mod->RegisterSymbol("func"), "func", params, ty.void_, body, ast::FunctionDecorationList{ - create(Source{}, ast::PipelineStage::kVertex), + create(ast::PipelineStage::kVertex), }); - mod()->AddFunction(func); + mod->AddFunction(func); EXPECT_TRUE(td()->Determine()) << td()->error(); - EXPECT_FALSE(v()->Validate(mod())); + EXPECT_FALSE(v()->Validate(mod)); EXPECT_EQ(v()->error(), "12:34 v-0015: runtime arrays may only appear as the last member " "of a struct: 'a'");